Compare commits

...
36 Commits
Author SHA1 Message Date
embeddedt ae21012ea2 Use a proper key implementation for the search cache (#254)
* Use a proper key implementation for the search cache
* Synchronize itemSearchNames accesses to prevent CMEs
* Use a ConcurrentHashMap instead of synchronizing
  This allows multiple threads to read at the same time, which is the more common scenario.
2022-05-29 12:25:39 -07:00
miozune 2b31129ef9 Use OverlayIdentifier for GT4 2022-05-29 11:32:49 -07:00
Raven Szewczyk ba77a63545 Make sure to use utf-8 for bookmark reading as well as writing (#253) 2022-05-27 19:38:54 +02:00
embeddedt 8f7d698e7d Add option to cache item grid rendering (#250)
* Add option to cache item grid rendering

* Fix highlighting for bookmarks

* Tweak GL state slightly

* Fix focus box being in the wrong place

* Fix flickering for one frame when searching

* Prevent potion effects from rendering over NEI slots

Fixes #231

* Invalidate the buffer if `invalidSlotMap` changes

* Clean up imports

* Delay blitting until after the buffer is refreshed

but still avoid waiting for the next frame

* Refactor slot focus logic to handle highlighting multiple slots

* Refresh grid when sorting bookmarks

* Minor code cleanup, fix some more hovering issues

* Remove `slotNeedsOutline`, it is now redundant

* Remove focus parameter from drawItem
2022-05-27 13:42:41 +02:00
glowredman 72d44fd711 Fix AppleCore's reflection
AppleCore accesses `getStackMouseOver` via reflection but it has been moved to the `PanelWidget` class -> the reflection fails
2022-05-16 10:40:12 -07:00
MuXiu1997 d735cc2a38 Use shortcut key to trigger overlay recipe (#248)
* Use shortcut key to trigger overlay recipe

* Add a way to remove overlay renderer

* Change of implementation

* Fix crash
2022-05-16 17:57:00 +02:00
slprimeandSerghei Borovetchi 91e9b2a5ae Panel settings (#240)
* panel settings

* Highlight hidden items; mark item with recipe

* open gui usage with recipeId

* small  changes

* restore gl after draw item

Co-authored-by: Serghei Borovetchi <[email protected]>
2022-05-06 21:41:45 +02:00
miozune 96e4fe55e8 Send chat to player when recipe loading was errored (#241) 2022-05-03 20:42:09 +02:00
miozune 8717df0cbb Fix scrolling recipes when hovering over ingredients changes stack size (#237) 2022-04-28 15:46:01 +02:00
miozune d6a6551561 Allow GuiRecipe to back to general GuiScreen (#236) 2022-04-25 15:31:50 +02:00
Jason Mitchell 995ed24056 Fix catalysts for gt6 2022-04-20 08:19:47 -07:00
Kiwiand[Kiwi233] 2917f2a4c9 Update zh_CN.lang (#235)
* Update zh_CN.lang

* Update zh_CN.lang

* Update zh_CN.lang

* Update zh_CN.lang

* Update zh_CN.lang

Co-authored-by: [Kiwi233] <[[email protected]]>
2022-04-14 20:04:31 +02:00
NoXъ 5b2ff42d4f typo correction, russification (#234) 2022-04-09 18:11:15 +02:00
miozune 6f2782b06e Add way to register catalysts via IMC (#232) 2022-04-08 21:15:24 +02:00
Glease f17bf6e8e2 fix weird cme (#230) 2022-03-12 15:03:44 +01:00
Glease 10ee4d17ef super unlikely NPE fix (#229) 2022-03-12 12:22:17 +01:00
miozune f6acd768f3 Fix not being able to scroll recipes when hovering over ingredients (#228) 2022-03-05 11:05:26 +01:00
miozune 8a5146b672 Workaround for issue where GT++ registers Chemical Plant handler twice 2022-03-03 08:23:55 -08:00
miozune 1632a90d15 Add support for Natura and Campfire Backport (#226) 2022-03-01 11:28:25 +01:00
miozune 269b16a8de Remove uncraftable catalysts 2022-02-17 18:45:51 -08:00
Serghei Borovetchi 1e93f719fe visibility fix 2022-02-17 18:45:26 -08:00
bombcar db6e3d33ca clean up repos 2022-02-11 08:12:11 -08:00
bombcar 991a6dc772 update buildscript, fix mcmod info not displaying 2022-02-11 08:12:11 -08:00
Serghei Borovetchi 5f1ed67a8b create presets module 2022-02-10 08:43:16 -08:00
miozune 49b22e0683 Add more util function 2022-02-10 08:38:02 -08:00
Kiwiand[Kiwi233] 00dacef241 Update zh_CN.lang (#213)
* Update zh_CN.lang

* Update zh_CN.lang

* Update zh_CN.lang

* Update zh_CN.lang

Co-authored-by: [Kiwi233] <[[email protected]]>
2022-02-07 21:42:39 +01:00
miozune c4da6706a5 Move fuel info from tooltip to foreground 2022-02-07 12:39:24 -08:00
Oleg Ivanov f588543b64 Add new chunk overlay mode for gregtech ore regions (#211)
* Add new chunk overlay mode for gregtech ore regions
* Change GregTech existence check to GregTech 5 only
* Add GT-like region shift on negative coords
2022-02-07 12:18:02 -08:00
Socolio f006a93dd5 Add mob overlay cache, optimize mob overlay spawn check 2022-02-07 12:14:26 -08:00
miozune 6609911d96 Add a way to compare NBT leniently (#209)
* Fix itemstack comparator not handling NBT leniently
* add util function to PositionedStack
2022-02-07 12:12:26 -08:00
bombcar 3291dab52d LGPL-3.0 2022-02-07 12:10:36 -08:00
bombcar b31de63fe6 buildscript 2022-02-07 12:10:36 -08:00
bombcar 0cfc3301f6 fix mcmod.info 2022-02-07 12:10:36 -08:00
Mikhail Golikov 837411aa41 Ignore "drop key" presses in slot click handler. 2022-02-01 02:55:14 +09:00
YannickMG ee3d685a14 Code & Javadoc cleanup 2022-01-30 17:48:14 -08:00
YannickMG 47951372cb Made handler tab names customizable
Allow Recipe Handlers to have a different tab name than what's displayed on top of the UI.
2022-01-30 17:48:14 -08:00
61 changed files with 4301 additions and 2246 deletions

No files matched your search

-674
View File
@@ -1,674 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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 <https://www.gnu.org/licenses/>.
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:
<program> Copyright (C) <year> <name of author>
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
<https://www.gnu.org/licenses/>.
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
<https://www.gnu.org/licenses/why-not-lgpl.html>.1996
-165
View File
@@ -1,165 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
+149 -44
View File
@@ -1,60 +1,165 @@
GTNH Modifications:
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (c) 2019 mitchej123
GNU LESSER GENERAL PUBLIC LICENSE - See COPYING & COPYING.LESSER
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
-----------------------------------------------------------------------------
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
Parts inspired/borrowed/backported from JEI under the MIT License:
0. Additional Definitions.
https://github.com/mezz/JustEnoughItems/tree/1.12
The MIT License (MIT)
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
Copyright (c) 2014-2015 mezz
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
-----------------------------------------------------------------------------
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
Base NEI License:
1. Exception to Section 3 of the GNU GPL.
The MIT License (MIT)
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
Copyright (c) 2014 ChickenBones
2. Conveying Modified Versions.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
+12 -5
View File
@@ -2,11 +2,9 @@
A continuation of NotEnoughItems for 1.7.10 by the developers of Gregtech: New Horizons modpack, with features either inspired and/or backported from JustEnoughItems
We've tested this against all of the mods included in GTNH, as well as a limited set of other mods (like Reika's mods). Every effort has been made to maintain backwards compatibility, however the focus is on the mods contained in the GTNH modpack.
We've tested this against all of the mods included in GTNH, as well as a limited set of other mods (like Reika's mods). Every effort has been made to maintain backwards compatibility, however the focus is on the mods contained in the GTNH modpack.
If you have issues with NEI outside of the GTNH modpack you may report them in the [GTNH NEI GitHub](https://github.com/GTNewHorizons/NotEnoughItems).
## New Features:
@@ -26,6 +24,15 @@ We've tested this against all of the mods included in GTNH, as well as a limited
## Other items of note:
* Licensed under LGPL - Use this however you want, but please give back any modifications
* Remove TMI style
* Removed inventory Load/Save state
## License
GTNH Modifications Copyright (c) 2019-2022 mitchej123 and the GTNH Team
Licensed under LGPL-3.0 or later - use this however you want, but please give back any modifications
Parts inspired/borrowed/backported from [JEI](https://github.com/mezz/JustEnoughItems/tree/1.12) under the MIT License.
Originial code Copyright (c) 2014-2015 mezz and was licensed under the MIT License.
+3
View File
@@ -0,0 +1,3 @@
compileJava {
options.encoding = "UTF-8"
}
+202 -107
View File
@@ -1,52 +1,65 @@
//version: 1642872913
//version: 1652851397
/*
DO NOT CHANGE THIS FILE!
Also, you may replace this file at any time if there is an update available.
Please check https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/main/build.gradle for updates.
*/
*/
import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.internal.logging.text.StyledTextOutput.Style
import org.gradle.internal.logging.text.StyledTextOutputFactory
import java.util.concurrent.TimeUnit
buildscript {
repositories {
maven {
name = "forge"
url = "https://maven.minecraftforge.net"
name 'forge'
url 'https://maven.minecraftforge.net'
}
maven {
name = "sonatype"
url = "https://oss.sonatype.org/content/repositories/snapshots/"
name 'sonatype'
url 'https://oss.sonatype.org/content/repositories/snapshots/'
}
maven {
name = "Scala CI dependencies"
url = "https://repo1.maven.org/maven2/"
name 'Scala CI dependencies'
url 'https://repo1.maven.org/maven2/'
}
maven {
name = "jitpack"
url = "https://jitpack.io"
name 'jitpack'
url 'https://jitpack.io'
}
}
dependencies {
classpath 'com.github.GTNewHorizons:ForgeGradle:1.2.5'
classpath 'com.github.GTNewHorizons:ForgeGradle:1.2.7'
}
}
plugins {
id 'java-library'
id 'idea'
id 'eclipse'
id 'scala'
id("org.ajoberstar.grgit") version("3.1.1")
id("com.github.johnrengelman.shadow") version("4.0.4")
id("com.palantir.git-version") version("0.12.3")
id('de.undercouch.download') version('4.1.2')
id("maven-publish")
id 'maven-publish'
id 'org.jetbrains.kotlin.jvm' version '1.5.30' apply false
id 'org.jetbrains.kotlin.kapt' version '1.5.30' apply false
id 'com.google.devtools.ksp' version '1.5.30-1.0.0' apply false
id 'org.ajoberstar.grgit' version '4.1.1'
id 'com.github.johnrengelman.shadow' version '4.0.4'
id 'com.palantir.git-version' version '0.13.0' apply false
id 'de.undercouch.download' version '5.0.1'
id 'com.github.gmazzo.buildconfig' version '3.0.3' apply false
}
if (project.file('.git/HEAD').isFile()) {
apply plugin: 'com.palantir.git-version'
}
def out = services.get(StyledTextOutputFactory).create('an-output')
apply plugin: 'forge'
def projectJavaVersion = JavaLanguageVersion.of(8)
@@ -91,27 +104,31 @@ checkPropertyExists("usesShadowedDependencies")
checkPropertyExists("developmentEnvironmentUserName")
boolean noPublishedSources = project.findProperty("noPublishedSources") ? project.noPublishedSources.toBoolean() : false
boolean usesMixinDebug = project.findProperty('usesMixinDebug') ?: project.usesMixins.toBoolean()
String javaSourceDir = "src/main/java/"
String scalaSourceDir = "src/main/scala/"
String kotlinSourceDir = "src/main/kotlin/"
String targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/")
String targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/")
if((getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists()) == false) {
throw new GradleException("Could not resolve \"modGroup\"! Could not find " + targetPackageJava + " or " + targetPackageScala)
String targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/")
if(!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) {
throw new GradleException("Could not resolve \"modGroup\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin)
}
if(apiPackage) {
targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
if((getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists()) == false) {
throw new GradleException("Could not resolve \"apiPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala)
targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
if(!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) {
throw new GradleException("Could not resolve \"apiPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin)
}
}
if(accessTransformersFile) {
String targetFile = "src/main/resources/META-INF/" + accessTransformersFile
if(getFile(targetFile).exists() == false) {
if(!getFile(targetFile).exists()) {
throw new GradleException("Could not resolve \"accessTransformersFile\"! Could not find " + targetFile)
}
}
@@ -123,15 +140,17 @@ if(usesMixins.toBoolean()) {
targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
if((getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists()) == false) {
throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala)
targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
if(!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) {
throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin)
}
String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java"
String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".scala"
String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java"
if((getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists()) == false) {
throw new GradleException("Could not resolve \"mixinPlugin\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava)
String targetFileKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".kt"
if(!(getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists() || getFile(targetFileKotlin).exists())) {
throw new GradleException("Could not resolve \"mixinPlugin\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava + " or " + targetFileKotlin)
}
}
@@ -139,8 +158,9 @@ if(coreModClass) {
String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java"
String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".scala"
String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java"
if((getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists()) == false) {
throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava)
String targetFileKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".kt"
if(!(getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists() || getFile(targetFileKotlin).exists())) {
throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava + " or " + targetFileKotlin)
}
}
@@ -153,17 +173,35 @@ configurations.all {
}
// Fix Jenkins' Git: chmod a file should not be detected as a change and append a '.dirty' to the version
'git config core.fileMode false'.execute()
try {
'git config core.fileMode false'.execute()
}
catch (Exception ignored) {
out.style(Style.Failure).println("git isn't installed at all")
}
// Pulls version first from the VERSION env and then git tag
String identifiedVersion
String versionOverride = System.getenv("VERSION") ?: null
try {
String versionOverride = System.getenv("VERSION") ?: null
identifiedVersion = versionOverride == null ? gitVersion() : versionOverride
version = minecraftVersion + "-" + identifiedVersion
}
catch (Exception e) {
throw new IllegalStateException("This mod must be version controlled by Git AND the repository must provide at least one tag, or the VERSION override must be set!");
catch (Exception ignored) {
out.style(Style.Failure).text(
'This mod must be version controlled by Git AND the repository must provide at least one tag,\n' +
'or the VERSION override must be set! ').style(Style.SuccessHeader).text('(Do NOT download from GitHub using the ZIP option, instead\n' +
'clone the repository, see ').style(Style.Info).text('https://gtnh.miraheze.org/wiki/Development').style(Style.SuccessHeader).println(' for details.)'
)
versionOverride = 'NO-GIT-TAG-SET'
identifiedVersion = versionOverride
}
version = minecraftVersion + '-' + identifiedVersion
ext {
modVersion = identifiedVersion
}
if(identifiedVersion == versionOverride) {
out.style(Style.Failure).text('Override version to ').style(Style.Identifier).text(modVersion).style(Style.Failure).println('!\7')
}
group = modGroup
@@ -174,9 +212,25 @@ else {
archivesBaseName = modId
}
def arguments = []
def jvmArguments = []
if (usesMixins.toBoolean()) {
arguments += [
"--tweakClass org.spongepowered.asm.launch.MixinTweaker"
]
if (usesMixinDebug.toBoolean()) {
jvmArguments += [
"-Dmixin.debug.countInjections=true",
"-Dmixin.debug.verbose=true",
"-Dmixin.debug.export=true"
]
}
}
minecraft {
version = minecraftVersion + "-" + forgeVersion + "-" + minecraftVersion
runDir = "run"
version = minecraftVersion + '-' + forgeVersion + '-' + minecraftVersion
runDir = 'run'
if (replaceGradleTokenInFile) {
replaceIn replaceGradleTokenInFile
@@ -187,16 +241,30 @@ minecraft {
replace gradleTokenModName, modName
}
if(gradleTokenVersion) {
replace gradleTokenVersion, versionDetails().lastTag
replace gradleTokenVersion, modVersion
}
if(gradleTokenGroupName) {
replace gradleTokenGroupName, modGroup
}
}
clientIntellijRun {
args(arguments)
jvmArgs(jvmArguments)
if(developmentEnvironmentUserName) {
args("--username", developmentEnvironmentUserName)
}
}
serverIntellijRun {
args(arguments)
jvmArgs(jvmArguments)
}
}
if(file("addon.gradle").exists()) {
apply from: "addon.gradle"
if(file('addon.gradle').exists()) {
apply from: 'addon.gradle'
}
apply from: 'repositories.gradle'
@@ -209,58 +277,63 @@ configurations {
repositories {
maven {
name = "Overmind forge repo mirror"
url = "https://gregtech.overminddl1.com/"
name 'Overmind forge repo mirror'
url 'https://gregtech.overminddl1.com/'
}
if(usesMixins.toBoolean()) {
maven {
name = "sponge"
url = "https://repo.spongepowered.org/repository/maven-public"
name 'sponge'
url 'https://repo.spongepowered.org/repository/maven-public'
}
maven {
url = "https://jitpack.io"
url 'https://jitpack.io'
}
}
}
dependencies {
if(usesMixins.toBoolean()) {
annotationProcessor("org.ow2.asm:asm-debug-all:5.0.3")
annotationProcessor("com.google.guava:guava:24.1.1-jre")
annotationProcessor("com.google.code.gson:gson:2.8.6")
annotationProcessor("org.spongepowered:mixin:0.8-SNAPSHOT")
annotationProcessor('org.ow2.asm:asm-debug-all:5.0.3')
annotationProcessor('com.google.guava:guava:24.1.1-jre')
annotationProcessor('com.google.code.gson:gson:2.8.6')
annotationProcessor('org.spongepowered:mixin:0.8-SNAPSHOT')
// using 0.8 to workaround a issue in 0.7 which fails mixin application
compile("com.github.GTNewHorizons:SpongePoweredMixin:0.7.12-GTNH") {
compile('com.github.GTNewHorizons:SpongePoweredMixin:0.7.12-GTNH') {
// Mixin includes a lot of dependencies that are too up-to-date
exclude module: "launchwrapper"
exclude module: "guava"
exclude module: "gson"
exclude module: "commons-io"
exclude module: "log4j-core"
exclude module: 'launchwrapper'
exclude module: 'guava'
exclude module: 'gson'
exclude module: 'commons-io'
exclude module: 'log4j-core'
}
compile("com.github.GTNewHorizons:SpongeMixins:1.5.0")
compile('com.github.GTNewHorizons:SpongeMixins:1.5.0')
}
}
apply from: 'dependencies.gradle'
def mixingConfigRefMap = "mixins." + modId + ".refmap.json"
def mixingConfigRefMap = 'mixins.' + modId + '.refmap.json'
def refMap = "${tasks.compileJava.temporaryDir}" + File.separator + mixingConfigRefMap
def mixinSrg = "${tasks.reobf.temporaryDir}" + File.separator + "mixins.srg"
task generateAssets {
if(usesMixins.toBoolean()) {
getFile("/src/main/resources/mixins." + modId + ".json").text = """{
if (usesMixins.toBoolean()) {
def mixinConfigFile = getFile("/src/main/resources/mixins." + modId + ".json");
if (!mixinConfigFile.exists()) {
mixinConfigFile.text = """{
"required": true,
"minVersion": "0.7.11",
"package": "${modGroup}.${mixinsPackage}",
"plugin": "${modGroup}.${mixinPlugin}",
"refmap": "${mixingConfigRefMap}",
"target": "@env(DEFAULT)",
"compatibilityLevel": "JAVA_8"
"compatibilityLevel": "JAVA_8",
"mixins": [],
"client": [],
"server": []
}
"""
}
}
}
@@ -324,15 +397,6 @@ afterEvaluate {
}
runClient {
def arguments = []
if(usesMixins.toBoolean()) {
arguments += [
"--mods=../build/libs/$modId-${version}.jar",
"--tweakClass org.spongepowered.asm.launch.MixinTweaker"
]
}
if(developmentEnvironmentUserName) {
arguments += [
"--username",
@@ -341,19 +405,12 @@ runClient {
}
args(arguments)
jvmArgs(jvmArguments)
}
runServer {
def arguments = []
if (usesMixins.toBoolean()) {
arguments += [
"--mods=../build/libs/$modId-${version}.jar",
"--tweakClass org.spongepowered.asm.launch.MixinTweaker"
]
}
args(arguments)
jvmArgs(jvmArguments)
}
tasks.withType(JavaExec).configureEach {
@@ -364,8 +421,7 @@ tasks.withType(JavaExec).configureEach {
)
}
processResources
{
processResources {
// this will ensure that this task is redone when the versions change.
inputs.property "version", project.version
inputs.property "mcversion", project.minecraft.version
@@ -374,18 +430,18 @@ processResources
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
// replace version and mcversion
// replace modVersion and minecraftVersion
expand "minecraftVersion": project.minecraft.version,
"modVersion": versionDetails().lastTag,
"modId": modId,
"modName": modName
"modVersion": modVersion,
"modId": modId,
"modName": modName
}
if(usesMixins.toBoolean()) {
from refMap
}
// copy everything else, thats not the mcmod.info
// copy everything else that's not the mcmod.info
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
}
@@ -393,7 +449,7 @@ processResources
def getManifestAttributes() {
def manifestAttributes = [:]
if(containsMixinsAndOrCoreModOnly.toBoolean() == false && (usesMixins.toBoolean() || coreModClass)) {
if(!containsMixinsAndOrCoreModOnly.toBoolean() && (usesMixins.toBoolean() || coreModClass)) {
manifestAttributes += ["FMLCorePluginContainsFMLMod": true]
}
@@ -409,14 +465,14 @@ def getManifestAttributes() {
manifestAttributes += [
"TweakClass" : "org.spongepowered.asm.launch.MixinTweaker",
"MixinConfigs" : "mixins." + modId + ".json",
"ForceLoadAsMod" : containsMixinsAndOrCoreModOnly.toBoolean() == false
"ForceLoadAsMod" : !containsMixinsAndOrCoreModOnly.toBoolean()
]
}
return manifestAttributes
}
task sourcesJar(type: Jar) {
from (sourceSets.main.allJava)
from (sourceSets.main.allSource)
from (file("$projectDir/LICENSE"))
getArchiveClassifier().set('sources')
}
@@ -471,7 +527,7 @@ task devJar(type: Jar) {
}
task apiJar(type: Jar) {
from (sourceSets.main.allJava) {
from (sourceSets.main.allSource) {
include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**'
}
@@ -496,14 +552,15 @@ artifacts {
}
}
// The gradle metadata includes all of the additional deps that we disabled from POM generation (including forgeBin with no groupID),
// The gradle metadata includes all of the additional deps that we disabled from POM generation (including forgeBin with no groupID),
// and isn't strictly needed with the POM so just disable it.
tasks.withType(GenerateModuleMetadata) {
enabled = false
}
// workaround variable hiding in pom processing
def projectConfigs = project.configurations
// publishing
publishing {
publications {
maven(MavenPublication) {
@@ -512,7 +569,7 @@ publishing {
artifact source: shadowJar, classifier: ""
}
if(!noPublishedSources) {
artifact source: sourcesJar, classifier: "src"
artifact source: sourcesJar, classifier: "sources"
}
artifact source: usesShadowedDependencies.toBoolean() ? shadowDevJar : devJar, classifier: "dev"
if (apiPackage) {
@@ -523,14 +580,21 @@ publishing {
artifactId = System.getenv("ARTIFACT_ID") ?: project.name
// Using the identified version, not project.version as it has the prepended 1.7.10
version = System.getenv("RELEASE_VERSION") ?: identifiedVersion
// Remove all non GTNH deps here.
// Original intention was to remove an invalid forgeBin being generated without a groupId (mandatory), but
// it also removes all of the MC deps
// remove extra garbage from minecraft and minecraftDeps configuration
pom.withXml {
def badArtifacts = [:].withDefault {[] as Set<String>}
for (configuration in [projectConfigs.minecraft, projectConfigs.minecraftDeps]) {
for (dependency in configuration.allDependencies) {
badArtifacts[dependency.group == null ? "" : dependency.group] += dependency.name
}
}
// example for specifying extra stuff to ignore
// badArtifacts["org.example.group"] += "artifactName"
Node pomNode = asNode()
pomNode.dependencies.'*'.findAll() {
it.groupId.text() != 'com.github.GTNewHorizons'
badArtifacts[it.groupId.text()].contains(it.artifactId.text())
}.each() {
it.parent().remove(it)
}
@@ -562,7 +626,7 @@ if (isNewBuildScriptVersionAvailable(projectDir.toString())) {
if (autoUpdateBuildScript.toBoolean()) {
performBuildScriptUpdate(projectDir.toString())
} else {
println("Build script update available! Run 'gradle updateBuildScript'")
out.style(Style.SuccessHeader).println("Build script update available! Run 'gradle updateBuildScript'")
}
}
@@ -574,7 +638,7 @@ boolean performBuildScriptUpdate(String projectDir) {
if (isNewBuildScriptVersionAvailable(projectDir)) {
def buildscriptFile = getFile("build.gradle")
availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } }
print("Build script updated. Please REIMPORT the project or RESTART your IDE!")
out.style(Style.Success).print("Build script updated. Please REIMPORT the project or RESTART your IDE!")
return true
}
return false
@@ -607,43 +671,74 @@ configure(updateBuildScript) {
// Deobfuscation
def deobf(String sourceURL) {
try {
URL url = new URL(sourceURL)
String fileName = url.getFile()
//get rid of directories:
int lastSlash = fileName.lastIndexOf("/")
if(lastSlash > 0) {
fileName = fileName.substring(lastSlash + 1)
}
//get rid of extension:
if(fileName.endsWith(".jar")) {
fileName = fileName.substring(0, fileName.lastIndexOf("."))
}
String hostName = url.getHost()
if(hostName.startsWith("www.")) {
hostName = hostName.substring(4)
}
List parts = Arrays.asList(hostName.split("\\."))
Collections.reverse(parts)
hostName = String.join(".", parts)
return deobf(sourceURL, hostName + "/" + fileName)
} catch(Exception e) {
return deobf(sourceURL, "deobf/" + String.valueOf(sourceURL.hashCode()))
}
}
// The method above is to be preferred. Use this method if the filename is not at the end of the URL.
def deobf(String sourceURL, String fileName) {
def bon2File = "$projectDir/deobf/BON2-2.5.0.jar"
def cacheFile = "$projectDir/deobf/out/" + fileName + ".jar"
def deobfFile = "$projectDir/deobf/out/" + fileName + "-deobf.jar"
String cacheDir = System.getProperty("user.home") + "/.gradle/caches/"
String bon2Dir = cacheDir + "forge_gradle/deobf"
String bon2File = bon2Dir + "/BON2-2.5.0.jar"
String obfFile = cacheDir + "modules-2/files-2.1/" + fileName + ".jar"
String deobfFile = cacheDir + "modules-2/files-2.1/" + fileName + "-deobf.jar"
if(file(deobfFile).exists()) {
return files(deobfFile)
}
download {
download.run {
src 'https://github.com/GTNewHorizons/BON2/releases/download/2.5.0/BON2-2.5.0.CUSTOM-all.jar'
dest bon2File
quiet true
overwrite false
}
download {
download.run {
src sourceURL
dest cacheFile
dest obfFile
quiet true
overwrite false
}
exec {
commandLine 'java', '-jar', bon2File, '--inputJar', cacheFile, '--outputJar', deobfFile, '--mcVer', '1.7.10', '--mappingsVer', 'stable_12', '--notch'
workingDir "$projectDir/deobf"
commandLine 'java', '-jar', bon2File, '--inputJar', obfFile, '--outputJar', deobfFile, '--mcVer', '1.7.10', '--mappingsVer', 'stable_12', '--notch'
workingDir bon2Dir
standardOutput = new ByteArrayOutputStream()
}
delete(cacheFile)
return files(deobfFile)
}
// Helper methods
def checkPropertyExists(String propertyName) {
if (project.hasProperty(propertyName) == false) {
if (!project.hasProperty(propertyName)) {
throw new GradleException("This project requires a property \"" + propertyName + "\"! Please add it your \"gradle.properties\". You can find all properties and their description here: https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/main/gradle.properties")
}
}
+3 -3
View File
@@ -1,7 +1,7 @@
// Add your dependencies here
dependencies {
compile("com.github.GTNewHorizons:CodeChickenLib:1.1.5.1:dev")
compile("com.github.GTNewHorizons:CodeChickenCore:1.1.3:dev")
shadowImplementation("org.apache.commons:commons-csv:1.5")
compile('com.github.GTNewHorizons:CodeChickenLib:1.1.5.3:dev')
compile('com.github.GTNewHorizons:CodeChickenCore:1.1.3:dev')
shadowImplementation('org.apache.commons:commons-csv:1.8')
}
+6 -6
View File
@@ -15,15 +15,15 @@ autoUpdateBuildScript = false
minecraftVersion = 1.7.10
forgeVersion = 10.13.4.1614
# Select a username for testing your mod with breakpoints. You may leave this empty for a random user name each time you
# Select a username for testing your mod with breakpoints. You may leave this empty for a random username each time you
# restart Minecraft in development. Choose this dependent on your mod:
# Do you need consistent player progressing (for example Thaumcraft)? -> Select a name
# Do you need to test how your custom blocks interacts with a player that is not the owner? -> leave name empty
developmentEnvironmentUserName = "Developer"
developmentEnvironmentUserName = Developer
# Define a source file of your project with:
# public static final String VERSION = "GRADLETOKEN_VERSION";
# The string's content will be replaced with your mods version when compiled. You should use this to specify your mod's
# The string's content will be replaced with your mod's version when compiled. You should use this to specify your mod's
# version in @Mod([...], version = VERSION, [...])
# Leave these properties empty to skip individual token replacements
replaceGradleTokenInFile = NEIModContainer.java
@@ -32,12 +32,12 @@ gradleTokenModName = GRADLETOKEN_MODNAME
gradleTokenVersion = GRADLETOKEN_VERSION
gradleTokenGroupName =
# In case your mod provides an API for other mods to implement you may declare its package here. Otherwise you can
# In case your mod provides an API for other mods to implement you may declare its package here. Otherwise, you can
# leave this property empty.
# Example value: apiPackage = api + modGroup = com.myname.mymodid -> com.myname.mymodid.api
apiPackage =
# Specify the configuration file for Forge's access transformers here. I must be placed into /src/main/resources/META-INF/
# Specify the configuration file for Forge's access transformers here. It must be placed into /src/main/resources/META-INF/
# Example value: mymodid_at.cfg
accessTransformersFile = nei_at.cfg
@@ -48,7 +48,7 @@ mixinPlugin =
# Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail!
mixinsPackage =
# Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin!
# This parameter is for legacy compatability only
# This parameter is for legacy compatibility only
# Example value: coreModClass = asm.FMLPlugin + modGroup = com.myname.mymodid -> com.myname.mymodid.asm.FMLPlugin
coreModClass = asm.NEICorePlugin
# If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class
+9 -3
View File
@@ -3,10 +3,16 @@
repositories {
mavenCentral()
maven {
name = "GTNH Maven"
url = "http://jenkins.usrv.eu:8081/nexus/content/groups/public/"
name 'GTNH Maven'
url 'http://jenkins.usrv.eu:8081/nexus/content/groups/public/'
}
maven {
url = "https://jitpack.io"
url 'https://cursemaven.com'
content {
includeGroup 'curse.maven'
}
}
maven {
url 'https://jitpack.io'
}
}
+194 -83
View File
@@ -5,15 +5,21 @@ import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.util.NBTJson;
import codechicken.nei.recipe.StackInfo;
import codechicken.nei.recipe.BookmarkRecipeId;
import codechicken.nei.ItemPanel.ItemPanelSlot;
import codechicken.nei.guihook.GuiContainerManager;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import org.apache.commons.io.IOUtils;
import org.lwjgl.opengl.GL11;
import javax.annotation.Nullable;
import static codechicken.lib.gui.GuiDraw.getMousePosition;
import static codechicken.lib.gui.GuiDraw.drawRect;
@@ -21,18 +27,18 @@ import static codechicken.lib.gui.GuiDraw.drawRect;
import java.awt.Point;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
public class BookmarkPanel extends ItemPanel
public class BookmarkPanel extends PanelWidget
{
protected File bookmarkFile;
@@ -47,7 +53,7 @@ public class BookmarkPanel extends ItemPanel
protected ArrayList<BookmarkGrid> namespaces = new ArrayList<>();
public int activeNamespaceIndex = 0;
protected int activeNamespaceIndex = 0;
protected static class BookmarkStackMeta
@@ -55,13 +61,15 @@ public class BookmarkPanel extends ItemPanel
public int factor;
public BookmarkRecipeId recipeId;
public boolean ingredient = false;
public boolean fluidDisplay = false;
public BookmarkStackMeta(BookmarkRecipeId recipeId, int count, boolean ingredient)
public BookmarkStackMeta(BookmarkRecipeId recipeId, int count, boolean ingredient, boolean fluidDisplay)
{
this.recipeId = recipeId;
this.factor = count;
this.ingredient = ingredient;
this.fluidDisplay = fluidDisplay;
}
}
@@ -93,11 +101,13 @@ public class BookmarkPanel extends ItemPanel
{
realItems.add(stackA);
metadata.add(meta);
refreshBuffer = true;
}
public void replaceItem(int idx, ItemStack stack)
{
realItems.set(idx, stack);
refreshBuffer = true;
}
public void removeRecipe(int idx, boolean removeFullRecipe)
@@ -119,7 +129,7 @@ public class BookmarkPanel extends ItemPanel
for (int slotIndex = metadata.size() - 1; slotIndex >= 0; slotIndex--) {
recipeIdB = getRecipeId(slotIndex);
if (recipeIdB != null && recipeIdA.equals(recipeIdB)) {
if (recipeIdB != null && recipeIdB.equals(recipeIdA)) {
removeItem(slotIndex);
}
@@ -131,6 +141,7 @@ public class BookmarkPanel extends ItemPanel
{
realItems.remove(idx);
metadata.remove(idx);
refreshBuffer = true;
return true;
}
@@ -156,33 +167,61 @@ public class BookmarkPanel extends ItemPanel
{
realItems.add(dst, realItems.remove(src));
metadata.add(dst, metadata.remove(src));
refreshBuffer = true;
}
private boolean isPartOfFocusedRecipe(ItemPanelSlot focused, int myIdx) {
return (NEIClientUtils.shiftKey()
&& LayoutManager.bookmarkPanel.sortedStackIndex == -1
&& focused != null
&& getRecipeId(focused.slotIndex) != null
&& getRecipeId(myIdx) != null
&& getRecipeId(focused.slotIndex).equals(getRecipeId(myIdx)));
}
@Override
protected void drawItem(Rectangle4i rect, int idx, ItemPanelSlot focus)
{
if (LayoutManager.bookmarkPanel.sortedNamespaceIndex == LayoutManager.bookmarkPanel.activeNamespaceIndex && LayoutManager.bookmarkPanel.sortedStackIndex == idx) {
protected void drawSlotOutline(@Nullable ItemPanelSlot focus, int idx, Rectangle4i rect) {
if(LayoutManager.bookmarkPanel.sortedNamespaceIndex == LayoutManager.bookmarkPanel.activeNamespaceIndex && LayoutManager.bookmarkPanel.sortedStackIndex == idx) {
drawRect(rect.x, rect.y, rect.w, rect.h, 0xee555555);//highlight
} else {
if (focus != null) {
if (focus.slotIndex == idx) {
drawRect(rect.x, rect.y, rect.w, rect.h, 0xee555555);//highlight
} else if (
LayoutManager.bookmarkPanel.sortedStackIndex == -1 && //disabled when sorting
NEIClientUtils.shiftKey() && //show only with shift key
getRecipeId(focus.slotIndex) != null && getRecipeId(idx) != null && getRecipeId(focus.slotIndex).equals(getRecipeId(idx))//is some recipeId
) {
drawRect(rect.x, rect.y, rect.w, rect.h, getMetadata(idx).ingredient? 0x88b3b300: 0x88009933);//highlight recipe
}
} else if(focus != null) {
BookmarkStackMeta meta = getMetadata(idx);
if (isPartOfFocusedRecipe(focus, idx)) {
drawRect(rect.x, rect.y, rect.w, rect.h, meta.ingredient? 0x88b3b300: 0x88009933);//highlight recipe
} else if(focus.slotIndex == idx) {
drawRect(rect.x, rect.y, rect.w, rect.h, 0xee555555);//highlight
}
GuiContainerManager.drawItem(rect.x + 1, rect.y + 1, getItem(idx), true);
}
}
@Override
protected void drawItem(Rectangle4i rect, int idx)
{
if (LayoutManager.bookmarkPanel.sortedNamespaceIndex != LayoutManager.bookmarkPanel.activeNamespaceIndex || LayoutManager.bookmarkPanel.sortedStackIndex != idx) {
final ItemStack stack = getItem(idx);
final BookmarkStackMeta meta = getMetadata(idx);
GuiContainerManager.drawItem(rect.x + 1, rect.y + 1, stack, true, meta.factor < 0 || meta.fluidDisplay? "": String.valueOf(stack.stackSize));
if (meta.recipeId != null && !meta.ingredient && NEIClientConfig.showRecipeMarker()) {
drawRecipeMarker(rect.x, rect.y, GuiContainerManager.getFontRenderer(stack));
}
}
}
protected void drawRecipeMarker(int offsetX, int offsetY, FontRenderer fontRenderer )
{
final float scaleFactor = fontRenderer.getUnicodeFlag() ? 0.85f : 0.5f;
final float inverseScaleFactor = 1.0f / scaleFactor;
GuiContainerManager.enable2DRender();
GL11.glScaled(scaleFactor, scaleFactor, scaleFactor);
final int X = (int) ( ( (float) offsetX + 1.0f) * inverseScaleFactor );
final int Y = (int) ( ( (float) offsetY + 1.0f) * inverseScaleFactor );
fontRenderer.drawStringWithShadow("R", X, Y, 0xA0A0A0);
GL11.glScaled(inverseScaleFactor, inverseScaleFactor, inverseScaleFactor);
GuiContainerManager.enable3DRender();
}
}
@@ -193,6 +232,7 @@ public class BookmarkPanel extends ItemPanel
grid = new BookmarkGrid();
}
@Override
public void init()
{
super.init();
@@ -243,9 +283,10 @@ public class BookmarkPanel extends ItemPanel
@Override
public String getLabelText()
{
return super.getLabelText() + " [" + grid.size() + "]";
return String.format("(%d/%d) [%d]", getPage(), Math.max(1, getNumPages()), grid.size());
}
public void addOrRemoveItem(ItemStack stackA)
{
addOrRemoveItem(stackA, "", null);
@@ -268,7 +309,7 @@ public class BookmarkPanel extends ItemPanel
final ItemStack normalizedA = StackInfo.loadFromNBT(nbTagA);
BookmarkRecipeId recipeId = null;
if (NEIClientConfig.saveCurrentRecipeInBookmarksEnabled() && handlerName != "" && ingredients != null && ingredients.size() > 0) {
if (NEIClientConfig.saveCurrentRecipeInBookmarksEnabled() && handlerName != "" && ingredients != null && !ingredients.isEmpty()) {
recipeId = new BookmarkRecipeId(handlerName, ingredients);
}
@@ -278,7 +319,7 @@ public class BookmarkPanel extends ItemPanel
BGrid.removeRecipe(idx, addFullRecipe);
} else {
if (addFullRecipe && handlerName != "" && ingredients != null) {
if (addFullRecipe && handlerName != "" && ingredients != null && !ingredients.isEmpty()) {
final Map<NBTTagCompound, Integer> unique = new HashMap<>();
final ArrayList<NBTTagCompound> sorted = new ArrayList<>();
@@ -298,12 +339,12 @@ public class BookmarkPanel extends ItemPanel
for (NBTTagCompound nbTag : sorted) {
nbTag.setInteger("Count", nbTag.getInteger("Count") * unique.get(nbTag));
BGrid.addItem(StackInfo.loadFromNBT(nbTag), new BookmarkStackMeta(recipeId, nbTag.getInteger("Count"), true));
BGrid.addItem(StackInfo.loadFromNBT(nbTag), new BookmarkStackMeta(recipeId, (saveStackSize ? 1: -1) * nbTag.getInteger("Count"), true, nbTag.hasKey("gtFluidName")));
}
}
BGrid.addItem(normalizedA, new BookmarkStackMeta(recipeId, nbTagA.getInteger("Count"), false));
BGrid.addItem(normalizedA, new BookmarkStackMeta(recipeId, (saveStackSize ? 1: -1) * nbTagA.getInteger("Count"), false, nbTagA.hasKey("gtFluidName")));
}
@@ -316,12 +357,8 @@ public class BookmarkPanel extends ItemPanel
public BookmarkRecipeId getBookmarkRecipeId(ItemStack stackA)
{
final Point mousePos = getMousePosition();
final ItemPanelSlot slot = getSlotMouseOver(mousePos.x, mousePos.y);
if (slot != null && StackInfo.equalItemAndNBT(slot.item, stackA, true)) {
return ((BookmarkGrid) grid).getRecipeId(slot.slotIndex);
}
BookmarkRecipeId mouseOverRecipeId = getBookmarkMouseOverRecipeId(stackA);
if (mouseOverRecipeId != null) return mouseOverRecipeId;
BookmarkRecipeId recipeId = ((BookmarkGrid) grid).findRecipeId(stackA);
@@ -337,6 +374,25 @@ public class BookmarkPanel extends ItemPanel
return recipeId;
}
public BookmarkRecipeId getBookmarkMouseOverRecipeId(ItemStack stackA)
{
final Point mousePos = getMousePosition();
final ItemPanelSlot slot = getSlotMouseOver(mousePos.x, mousePos.y);
if (slot != null) {
if (stackA == null || StackInfo.equalItemAndNBT(slot.item, stackA, true)) {
return ((BookmarkGrid) grid).getRecipeId(slot.slotIndex);
}
}
return null;
}
public BookmarkRecipeId getBookmarkMouseOverRecipeId()
{
return getBookmarkMouseOverRecipeId(null);
}
protected String getNamespaceLabelText(boolean shortFormat)
{
String activePage = String.valueOf(activeNamespaceIndex + 1);
@@ -450,6 +506,10 @@ public class BookmarkPanel extends ItemPanel
public void saveBookmarks()
{
if (bookmarkFile == null) {
return;
}
ArrayList<String> strings = new ArrayList<>();
for (int grpIdx = 0; grpIdx < namespaces.size() - 1; grpIdx++) {
@@ -487,12 +547,10 @@ public class BookmarkPanel extends ItemPanel
}
if (bookmarkFile != null) {
try(FileWriter writer = new FileWriter(bookmarkFile)) {
IOUtils.writeLines(strings, "\n", writer);
} catch (IOException e) {
NEIClientConfig.logger.error("Filed to save bookmarks list to file {}", bookmarkFile, e);
}
try (FileOutputStream output = new FileOutputStream(bookmarkFile)) {
IOUtils.writeLines(strings, "\n", output, StandardCharsets.UTF_8);
} catch (IOException e) {
NEIClientConfig.logger.error("Filed to save bookmarks list to file {}", bookmarkFile, e);
}
}
@@ -511,9 +569,9 @@ public class BookmarkPanel extends ItemPanel
}
List<String> itemStrings;
try (FileReader reader = new FileReader(bookmarkFile)) {
try (FileInputStream reader = new FileInputStream(bookmarkFile)) {
NEIClientConfig.logger.info("Loading bookmarks from file {}", bookmarkFile);
itemStrings = IOUtils.readLines(reader);
itemStrings = IOUtils.readLines(reader, StandardCharsets.UTF_8);
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to load bookmarks from file {}", bookmarkFile, e);
return;
@@ -559,8 +617,9 @@ public class BookmarkPanel extends ItemPanel
if (itemStack != null) {
namespaces.get(activeNamespaceIndex).addItem(itemStack, new BookmarkStackMeta(
recipeId,
jsonObject.has("factor")? jsonObject.get("factor").getAsInt(): 1,
jsonObject.has("ingredient")? jsonObject.get("ingredient").getAsBoolean(): false
jsonObject.has("factor")? jsonObject.get("factor").getAsInt(): 0,
jsonObject.has("ingredient")? jsonObject.get("ingredient").getAsBoolean(): false,
itemStackNBT.hasKey("gtFluidName")
));
} else {
NEIClientConfig.logger.warn("Failed to load bookmarked ItemStack from json string, the item no longer exists:\n{}", itemStr);
@@ -584,19 +643,38 @@ public class BookmarkPanel extends ItemPanel
{
loadBookmarksIfNeeded();
super.resize(gui);
}
final int buttonHeight = 16;
final int buttonWidth = 16;
final int buttonTop = gui.height - buttonHeight - 2;
final int leftBorder = LayoutManager.bookmarksButton.x + LayoutManager.bookmarksButton.w + 2;
@Override
protected int resizeHeader(GuiContainer gui)
{
final LayoutStyleMinecraft layout = (LayoutStyleMinecraft) LayoutManager.getLayoutStyle();
final int rows = (int) Math.ceil((double) layout.buttonCount / layout.numButtons);
final int diff = rows * 18 + getMarginTop(gui) - y;
if (diff > 0) {
y += diff;
h -= diff;
}
return super.resizeHeader(gui);
}
@Override
protected int resizeFooter(GuiContainer gui)
{
final int BUTTON_SIZE = 16;
final ButtonCycled button = LayoutManager.bookmarksButton;
final int leftBorder = y + h > button.y? button.x + button.w + 2: x;
final int rightBorder = x + w;
final int center = leftBorder + (rightBorder - leftBorder) / 2;
final int center = leftBorder + Math.max(0, (rightBorder - leftBorder) / 2);
int labelWidth = 2;
namespacePrev.h = namespaceNext.h = buttonHeight;
namespacePrev.w = namespaceNext.w = buttonWidth;
namespacePrev.y = namespaceNext.y = buttonTop;
namespacePrev.h = namespaceNext.h = BUTTON_SIZE;
namespacePrev.w = namespaceNext.w = BUTTON_SIZE;
namespacePrev.y = namespaceNext.y = y + h - BUTTON_SIZE;
if (rightBorder - leftBorder >= 70) {
@@ -607,12 +685,13 @@ public class BookmarkPanel extends ItemPanel
namespaceLabel.text = getNamespaceLabelText(true);
}
namespaceLabel.y = buttonTop + 5;
namespaceLabel.y = namespacePrev.y + 5;
namespaceLabel.x = center;
namespacePrev.x = center - labelWidth / 2 - 2 - namespacePrev.w;
namespaceNext.x = center + labelWidth / 2 + 2;
return BUTTON_SIZE + 2;
}
@Override
@@ -620,38 +699,62 @@ public class BookmarkPanel extends ItemPanel
{
super.setVisible();
LayoutManager.addWidget(namespacePrev);
LayoutManager.addWidget(namespaceNext);
LayoutManager.addWidget(namespaceLabel);
if (grid.getPerPage() > 0) {
LayoutManager.addWidget(namespacePrev);
LayoutManager.addWidget(namespaceNext);
LayoutManager.addWidget(namespaceLabel);
}
}
protected String getPositioningSettingName()
{
return "world.panels.bookmarks";
}
@Override
public int getMarginLeft(GuiContainer gui)
{
return 5;
return PADDING;
}
@Override
public int getMarginTop(GuiContainer gui)
{
LayoutStyleMinecraft layout = (LayoutStyleMinecraft)LayoutManager.getLayoutStyle();
return 2 + (((int)Math.ceil((double)layout.buttonCount / layout.numButtons)) * 18);
return PADDING;
}
@Override
public int getWidth(GuiContainer gui)
{
return LayoutManager.getLeftSize(gui) - ((gui.xSize + gui.width) / 2 + 3) - 16;
return gui.width - (gui.xSize + gui.width) / 2 - PADDING * 2;
}
@Override
public int getHeight(GuiContainer gui)
{
// - 19 = 22 + 1 -> input in bottom
return gui.height - getMarginTop(gui) - 23;
return gui.height - getMarginTop(gui) - PADDING;
}
protected ItemStack getDraggedStackWithQuantity(int mouseDownSlot)
{
final ItemStack stack = grid.getItem(mouseDownSlot);
if (stack == null) {
return null;
}
final BookmarkStackMeta meta = ((BookmarkGrid) grid).getMetadata(mouseDownSlot);
int amount = stack.stackSize;
if (meta.factor < 0 && !meta.fluidDisplay) {
amount = NEIClientConfig.getItemQuantity();
if (amount == 0) {
amount = stack.getMaxStackSize();
}
}
return NEIServerUtils.copyStack(stack, amount);
}
@Override
public void mouseDragged(int mousex, int mousey, int button, long heldTime)
{
@@ -665,6 +768,7 @@ public class BookmarkPanel extends ItemPanel
if (stack != null && (mouseOverSlot == null || mouseOverSlot.slotIndex != mouseDownSlot || heldTime > 250)) {
sortedNamespaceIndex = activeNamespaceIndex;
sortedStackIndex = mouseDownSlot;
grid.refreshBuffer = true;
}
} else {
@@ -736,21 +840,16 @@ public class BookmarkPanel extends ItemPanel
super.postDraw(mousex, mousey);
}
@Override
protected ItemStack getDraggedStackWithQuantity(int mouseDownSlot)
{
ItemStack stack = grid.getItem(mouseDownSlot);
return stack != null? stack.copy(): null;
}
@Override
public void mouseUp(int mousex, int mousey, int button)
{
if (sortedStackIndex != -1) {
draggedStack = null;
sortedNamespaceIndex = -1;
sortedStackIndex = -1;
mouseDownSlot = -1;
grid.refreshBuffer = true; /* make sure grid redraws the new item */
saveBookmarks();
} else {
super.mouseUp(mousex, mousey, button);
@@ -782,7 +881,6 @@ public class BookmarkPanel extends ItemPanel
if (slot != null) {
final BookmarkGrid BGrid = (BookmarkGrid)grid;
final BookmarkRecipeId recipeId = BGrid.getRecipeId(slot.slotIndex);
final BookmarkStackMeta meta = BGrid.getMetadata(slot.slotIndex);
final boolean addFullRecipe = NEIClientUtils.shiftKey();
if (addFullRecipe) {
@@ -791,19 +889,15 @@ public class BookmarkPanel extends ItemPanel
for (int slotIndex = grid.size() - 1; slotIndex >= 0; slotIndex--) {
iMeta = BGrid.getMetadata(slotIndex);
if (iMeta.recipeId != null && iMeta.recipeId.equals(recipeId)) {
NBTTagCompound nbTag = StackInfo.itemStackToNBT(BGrid.getItem(slotIndex), true);
nbTag.setInteger("Count", Math.max(nbTag.getInteger("Count") + iMeta.factor * shift, iMeta.factor));
BGrid.replaceItem(slotIndex, StackInfo.loadFromNBT(nbTag));
if (iMeta.recipeId != null && iMeta.recipeId.equals(recipeId) && slotIndex != slot.slotIndex) {
shiftStackSize(slotIndex, shift);
}
}
}
NBTTagCompound nbTag = StackInfo.itemStackToNBT(slot.item, true);
nbTag.setInteger("Count", Math.max(nbTag.getInteger("Count") + meta.factor * shift, meta.factor));
BGrid.replaceItem(slot.slotIndex, StackInfo.loadFromNBT(nbTag));
shiftStackSize(slot.slotIndex, shift);
saveBookmarks();
@@ -815,4 +909,21 @@ public class BookmarkPanel extends ItemPanel
return super.onMouseWheel(shift, mousex, mousey);
}
protected void shiftStackSize(int slotIndex, int shift)
{
final BookmarkGrid BGrid = (BookmarkGrid)grid;
final NBTTagCompound nbTag = StackInfo.itemStackToNBT(BGrid.getItem(slotIndex), true);
final BookmarkStackMeta meta = BGrid.getMetadata(slotIndex);
final int factor = Math.abs(meta.factor);
if (nbTag.getInteger("Count") == factor && meta.factor < 0 && shift > 0) {
meta.factor = factor;
} else {
meta.factor = nbTag.getInteger("Count") == factor && shift < 0? -1 * factor: factor;
nbTag.setInteger("Count", Math.max(nbTag.getInteger("Count") + factor * shift, factor));
BGrid.replaceItem(slotIndex, StackInfo.loadFromNBT(nbTag));
}
}
}
@@ -6,6 +6,8 @@ import codechicken.lib.packet.PacketCustom;
import codechicken.nei.api.API;
import codechicken.nei.api.ItemInfo;
import codechicken.nei.recipe.GuiRecipeTab;
import codechicken.nei.recipe.StackInfo;
import com.google.common.collect.Lists;
import cpw.mods.fml.client.CustomModLoadingErrorDisplayException;
import cpw.mods.fml.common.FMLCommonHandler;
@@ -160,6 +162,7 @@ public class ClientHandler
loadSerialHandlers();
loadHeightHackHandlers();
ItemInfo.preInit();
StackInfo.loadGuidFilters();
}
public static void loadSerialHandlers() {
@@ -1,10 +1,12 @@
package codechicken.nei;
import codechicken.lib.render.CCRenderState;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.api.INEIGuiHandler;
import codechicken.nei.api.TaggedInventoryArea;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import org.lwjgl.opengl.GL11;
@@ -50,7 +52,21 @@ public class GuiExtendedCreativeInv extends GuiContainer implements INEIGuiHandl
}
@Override
public boolean hideItemPanelSlot(GuiContainer gui, int x, int y, int w, int h) {
return false;
public boolean hideItemPanelSlot(GuiContainer gui, int x, int y, int w, int h)
{
return (new Rectangle4i(guiLeft - 15, guiTop + 18, 18, 18 * 4 + 4)).intersects(new Rectangle4i(x, y, w, h));
}
@Override
protected void handleMouseClick(Slot p_146984_1_, int p_146984_2_, int p_146984_3_, int p_146984_4_)
{
//Hack for armor slots, because they are outside the container
if (p_146984_1_ != null && p_146984_4_ == 4 && p_146984_1_.xDisplayPosition < 0) {
p_146984_4_ = 0;
}
super.handleMouseClick(p_146984_1_, p_146984_2_, p_146984_3_, p_146984_4_);
}
}
@@ -252,6 +252,7 @@ public class ItemList
try {
filtered = ItemList.forkJoinPool.submit(() -> items.parallelStream()
.filter(PresetsWidget::matches)
.filter(filter::matches)
.collect(Collectors.toCollection(ArrayList::new))).get();
} catch (InterruptedException | ExecutionException e) {
+105 -422
View File
@@ -1,37 +1,22 @@
package codechicken.nei;
import codechicken.nei.api.GuiInfo;
import codechicken.nei.api.INEIGuiHandler;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.recipe.GuiCraftingRecipe;
import codechicken.nei.recipe.GuiRecipe;
import codechicken.nei.recipe.GuiUsageRecipe;
import codechicken.nei.recipe.StackInfo;
import codechicken.lib.vec.Rectangle4i;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.gui.inventory.GuiContainerCreative;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidContainerItem;
import static codechicken.nei.LayoutManager.searchField;
import javax.annotation.Nullable;
import static codechicken.lib.gui.GuiDraw.drawRect;
import java.util.ArrayList;
import java.util.regex.Pattern;
public class ItemPanel extends Widget
public class ItemPanel extends PanelWidget
{
public ItemStack draggedStack;
public int mouseDownSlot = -1;
public Button pagePrev;
public Button pageNext;
public Label pageLabel;
/**
* Backwards compat :-/
*/
@SuppressWarnings("unused")
@Deprecated
private int itemsPerPage = 0;
@@ -40,8 +25,15 @@ public class ItemPanel extends Widget
@Deprecated
public ArrayList<ItemStack> realItems = new ArrayList<>();
public ItemStack getStackMouseOver(int mousex, int mousey) {
// *looks angrily at AppleCore*
return super.getStackMouseOver(mousex, mousey);
};
protected Pattern SPECIAL_REGEX_CHARS = Pattern.compile("[{}()\\[\\].+*?^$\\\\|]");
public Button more;
public Button less;
public ItemQuantityField quantity;
public static class ItemPanelSlot
{
@@ -77,18 +69,26 @@ public class ItemPanel extends Widget
if (newItems != null) {
realItems = newItems;
newItems = null;
refreshBuffer = true;
}
super.refresh(gui);
}
@Override
protected void drawSlotOutline(@Nullable ItemPanelSlot focused, int slotIdx, Rectangle4i rect) {
if (PresetsWidget.inEditMode()) {
if(!PresetsWidget.isHidden(getItem(slotIdx)))
drawRect(rect.x, rect.y, rect.w, rect.h, 0xee555555);
} else {
super.drawSlotOutline(focused, slotIdx, rect);
}
}
}
protected ItemsGrid grid = new ItemPanelGrid();
public ArrayList<ItemStack> getItems()
public ItemPanel()
{
return grid.getItems();
grid = new ItemPanelGrid();
}
public static void updateItemList(ArrayList<ItemStack> newItems)
@@ -97,148 +97,116 @@ public class ItemPanel extends Widget
ItemPanels.itemPanel.realItems = newItems;
}
@Override
public void init()
{
super.init();
more = new Button("+")
{
@Override
public boolean onButtonPress(boolean rightclick) {
if (rightclick)
return false;
int modifier = NEIClientUtils.controlKey() ? 64 : NEIClientUtils.shiftKey() ? 10 : 1;
int quantity = NEIClientConfig.getItemQuantity() + modifier;
if (quantity < 0) {
quantity = 0;
}
ItemPanels.itemPanel.quantity.setText(Integer.toString(quantity));
return true;
}
};
less = new Button("-")
{
@Override
public boolean onButtonPress(boolean rightclick) {
if (rightclick)
return false;
int modifier = NEIClientUtils.controlKey() ? -64 : NEIClientUtils.shiftKey() ? -10 : -1;
int quantity = NEIClientConfig.getItemQuantity() + modifier;
if (quantity < 0) {
quantity = 0;
}
ItemPanels.itemPanel.quantity.setText(Integer.toString(quantity));
return true;
}
};
quantity = new ItemQuantityField("quantity");
}
@Deprecated
public void scroll(int i)
{
grid.shiftPage(i);
}
public ItemsGrid getGrid()
public String getLabelText()
{
return grid;
return String.format("(%d/%d)", getPage(), Math.max(1, getNumPages()));
}
public void init() {
pageLabel = new Label("(0/0)", true);
pagePrev = new Button("Prev")
{
public boolean onButtonPress(boolean rightclick) {
if (!rightclick) {
grid.shiftPage(-1);
return true;
}
return false;
}
@Override
public String getRenderLabel() {
return "<";
}
};
pageNext = new Button("Next")
{
public boolean onButtonPress(boolean rightclick) {
if (!rightclick) {
grid.shiftPage(1);
return true;
}
return false;
}
@Override
public String getRenderLabel() {
return ">";
}
};
protected String getPositioningSettingName()
{
return "world.panels.items";
}
public int getMarginLeft(GuiContainer gui)
{
if (gui instanceof GuiContainerCreative && NEIClientUtils.getGamemode() == 2) {
//then activate creative+ first render creative gui and oly then creative+
return (gui.width + 176) / 2 + 2;
}
return (gui.width + gui.xSize) / 2 + 2;
return (gui.width + gui.xSize) / 2 + PADDING;
}
public int getMarginTop(GuiContainer gui)
{
return 2;
return PADDING;
}
public int getWidth(GuiContainer gui)
{
return LayoutManager.getSideWidth(gui) - getMarginLeft(gui);
return gui.width - (gui.xSize + gui.width) / 2 - PADDING * 2;
}
public int getHeight(GuiContainer gui)
{
// - 19 = 2 + 16 + 1 -> input in bottom
return gui.height - getMarginTop(gui) - 19;
return gui.height - getMarginTop(gui) - PADDING;
}
public String getLabelText()
protected int resizeFooter(GuiContainer gui)
{
return "(" + getPage() + "/" + Math.max(1, getNumPages()) + ")";
}
public void resize(GuiContainer gui)
{
final int marginLeft = getMarginLeft(gui);
final int marginTop = getMarginTop(gui);
final int width = getWidth(gui);
final int height = getHeight(gui);
final int buttonHeight = 16;
final int buttonWidth = 16;
pagePrev.w = pageNext.w = buttonWidth;
pagePrev.h = pageNext.h = buttonHeight;
pagePrev.y = pageNext.y = marginTop;
pagePrev.x = marginLeft;
pageNext.x = marginLeft + width - buttonWidth;
pageLabel.x = marginLeft + width / 2;
pageLabel.y = marginTop + 5;
pageLabel.text = getLabelText();
y = marginTop + buttonHeight + 2;
x = marginLeft;
w = width;
h = height - buttonHeight - 2;
grid.setGridSize(x, y, w, h);
grid.refresh(gui);
final int BUTTON_SIZE = 16;
more.w = less.w = BUTTON_SIZE;
more.h = less.h = quantity.h = BUTTON_SIZE;
less.x = x;
more.x = x + w - BUTTON_SIZE;
more.y = less.y = quantity.y = y + h - BUTTON_SIZE;
quantity.x = x + BUTTON_SIZE + 2;
quantity.w = more.x - quantity.x - 2;
return BUTTON_SIZE + 2;
}
@Override
public void setVisible()
{
LayoutManager.addWidget(pagePrev);
LayoutManager.addWidget(pageNext);
LayoutManager.addWidget(pageLabel);
}
@Override
public void draw(int mousex, int mousey)
{
grid.draw(mousex, mousey);
}
@Override
public void postDraw(int mousex, int mousey) {
if (draggedStack != null) {
GuiContainerManager.drawItems.zLevel += 100;
GuiContainerManager.drawItem(mousex - 8, mousey - 8, draggedStack, true);
GuiContainerManager.drawItems.zLevel -= 100;
}
}
@Override
public void mouseDragged(int mousex, int mousey, int button, long heldTime) {
if (mouseDownSlot >= 0 && draggedStack == null && NEIClientUtils.getHeldItem() == null &&
NEIClientConfig.hasSMPCounterPart() && !GuiInfo.hasCustomSlots(NEIClientUtils.getGuiContainer())) {
ItemPanelSlot mouseOverSlot = getSlotMouseOver(mousex, mousey);
if (mouseOverSlot == null || mouseOverSlot.slotIndex != mouseDownSlot || heldTime > 500) {
draggedStack = getDraggedStackWithQuantity(mouseDownSlot);
}
super.setVisible();
if (grid.getPerPage() > 0) {
LayoutManager.addWidget(more);
LayoutManager.addWidget(less);
LayoutManager.addWidget(quantity);
}
}
protected ItemStack getDraggedStackWithQuantity(int mouseDownSlot)
@@ -258,289 +226,4 @@ public class ItemPanel extends Widget
return null;
}
@Override
public boolean handleClick(int mousex, int mousey, int button)
{
if (handleClickExt(mousex, mousey, button))
return true;
if (NEIClientUtils.getHeldItem() != null) {
if (!grid.contains(mousex, mousey)) {
return false;
}
if (NEIClientConfig.canPerformAction("delete") && NEIClientConfig.canPerformAction("item"))
if (button == 1)
NEIClientUtils.decreaseSlotStack(-999);
else
NEIClientUtils.deleteHeldItem();
else
NEIClientUtils.dropHeldItem();
return true;
}
ItemPanelSlot hoverSlot = getSlotMouseOver(mousex, mousey);
if (hoverSlot != null) {
if (button == 2) {
if (hoverSlot.item != null) {
draggedStack = getDraggedStackWithQuantity(hoverSlot.slotIndex);
}
} else {
mouseDownSlot = hoverSlot.slotIndex;
}
return true;
}
return false;
}
@Override
public boolean handleClickExt(int mouseX, int mouseY, int button)
{
if (ItemPanels.itemPanel.draggedStack != null) {
return ItemPanels.itemPanel.handleDraggedClick(mouseX, mouseY, button);
}
if (ItemPanels.bookmarkPanel.draggedStack != null) {
return ItemPanels.bookmarkPanel.handleDraggedClick(mouseX, mouseY, button);
}
return false;
}
protected boolean handleDraggedClick(int mouseX, int mouseY, int button)
{
if (draggedStack == null) {
return false;
}
if (handleFillFluidContainerClick(mouseX, mouseY, button)) {
return true;
}
if (handleSearchInputClick(mouseX, mouseY, button)) {
return true;
}
if (handleGUIContainerClick(mouseX, mouseY, button)) {
return true;
}
if (handleCheatItemClick(mouseX, mouseY, button)) {
return true;
}
final GuiContainer gui = NEIClientUtils.getGuiContainer();
if (mouseX < gui.guiLeft || mouseY < gui.guiTop || mouseX >= gui.guiLeft + gui.xSize || mouseY >= gui.guiTop + gui.ySize) {
draggedStack = null;
}
return true;
}
protected boolean handleFillFluidContainerClick(int mouseX, int mouseY, int button)
{
if (button == 2) {
return false;
}
ItemPanelSlot mouseOverSlot = ItemPanels.itemPanel.getSlotMouseOver(mouseX, mouseY);
if (mouseOverSlot == null) {
mouseOverSlot = ItemPanels.bookmarkPanel.getSlotMouseOver(mouseX, mouseY);
}
if (mouseOverSlot != null && draggedStack.getItem() instanceof IFluidContainerItem) {
FluidStack fluidStack = StackInfo.getFluid(mouseOverSlot.item);
if (fluidStack != null) {
final int stackSize = draggedStack.stackSize;
fluidStack = fluidStack.copy();
if (fluidStack.amount == 0) {
fluidStack.amount = 1000;
}
if (mouseOverSlot.item.stackSize > 1) {
fluidStack.amount *= mouseOverSlot.item.stackSize;
}
draggedStack.stackSize = 1;
((IFluidContainerItem) draggedStack.getItem()).fill(draggedStack, fluidStack, true);
draggedStack.stackSize = stackSize;
if (button == 1 && ((IFluidContainerItem) draggedStack.getItem()).getFluid(draggedStack) != null) {
ItemPanels.bookmarkPanel.addOrRemoveItem(draggedStack.copy());
}
}
return true;
}
return false;
}
protected boolean handleGUIContainerClick(int mouseX, int mouseY, int button)
{
final GuiContainer gui = NEIClientUtils.getGuiContainer();
boolean handled = false;
try {
GuiInfo.readLock.lock();
for (INEIGuiHandler handler : GuiInfo.guiHandlers) {
if (handler.handleDragNDrop(gui, mouseX, mouseY, draggedStack, button)) {
handled = true;
break;
}
}
} finally {
GuiInfo.readLock.unlock();
}
if (draggedStack.stackSize == 0) {
draggedStack = null;
}
return handled;
}
protected boolean handleCheatItemClick(int mouseX, int mouseY, int button)
{
final GuiContainer gui = NEIClientUtils.getGuiContainer();
final Slot overSlot = gui.getSlotAtPosition(mouseX, mouseY);
if (overSlot != null && overSlot.isItemValid(draggedStack)) {
if (NEIClientConfig.canCheatItem(draggedStack)) {
int contents = overSlot.getHasStack() ? overSlot.getStack().stackSize : 0;
final int add = button == 0 ? draggedStack.stackSize : 1;
if (overSlot.getHasStack() && !NEIServerUtils.areStacksSameType(draggedStack, overSlot.getStack())) {
contents = 0;
}
final int total = Math.min(contents + add, Math.min(overSlot.getSlotStackLimit(), draggedStack.getMaxStackSize()));
if (total > contents) {
NEIClientUtils.setSlotContents(overSlot.slotNumber, NEIServerUtils.copyStack(draggedStack, total), true);
NEICPH.sendGiveItem(NEIServerUtils.copyStack(draggedStack, total), false, false);
draggedStack.stackSize -= total - contents;
}
if (draggedStack.stackSize == 0) {
draggedStack = null;
}
} else {
draggedStack = null;
}
return true;
}
return false;
}
protected boolean handleSearchInputClick(int mouseX, int mouseY, int button)
{
if (searchField.contains(mouseX, mouseY)) {
final FluidStack fluidStack = StackInfo.getFluid(draggedStack);
if (fluidStack != null) {
searchField.setText(SPECIAL_REGEX_CHARS.matcher(fluidStack.getLocalizedName()).replaceAll("\\\\$0"));
} else {
searchField.setText(SPECIAL_REGEX_CHARS.matcher(draggedStack.getDisplayName()).replaceAll("\\\\$0"));
}
return true;
}
return false;
}
@Override
public void mouseUp(int mousex, int mousey, int button) {
ItemPanelSlot hoverSlot = getSlotMouseOver(mousex, mousey);
if (hoverSlot != null && hoverSlot.slotIndex == mouseDownSlot && draggedStack == null) {
ItemStack item = hoverSlot.item;
if (NEIController.manager.window instanceof GuiRecipe || !NEIClientConfig.canCheatItem(item)) {
if (button == 0)
GuiCraftingRecipe.openRecipeGui("item", item);
else if (button == 1)
GuiUsageRecipe.openRecipeGui("item", item);
draggedStack = null;
mouseDownSlot = -1;
return;
}
NEIClientUtils.cheatItem(getDraggedStackWithQuantity(hoverSlot.slotIndex), button, -1);
}
mouseDownSlot = -1;
}
@Override
public boolean onMouseWheel(int i, int mousex, int mousey) {
if (!contains(mousex, mousey))
return false;
grid.shiftPage(-i);
return true;
}
@Override
public boolean handleKeyPress(int keyID, char keyChar) {
if (keyID == NEIClientConfig.getKeyBinding("gui.next")) {
grid.shiftPage(1);
return true;
}
if (keyID == NEIClientConfig.getKeyBinding("gui.prev")) {
grid.shiftPage(-1);
return true;
}
return false;
}
@Override
public ItemStack getStackMouseOver(int mousex, int mousey) {
ItemPanelSlot slot = getSlotMouseOver(mousex, mousey);
return slot == null ? null : slot.item;
}
public ItemPanelSlot getSlotMouseOver(int mousex, int mousey)
{
return grid.getSlotMouseOver(mousex, mousey);
}
public int getPage() {
return grid.page + 1;
}
public int getNumPages() {
return grid.numPages;
}
@Override
public boolean contains(int px, int py)
{
return grid.contains(px, py);
}
}
+104 -43
View File
@@ -5,16 +5,24 @@ import codechicken.nei.api.GuiInfo;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.recipe.StackInfo;
import codechicken.nei.ItemPanel.ItemPanelSlot;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.shader.Framebuffer;
import net.minecraft.item.ItemStack;
import org.lwjgl.opengl.GL11;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import static codechicken.lib.gui.GuiDraw.drawRect;
public class ItemsGrid
{
protected static final int SLOT_SIZE = 18;
public static final int SLOT_SIZE = 18;
protected int width;
protected int height;
@@ -22,6 +30,8 @@ public class ItemsGrid
protected int marginLeft;
protected int marginTop;
protected int paddingLeft;
protected ArrayList<ItemStack> realItems = new ArrayList<>();
protected int page;
@@ -36,6 +46,10 @@ public class ItemsGrid
protected boolean[] validSlotMap;
protected boolean[] invalidSlotMap;
@Nullable
private Framebuffer framebuffer = null;
protected boolean refreshBuffer = true;
public ArrayList<ItemStack> getItems()
{
return realItems;
@@ -90,20 +104,19 @@ public class ItemsGrid
public void setGridSize(int mleft, int mtop, int w, int h)
{
if(width != w || height != h || mleft != marginLeft || mtop != marginTop)
refreshBuffer = true;
//I don't like this big condition
if (marginLeft != mleft || marginTop != mtop || width != w || height != h) {
marginLeft = mleft;
marginTop = mtop;
marginLeft = mleft;
marginTop = mtop;
width = Math.max(0, w);
height = Math.max(0, h);
width = Math.max(0, w);
height = Math.max(0, h);
columns = width / SLOT_SIZE;
rows = height / SLOT_SIZE;
}
columns = width / SLOT_SIZE;
rows = height / SLOT_SIZE;
paddingLeft = (width % SLOT_SIZE) / 2;
}
public void shiftPage(int shift)
@@ -127,6 +140,8 @@ public class ItemsGrid
}
page = Math.max(0, Math.min(page, numPages - 1));
if(shift != 0)
refreshBuffer = true;
}
public void refresh(GuiContainer gui)
@@ -137,12 +152,15 @@ public class ItemsGrid
private void updateGuiOverlapSlots(GuiContainer gui)
{
boolean[] oldSlotMap = invalidSlotMap;
invalidSlotMap = new boolean[rows * columns];
perPage = columns * rows;
checkGuiOverlap(gui, 0, columns - 2, 1);
checkGuiOverlap(gui, columns - 1, 1, -1);
if(NEIClientConfig.shouldCacheItemRendering() && !Arrays.equals(oldSlotMap, invalidSlotMap)) {
refreshBuffer = true;
}
}
private void checkGuiOverlap(GuiContainer gui, int start, int end, int dir)
@@ -154,7 +172,7 @@ public class ItemsGrid
for (int r = 0; r < rows; r++) {
final int idx = columns * r + c;
if (!slotValid(gui, r, c) && idx >= 0 && idx < invalidSlotMap.length && !invalidSlotMap[idx]) {
if (GuiInfo.hideItemPanelSlot(gui, getSlotRect(r, c)) && idx >= 0 && idx < invalidSlotMap.length && !invalidSlotMap[idx]) {
invalidSlotMap[idx] = true;
validColumn = false;
perPage--;
@@ -166,22 +184,6 @@ public class ItemsGrid
}
private boolean slotValid(GuiContainer gui, int row, int column)
{
Rectangle4i rect = getSlotRect(row, column);
try {
GuiInfo.readLock.lock();
if (GuiInfo.guiHandlers.stream().anyMatch(handler -> handler.hideItemPanelSlot(gui, rect.x, rect.y, rect.w, rect.h))) {
return false;
}
} finally {
GuiInfo.readLock.unlock();
}
return true;
}
public Rectangle4i getSlotRect(int i)
{
return getSlotRect(i / columns, i % columns);
@@ -189,7 +191,7 @@ public class ItemsGrid
public Rectangle4i getSlotRect(int row, int column)
{
return new Rectangle4i(marginLeft + (width % SLOT_SIZE) / 2 + column * SLOT_SIZE, marginTop + row * SLOT_SIZE, SLOT_SIZE, SLOT_SIZE);
return new Rectangle4i(marginLeft + paddingLeft + column * SLOT_SIZE, marginTop + row * SLOT_SIZE, SLOT_SIZE, SLOT_SIZE);
}
public boolean isInvalidSlot(int idx)
@@ -197,36 +199,95 @@ public class ItemsGrid
return invalidSlotMap[idx];
}
private void drawSlotOutlines(int mousex, int mousey)
{
ItemPanelSlot focused = getSlotMouseOver(mousex, mousey);
int idx = page * perPage;
for (int i = 0; i < rows * columns && idx < size(); i++) {
if(!invalidSlotMap[i]) {
drawSlotOutline(focused, idx, getSlotRect(i));
idx++;
}
}
}
protected void drawSlotOutline(@Nullable ItemPanelSlot focused, int slotIdx, Rectangle4i rect) {
if(focused != null && focused.slotIndex == slotIdx)
drawRect(rect.x, rect.y, rect.w, rect.h, 0xee555555);//highlight
}
private void blitExistingBuffer() {
Minecraft minecraft = Minecraft.getMinecraft();
GL11.glEnable(GL11.GL_BLEND);
OpenGlHelper.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
framebuffer.bindFramebufferTexture();
GL11.glEnable(GL11.GL_TEXTURE_2D);
ScaledResolution res = new ScaledResolution(minecraft, minecraft.displayWidth, minecraft.displayHeight);
Tessellator tessellator = Tessellator.instance;
tessellator.startDrawingQuads();
tessellator.addVertexWithUV(0, res.getScaledHeight_double(), 0.0, 0, 0);
tessellator.addVertexWithUV(res.getScaledWidth_double(), res.getScaledHeight_double(), 0.0, 1, 0);
tessellator.addVertexWithUV(res.getScaledWidth_double(), 0, 0.0, 1, 1);
tessellator.addVertexWithUV(0, 0, 0, 0, 1);
tessellator.draw();
OpenGlHelper.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO);
}
public void draw(int mousex, int mousey)
{
if (getPerPage() == 0) {
return;
}
ItemPanelSlot slot = getSlotMouseOver(mousex, mousey);
boolean shouldCache = NEIClientConfig.shouldCacheItemRendering() && !PresetsWidget.inEditMode();
if(shouldCache) {
Minecraft minecraft = Minecraft.getMinecraft();
if (framebuffer == null) {
framebuffer = new Framebuffer(minecraft.displayWidth, minecraft.displayHeight, true);
framebuffer.framebufferColor[0] = 0.0F;
framebuffer.framebufferColor[1] = 0.0F;
framebuffer.framebufferColor[2] = 0.0F;
}
drawSlotOutlines(mousex, mousey);
if (refreshBuffer) {
framebuffer.createBindFramebuffer(minecraft.displayWidth, minecraft.displayHeight);
framebuffer.framebufferClear();
framebuffer.bindFramebuffer(false);
/* Set up some rendering state needed for items to work correctly */
GL11.glDisable(GL11.GL_BLEND);
GL11.glDepthMask(true);
OpenGlHelper.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
} else {
blitExistingBuffer();
return;
}
} else {
drawSlotOutlines(mousex, mousey);
}
GuiContainerManager.enableMatrixStackLogging();
int idx = page * perPage;
for (int i = 0; i < rows * columns && idx < size(); i++) {
if (!invalidSlotMap[i]) {
drawItem(getSlotRect(i), idx, slot);
drawItem(getSlotRect(i), idx);
idx ++;
}
}
GuiContainerManager.disableMatrixStackLogging();
if (refreshBuffer && shouldCache) {
refreshBuffer = false;
Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
blitExistingBuffer();
}
}
protected void drawItem(Rectangle4i rect, int idx, ItemPanelSlot focus)
protected void drawItem(Rectangle4i rect, int idx)
{
if (focus != null && focus.slotIndex == idx) {
drawRect(rect.x, rect.y, rect.w, rect.h, 0xee555555);//highlight
}
GuiContainerManager.drawItem(rect.x + 1, rect.y + 1, getItem(idx));
}
@@ -237,7 +298,7 @@ public class ItemsGrid
}
final int overRow = (int) ((mousey - marginTop) / SLOT_SIZE);
final int overColumn = (int) ((mousex - marginLeft - (width % SLOT_SIZE) / 2) / SLOT_SIZE);
final int overColumn = (int) ((mousex - marginLeft - paddingLeft) / SLOT_SIZE);
final int slt = columns * overRow + overColumn;
int idx = page * perPage + slt;
@@ -257,12 +318,12 @@ public class ItemsGrid
public boolean contains(int px, int py)
{
if (!(new Rectangle4i(marginLeft, marginTop, width, height)).contains(px, py)) {
if (!(new Rectangle4i(marginLeft + paddingLeft, marginTop, columns * SLOT_SIZE, height)).contains(px, py)) {
return false;
}
final int r = (int) ((py - marginTop) / SLOT_SIZE);
final int c = (int) ((px - marginLeft - (width % SLOT_SIZE) / 2) / SLOT_SIZE);
final int c = (int) ((px - marginLeft - paddingLeft) / SLOT_SIZE);
final int slt = columns * r + c;
return r >= rows || c >= columns || !invalidSlotMap[slt];
@@ -37,7 +37,6 @@ import static codechicken.lib.gui.GuiDraw.drawRect;
import static codechicken.lib.gui.GuiDraw.drawTexturedModalRect;
import static codechicken.nei.NEIClientConfig.canPerformAction;
import static codechicken.nei.NEIClientConfig.disabledActions;
import static codechicken.nei.NEIClientConfig.getItemQuantity;
import static codechicken.nei.NEIClientConfig.getKeyBinding;
import static codechicken.nei.NEIClientConfig.getOptionList;
import static codechicken.nei.NEIClientConfig.getSearchExpression;
@@ -49,7 +48,6 @@ import static codechicken.nei.NEIClientConfig.isHidden;
import static codechicken.nei.NEIClientConfig.showIDs;
import static codechicken.nei.NEIClientConfig.toggleBooleanSetting;
import static codechicken.nei.NEIClientConfig.world;
import static codechicken.nei.NEIClientUtils.controlKey;
import static codechicken.nei.NEIClientUtils.cycleGamemode;
import static codechicken.nei.NEIClientUtils.decreaseSlotStack;
import static codechicken.nei.NEIClientUtils.deleteEverything;
@@ -77,22 +75,26 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
/**
* Sorted bottom first
*/
private static TreeSet<Widget> drawWidgets;
private static TreeSet<Widget> drawWidgets = new TreeSet<>(new WidgetZOrder(false));
/**
* Sorted top first
*/
private static TreeSet<Widget> controlWidgets;
private static TreeSet<Widget> controlWidgets = new TreeSet<>(new WidgetZOrder(true));
public static ItemPanel itemPanel;
public static BookmarkPanel bookmarkPanel;
public static SubsetWidget dropDown;
public static PresetsWidget presetsPanel;
public static TextField searchField;
public static ButtonCycled options;
public static ButtonCycled bookmarksButton;
@Deprecated
public static Button more;
@Deprecated
public static Button less;
@Deprecated
public static ItemQuantityField quantity;
public static Button delete;
@@ -141,9 +143,12 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
}
}
@Deprecated
public static int getSideWidth(GuiContainer gui) {
return gui.width - 3;
}
@Deprecated
public static int getLeftSize(GuiContainer gui) {
return getSideWidth(gui);
}
@@ -177,7 +182,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
@Override
public boolean objectUnderMouse(GuiContainer gui, int mousex, int mousey) {
if (!isHidden() && isEnabled())
for (Widget widget : controlWidgets)
for (Widget widget : drawWidgets)
if (widget.contains(mousex, mousey))
return true;
@@ -238,7 +243,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
@Override
public ItemStack getStackUnderMouse(GuiContainer gui, int mousex, int mousey) {
if (!isHidden() && isEnabled()) {
for (Widget widget : controlWidgets) {
for (Widget widget : drawWidgets) {
ItemStack stack = widget.getStackMouseOver(mousex, mousey);
if (stack != null)
return stack;
@@ -275,7 +280,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
@Override
public List<String> handleTooltip(GuiContainer gui, int mousex, int mousey, List<String> currenttip) {
if (!isHidden() && isEnabled() && GuiContainerManager.shouldShowTooltip(gui)) {
for (Widget widget : controlWidgets)
for (Widget widget : drawWidgets)
currenttip = widget.handleTooltip(mousex, mousey, currenttip);
}
return currenttip;
@@ -306,6 +311,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
public static void layout(GuiContainer gui) {
VisiblityData visiblity = new VisiblityData();
if (isHidden())
visiblity.showNEI = false;
@@ -315,8 +321,15 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
if (gui.height - gui.ySize <= 40)
visiblity.showSearchSection = false;
if (visiblity.showBookmarkPanel || gui.guiTop <= 20)
visiblity.showSubsetDropdown = false;
if (!visiblity.showBookmarkPanel || gui.guiTop <= 20)
visiblity.showPresetsDropdown = false;
if (gui.guiLeft - 4 < 76)
visiblity.showWidgets = false;
try {
GuiInfo.readLock.lock();
GuiInfo.guiHandlers.forEach(handler -> handler.modifyVisiblity(gui, visiblity));
@@ -339,6 +352,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
bookmarkPanel.init();
dropDown = new SubsetWidget();
presetsPanel = new PresetsWidget();
searchField = new SearchField("search");
options = new ButtonCycled(3)
@@ -411,43 +425,10 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
return translate("bookmark.toggle");
}
};
more = new Button("+")
{
@Override
public boolean onButtonPress(boolean rightclick) {
if (rightclick)
return false;
int modifier = controlKey() ? 64 : shiftKey() ? 10 : 1;
int quantity = getItemQuantity() + modifier;
if (quantity < 0)
quantity = 0;
LayoutManager.quantity.setText(Integer.toString(quantity));
return true;
}
};
less = new Button("-")
{
@Override
public boolean onButtonPress(boolean rightclick) {
if (rightclick)
return false;
int modifier = controlKey() ? -64 : shiftKey() ? -10 : -1;
int quantity = getItemQuantity() + modifier;
if (quantity < 0)
quantity = 0;
LayoutManager.quantity.setText(Integer.toString(quantity));
return true;
}
};
quantity = new ItemQuantityField("quantity");
more = ItemPanels.itemPanel.more;
less = ItemPanels.itemPanel.less;
quantity = ItemPanels.itemPanel.quantity;
delete = new Button()
{
@Override
@@ -671,12 +652,14 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
addWidget(options);
addWidget(bookmarksButton);
if (visiblity.showItemPanel) {
addWidget(itemPanel);
itemPanel.setVisible();
addWidget(more);
addWidget(less);
addWidget(quantity);
if (PresetsWidget.inEditMode()) {
drawWidgets.add(itemPanel);
} else {
addWidget(itemPanel);
}
itemPanel.setVisible();
}
if (visiblity.showBookmarkPanel) {
@@ -684,6 +667,10 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
bookmarkPanel.setVisible();
}
if (visiblity.showPresetsDropdown) {
addWidget(presetsPanel);
}
if (visiblity.showSearchSection) {
addWidget(searchField);
}
@@ -707,7 +694,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
addWidget(delete);
}
if (!visiblity.showBookmarkPanel) {
if (visiblity.showSubsetDropdown) {
// Bookmarks or Subset/dropdown
addWidget(dropDown);
}
@@ -738,7 +725,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
if (!isEnabled())
return;
for (Widget widget : controlWidgets)
for (Widget widget : drawWidgets)
widget.update();
}
@@ -747,7 +734,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
if (isHidden() || !isEnabled())
return false;
for (Widget widget : controlWidgets)
for (Widget widget : drawWidgets)
if (widget.onMouseWheel(scrolled, mousex, mousey))
return true;
@@ -787,7 +774,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
@Override
public void renderSlotOverlay(GuiContainer window, Slot slot) {
ItemStack item = slot.getStack();
if (world.nbt.getBoolean("searchinventories") && (item == null ? !getSearchExpression().equals("") : !ItemList.getItemListFilter().matches(item))) {
if (world.nbt.getBoolean("searchinventories") && (item == null ? !getSearchExpression().equals("") : !((SearchField) searchField).getFilter().matches(item))) {
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glTranslatef(0, 0, 150);
drawRect(slot.xDisplayPosition, slot.yDisplayPosition, 16, 16, 0x80000000);
@@ -10,15 +10,13 @@ import static codechicken.nei.LayoutManager.bookmarkPanel;
import static codechicken.nei.LayoutManager.bookmarksButton;
import static codechicken.nei.LayoutManager.delete;
import static codechicken.nei.LayoutManager.dropDown;
import static codechicken.nei.LayoutManager.presetsPanel;
import static codechicken.nei.LayoutManager.gamemode;
import static codechicken.nei.LayoutManager.heal;
import static codechicken.nei.LayoutManager.itemPanel;
import static codechicken.nei.LayoutManager.itemPresenceOverlays;
import static codechicken.nei.LayoutManager.less;
import static codechicken.nei.LayoutManager.magnet;
import static codechicken.nei.LayoutManager.more;
import static codechicken.nei.LayoutManager.options;
import static codechicken.nei.LayoutManager.quantity;
import static codechicken.nei.LayoutManager.rain;
import static codechicken.nei.LayoutManager.searchField;
import static codechicken.nei.LayoutManager.timeButtons;
@@ -118,16 +116,6 @@ public class LayoutStyleMinecraft extends LayoutStyle
itemPanel.resize(gui);
bookmarkPanel.resize(gui);
more.w = more.h = less.w = less.h = 16;
less.x = itemPanel.pagePrev.x;
more.x = gui.width - less.w - 2;
more.y = less.y = gui.height - more.h - 2;
quantity.x = less.x + less.w + 2;
quantity.y = less.y;
quantity.w = more.x - quantity.x - 2;
quantity.h = less.h;
options.x = isEnabled() ? 0 : 6;
options.y = isEnabled() ? gui.height - 22 : gui.height - 28;
options.w = 22;
@@ -138,15 +126,20 @@ public class LayoutStyleMinecraft extends LayoutStyle
bookmarksButton.w = 22;
bookmarksButton.h = 22;
searchField.y = gui.height - searchField.h - 2;
dropDown.h = 18;
dropDown.w = 150;
dropDown.y = 0;
dropDown.x = (gui.width - gui.xSize) / 2 + gui.xSize - dropDown.w;
dropDown.x = Math.min(numButtons, buttonCount) * 20 + 3;
dropDown.h = 20;
dropDown.w = itemPanel.x - dropDown.x - 3;
presetsPanel.h = 16;
presetsPanel.w = 150;
presetsPanel.y = 2;
presetsPanel.x = (gui.width - gui.xSize) / 2 + gui.xSize - presetsPanel.w;
searchField.h = 20;
searchField.w = 150;
searchField.x = (gui.width - searchField.w) / 2;
searchField.y = gui.height - searchField.h - 2;
if (!visiblity.showItemSection) {
searchField.setFocus(false);
@@ -155,8 +148,8 @@ public class LayoutStyleMinecraft extends LayoutStyle
}
public void layoutButton(Button button) {
button.x = 2 + (buttonCount % numButtons) * 20;
button.y = (buttonCount / numButtons) * 18;
button.x = 2 + (buttonCount % numButtons) * 19;
button.y = 2 + (buttonCount / numButtons) * 18;
button.h = 17;
button.w = button.contentWidth() + 6;
@@ -16,6 +16,7 @@ import codechicken.nei.config.ConfigSet;
import codechicken.nei.config.GuiHighlightTips;
import codechicken.nei.config.GuiNEIOptionList;
import codechicken.nei.config.GuiOptionList;
import codechicken.nei.config.GuiPanelSettings;
import codechicken.nei.config.OptionCycled;
import codechicken.nei.config.OptionGamemodes;
import codechicken.nei.config.OptionList;
@@ -33,6 +34,7 @@ import codechicken.obfuscator.ObfuscationRun;
import com.google.common.base.Objects;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
@@ -154,6 +156,20 @@ public class NEIClientConfig {
tag.getTag("world.highlight_tips.y").getIntValue(100);
API.addOption(new OptionOpenGui("world.highlight_tips", GuiHighlightTips.class));
tag.getTag("world.panels.bookmarks.left").getIntValue(0);
tag.getTag("world.panels.bookmarks.right").getIntValue(0);
tag.getTag("world.panels.bookmarks.top").getIntValue(0);
tag.getTag("world.panels.bookmarks.bottom").getIntValue(0);
tag.getTag("world.panels.items.left").getIntValue(0);
tag.getTag("world.panels.items.right").getIntValue(0);
tag.getTag("world.panels.items.top").getIntValue(0);
tag.getTag("world.panels.items.bottom").getIntValue(0);
API.addOption(new OptionOpenGui("world.panels", GuiPanelSettings.class));
tag.getTag("inventory.profileRecipes").getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.profileRecipes", true));
@@ -167,6 +183,9 @@ public class NEIClientConfig {
return isMouseScrollTransferEnabled();
}
});
tag.getTag("inventory.cacheItemRendering").getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.cacheItemRendering", true));
tag.getTag("itemLoadingTimeout").getIntValue(500);
@@ -190,12 +209,25 @@ public class NEIClientConfig {
return true;
}
});
tag.getTag("inventory.worldSpecificPresets").setComment("Global or world specific presets").getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.worldSpecificPresets", true) {
@Override
public boolean onClick(int button) {
super.onClick(button);
initPresetsFile(worldPath);
return true;
}
});
tag.getTag("inventory.bookmarksEnabled").setComment("Enable/disable bookmarks").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.bookmarksEnabled", true));
tag.getTag("inventory.saveCurrentRecipeInBookmarksEnabled").setComment("Save Current Recipe in Bookmarks").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.saveCurrentRecipeInBookmarksEnabled", true));
tag.getTag("inventory.useNBTInBookmarks").setComment("Use NBT in Bookmarks").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.useNBTInBookmarks", true));
tag.getTag("inventory.showRecipeMarker").setComment("Show Recipe Marker").getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.showRecipeMarker", true));
tag.getTag("inventory.jei_style_tabs").setComment("Enable/disable JEI Style Tabs").getBooleanValue(true);
API.addOption(new OptionToggleButtonBoubs("inventory.jei_style_tabs", true));
@@ -271,6 +303,7 @@ public class NEIClientConfig {
API.addKeyBind("gui.hide", Keyboard.KEY_O);
API.addKeyBind("gui.search", Keyboard.KEY_F);
API.addKeyBind("gui.bookmark", Keyboard.KEY_A);
API.addKeyBind("gui.overlay", Keyboard.KEY_S);
API.addKeyBind("gui.hide_bookmarks", Keyboard.KEY_B);
API.addKeyBind("world.chunkoverlay", Keyboard.KEY_F9);
API.addKeyBind("world.moboverlay", Keyboard.KEY_F7);
@@ -303,6 +336,7 @@ public class NEIClientConfig {
}
initBookmarkFile(worldPath);
initPresetsFile(worldPath);
world = new ConfigSet(new File(specificDir, "NEI.dat"), new ConfigFile(new File(specificDir, "NEI.cfg")));
onWorldLoad(newWorld);
}
@@ -313,7 +347,7 @@ public class NEIClientConfig {
setWorldDefaults();
creativeInv = new ItemStack[54];
LayoutManager.searchField.setText(getSearchExpression());
LayoutManager.quantity.setText(Integer.toString(getItemQuantity()));
ItemPanels.itemPanel.quantity.setText(Integer.toString(getItemQuantity()));
SubsetWidget.loadHidden();
if (newWorld && Minecraft.getMinecraft().isSingleplayer())
@@ -386,6 +420,16 @@ public class NEIClientConfig {
ItemPanels.bookmarkPanel.setBookmarkFile(worldPath);
}
private static void initPresetsFile(String worldPath)
{
if (!global.config.getTag("inventory.worldSpecificPresets").getBooleanValue()) {
worldPath = "global";
}
PresetsWidget.loadPresets(worldPath);
}
public static boolean isWorldSpecific(String setting) {
if(world == null) return false;
ConfigTag tag = world.config.getTag(setting, false);
@@ -412,6 +456,9 @@ public class NEIClientConfig {
public static boolean useNBTInBookmarks() {
return getBooleanSetting("inventory.useNBTInBookmarks");
}
public static boolean showRecipeMarker() {
return getBooleanSetting("inventory.showRecipeMarker");
}
public static boolean areJEIStyleTabsVisible() {
return getBooleanSetting("inventory.jei_style_tabs");
}
@@ -507,6 +554,10 @@ public class NEIClientConfig {
return !getBooleanSetting("inventory.invertMouseScrollTransfer");
}
public static boolean shouldCacheItemRendering() {
return getBooleanSetting("inventory.cacheItemRendering") && OpenGlHelper.framebufferSupported;
}
public static boolean getMagnetMode() {
return enabledActions.contains("magnet");
}
@@ -8,6 +8,7 @@ import codechicken.nei.api.ItemInfo;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.guihook.IContainerInputHandler;
import codechicken.nei.guihook.IContainerSlotClickHandler;
import codechicken.nei.recipe.GuiRecipe;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.gui.inventory.GuiContainerCreative;
import net.minecraft.entity.player.InventoryPlayer;
@@ -137,6 +138,7 @@ public class NEIController implements IContainerSlotClickHandler, IContainerInpu
}
if (NEIClientUtils.controlKey()
&& modifier != 4//Drop key pressed: net.minecraft.client.gui.inventory.GuiContainer.keyTyped
&& slot != null && slot.getStack() != null
&& slot.isItemValid(slot.getStack())) {
NEIClientUtils.cheatItem(slot.getStack(), button, 1);
@@ -227,6 +229,11 @@ public class NEIController implements IContainerSlotClickHandler, IContainerInpu
if (!NEIClientConfig.isEnabled() || GuiInfo.hasCustomSlots(gui) || !NEIClientConfig.isMouseScrollTransferEnabled())
return false;
// slot in GuiRecipe does not contain actual stack
// and scroll should be handled by GuiRecipe, not here
if (gui instanceof GuiRecipe)
return false;
Point mousePos = getMousePosition();
Slot mouseover = manager.window.getSlotAtPosition(mousePos.x, mousePos.y);
if (mouseover != null && mouseover.getHasStack()) {
@@ -13,6 +13,7 @@ import cpw.mods.fml.client.FMLFileResourcePack;
import cpw.mods.fml.client.FMLFolderResourcePack;
import cpw.mods.fml.common.DummyModContainer;
import cpw.mods.fml.common.LoadController;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModMetadata;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLInterModComms;
@@ -24,15 +25,14 @@ import cpw.mods.fml.common.versioning.VersionRange;
import net.minecraft.util.EnumChatFormatting;
import java.io.File;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.*;
public class NEIModContainer extends DummyModContainer
{
public static LinkedList<IConfigureNEI> plugins = new LinkedList<>();
private static boolean gregTech5Loaded;
public NEIModContainer() {
super(getModMetadata());
loadMetadata();
@@ -43,9 +43,16 @@ public class NEIModContainer extends DummyModContainer
modMetadata.name = "GRADLETOKEN_MODNAME";
modMetadata.modId = "GRADLETOKEN_MODID";
modMetadata.version = "GRADLETOKEN_VERSION";
modMetadata.authorList = Arrays.asList( "ChickenBones", "mitchej123" );
modMetadata.url = "https://github.com/GTNewHorizons/NotEnoughItems";
modMetadata.description = "Recipe Viewer, Inventory Manager, Item Spawner, Cheats and more; GTNH Version includes many enhancements.";
return modMetadata;
}
public static boolean isGT5Loaded() {
return gregTech5Loaded;
}
@Override
public Set<ArtifactVersion> getRequirements() {
Set<ArtifactVersion> deps = new HashSet<>();
@@ -92,6 +99,7 @@ public class NEIModContainer extends DummyModContainer
@Subscribe
public void preInit(FMLPreInitializationEvent event) {
gregTech5Loaded = Loader.isModLoaded("gregtech") && !Loader.isModLoaded("gregapi_post");
if (CommonUtils.isClient())
ClientHandler.preInit();
}
@@ -107,7 +115,6 @@ public class NEIModContainer extends DummyModContainer
public void postInit(FMLPostInitializationEvent event) {
if (CommonUtils.isClient()) {
GuiRecipeTab.loadHandlerInfo();
RecipeCatalysts.loadCatalystInfo();
ClientHandler.postInit();
}
}
@@ -0,0 +1,48 @@
package codechicken.nei;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.api.INEIGuiAdapter;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.InventoryEffectRenderer;
import net.minecraft.potion.PotionEffect;
import java.util.Collection;
/**
* Inspired by InventoryEffectRendererGuiHandler.java in JEI
*/
public class NEIPotionGuiHandler extends INEIGuiAdapter {
@Override
public boolean hideItemPanelSlot(GuiContainer guiContainer, int slotX, int slotY, int slotW, int slotH) {
if(guiContainer instanceof InventoryEffectRenderer) {
int x = guiContainer.guiLeft - 124;
int y = guiContainer.guiTop;
Minecraft minecraft = guiContainer.mc;
if (minecraft == null) {
return false;
}
EntityPlayerSP player = minecraft.thePlayer;
if (player == null) {
return false;
}
Collection<PotionEffect> activePotionEffects = player.getActivePotionEffects();
if (activePotionEffects.isEmpty()) {
return false;
}
int height = 33;
if (activePotionEffects.size() > 5) {
height = 132 / (activePotionEffects.size() - 1);
}
Rectangle4i slotRect = new Rectangle4i(slotX, slotY, slotW, slotH);
for (PotionEffect potioneffect : activePotionEffects) {
Rectangle4i box = new Rectangle4i(x, y, 140, 32);
if(box.intersects(slotRect))
return true;
y += height;
}
}
return false;
}
}
@@ -5,6 +5,7 @@ import codechicken.core.ServerUtils;
import codechicken.lib.inventory.InventoryRange;
import codechicken.lib.inventory.InventoryUtils;
import codechicken.lib.packet.PacketCustom;
import codechicken.nei.util.NBTHelper;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.command.ICommandSender;
@@ -149,6 +150,19 @@ public class NEIServerUtils
ItemStack.areItemStackTagsEqual(stack2, stack1));
}
/**
* NBT-friendly version of {@link #areStacksSameType(ItemStack, ItemStack)}
* @param stack1 The {@link ItemStack} being compared.
* @param stack2 The {@link ItemStack} to compare to.
* @return whether the two items are the same in terms of itemID, damage and NBT.
*/
public static boolean areStacksSameTypeWithNBT(ItemStack stack1, ItemStack stack2) {
return stack1 != null && stack2 != null &&
stack1.getItem() == stack2.getItem() &&
(!stack2.getHasSubtypes() || stack2.getItemDamage() == stack1.getItemDamage()) &&
NBTHelper.matchTag(stack1.getTagCompound(), stack2.getTagCompound());
}
/**
* {@link ItemStack}s with damage -1 are wildcards allowing all damages. Eg all colours of wool are allowed to create Beds.
*
@@ -162,6 +176,24 @@ public class NEIServerUtils
(stack1.getItemDamage() == stack2.getItemDamage() || stack1.getItemDamage() == OreDictionary.WILDCARD_VALUE || stack2.getItemDamage() == OreDictionary.WILDCARD_VALUE || stack1.getItem().isDamageable());
}
/**
* NBT-friendly version of {@link #areStacksSameTypeCrafting(ItemStack, ItemStack)}
* @param stack1 The {@link ItemStack} being compared.
* @param stack2 The {@link ItemStack} to compare to.
* @return whether the two items are the same from the perspective of a crafting inventory.
*/
public static boolean areStacksSameTypeCraftingWithNBT(ItemStack stack1, ItemStack stack2) {
return stack1 != null && stack2 != null &&
stack1.getItem() == stack2.getItem() &&
(
stack1.getItemDamage() == stack2.getItemDamage() ||
stack1.getItemDamage() == OreDictionary.WILDCARD_VALUE ||
stack2.getItemDamage() == OreDictionary.WILDCARD_VALUE ||
stack1.getItem().isDamageable()
) &&
NBTHelper.matchTag(stack1.getTagCompound(), stack2.getTagCompound());
}
/**
* A simple function for comparing ItemStacks in a compatible with comparators.
*
@@ -0,0 +1,375 @@
package codechicken.nei;
import codechicken.nei.api.GuiInfo;
import codechicken.nei.api.INEIGuiHandler;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.recipe.GuiCraftingRecipe;
import codechicken.nei.recipe.GuiRecipe;
import codechicken.nei.recipe.GuiUsageRecipe;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.ItemPanel.ItemPanelSlot;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
import java.util.ArrayList;
public abstract class PanelWidget extends Widget
{
protected static final int PADDING = 2;
public ItemStack draggedStack;
public int mouseDownSlot = -1;
public Button pagePrev;
public Button pageNext;
public Label pageLabel;
protected ItemsGrid grid;
public ArrayList<ItemStack> getItems()
{
return grid.getItems();
}
public ItemsGrid getGrid()
{
return grid;
}
public void init() {
pageLabel = new Label("0/0", true);
pagePrev = new Button("Prev")
{
public boolean onButtonPress(boolean rightclick) {
if (!rightclick) {
grid.shiftPage(-1);
return true;
}
return false;
}
@Override
public String getRenderLabel() {
return "<";
}
};
pageNext = new Button("Next")
{
public boolean onButtonPress(boolean rightclick) {
if (!rightclick) {
grid.shiftPage(1);
return true;
}
return false;
}
@Override
public String getRenderLabel() {
return ">";
}
};
}
public abstract String getLabelText();
protected abstract String getPositioningSettingName();
public abstract int getMarginLeft(GuiContainer gui);
public abstract int getMarginTop(GuiContainer gui);
public abstract int getWidth(GuiContainer gui);
public abstract int getHeight(GuiContainer gui);
public void resize(GuiContainer gui)
{
final Rectangle4i margin = new Rectangle4i(getMarginLeft(gui), getMarginTop(gui), getWidth(gui), getHeight(gui));
final int minWidth = 5 * ItemsGrid.SLOT_SIZE;
final int minHeight = 9 * ItemsGrid.SLOT_SIZE;
final String settingName = getPositioningSettingName();
int paddingLeft = (int)Math.ceil(margin.w * NEIClientConfig.getSetting(settingName + ".left").getIntValue() / 100000.0);
int paddingTop = (int)Math.ceil(margin.h * NEIClientConfig.getSetting(settingName + ".top").getIntValue() / 100000.0);
int paddingRight = (int)Math.ceil(margin.w * NEIClientConfig.getSetting(settingName + ".right").getIntValue()/ 100000.0);
int paddingBottom = (int)Math.ceil(margin.h * NEIClientConfig.getSetting(settingName + ".bottom").getIntValue() / 100000.0);
int deltaHeight = Math.min(0, margin.h - paddingTop - paddingBottom - minHeight) / 2;
paddingLeft = Math.min(paddingLeft, Math.max(0, margin.w - paddingRight - minWidth));
paddingRight = Math.min(paddingRight, Math.max(0, margin.w - paddingLeft - minWidth));
paddingTop = Math.min(margin.h - minHeight, Math.max(0, paddingTop + deltaHeight));
paddingBottom = Math.min(margin.h - paddingTop - minHeight, Math.max(0, paddingBottom - deltaHeight));
x = margin.x + paddingLeft;
y = margin.y + paddingTop;
w = margin.w - paddingLeft - paddingRight;
h = margin.h - paddingTop - paddingBottom;
final int header = resizeHeader(gui);
final int footer = resizeFooter(gui);
grid.setGridSize(x, y + header, w, h - header - footer);
grid.refresh(gui);
}
protected int resizeHeader(GuiContainer gui)
{
final int BUTTON_SIZE = 16;
int paddingLeft = 0;
int paddingRight = 0;
while (paddingLeft < w && GuiInfo.hideItemPanelSlot(gui, new Rectangle4i(x + paddingLeft, y, ItemsGrid.SLOT_SIZE, ItemsGrid.SLOT_SIZE))) {
paddingLeft += ItemsGrid.SLOT_SIZE;
}
while (paddingRight < w && GuiInfo.hideItemPanelSlot(gui, new Rectangle4i(x + w - paddingRight - ItemsGrid.SLOT_SIZE, y, ItemsGrid.SLOT_SIZE, ItemsGrid.SLOT_SIZE))) {
paddingRight += ItemsGrid.SLOT_SIZE;
}
if (paddingLeft + paddingRight >= w) {
return 0;
}
pagePrev.w = pageNext.w = BUTTON_SIZE;
pagePrev.h = pageNext.h = BUTTON_SIZE;
pagePrev.y = pageNext.y = y;
pagePrev.x = x + paddingLeft;
pageNext.x = x + w - pageNext.w - paddingRight;
pageLabel.x = x + paddingLeft + (w - paddingLeft - paddingRight) / 2;
pageLabel.y = y + 5;
pageLabel.text = getLabelText();
return BUTTON_SIZE + 2;
}
protected abstract int resizeFooter(GuiContainer gui);
public void setVisible()
{
if (grid.getPerPage() > 0) {
LayoutManager.addWidget(pagePrev);
LayoutManager.addWidget(pageNext);
LayoutManager.addWidget(pageLabel);
}
}
@Override
public void draw(int mousex, int mousey)
{
grid.draw(mousex, mousey);
}
@Override
public void postDraw(int mousex, int mousey)
{
if (draggedStack != null) {
GuiContainerManager.drawItems.zLevel += 100;
GuiContainerManager.drawItem(mousex - 8, mousey - 8, draggedStack);
GuiContainerManager.drawItems.zLevel -= 100;
}
}
@Override
public void mouseDragged(int mousex, int mousey, int button, long heldTime)
{
if (mouseDownSlot >= 0 && draggedStack == null && NEIClientUtils.getHeldItem() == null &&
NEIClientConfig.hasSMPCounterPart() && !GuiInfo.hasCustomSlots(NEIClientUtils.getGuiContainer())) {
ItemPanelSlot mouseOverSlot = getSlotMouseOver(mousex, mousey);
if (mouseOverSlot == null || mouseOverSlot.slotIndex != mouseDownSlot || heldTime > 500) {
draggedStack = getDraggedStackWithQuantity(mouseDownSlot);
mouseDownSlot = -1;
}
}
}
protected abstract ItemStack getDraggedStackWithQuantity(int mouseDownSlot);
@Override
public boolean handleClick(int mousex, int mousey, int button)
{
if (handleClickExt(mousex, mousey, button))
return true;
if (NEIClientUtils.getHeldItem() != null) {
if (!grid.contains(mousex, mousey)) {
return false;
}
if (NEIClientConfig.canPerformAction("delete") && NEIClientConfig.canPerformAction("item"))
if (button == 1)
NEIClientUtils.decreaseSlotStack(-999);
else
NEIClientUtils.deleteHeldItem();
else
NEIClientUtils.dropHeldItem();
return true;
}
ItemPanelSlot hoverSlot = getSlotMouseOver(mousex, mousey);
if (hoverSlot != null) {
if (button == 2) {
if (hoverSlot.item != null) {
draggedStack = getDraggedStackWithQuantity(hoverSlot.slotIndex);
}
} else {
mouseDownSlot = hoverSlot.slotIndex;
}
return true;
}
return false;
}
@Override
public boolean handleClickExt(int mouseX, int mouseY, int button)
{
if (ItemPanels.itemPanel.draggedStack != null) {
return ItemPanels.itemPanel.handleDraggedClick(mouseX, mouseY, button);
}
if (ItemPanels.bookmarkPanel.draggedStack != null) {
return ItemPanels.bookmarkPanel.handleDraggedClick(mouseX, mouseY, button);
}
return false;
}
protected boolean handleDraggedClick(int mouseX, int mouseY, int button)
{
if (draggedStack == null) {
return false;
}
if (handleGUIContainerClick(mouseX, mouseY, button)) {
return true;
}
final GuiContainer gui = NEIClientUtils.getGuiContainer();
if (mouseX < gui.guiLeft || mouseY < gui.guiTop || mouseX >= gui.guiLeft + gui.xSize || mouseY >= gui.guiTop + gui.ySize) {
draggedStack = null;
}
return true;
}
protected boolean handleGUIContainerClick(int mouseX, int mouseY, int button)
{
final GuiContainer gui = NEIClientUtils.getGuiContainer();
boolean handled = false;
try {
GuiInfo.readLock.lock();
for (INEIGuiHandler handler : GuiInfo.guiHandlers) {
if (handler.handleDragNDrop(gui, mouseX, mouseY, draggedStack, button)) {
handled = true;
break;
}
}
} finally {
GuiInfo.readLock.unlock();
}
if (draggedStack.stackSize == 0) {
draggedStack = null;
}
return handled;
}
@Override
public void mouseUp(int mousex, int mousey, int button)
{
ItemPanelSlot hoverSlot = getSlotMouseOver(mousex, mousey);
if (hoverSlot != null && hoverSlot.slotIndex == mouseDownSlot && draggedStack == null) {
ItemStack item = hoverSlot.item;
if (NEIController.manager.window instanceof GuiRecipe || !NEIClientConfig.canCheatItem(item)) {
if (button == 0) {
GuiCraftingRecipe.openRecipeGui("item", item);
} else if (button == 1) {
GuiUsageRecipe.openRecipeGui("item", item);
}
mouseDownSlot = -1;
return;
}
NEIClientUtils.cheatItem(getDraggedStackWithQuantity(hoverSlot.slotIndex), button, -1);
}
mouseDownSlot = -1;
}
@Override
public boolean onMouseWheel(int i, int mousex, int mousey)
{
if (!contains(mousex, mousey))
return false;
grid.shiftPage(-i);
return true;
}
@Override
public boolean handleKeyPress(int keyID, char keyChar)
{
if (keyID == NEIClientConfig.getKeyBinding("gui.next")) {
grid.shiftPage(1);
return true;
}
if (keyID == NEIClientConfig.getKeyBinding("gui.prev")) {
grid.shiftPage(-1);
return true;
}
return false;
}
@Override
public ItemStack getStackMouseOver(int mousex, int mousey)
{
ItemPanelSlot slot = getSlotMouseOver(mousex, mousey);
return slot == null ? null : slot.item;
}
public ItemPanelSlot getSlotMouseOver(int mousex, int mousey)
{
return grid.getSlotMouseOver(mousex, mousey);
}
public int getPage() {
return grid.page + 1;
}
public int getNumPages() {
return grid.numPages;
}
@Override
public boolean contains(int px, int py)
{
return grid.contains(px, py);
}
}
@@ -98,6 +98,17 @@ public class PositionedStack
return false;
}
/**
* NBT-friendly version of {@link #contains(ItemStack)}
*/
public boolean containsWithNBT(ItemStack ingredient) {
for(ItemStack item : items)
if(NEIServerUtils.areStacksSameTypeCraftingWithNBT(item, ingredient))
return true;
return false;
}
public boolean contains(Item ingred) {
for(ItemStack item : items)
if(item.getItem() == ingred)
File diff suppressed because it is too large. Load diff
@@ -217,6 +217,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider, ItemsLoa
for(SubsetTag tag : sorted)
tag.cacheState();
}
public void addFiltersWithItem(List<ItemFilter> filters, String itemSearch) {
if(itemSearch == null) {
addFilters(filters);
@@ -229,6 +230,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider, ItemsLoa
}
}
public void addFilters(List<ItemFilter> filters) {
if(filter != null)
filters.add(filter);
@@ -11,6 +11,14 @@ public class VisiblityData
* Bookmark panel and associated buttons
*/
public boolean showBookmarkPanel = true;
/**
* Subset dropdown
*/
public boolean showSubsetDropdown = true;
/**
* Presets dropdown
*/
public boolean showPresetsDropdown = true;
/**
* Item and search section
*/
@@ -40,6 +48,6 @@ public class VisiblityData
if(!showWidgets)
showItemSection = showUtilityButtons = false;
if(!showItemSection)
showBookmarkPanel = showSearchSection = showItemPanel = false;
showBookmarkPanel = showSubsetDropdown = showPresetsDropdown = showSearchSection = showItemPanel = false;
}
}
@@ -15,11 +15,14 @@ import net.minecraft.world.biome.BiomeGenBase;
import net.minecraft.world.chunk.Chunk;
import org.lwjgl.opengl.GL11;
public class WorldOverlayRenderer implements IKeyStateTracker
{
public static int mobOverlay = 0;
public class WorldOverlayRenderer implements IKeyStateTracker {
public static int chunkOverlay = 0;
public static int mobOverlay = 0;
private static byte[] mobSpawnCache;
private static long mobOverlayUpdateTime;
public static void reset() {
mobOverlay = 0;
chunkOverlay = 0;
@@ -33,7 +36,7 @@ public class WorldOverlayRenderer implements IKeyStateTracker
if (KeyManager.keyStates.get("world.moboverlay").down)
mobOverlay = (mobOverlay + 1) % 2;
if (KeyManager.keyStates.get("world.chunkoverlay").down)
chunkOverlay = (chunkOverlay + 1) % 3;
chunkOverlay = (chunkOverlay + 1) % (NEIModContainer.isGT5Loaded() ? 4 : 3);
}
public static void render(float frame) {
@@ -46,9 +49,56 @@ public class WorldOverlayRenderer implements IKeyStateTracker
GL11.glPopMatrix();
}
private static void buildMobSpawnOverlay(Entity entity) {
if (mobSpawnCache == null) {
mobSpawnCache = new byte[33 * 33 * 33]; // 35kB
}
World world = entity.worldObj;
int x1 = (int) entity.posX;
int z1 = (int) entity.posZ;
int y1 = (int) MathHelper.clip(entity.posY, 16, world.getHeight() - 16);
for (int i = 0; i <= 32; i++) {
int x = x1 - 16 + i;
for (int j = 0; j <= 32; j++) {
int z = z1 - 16 + j;
int bufIndex = (i * 33 + j) * 33;
Chunk chunk = world.getChunkFromBlockCoords(x, z);
BiomeGenBase biome = world.getBiomeGenForCoords(x, z);
if (biome.getSpawnableList(EnumCreatureType.monster).isEmpty() || biome.getSpawningChance() <= 0) {
mobSpawnCache[bufIndex] = -1;
continue;
}
int maxHeight = chunk.worldObj.getHeightValue(x, z);
for (int k = 0; k <= 32; k++) {
int y = y1 - 16 + k;
if (y > maxHeight) {
mobSpawnCache[bufIndex + k] = -1;
break;
}
mobSpawnCache[bufIndex + k] = getSpawnMode(chunk, x, y, z);
}
}
}
}
private static void renderMobSpawnOverlay(Entity entity) {
if (mobOverlay == 0)
if (mobOverlay == 0) {
if (mobSpawnCache != null) {
mobSpawnCache = null;
}
return;
}
long worldTime = entity.worldObj.getTotalWorldTime();
if (mobSpawnCache == null || mobOverlayUpdateTime != worldTime) {
mobOverlayUpdateTime = worldTime;
buildMobSpawnOverlay(entity);
}
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND);
@@ -65,32 +115,37 @@ public class WorldOverlayRenderer implements IKeyStateTracker
int z1 = (int) entity.posZ;
int y1 = (int) MathHelper.clip(entity.posY, 16, world.getHeight() - 16);
for (int x = x1 - 16; x <= x1 + 16; x++)
for (int z = z1 - 16; z <= z1 + 16; z++) {
Chunk chunk = world.getChunkFromBlockCoords(x, z);
BiomeGenBase biome = world.getBiomeGenForCoords(x, z);
if (biome.getSpawnableList(EnumCreatureType.monster).isEmpty() || biome.getSpawningChance() <= 0)
continue;
for (int i = 0; i <= 32; i++) {
int x = x1 - 16 + i;
for (int j = 0; j <= 32; j++) {
int z = z1 - 16 + j;
int cacheIndex = (i * 33 + j) * 33;
for (int y = y1 - 16; y < y1 + 16; y++) {
int spawnMode = getSpawnMode(chunk, x, y, z);
if (spawnMode == 0)
for (int k = 0; k <= 32; k++) {
int y = y1 - 16 + k;
int spawnMode = mobSpawnCache[cacheIndex + k];
if (spawnMode == 0) {
continue;
} else if (spawnMode == -1) {
break;
}
if (spawnMode != curSpawnMode) {
if (spawnMode == 1)
if (spawnMode == 1) {
GL11.glColor4f(1, 1, 0, 1);
else
} else {
GL11.glColor4f(1, 0, 0, 1);
}
curSpawnMode = spawnMode;
}
GL11.glVertex3d(x, y + 0.004, z);
GL11.glVertex3d(x + 1, y + 0.004, z + 1);
GL11.glVertex3d(x + 1, y + 0.004, z);
GL11.glVertex3d(x, y + 0.004, z + 1);
GL11.glVertex3d(x, y + 0.02, z);
GL11.glVertex3d(x + 1, y + 0.02, z + 1);
GL11.glVertex3d(x + 1, y + 0.02, z);
GL11.glVertex3d(x, y + 0.02, z + 1);
}
}
}
GL11.glEnd();
GL11.glEnable(GL11.GL_LIGHTING);
@@ -100,10 +155,12 @@ public class WorldOverlayRenderer implements IKeyStateTracker
private static final Entity dummyEntity = new EntityPig(null);
private static final AxisAlignedBB aabb = AxisAlignedBB.getBoundingBox(0, 0, 0, 0, 0, 0);
private static int getSpawnMode(Chunk chunk, int x, int y, int z) {
private static byte getSpawnMode(Chunk chunk, int x, int y, int z) {
if (!SpawnerAnimals.canCreatureTypeSpawnAtLocation(EnumCreatureType.monster, chunk.worldObj, x, y, z) ||
chunk.getSavedLightValue(EnumSkyBlock.Block, x & 15, y, z & 15) >= 8)
chunk.getSavedLightValue(EnumSkyBlock.Block, x & 15, y, z & 15) >= 8) {
return 0;
}
aabb.minX = x + 0.2;
aabb.maxX = x + 0.8;
@@ -111,14 +168,11 @@ public class WorldOverlayRenderer implements IKeyStateTracker
aabb.maxY = y + 1.8;
aabb.minZ = z + 0.2;
aabb.maxZ = z + 0.8;
if (!chunk.worldObj.checkNoEntityCollision(aabb) ||
!chunk.worldObj.getCollidingBoundingBoxes(dummyEntity, aabb).isEmpty() ||
chunk.worldObj.isAnyLiquid(aabb))
if (!chunk.worldObj.getCollidingBoundingBoxes(dummyEntity, aabb).isEmpty() || chunk.worldObj.isAnyLiquid(aabb)) {
return 0;
}
if (chunk.getSavedLightValue(EnumSkyBlock.Sky, x & 15, y, z & 15) >= 8)
return 1;
return 2;
return (byte) (chunk.getSavedLightValue(EnumSkyBlock.Sky, x & 15, y, z & 15) >= 8 ? 1 : 2);
}
private static void renderChunkBounds(Entity entity) {
@@ -172,40 +226,93 @@ public class WorldOverlayRenderer implements IKeyStateTracker
GL11.glVertex3d(x1, y2, z1);
}
if (chunkOverlay == 2 && cx == 0 && cz == 0) {
dy = 32;
y1 = Math.floor(entity.posY - dy / 2);
y2 = y1 + dy;
if (y1 < 0) {
y1 = 0;
y2 = dy;
}
if (cx == 0 && cz == 0) {
if (chunkOverlay == 2) {
dy = 32;
y1 = Math.floor(entity.posY - dy / 2);
y2 = y1 + dy;
if (y1 < 0) {
y1 = 0;
y2 = dy;
}
if (y1 > entity.worldObj.getHeight()) {
y2 = entity.worldObj.getHeight();
y1 = y2 - dy;
}
if (y1 > entity.worldObj.getHeight()) {
y2 = entity.worldObj.getHeight();
y1 = y2 - dy;
}
GL11.glColor4d(0, 0.9, 0, 0.4);
for (double y = (int) y1; y <= y2; y++) {
GL11.glVertex3d(x2, y, z1);
GL11.glVertex3d(x2, y, z2);
GL11.glVertex3d(x1, y, z1);
GL11.glVertex3d(x1, y, z2);
GL11.glVertex3d(x1, y, z2);
GL11.glVertex3d(x2, y, z2);
GL11.glVertex3d(x1, y, z1);
GL11.glVertex3d(x2, y, z1);
}
for (double h = 1; h <= 15; h++) {
GL11.glVertex3d(x1 + h, y1, z1);
GL11.glVertex3d(x1 + h, y2, z1);
GL11.glVertex3d(x1 + h, y1, z2);
GL11.glVertex3d(x1 + h, y2, z2);
GL11.glVertex3d(x1, y1, z1 + h);
GL11.glVertex3d(x1, y2, z1 + h);
GL11.glVertex3d(x2, y1, z1 + h);
GL11.glVertex3d(x2, y2, z1 + h);
GL11.glColor4d(0, 0.9, 0, 0.4);
for (double y = (int) y1; y <= y2; y++) {
GL11.glVertex3d(x2, y, z1);
GL11.glVertex3d(x2, y, z2);
GL11.glVertex3d(x1, y, z1);
GL11.glVertex3d(x1, y, z2);
GL11.glVertex3d(x1, y, z2);
GL11.glVertex3d(x2, y, z2);
GL11.glVertex3d(x1, y, z1);
GL11.glVertex3d(x2, y, z1);
}
for (double h = 1; h <= 15; h++) {
GL11.glVertex3d(x1 + h, y1, z1);
GL11.glVertex3d(x1 + h, y2, z1);
GL11.glVertex3d(x1 + h, y1, z2);
GL11.glVertex3d(x1 + h, y2, z2);
GL11.glVertex3d(x1, y1, z1 + h);
GL11.glVertex3d(x1, y2, z1 + h);
GL11.glVertex3d(x2, y1, z1 + h);
GL11.glVertex3d(x2, y2, z1 + h);
}
} else if (chunkOverlay == 3) {
int gx1 = ((entity.chunkCoordX < 0 ? entity.chunkCoordX - 3 : entity.chunkCoordX) / 3 * 3) << 4;
int gz1 = ((entity.chunkCoordZ < 0 ? entity.chunkCoordZ - 3 : entity.chunkCoordZ) / 3 * 3) << 4;
if (entity.chunkCoordX < 0) {
gx1 += 16;
}
if (entity.chunkCoordZ < 0) {
gz1 += 16;
}
int gx2 = gx1 + 48;
int gz2 = gz1 + 48;
GL11.glColor4d(0, 0.9, 0, 0.4);
for (double y = (int) y1; y <= y2; y++) {
GL11.glVertex3d(gx2, y, gz1);
GL11.glVertex3d(gx2, y, gz2);
GL11.glVertex3d(gx1, y, gz1);
GL11.glVertex3d(gx1, y, gz2);
GL11.glVertex3d(gx1, y, gz2);
GL11.glVertex3d(gx2, y, gz2);
GL11.glVertex3d(gx1, y, gz1);
GL11.glVertex3d(gx2, y, gz1);
}
for (double h = 4; h <= 44; h += 4) {
if (h % 16 == 0) {
continue;
}
GL11.glVertex3d(gx1 + h, y1, gz1);
GL11.glVertex3d(gx1 + h, y2, gz1);
GL11.glVertex3d(gx1 + h, y1, gz2);
GL11.glVertex3d(gx1 + h, y2, gz2);
GL11.glVertex3d(gx1, y1, gz1 + h);
GL11.glVertex3d(gx1, y2, gz1 + h);
GL11.glVertex3d(gx2, y1, gz1 + h);
GL11.glVertex3d(gx2, y2, gz1 + h);
}
GL11.glColor4d(0, 0, 0.9, 0.4);
gx1 += 23;
gz1 += 23;
gx2 = gx1 + 1;
gz2 = gz1 + 1;
GL11.glVertex3d(gx1, y1, gz1);
GL11.glVertex3d(gx1, y2, gz1);
GL11.glVertex3d(gx2, y1, gz1);
GL11.glVertex3d(gx2, y2, gz1);
GL11.glVertex3d(gx1, y1, gz2);
GL11.glVertex3d(gx1, y2, gz2);
GL11.glVertex3d(gx2, y1, gz2);
GL11.glVertex3d(gx2, y2, gz2);
}
}
}
@@ -1,9 +1,15 @@
package codechicken.nei.api;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.NEIChestGuiHandler;
import codechicken.nei.NEICreativeGuiHandler;
import codechicken.nei.NEIDummySlotHandler;
import codechicken.nei.NEIPotionGuiHandler;
import codechicken.nei.recipe.GuiRecipeCatalyst;
import codechicken.nei.recipe.SearchInputDropHandler;
import codechicken.nei.recipe.FillFluidContainerHandler;
import codechicken.nei.recipe.CheatItemHandler;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.gui.inventory.GuiContainerCreative;
@@ -25,6 +31,10 @@ public class GuiInfo {
API.registerNEIGuiHandler(new NEIChestGuiHandler());
API.registerNEIGuiHandler(new NEIDummySlotHandler());
API.registerNEIGuiHandler(new GuiRecipeCatalyst(null));
API.registerNEIGuiHandler(new SearchInputDropHandler());
API.registerNEIGuiHandler(new FillFluidContainerHandler());
API.registerNEIGuiHandler(new CheatItemHandler());
API.registerNEIGuiHandler(new NEIPotionGuiHandler());
customSlotGuis.add(GuiContainerCreative.class);
}
@@ -40,4 +50,28 @@ public class GuiInfo {
public static boolean hasCustomSlots(GuiContainer gui) {
return customSlotGuis.contains(gui.getClass());
}
public static boolean hideItemPanelSlot(GuiContainer gui, Rectangle4i rect)
{
try {
readLock.lock();
if (guiHandlers.stream().anyMatch(handler -> handler.hideItemPanelSlot(gui, rect.x, rect.y, rect.w, rect.h))) {
return true;
}
} finally {
readLock.unlock();
}
for (Object item : gui.buttonList) {
GuiButton button = (GuiButton) item;
if ((new Rectangle4i(button.xPosition, button.yPosition, button.width, button.height)).intersects(rect)) {
return true;
}
}
return false;
}
}
@@ -1,8 +1,13 @@
package codechicken.nei.api;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.inventory.GuiContainer;
public interface IGuiContainerOverlay
{
public GuiContainer getFirstScreen();
GuiContainer getFirstScreen();
default GuiScreen getFirstScreenGeneral() {
return getFirstScreen();
}
}
@@ -58,6 +58,7 @@ import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
/**
* This is an internal class for storing information about items, to be accessed by the API
@@ -82,8 +83,36 @@ public class ItemInfo
public static final HashMap<Item, String> itemOwners = new HashMap<>();
private static class ItemStackKey {
public final ItemStack stack;
public ItemStackKey(ItemStack stack) {
this.stack = stack;
}
@Override
public int hashCode() {
if(this.stack == null)
return 1;
int hashCode = 1;
hashCode = 31 * hashCode + stack.stackSize;
hashCode = 31 * hashCode + Item.getIdFromItem(stack.getItem());
hashCode = 31 * hashCode + stack.getItemDamage();
hashCode = 31 * hashCode + (!stack.hasTagCompound() ? 0 : stack.getTagCompound().hashCode());
return hashCode;
}
@Override
public boolean equals(Object o) {
if(o == this)
return true;
if(!(o instanceof ItemStackKey))
return false;
return ItemStack.areItemStacksEqual(this.stack, ((ItemStackKey)o).stack);
}
}
//lookup optimisation
public static final HashMap<ItemStack, String> itemSearchNames = new HashMap<>();
public static final ConcurrentHashMap<ItemStackKey, String> itemSearchNames = new ConcurrentHashMap<>();
public static boolean isHidden(ItemStack stack) {
return hiddenItems.contains(stack);
@@ -129,7 +158,18 @@ public class ItemInfo
}
private static void addSearchOptimisation() {
ItemList.loadCallbacks.add(itemSearchNames::clear);
ItemList.loadCallbacks.add(ItemInfo::populateSearchMap);
}
private static void populateSearchMap() {
/* Create a snapshot of the current keys in the cache */
HashSet<ItemStackKey> oldItems = new HashSet<>(itemSearchNames.keySet());
for(ItemStack stack : ItemList.items) {
/* Populate each entry and remove it from the snapshot */
getSearchName(stack);
oldItems.remove(new ItemStackKey(stack));
}
itemSearchNames.keySet().removeAll(oldItems);
}
private static void addHiddenItemFilter() {
@@ -517,11 +557,8 @@ public class ItemInfo
}
public static String getSearchName(ItemStack stack) {
String s = itemSearchNames.get(stack);
if(s == null) {
s = EnumChatFormatting.getTextWithoutFormattingCodes(GuiContainerManager.concatenatedDisplayName(stack, true).toLowerCase());
itemSearchNames.put(stack, s);
}
return s;
return itemSearchNames.computeIfAbsent(new ItemStackKey(stack), key ->
EnumChatFormatting.getTextWithoutFormattingCodes(GuiContainerManager.concatenatedDisplayName(key.stack, true).toLowerCase())
);
}
}
@@ -4,12 +4,14 @@ import codechicken.core.launch.CodeChickenCorePlugin;
import codechicken.lib.asm.ASMInit;
import cpw.mods.fml.relauncher.IFMLCallHook;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin.TransformerExclusions;
import java.io.File;
import java.util.Map;
@TransformerExclusions(value = {"codechicken.nei.asm"})
@MCVersion( "1.7.10" )
public class NEICorePlugin implements IFMLLoadingPlugin, IFMLCallHook
{
public static File location;
@@ -0,0 +1,317 @@
package codechicken.nei.config;
import codechicken.core.gui.GuiScreenWidget;
import codechicken.lib.render.CCRenderState;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.ItemPanels;
import codechicken.nei.ItemsGrid;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.item.ItemStack;
import codechicken.nei.guihook.GuiContainerManager;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import java.awt.Point;
import java.util.ArrayList;
import static codechicken.lib.gui.GuiDraw.getMousePosition;
public class GuiPanelSettings extends GuiScreenWidget
{
private final Option opt;
private PanelPlaceholder bookmarksPanel;
private PanelPlaceholder itemsPanel;
protected static class PanelResizeButton
{
private int x;
private int y;
private int w;
private int h;
public PanelResizeButton(int w, int h)
{
this.w = w;
this.h = h;
}
public void draw(int mousex, int mousey)
{
drawRect(x, y, x + w, y + h, 0xbbaaaaaa);
drawRect(x + 2, y + 2, x + w - 2, y + h - 2, contains(mousex, mousey)? 0xFF000000: 0xbb000000);
}
public boolean contains(int pointX, int pointY)
{
return (new Rectangle4i(x, y, w, h)).contains(pointX, pointY);
}
}
protected static class PanelPlaceholder
{
protected static int PANEL_SIZE = 16;
private final Option opt;
private final String name;
private Rectangle4i margin;
private Point dragDown;
private String dragDir;
private int x = 0;
private int y = 0;
private int w = 0;
private int h = 0;
private PanelResizeButton leftButton = new PanelResizeButton(PANEL_SIZE, PANEL_SIZE * 2);
private PanelResizeButton topButton = new PanelResizeButton(PANEL_SIZE * 2, PANEL_SIZE);
private PanelResizeButton rightButton = new PanelResizeButton(PANEL_SIZE, PANEL_SIZE * 2);
private PanelResizeButton bottomButton = new PanelResizeButton(PANEL_SIZE * 2, PANEL_SIZE);
public PanelPlaceholder(Option opt, String name)
{
this.opt = opt;
this.name = name;
}
public void resize(Rectangle4i margin)
{
this.margin = margin;
int[] padding = getPaddings();
x = margin.x + padding[0];
y = margin.y + padding[1];
w = margin.w - padding[2] - padding[0];
h = margin.h - padding[3] - padding[1];
leftButton.x = x;
leftButton.y = y + h / 2 - PANEL_SIZE;
rightButton.x = x + w - PANEL_SIZE;
rightButton.y = y + h / 2 - PANEL_SIZE;
topButton.x = x + w / 2 - PANEL_SIZE;
topButton.y = y;
bottomButton.x = x + w / 2 - PANEL_SIZE;
bottomButton.y = y + h - PANEL_SIZE;
}
public void draw(int mousex, int mousey)
{
drawRect(x, y, x + w, y + PANEL_SIZE, 0xbbaaaaaa); //top-panel
drawRect(x, y + h - PANEL_SIZE, x + w, y + h, 0xbbaaaaaa); //bottom-panel
drawRect(x, y, x + 2, y + h, 0xbbaaaaaa); //border left
drawRect(x + w, y, x + w - 2, y + h, 0xbbaaaaaa); //border right
drawRect(x, y, x + w, y + 2, 0xbbaaaaaa); //border top
drawRect(x, y + h, x + w, y + h - 2, 0xbbaaaaaa); //border bottom
drawItems();
leftButton.draw(mousex, mousey);
rightButton.draw(mousex, mousey);
topButton.draw(mousex, mousey);
bottomButton.draw(mousex, mousey);
}
protected int[] getPaddings()
{
final int minWidth = 5 * ItemsGrid.SLOT_SIZE;
final int minHeight = 9 * ItemsGrid.SLOT_SIZE;
int paddingLeft = (int)Math.ceil(margin.w * opt.renderTag(name + ".left").getIntValue() / 100000.0);
int paddingTop = (int)Math.ceil(margin.h * opt.renderTag(name + ".top").getIntValue() / 100000.0);
int paddingRight = (int)Math.ceil(margin.w * opt.renderTag(name + ".right").getIntValue() / 100000.0);
int paddingBottom = (int)Math.ceil(margin.h * opt.renderTag(name + ".bottom").getIntValue() / 100000.0);
if (dragDir != null) {
final Point mouse = getMousePosition();
Point drag = new Point(mouse.x - dragDown.x, mouse.y - dragDown.y);
if (dragDir == "left") {
paddingLeft = Math.min(Math.max(0, margin.w - paddingRight - minWidth), Math.max(0, paddingLeft + drag.x));
} else if (dragDir == "right") {
paddingRight = Math.min(Math.max(0, margin.w - paddingLeft - minWidth), Math.max(0, paddingRight - drag.x));
} else if (dragDir == "top") {
paddingTop = Math.min(Math.max(0, margin.h - paddingBottom - minHeight), Math.max(0, paddingTop + drag.y));
} else if (dragDir == "bottom") {
paddingBottom = Math.min(Math.max(0, margin.h - paddingTop - minHeight), Math.max(0, paddingBottom - drag.y));
} else if (dragDir == "move") {
int width = margin.w - paddingRight - paddingLeft;
int height = margin.h - paddingTop - paddingBottom;
paddingLeft = Math.min(Math.max(0, margin.w - width), Math.max(0, paddingLeft + drag.x));
paddingTop = Math.min(Math.max(0, margin.h - height), Math.max(0, paddingTop + drag.y));
paddingRight = margin.w - paddingLeft - width;
paddingBottom = margin.h - paddingTop - height;
}
}
int deltaHeight = Math.min(0, margin.h - paddingTop - paddingBottom - minHeight) / 2;
paddingLeft = Math.min(paddingLeft, Math.max(0, margin.w - paddingRight - minWidth));
paddingRight = Math.min(paddingRight, Math.max(0, margin.w - paddingLeft - minWidth));
paddingTop = Math.min(margin.h - minHeight, Math.max(0, paddingTop + deltaHeight));
paddingBottom = Math.min(margin.h - paddingTop - minHeight, Math.max(0, paddingBottom - deltaHeight));
return new int[]{ paddingLeft, paddingTop, paddingRight, paddingBottom };
}
protected void drawItems()
{
final int columns = w / ItemsGrid.SLOT_SIZE;
final int rows = (h - (PANEL_SIZE + 2) * 2) / ItemsGrid.SLOT_SIZE;
final int paddingLeft = (w % ItemsGrid.SLOT_SIZE) / 2;
final ArrayList<ItemStack> items = ItemPanels.itemPanel.getItems();
for (int r = 0; r < rows; r ++) {
for (int c = 0; c < columns; c++) {
GuiContainerManager.drawItem(
x + paddingLeft + ItemsGrid.SLOT_SIZE * c + 1,
y + PANEL_SIZE + 2 + ItemsGrid.SLOT_SIZE * r + 1,
items.get((r * columns + c) % items.size())
);
}
}
}
public boolean contains(int pointX, int pointY)
{
return (new Rectangle4i(x, y, w, h)).contains(pointX, pointY);
}
protected void mouseClicked(int x, int y, int button)
{
if (contains(x, y)) {
dragDown = getMousePosition();
if (leftButton.contains(x, y)) {
dragDir = "left";
} else if (rightButton.contains(x, y)) {
dragDir = "right";
} else if (topButton.contains(x, y)) {
dragDir = "top";
} else if (bottomButton.contains(x, y)) {
dragDir = "bottom";
} else {
dragDir = "move";
}
}
}
protected void mouseMovedOrUp(int x, int y, int button)
{
if (button == 0 && dragDown != null) {
int[] padding = getPaddings();
opt.renderTag(name + ".left").setIntValue(padding[0] * 100000 / margin.w);
opt.renderTag(name + ".top").setIntValue(padding[1] * 100000 / margin.h);
opt.renderTag(name + ".right").setIntValue(padding[2] * 100000 / margin.w);
opt.renderTag(name + ".bottom").setIntValue(padding[3] * 100000 / margin.h);
dragDir = null;
dragDown = null;
}
}
}
public GuiPanelSettings(Option opt) {
super(176, 198);
this.opt = opt;
bookmarksPanel = new PanelPlaceholder(opt, opt.name + ".bookmarks");
itemsPanel = new PanelPlaceholder(opt, opt.name + ".items");
}
@Override
public boolean doesGuiPauseGame()
{
return true;
}
@Override
public void keyTyped(char c, int keycode)
{
if (keycode == Keyboard.KEY_ESCAPE || keycode == Keyboard.KEY_BACK) {
Minecraft.getMinecraft().displayGuiScreen(opt.slot.getGui());
return;
}
super.keyTyped(c, keycode);
}
protected void drawGuiContainerBackgroundLayer(float var1, int var2, int var3) {
GL11.glColor4f(1, 1, 1, 1);
CCRenderState.changeTexture("nei:textures/gui/inv.png");
int x = guiLeft;
int y = guiTop - 4;
drawTexturedModalRect(x - 23, y, 0, 0, 199, 204);
}
@Override
public void drawScreen(int mousex, int mousey, float f)
{
drawGuiContainerBackgroundLayer(f, mousex, mousey);
drawDefaultBackground();
RenderHelper.enableGUIStandardItemLighting();
GL11.glPushMatrix();
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
bookmarksPanel.resize(getBookmarkDefaultSize());
itemsPanel.resize(getItemsDefaultSize());
bookmarksPanel.draw(mousex, mousey);
itemsPanel.draw(mousex, mousey);
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
GL11.glPopMatrix();
RenderHelper.enableStandardItemLighting();
}
private Rectangle4i getBookmarkDefaultSize()
{
return new Rectangle4i(2, 2, guiLeft - 4, height - 4);
}
protected Rectangle4i getItemsDefaultSize()
{
return new Rectangle4i(guiLeft + xSize + 2, 2, width - (guiLeft + xSize + 4), height - 4);
}
@Override
protected void mouseClicked(int x, int y, int button)
{
bookmarksPanel.mouseClicked(x, y, button);
itemsPanel.mouseClicked(x, y, button);
}
@Override
protected void mouseMovedOrUp(int x, int y, int button)
{
bookmarksPanel.mouseMovedOrUp(x, y, button);
itemsPanel.mouseMovedOrUp(x, y, button);
}
}
@@ -2,17 +2,26 @@ package codechicken.nei.config;
import codechicken.core.CommonUtils;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIServerUtils;
import codechicken.nei.recipe.CatalystInfo;
import codechicken.nei.recipe.GuiRecipeTab;
import codechicken.nei.recipe.HandlerInfo;
import codechicken.nei.recipe.RecipeCatalysts;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.event.FMLInterModComms;
import cpw.mods.fml.common.event.FMLInterModComms.IMCMessage;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class IMCHandler {
private static final Set<String> processedCatalystSenders = new HashSet<>();
private IMCHandler() {}
public static void processIMC(List<FMLInterModComms.IMCMessage> messages) {
@@ -20,10 +29,19 @@ public class IMCHandler {
String type = message.key;
if (type == null || type.isEmpty()) continue;
if (CommonUtils.isClient()) {
if (type.equals("registerHandlerInfo")) {
handleRegisterHandlerInfo(message);
} else if (type.equals("removeHandlerInfo")) {
handleRemoveHandlerInfo(message);
switch (type) {
case "registerHandlerInfo":
handleRegisterHandlerInfo(message);
break;
case "removeHandlerInfo":
handleRemoveHandlerInfo(message);
break;
case "registerCatalystInfo":
handleRegisterCatalystInfo(message);
break;
case "removeCatalystInfo":
handleRemoveCatalystInfo(message);
break;
}
}
@@ -91,6 +109,72 @@ public class IMCHandler {
GuiRecipeTab.handlerRemoverFromIMC.add(handler);
}
private static void handleRegisterCatalystInfo(IMCMessage message) {
if (!message.isNBTMessage()) {
logInvalidMessage(message, "NBT");
return;
}
if (!processedCatalystSenders.contains(message.getSender())) {
NEIClientConfig.logger.info("Processing registerCatalystInfo from " + message.getSender());
processedCatalystSenders.add(message.getSender());
}
final NBTTagCompound tag = message.getNBTValue();
final String handlerID = tag.getString("handlerID");
if (handlerID.isEmpty()) {
NEIClientConfig.logger.warn("Missing handlerID for registerCatalystInfo!");
return;
}
final String itemName = tag.getString("itemName");
final String nbtInfo = tag.hasKey("nbtInfo") ? tag.getString("nbtInfo") : null;
if (itemName.isEmpty()) {
NEIClientConfig.logger.warn(String.format("Missing itemName for registerCatalystInfo in `%s`!", handlerID));
return;
}
final ItemStack itemStack = NEIServerUtils.getModdedItem(itemName, nbtInfo);
if (itemStack == null) {
NEIClientConfig.logger.warn(String.format("Cannot find item `%s`!", itemName));
return;
}
final int priority = tag.getInteger("priority");
RecipeCatalysts.addOrPut(RecipeCatalysts.catalystsAdderFromIMC, handlerID, new CatalystInfo(itemStack, priority));
NEIClientConfig.logger.info(String.format("Added catalyst `%s` to handler %s", itemStack.getDisplayName(), handlerID));
}
private static void handleRemoveCatalystInfo(IMCMessage message) {
if (!message.isNBTMessage()) {
logInvalidMessage(message, "NBT");
return;
}
NEIClientConfig.logger.info("Processing removeCatalystInfo from " + message.getSender());
final NBTTagCompound tag = message.getNBTValue();
final String handlerID = tag.getString("handlerID");
if (handlerID.isEmpty()) {
NEIClientConfig.logger.warn("Missing handlerID for registerCatalystInfo!");
return;
}
final String itemName = tag.getString("itemName");
final String nbtInfo = tag.hasKey("nbtInfo") ? tag.getString("nbtInfo") : null;
if (itemName.isEmpty()) {
NEIClientConfig.logger.warn(String.format("Missing itemName for registerCatalystInfo in `%s`!", handlerID));
return;
}
final ItemStack itemStack = NEIServerUtils.getModdedItem(itemName, nbtInfo);
if (itemStack == null) {
NEIClientConfig.logger.warn(String.format("Cannot find item `%s`!", itemName));
return;
}
if (RecipeCatalysts.catalystsRemoverFromIMC.containsKey(handlerID)) {
RecipeCatalysts.catalystsRemoverFromIMC.get(handlerID).add(itemStack);
} else {
RecipeCatalysts.catalystsRemoverFromIMC.put(handlerID, new ArrayList<>(Collections.singletonList(itemStack)));
}
NEIClientConfig.logger.info(String.format("Removed catalyst `%s` from handler %s", itemStack.getDisplayName(), handlerID));
}
private static void logInvalidMessage(FMLInterModComms.IMCMessage message, String type) {
FMLLog.bigWarning(String.format("Received invalid IMC '%s' from %s. Not a %s Message.", message.key, message.getSender(), type));
@@ -4,8 +4,6 @@ import codechicken.nei.Image;
import codechicken.nei.LayoutManager;
import codechicken.nei.drawable.DrawableBuilder;
import codechicken.nei.drawable.DrawableResource;
import org.lwjgl.opengl.GL11;
import java.awt.Rectangle;
public class OptionToggleButtonBoubs extends OptionButton {
@@ -14,6 +14,7 @@ import net.minecraft.util.EnumChatFormatting;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import java.awt.Point;
import java.io.PrintWriter;
@@ -179,30 +180,47 @@ public class GuiContainerManager
}
public static void drawItem(int i, int j, ItemStack itemstack) {
drawItem(i, j, itemstack, getFontRenderer(itemstack));
drawItem(i, j, itemstack, false);
}
public static void drawItem(int i, int j, ItemStack itemstack, boolean smallAmount) {
drawItem(i, j, itemstack, getFontRenderer(itemstack), smallAmount);
drawItem(i, j, itemstack, smallAmount, null);
}
public static void drawItem(int i, int j, ItemStack itemstack, boolean smallAmount, String stackSize) {
drawItem(i, j, itemstack, getFontRenderer(itemstack), smallAmount, stackSize);
}
public static void drawItem(int i, int j, ItemStack itemstack, FontRenderer fontRenderer) {
drawItem(i, j, itemstack, fontRenderer, false);
drawItem(i, j, itemstack, fontRenderer, false, null);
}
private static int modelviewDepth = -1;
private static final HashSet<String> stackTraces = new HashSet<>();
public static void drawItem(int i, int j, ItemStack itemstack, FontRenderer fontRenderer, boolean smallAmount) {
public static void drawItem(int i, int j, ItemStack itemstack, FontRenderer fontRenderer, boolean smallAmount, String stackSize) {
enable3DRender();
//for lighting correction
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
float zLevel = drawItems.zLevel += 100F;
try {
drawItems.renderItemAndEffectIntoGUI(fontRenderer, renderEngine, itemstack, i, j);
if (!smallAmount) {
drawItems.renderItemOverlayIntoGUI(fontRenderer, renderEngine, itemstack, i, j);
} else if (itemstack.stackSize > 1) {
drawBigStackSize(i, j, itemstack.stackSize);
if (stackSize == null) {
stackSize = itemstack.stackSize > 1? String.valueOf(itemstack.stackSize): "";
}
if (smallAmount) {
if (!stackSize.isEmpty()) {
drawBigStackSize(i, j, stackSize);
}
// stackSize = "". it needed for correct draw item with alpha and blend
drawItems.renderItemOverlayIntoGUI(fontRenderer, renderEngine, itemstack, i, j, "");
} else {
drawItems.renderItemOverlayIntoGUI(fontRenderer, renderEngine, itemstack, i, j, stackSize);
}
if (!checkMatrixStack())
@@ -227,29 +245,27 @@ public class GuiContainerManager
drawItems.renderItemIntoGUI(fontRenderer, renderEngine, new ItemStack(Blocks.fire), i, j);
}
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
enable2DRender();
drawItems.zLevel = zLevel - 100;
}
//copy from appeng.client.render.AppEngRenderItem
protected static void drawBigStackSize(int offsetX, int offsetY, int amount)
protected static void drawBigStackSize(int offsetX, int offsetY, String stackSize)
{
final float scaleFactor = fontRenderer.getUnicodeFlag() ? 0.85f : 0.5f;
final float inverseScaleFactor = 1.0f / scaleFactor;
final String stackSize = String.valueOf( amount );
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glPushMatrix();
enable2DRender();
GL11.glScaled(scaleFactor, scaleFactor, scaleFactor);
final int X = (int) ( ( (float) offsetX + 16.0f - fontRenderer.getStringWidth( stackSize ) * scaleFactor ) * inverseScaleFactor );
final int Y = (int) ( ( (float) offsetY + 16.0f - 7.0f * scaleFactor ) * inverseScaleFactor );
fontRenderer.drawStringWithShadow(stackSize, X, Y, 16777215);
GL11.glScaled(inverseScaleFactor, inverseScaleFactor, inverseScaleFactor);
enable3DRender();
GL11.glPopMatrix();
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_DEPTH_TEST);
}
public static void enableMatrixStackLogging() {
@@ -5,7 +5,6 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonArray;
import com.google.gson.JsonPrimitive;
import codechicken.nei.util.NBTJson;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.PositionedStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.item.ItemStack;
@@ -25,15 +24,24 @@ public class BookmarkRecipeId
public List<NBTTagCompound> ingredients = new ArrayList<>();
public BookmarkRecipeId(String handlerName, List<PositionedStack> stacks)
public BookmarkRecipeId(String handlerName, List<?> stacks)
{
this.handlerName = handlerName;
for (PositionedStack pos : stacks) {
final NBTTagCompound nbt = StackInfo.itemStackToNBT(getItemStackWithMinimumDamage(pos.items));
if (nbt != null) {
ingredients.add(nbt);
for (Object pos : stacks) {
if (pos instanceof PositionedStack) {
pos = getItemStackWithMinimumDamage(((PositionedStack) pos).items);
}
if (pos instanceof ItemStack) {
pos = StackInfo.itemStackToNBT((ItemStack) pos);
}
if (pos instanceof NBTTagCompound) {
ingredients.add((NBTTagCompound) pos);
}
}
}
@@ -57,6 +65,11 @@ public class BookmarkRecipeId
}
public BookmarkRecipeId()
{
}
public boolean equalsIngredients(List<PositionedStack> stacks)
{
@@ -70,7 +83,7 @@ public class BookmarkRecipeId
final NBTTagCompound tagCompoundA = StackInfo.itemStackToNBT(getItemStackWithMinimumDamage(pStack.items));
final NBTTagCompound tagCompoundB = ingredients.get(idx);
if (tagCompoundB == null || !tagCompoundA.equals(tagCompoundB)) {
if (tagCompoundB == null || !tagCompoundB.equals(tagCompoundA)) {
return false;
}
@@ -166,4 +179,9 @@ public class BookmarkRecipeId
return false;
}
public BookmarkRecipeId copy()
{
return new BookmarkRecipeId(handlerName, ingredients);
}
}
@@ -49,14 +49,14 @@ public class CatalystInfoList extends ForwardingList<CatalystInfo> {
}
public boolean contains(ItemStack stack) {
return catalystInfoList.stream().anyMatch(c -> NEIServerUtils.areStacksSameType(c.getStack(), stack));
return catalystInfoList.stream().anyMatch(c -> NEIServerUtils.areStacksSameTypeCraftingWithNBT(c.getStack(), stack));
}
public boolean remove(ItemStack stack) {
Iterator<CatalystInfo> iter = catalystInfoList.iterator();
while (iter.hasNext()) {
ItemStack next = iter.next().getStack();
if (NEIServerUtils.areStacksSameType(next, stack)) {
if (NEIServerUtils.areStacksSameTypeCraftingWithNBT(next, stack)) {
iter.remove();
return true;
}
@@ -0,0 +1,50 @@
package codechicken.nei.recipe;
import codechicken.nei.NEICPH;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.NEIServerUtils;
import codechicken.nei.api.INEIGuiAdapter;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
public class CheatItemHandler extends INEIGuiAdapter
{
@Override
public boolean handleDragNDrop(GuiContainer gui, int mouseX, int mouseY, ItemStack draggedStack, int button)
{
final Slot overSlot = gui.getSlotAtPosition(mouseX, mouseY);
if (overSlot != null && overSlot.isItemValid(draggedStack)) {
if (NEIClientConfig.canCheatItem(draggedStack)) {
int contents = overSlot.getHasStack() ? overSlot.getStack().stackSize : 0;
final int add = button == 0 ? draggedStack.stackSize : 1;
if (overSlot.getHasStack() && !NEIServerUtils.areStacksSameType(draggedStack, overSlot.getStack())) {
contents = 0;
}
final int total = Math.min(contents + add, Math.min(overSlot.getSlotStackLimit(), draggedStack.getMaxStackSize()));
if (total > contents) {
NEIClientUtils.setSlotContents(overSlot.slotNumber, NEIServerUtils.copyStack(draggedStack, total), true);
NEICPH.sendGiveItem(NEIServerUtils.copyStack(draggedStack, total), false, false);
draggedStack.stackSize -= total - contents;
}
} else {
draggedStack.stackSize = 0;
}
return true;
}
return false;
}
}
@@ -0,0 +1,94 @@
package codechicken.nei.recipe;
import codechicken.nei.ItemPanel.ItemPanelSlot;
import codechicken.nei.ItemPanels;
import codechicken.nei.api.INEIGuiAdapter;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidContainerItem;
public class FillFluidContainerHandler extends INEIGuiAdapter
{
@Override
public boolean handleDragNDrop(GuiContainer gui, int mouseX, int mouseY, ItemStack draggedStack, int button)
{
if (button == 2) {
return false;
}
if (draggedStack.getItem() instanceof IFluidContainerItem || FluidContainerRegistry.isContainer(draggedStack)) {
ItemPanelSlot mouseOverSlot = ItemPanels.itemPanel.getSlotMouseOver(mouseX, mouseY);
if (mouseOverSlot == null) {
mouseOverSlot = ItemPanels.bookmarkPanel.getSlotMouseOver(mouseX, mouseY);
}
if (mouseOverSlot != null) {
FluidStack fluidStack = StackInfo.getFluid(mouseOverSlot.item);
if (fluidStack != null) {
ItemStack container = fillContainer(draggedStack, fluidStack);
if (container != null) {
container.stackSize = draggedStack.stackSize;
if (ItemPanels.itemPanel.draggedStack != null) {
ItemPanels.itemPanel.draggedStack = container;
} else {
ItemPanels.bookmarkPanel.draggedStack = container;
}
}
if (button == 1 && StackInfo.getFluid(container != null? container: draggedStack) != null) {
ItemPanels.bookmarkPanel.addOrRemoveItem((container != null? container: draggedStack).copy());
}
}
return true;
}
}
return false;
}
protected ItemStack fillContainer(ItemStack draggedStack, FluidStack fluidStack)
{
fluidStack = fluidStack.copy();
draggedStack = draggedStack.copy();
draggedStack.stackSize = 1;
if (fluidStack.amount == 0) {
fluidStack.amount = 1000;
}
if (FluidContainerRegistry.isContainer(draggedStack)) {
if (FluidContainerRegistry.getContainerCapacity(draggedStack) > 0) {
draggedStack = FluidContainerRegistry.drainFluidContainer(draggedStack);
}
return FluidContainerRegistry.fillFluidContainer(fluidStack, draggedStack);
} else if (draggedStack.getItem() instanceof IFluidContainerItem) {
IFluidContainerItem item = (IFluidContainerItem) draggedStack.getItem();
if (item.getCapacity(draggedStack) > 0) {
item.drain(draggedStack, item.getCapacity(draggedStack), true);
}
if (item.fill(draggedStack, fluidStack, true) > 0) {
return draggedStack;
}
}
return null;
}
}
@@ -2,9 +2,11 @@ package codechicken.nei.recipe;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.PositionedStack;
import net.minecraft.client.Minecraft;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.FurnaceRecipes;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -87,26 +89,13 @@ public class FuelRecipeHandler extends FurnaceRecipeHandler
}
@Override
public List<String> handleItemTooltip(GuiRecipe gui, ItemStack stack, List<String> currenttip, int recipe) {
public void drawExtras(int recipe) {
super.drawExtras(recipe);
CachedFuelRecipe crecipe = (CachedFuelRecipe) arecipes.get(recipe);
FuelPair fuel = crecipe.fuel;
float burnTime = fuel.burnTime / 200F;
if (gui.isMouseOver(fuel.stack, recipe) && burnTime < 1) {
burnTime = 1F / burnTime;
String s_time = Float.toString(burnTime);
if (burnTime == Math.round(burnTime))
s_time = Integer.toString((int) burnTime);
currenttip.add(translate("recipe.fuel.required", s_time));
} else if ((gui.isMouseOver(crecipe.getResult(), recipe) || gui.isMouseOver(crecipe.getIngredient(), recipe)) && burnTime > 1) {
String s_time = Float.toString(burnTime);
if (burnTime == Math.round(burnTime))
s_time = Integer.toString((int) burnTime);
currenttip.add(translate("recipe.fuel." + (gui.isMouseOver(crecipe.getResult(), recipe) ? "produced" : "processed"), s_time));
}
return currenttip;
NumberFormat numberInstance = NumberFormat.getNumberInstance();
numberInstance.setMaximumFractionDigits(2);
String smeltCount = numberInstance.format(fuel.burnTime / 200f);
Minecraft.getMinecraft().fontRenderer.drawString(translate("recipe.fuel.smeltCount", smeltCount), 73, 51, 0xFF000000);
}
}
@@ -2,41 +2,57 @@ package codechicken.nei.recipe;
import codechicken.core.TaskProfiler;
import codechicken.nei.ItemList;
import codechicken.nei.ItemPanels;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.PositionedStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import codechicken.nei.ItemPanels;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
public class GuiCraftingRecipe extends GuiRecipe
{
public class GuiCraftingRecipe extends GuiRecipe {
public static boolean openRecipeGui(String outputId, Object... results) {
return openRecipeGui(outputId, false, results);
}
public static boolean openRecipeGui(String outputId, Boolean overlay, Object... results) {
Minecraft mc = NEIClientUtils.mc();
GuiScreen prevscreen = mc.currentScreen;// instanceof GuiContainer ? (GuiContainer) mc.currentScreen : null;
ArrayList<ICraftingHandler> handlers;
TaskProfiler profiler = ProfilerRecipeHandler.getProfiler();
profiler.start("recipe.concurrent.crafting");
// Pre-find the fuels so we're not fighting over it
FuelRecipeHandler.findFuelsOnceParallel();
try {
handlers = serialCraftingHandlers.stream().map(h -> h.getRecipeHandler(outputId, results))
.filter(h -> h.numRecipes() > 0)
.collect(Collectors.toCollection(ArrayList::new));
.filter(h -> h.numRecipes() > 0)
.collect(Collectors.toCollection(ArrayList::new));
handlers.addAll(ItemList.forkJoinPool.submit(() -> craftinghandlers.parallelStream()
.map(h -> h.getRecipeHandler(outputId, results))
.filter(h -> h.numRecipes() > 0)
.collect(Collectors.toCollection(ArrayList::new))).get());
.map(h -> h.getRecipeHandler(outputId, results))
.filter(h -> h.numRecipes() > 0)
.collect(Collectors.toCollection(ArrayList::new))).get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
EntityPlayer player = Minecraft.getMinecraft().thePlayer;
if (player != null) {
IChatComponent chat = new ChatComponentTranslation("nei.chat.recipe.error");
chat.getChatStyle().setColor(EnumChatFormatting.RED);
player.addChatComponentMessage(chat);
}
return false;
} finally {
profiler.end();
@@ -47,18 +63,49 @@ public class GuiCraftingRecipe extends GuiRecipe
handlers.sort(NEIClientConfig.HANDLER_COMPARATOR);
mc.displayGuiScreen(new GuiCraftingRecipe(prevscreen, handlers));
if (NEIClientConfig.saveCurrentRecipeInBookmarksEnabled() && !NEIClientUtils.shiftKey() && outputId.equals("item") && mc.currentScreen instanceof GuiRecipe) {
GuiCraftingRecipe.openTargetRecipe((GuiRecipe)mc.currentScreen, (ItemStack)results[0]);
BookmarkRecipeId recipeId = null;
if ("item".equals(outputId)) {
recipeId = getRecipeId(prevscreen, (ItemStack) results[0]);
}
GuiCraftingRecipe gui = new GuiCraftingRecipe(prevscreen, handlers, recipeId);
mc.displayGuiScreen(gui);
if (NEIClientConfig.saveCurrentRecipeInBookmarksEnabled())
if (!NEIClientUtils.shiftKey() || overlay) {
gui.openTargetRecipe(gui.recipeId);
}
if (overlay) {
if (!NEIClientConfig.saveCurrentRecipeInBookmarksEnabled() || gui.recipeId == null) {
mc.displayGuiScreen(prevscreen);
return false;
}
gui.overlayRecipe(gui.recipeId.position);
}
return true;
}
protected static void openTargetRecipe(GuiRecipe currentScreen, ItemStack stackover)
{
currentScreen.openTargetRecipe(ItemPanels.bookmarkPanel.getBookmarkRecipeId(stackover));
protected static BookmarkRecipeId getRecipeId(GuiScreen gui, ItemStack stackover) {
if (gui instanceof GuiRecipe) {
final List<PositionedStack> ingredients = ((GuiRecipe) gui).getFocusedRecipeIngredients();
final String handlerName = ((GuiRecipe) gui).getHandlerName();
if (ingredients != null && !ingredients.isEmpty()) {
return new BookmarkRecipeId(handlerName, ingredients);
}
}
return ItemPanels.bookmarkPanel.getBookmarkRecipeId(stackover);
}
private GuiCraftingRecipe(GuiScreen prevgui, ArrayList<ICraftingHandler> handlers, BookmarkRecipeId recipeId) {
this(prevgui, handlers);
this.recipeId = recipeId;
}
private GuiCraftingRecipe(GuiScreen prevgui, ArrayList<ICraftingHandler> handlers) {
@@ -68,10 +115,10 @@ public class GuiCraftingRecipe extends GuiRecipe
public static void registerRecipeHandler(ICraftingHandler handler) {
final String handlerId = handler.getHandlerId();
if(craftinghandlers.stream().anyMatch(h -> h.getHandlerId().equals(handlerId)) || serialCraftingHandlers.stream().anyMatch(h -> h.getHandlerId().equals(handlerId)))
if (craftinghandlers.stream().anyMatch(h -> h.getHandlerId().equals(handlerId)) || serialCraftingHandlers.stream().anyMatch(h -> h.getHandlerId().equals(handlerId)))
return;
if(NEIClientConfig.serialHandlers.contains(handlerId))
if (NEIClientConfig.serialHandlers.contains(handlerId))
serialCraftingHandlers.add(handler);
else
craftinghandlers.add(handler);
@@ -63,8 +63,10 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
public int page;
public int recipetype;
public BookmarkRecipeId recipeId;
public ContainerRecipe slotcontainer;
public GuiContainer firstGui;
public GuiScreen firstGuiGeneral;
public GuiScreen prevGui;
public GuiButton nextpage;
public GuiButton prevpage;
@@ -89,12 +91,15 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
slotcontainer = (ContainerRecipe) inventorySlots;
this.prevGui = prevgui;
this.firstGuiGeneral = prevgui;
if(prevgui instanceof GuiContainer)
this.firstGui = (GuiContainer)prevgui;
if (prevgui instanceof IGuiContainerOverlay)
if (prevgui instanceof IGuiContainerOverlay) {
this.firstGui = ((IGuiContainerOverlay) prevgui).getFirstScreen();
this.firstGuiGeneral = ((IGuiContainerOverlay) prevgui).getFirstScreenGeneral();
}
}
/**
@@ -311,7 +316,7 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
public void keyTyped(char c, int i) {
if (i == Keyboard.KEY_ESCAPE) //esc
{
mc.displayGuiScreen(firstGui);
mc.displayGuiScreen(firstGuiGeneral);
return;
}
if (GuiContainerManager.getManager(this).lastKeyTyped(i, c))
@@ -324,7 +329,7 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
}
if (i == mc.gameSettings.keyBindInventory.getKeyCode())
mc.displayGuiScreen(firstGui);
mc.displayGuiScreen(firstGuiGeneral);
else if (i == NEIClientConfig.getKeyBinding("gui.back"))
mc.displayGuiScreen(prevGui);
else if (i == NEIClientConfig.getKeyBinding("gui.prev_machine"))
@@ -441,16 +446,19 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
setRecipePage(--recipetype);
}
private void overlayRecipe(int recipe) {
protected void overlayRecipe(int recipe) {
if (handler == null || !handler.hasOverlay(firstGui, firstGui.inventorySlots, recipe)) {
mc.displayGuiScreen(firstGui);
return;
}
final IRecipeOverlayRenderer renderer = handler.getOverlayRenderer(firstGui, recipe);
final IOverlayHandler overlayHandler = handler.getOverlayHandler(firstGui, recipe);
final boolean shift = NEIClientUtils.shiftKey();
if (handler != null && (renderer == null || shift)) {
mc.displayGuiScreen(firstGui);
mc.displayGuiScreen(firstGui);
if (renderer == null || shift) {
overlayHandler.overlayRecipe(firstGui, currenthandlers.get(recipetype), recipe, shift);
} else if (renderer != null) {
mc.displayGuiScreen(firstGui);
} else {
LayoutManager.overlayRenderer = renderer;
}
}
@@ -644,6 +652,11 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
return firstGui;
}
@Override
public GuiScreen getFirstScreenGeneral() {
return firstGuiGeneral;
}
public boolean isMouseOver(PositionedStack stack, int recipe) {
Slot stackSlot = slotcontainer.getSlotWithStack(stack, getRecipePosition(recipe).x, getRecipePosition(recipe).y);
Point mousepos = GuiDraw.getMousePosition();
@@ -66,7 +66,7 @@ public abstract class GuiRecipeTab extends Widget {
this.selected = false;
if(handler instanceof TemplateRecipeHandler) {
handlerID = (((TemplateRecipeHandler)handler).getOverlayIdentifier());
handlerID = handler.getOverlayIdentifier();
} else {
handlerID = null;
}
@@ -130,7 +130,7 @@ public abstract class GuiRecipeTab extends Widget {
}
public void addTooltips(List<String> tooltip) {
tooltip.add(handler.getRecipeName().trim());
tooltip.add(handler.getRecipeTabName().trim());
String handlerMod = getHandlerMod(handlerName, handlerID);
tooltip.add(EnumChatFormatting.BLUE + handlerMod);
@@ -162,7 +162,7 @@ public abstract class GuiRecipeTab extends Widget {
final String handlerID;
if (handler instanceof TemplateRecipeHandler) {
handlerID = ((TemplateRecipeHandler) handler).getOverlayIdentifier();
handlerID = handler.getOverlayIdentifier();
} else {
handlerID = null;
}
@@ -272,9 +272,6 @@ public abstract class GuiRecipeTab extends Widget {
handlerMap.put(handler, info);
NEIClientConfig.logger.info("Loaded " + handler);
}
} catch (IOException e) {
NEIClientConfig.logger.info("Error parsing CSV");
e.printStackTrace();
} catch (Exception e) {
NEIClientConfig.logger.info("Error parsing CSV");
e.printStackTrace();
@@ -6,6 +6,10 @@ import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
@@ -35,6 +39,12 @@ public class GuiUsageRecipe extends GuiRecipe
.collect(Collectors.toCollection(ArrayList::new))).get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
EntityPlayer player = Minecraft.getMinecraft().thePlayer;
if (player != null) {
IChatComponent chat = new ChatComponentTranslation("nei.chat.recipe.error");
chat.getChatStyle().setColor(EnumChatFormatting.RED);
player.addChatComponentMessage(chat);
}
return false;
} finally {
profiler.end();
@@ -45,10 +55,29 @@ public class GuiUsageRecipe extends GuiRecipe
handlers.sort(NEIClientConfig.HANDLER_COMPARATOR);
mc.displayGuiScreen(new GuiUsageRecipe(prevscreen, handlers));
BookmarkRecipeId recipeId = null;
if (prevscreen instanceof GuiRecipe && ((GuiRecipe) prevscreen).recipeId != null) {
recipeId = (((GuiRecipe) prevscreen).recipeId).copy();
}
GuiUsageRecipe gui = new GuiUsageRecipe(prevscreen, handlers, recipeId);
mc.displayGuiScreen(gui);
if (!NEIClientUtils.shiftKey()) {
gui.openTargetRecipe(recipeId);
}
return true;
}
private GuiUsageRecipe(GuiContainer prevgui, ArrayList<IUsageHandler> handlers, BookmarkRecipeId recipeId)
{
this(prevgui, handlers);
this.recipeId = recipeId;
}
private GuiUsageRecipe(GuiContainer prevgui, ArrayList<IUsageHandler> handlers) {
super(prevgui);
currenthandlers = handlers;
@@ -29,46 +29,55 @@ public interface IRecipeHandler
* @return The name of this inventory.
* To be displayed at the top of the viewing container.
*/
public String getRecipeName();
String getRecipeName();
/**
* For legacy compatibility reasons, this method's default implementation returns the recipe name. This is also the expected behavior
*
* @return The name of this inventory.
* To be displayed in the tooltip in the tab at the top of the viewing container.
*/
default String getRecipeTabName() {
return getRecipeName();
}
/**
*
* @return The number of recipes that this handler contains.
*/
public int numRecipes();
int numRecipes();
/**
* Draw the background of this recipe handler (basically the slot layout image).
* @param gui A GuiManager for drawing functions.
* @param recipe The recipe index to draw at this position.
*/
public void drawBackground(int recipe);
void drawBackground(int recipe);
/**
* Draw the foreground of this recipe handler (for things like progress bars).
* @param gui A GuiManager for drawing functions.
* @param recipe The recipe index to draw at this position.
*/
public void drawForeground(int recipe);
void drawForeground(int recipe);
/**
*
* @param recipe The recipe index to get items for.
* @return A list of the ingredient {@link PositionedStack}s in this recipe relative to the top left corner of your recipe drawing space.
*/
public List<PositionedStack> getIngredientStacks(int recipe);
List<PositionedStack> getIngredientStacks(int recipe);
/**
*
* @param recipe The recipe index to get items for.
* @param recipetype The recipe index to get items for.
* @return A list of the other {@link PositionedStack}s in this recipe relative to the top left corner of your recipe drawing space. For example fuel in furnaces.
*/
public List<PositionedStack> getOtherStacks(int recipetype);
List<PositionedStack> getOtherStacks(int recipetype);
/**
*
* @param recipe The recipe index to get the result for.
* @return The recipe result {@link PositionedStack} relative to the top left corner of your recipe drawing space.
*/
public PositionedStack getResultStack(int recipe);
PositionedStack getResultStack(int recipe);
/**
* A tick function called for updating progress bars and cycling damage items.
*/
public void onUpdate();
void onUpdate();
/**
*
* @param recipe The recipe index to check for.
@@ -76,33 +85,33 @@ public interface IRecipeHandler
* @param container The container of the GUI.
* @return true if this recipe can render an overlay for the specified type of inventory GUI.
*/
public boolean hasOverlay(GuiContainer gui, Container container, int recipe);
boolean hasOverlay(GuiContainer gui, Container container, int recipe);
/**
*
* @param recipe The recipe index to get the overlay renderer for.
* @return An instance of {@link IRecipeOverlayRenderer} to be used for rendering the overlay of this specific recipe.
*/
public IRecipeOverlayRenderer getOverlayRenderer(GuiContainer gui, int recipe);
IRecipeOverlayRenderer getOverlayRenderer(GuiContainer gui, int recipe);
/**
*
* @param recipe The recipe index to get the overlay renderer for.
* @return An instance of {@link IOverlayHandler} to be used for rendering the overlay of this specific recipe.
*/
public IOverlayHandler getOverlayHandler(GuiContainer gui, int recipe);
IOverlayHandler getOverlayHandler(GuiContainer gui, int recipe);
/**
* Simply works with the {@link codechicken.nei.api.DefaultOverlayRenderer}
* If the current container has been registered with this identifier, the question mark appears and an overlay guide can be drawn.
*
* @return The overlay identifier of this recipe type.
*/
public default String getOverlayIdentifier() {
default String getOverlayIdentifier() {
return null;
}
/**
*
* @return The number of recipes that can fit on a page in the viewer (1 or 2)
*/
public int recipiesPerPage();
int recipiesPerPage();
/**
*
* @param gui An instance of the currentscreen
@@ -110,16 +119,16 @@ public interface IRecipeHandler
* @param recipe The recipe index being handled
* @return The modified tooltip. DO NOT return null
*/
public List<String> handleTooltip(GuiRecipe gui, List<String> currenttip, int recipe);
List<String> handleTooltip(GuiRecipe gui, List<String> currenttip, int recipe);
/**
*
* @param gui An instance of the currentscreen
* @param The itemstack currently under the mouse
* @param The current tooltip, will contain item name and info
* @param stack The itemstack currently under the mouse
* @param currenttip The current tooltip, will contain item name and info
* @param recipe The recipe index being handled
* @return The modified tooltip. DO NOT return null
*/
public List<String> handleItemTooltip(GuiRecipe gui, ItemStack stack, List<String> currenttip, int recipe);
List<String> handleItemTooltip(GuiRecipe gui, ItemStack stack, List<String> currenttip, int recipe);
/**
*
@@ -128,7 +137,7 @@ public interface IRecipeHandler
* @param keyCode The KeyCode as defined in {@link Keyboard}
* @return true to terminate further processing of this event.
*/
public boolean keyTyped(GuiRecipe gui, char keyChar, int keyCode, int recipe);
boolean keyTyped(GuiRecipe gui, char keyChar, int keyCode, int recipe);
/**
*
@@ -136,7 +145,7 @@ public interface IRecipeHandler
* @param button The button index being pressed, {0 = Left Click, 1 = Right Click, 2 = Middle Click}
* @return true to terminate further processing of this event.
*/
public boolean mouseClicked(GuiRecipe gui, int button, int recipe);
boolean mouseClicked(GuiRecipe gui, int button, int recipe);
/**
* For legacy compatibility reasons, this method has a do-nothing default implementation.
@@ -29,6 +29,8 @@ import java.util.Map;
public class RecipeCatalysts {
private static final Map<String, CatalystInfoList> catalystsAdderFromAPI = new HashMap<>();
private static final Map<String, List<ItemStack>> catalystsRemoverFromAPI = new HashMap<>();
public static final Map<String, CatalystInfoList> catalystsAdderFromIMC = new HashMap<>();
public static final Map<String, List<ItemStack>> catalystsRemoverFromIMC = new HashMap<>();
private static final Map<String, CatalystInfoList> recipeCatalystMap = new HashMap<>();
private static Map<String, List<PositionedStack>> positionedRecipeCatalystMap = new HashMap<>();
private static final List<String> forceClassNameList = new ArrayList<>();
@@ -161,6 +163,7 @@ public class RecipeCatalysts {
// todo
final String minVersion = record.get("minVersion");
final String maxVersion = record.get("maxVersion");
//
final boolean forceClassName = Boolean.parseBoolean(record.get("forceClassName"));
if (requiresMod && !Loader.isModLoaded(modId)) continue;
@@ -209,6 +212,13 @@ public class RecipeCatalysts {
}
}
for (Map.Entry<String, CatalystInfoList> entry : catalystsAdderFromIMC.entrySet()) {
String handlerID = entry.getKey();
for (CatalystInfo catalyst : entry.getValue()) {
addOrPut(recipeCatalystMap, handlerID, catalyst);
}
}
for (Map.Entry<String, List<ItemStack>> entry : catalystsRemoverFromAPI.entrySet()) {
String handlerID = entry.getKey();
if (recipeCatalystMap.containsKey(handlerID)) {
@@ -217,6 +227,14 @@ public class RecipeCatalysts {
}
}
for (Map.Entry<String, List<ItemStack>> entry : catalystsRemoverFromIMC.entrySet()) {
String handlerID = entry.getKey();
if (recipeCatalystMap.containsKey(handlerID)) {
CatalystInfoList catalysts = recipeCatalystMap.get(handlerID);
entry.getValue().forEach(catalysts::remove);
}
}
updatePosition(getHeight(), true);
}
@@ -234,7 +252,7 @@ public class RecipeCatalysts {
handler.getHandlerId());
}
private static void addOrPut(Map<String, CatalystInfoList> map, String handlerID, CatalystInfo catalyst) {
public static void addOrPut(Map<String, CatalystInfoList> map, String handlerID, CatalystInfo catalyst) {
if (map.containsKey(handlerID)) {
map.get(handlerID).add(catalyst);
} else {
@@ -1,29 +1,29 @@
package codechicken.nei.recipe;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.ItemPanels;
import codechicken.nei.LayoutManager;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.PositionedStack;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.guihook.IContainerInputHandler;
import codechicken.nei.PositionedStack;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
import java.awt.*;
import java.util.List;
public class RecipeItemInputHandler implements IContainerInputHandler
{
public class RecipeItemInputHandler implements IContainerInputHandler {
@Override
public boolean lastKeyTyped(GuiContainer gui, char keyChar, int keyCode)
{
public boolean lastKeyTyped(GuiContainer gui, char keyChar, int keyCode) {
ItemStack stackover = GuiContainerManager.getStackMouseOver(gui);
if(stackover == null)
return false;
if (stackover == null) return false;
if(keyCode == NEIClientConfig.getKeyBinding("gui.recipe"))
if (keyCode == NEIClientConfig.getKeyBinding("gui.recipe"))
return GuiCraftingRecipe.openRecipeGui("item", stackover.copy());
if(keyCode == NEIClientConfig.getKeyBinding("gui.usage"))
if (keyCode == NEIClientConfig.getKeyBinding("gui.usage"))
return GuiUsageRecipe.openRecipeGui("item", stackover.copy());
if (keyCode == NEIClientConfig.getKeyBinding("gui.bookmark")) {
@@ -39,68 +39,68 @@ public class RecipeItemInputHandler implements IContainerInputHandler
ItemPanels.bookmarkPanel.addOrRemoveItem(stackover.copy(), handlerName, ingredients);
}
if (keyCode == NEIClientConfig.getKeyBinding("gui.overlay")) {
if (NEIClientUtils.controlKey()) {
LayoutManager.overlayRenderer = null;
return true;
}
if (!NEIClientConfig.saveCurrentRecipeInBookmarksEnabled()) return false;
final BookmarkRecipeId mouseOverRecipeId = ItemPanels.bookmarkPanel.getBookmarkMouseOverRecipeId();
if (mouseOverRecipeId == null || mouseOverRecipeId.ingredients == null || mouseOverRecipeId.ingredients.isEmpty())
return false;
return GuiCraftingRecipe.openRecipeGui("item", true, stackover.copy());
}
return false;
}
@Override
public boolean mouseClicked(GuiContainer gui, int mousex, int mousey, int button)
{
public boolean mouseClicked(GuiContainer gui, int mousex, int mousey, int button) {
ItemStack stackover = GuiContainerManager.getStackMouseOver(gui);
if(stackover == null)
return false;
if (stackover == null) return false;
if (!(gui instanceof GuiRecipe))
return false;
if (!(gui instanceof GuiRecipe)) return false;
//disabled open recipe gui if hold shift (player have move recipe)
if (button == 0 && ItemPanels.bookmarkPanel.getStackMouseOver(mousex, mousey) != null && NEIClientUtils.shiftKey()) {
return false;
}
if(button == 0)
return GuiCraftingRecipe.openRecipeGui("item", stackover.copy());
if (button == 0) return GuiCraftingRecipe.openRecipeGui("item", stackover.copy());
if(button == 1)
return GuiUsageRecipe.openRecipeGui("item", stackover.copy());
if (button == 1) return GuiUsageRecipe.openRecipeGui("item", stackover.copy());
return false;
}
@Override
public void onKeyTyped(GuiContainer gui, char keyChar, int keyID)
{
public void onKeyTyped(GuiContainer gui, char keyChar, int keyID) {
}
@Override
public void onMouseClicked(GuiContainer gui, int mousex, int mousey, int button)
{
public void onMouseClicked(GuiContainer gui, int mousex, int mousey, int button) {
}
@Override
public void onMouseUp(GuiContainer gui, int mousex, int mousey, int button)
{
public void onMouseUp(GuiContainer gui, int mousex, int mousey, int button) {
}
@Override
public boolean keyTyped(GuiContainer gui, char keyChar, int keyID)
{
public boolean keyTyped(GuiContainer gui, char keyChar, int keyID) {
return false;
}
@Override
public boolean mouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled)
{
public boolean mouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled) {
return false;
}
@Override
public void onMouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled)
{
public void onMouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled) {
}
@Override
public void onMouseDragged(GuiContainer gui, int mousex, int mousey, int button, long heldTime)
{
public void onMouseDragged(GuiContainer gui, int mousex, int mousey, int button, long heldTime) {
}
}
@@ -0,0 +1,41 @@
package codechicken.nei.recipe;
import codechicken.nei.api.INEIGuiAdapter;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import net.minecraft.util.EnumChatFormatting;
import java.util.regex.Pattern;
import static codechicken.nei.LayoutManager.searchField;
public class SearchInputDropHandler extends INEIGuiAdapter
{
protected static final Pattern SPECIAL_REGEX_CHARS = Pattern.compile("[{}()\\[\\].+*?^$\\\\|]");
@Override
public boolean handleDragNDrop(GuiContainer gui, int mouseX, int mouseY, ItemStack draggedStack, int button)
{
if (searchField.contains(mouseX, mouseY)) {
final FluidStack fluidStack = StackInfo.getFluid(draggedStack);
if (fluidStack != null) {
searchField.setText(formattingText(fluidStack.getLocalizedName()));
} else {
searchField.setText(formattingText(draggedStack.getDisplayName()));
}
return true;
}
return false;
}
protected String formattingText(String displayName)
{
return SPECIAL_REGEX_CHARS.matcher(EnumChatFormatting.getTextWithoutFormattingCodes(displayName)).replaceAll("\\\\$0");
}
}
@@ -1,19 +1,35 @@
package codechicken.nei.recipe;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.api.IStackStringifyHandler;
import codechicken.nei.recipe.stackinfo.DefaultStackStringifyHandler;
import codechicken.nei.recipe.stackinfo.GTFluidStackStringifyHandler;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.fluids.FluidStack;
import org.apache.commons.io.IOUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.WeakHashMap;
public class StackInfo
{
public static final ArrayList<IStackStringifyHandler> stackStringifyHandlers = new ArrayList<>();
public static final ArrayList<IStackStringifyHandler> stackStringifyHandlers = new ArrayList<>();
private static final HashMap<String, HashMap<String, String[]>> guidfilters = new HashMap<>();
private static final WeakHashMap<ItemStack, String> guidcache = new WeakHashMap<>();
static {
stackStringifyHandlers.add(new DefaultStackStringifyHandler());
stackStringifyHandlers.add(new GTFluidStackStringifyHandler());
@@ -39,7 +55,7 @@ public class StackInfo
{
ItemStack stack = null;
for (int i = stackStringifyHandlers.size() - 1; i >= 0 && stack == null; i--) {
for (int i = stackStringifyHandlers.size() - 1; i >= 0 && nbtTag != null && stack == null; i--) {
stack = stackStringifyHandlers.get(i).convertNBTToItemStack(nbtTag);
}
@@ -73,4 +89,119 @@ public class StackInfo
return fluid;
}
public static String getItemStackGUID(ItemStack stack)
{
if (!guidcache.containsKey(stack)) {
final NBTTagCompound nbTag = itemStackToNBT(stack, false);
if (nbTag == null) {
return null;
}
nbTag.removeTag("Count");
if (nbTag.getShort("Damage") == 0) {
nbTag.removeTag("Damage");
}
if (nbTag.hasKey("tag") && nbTag.getCompoundTag("tag").hasNoTags()) {
nbTag.removeTag("tag");
}
if (nbTag.hasKey("strId") && guidfilters.containsKey(nbTag.getString("strId"))) {
final ArrayList<String> keys = new ArrayList<>();
final String strId = nbTag.getString("strId");
keys.add(strId);
guidfilters.get(strId).forEach((key, rule) -> {
Object local = nbTag;
for (int i = 0; i < rule.length; i++) {
try {
if (local instanceof NBTTagCompound) {
local = ((NBTTagCompound) local).getTag(rule[i]);
} else if (local instanceof NBTTagList) {
local = ((NBTTagList) local).tagList.get(Integer.parseInt(rule[i]));
} else {
break;
}
} catch (Throwable e) {
break;
}
}
if (local instanceof NBTBase) {
keys.add(((NBTBase)local).toString());
} else if (local != null) {
keys.add(String.valueOf(local));
}
});
synchronized (guidcache) {
guidcache.put(stack, keys.toString());
}
} else {
synchronized (guidcache) {
guidcache.put(stack, nbTag.toString());
}
}
}
return guidcache.get(stack);
}
public static void loadGuidFilters()
{
guidfilters.clear();
final File guidFlitersFile = new File(NEIClientConfig.configDir, "guidfilters.cfg");
List<String> itemStrings = new ArrayList<>();
if (guidFlitersFile.exists()) {
try (FileReader reader = new FileReader(guidFlitersFile)) {
NEIClientConfig.logger.info("Loading guid filters from file {}", guidFlitersFile);
itemStrings = IOUtils.readLines(reader);
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to load bookmarks from file {}", guidFlitersFile, e);
e.printStackTrace();
}
} else {
final URL filterUrl = Thread.currentThread().getContextClassLoader().getResource("assets/nei/guidfilters.cfg");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(filterUrl.openStream()))) {
itemStrings = IOUtils.readLines(reader);
} catch (IOException e) {
NEIClientConfig.logger.info("Error parsing guid filters");
e.printStackTrace();
} catch (Exception e) {
NEIClientConfig.logger.info("Error parsing guid filters");
e.printStackTrace();
}
}
for (String guidStr: itemStrings) {
final String[] parts = guidStr.split(",");
final HashMap<String, String[]> rules = new HashMap<>();
for (int j = 1; j < parts.length; j++) {
rules.put(parts[j], parts[j].split("\\."));
}
guidfilters.put(parts[0], rules);
}
}
}
@@ -219,6 +219,17 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
return false;
}
/**
* NBT-friendly version of {@link #contains(Collection, ItemStack)}
*/
public boolean containsWithNBT(Collection<PositionedStack> ingredients, ItemStack ingredient) {
for (PositionedStack stack : ingredients)
if (stack.containsWithNBT(ingredient))
return true;
return false;
}
/**
* @param ingred
* @return true if any of the permutations of any of the ingredients contain this stack
@@ -0,0 +1,59 @@
package codechicken.nei.util;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagEnd;
import net.minecraft.nbt.NBTTagList;
import javax.annotation.Nullable;
import java.util.Set;
public class NBTHelper {
/*
* Taken from Botania r1.11-379 by Vazkii under the Botania License
* You can obtain one at https://botaniamod.net/license.php
*/
/**
* Returns true if the `target` tag contains all of the tags and values present in the `template` tag. Recurses into
* compound tags and matches all template keys and values; recurses into list tags and matches the template against
* the first elements of target. Empty lists and compounds in the template will match target lists and compounds of
* any size.
*/
public static boolean matchTag(@Nullable NBTBase template, @Nullable NBTBase target) {
if (template instanceof NBTTagCompound && target instanceof NBTTagCompound) {
return matchTagCompound((NBTTagCompound) template, (NBTTagCompound) target);
} else if (template instanceof NBTTagList && target instanceof NBTTagList) {
return matchTagList((NBTTagList) template, (NBTTagList) target);
} else {
return template == null || (target != null && target.equals(template));
}
}
private static boolean matchTagCompound(NBTTagCompound template, NBTTagCompound target) {
if (template.tagMap.size() > target.tagMap.size()) return false;
//noinspection unchecked
for (String key : (Set<String>) template.func_150296_c()) {
if (!matchTag(template.getTag(key), target.getTag(key))) return false;
}
return true;
}
private static boolean matchTagList(NBTTagList template, NBTTagList target) {
if (template.tagCount() > target.tagCount()) return false;
for (int i = 0; i < template.tagCount(); i++) {
if (!matchTag(get(template, i), get(target, i))) return false;
}
return true;
}
private static NBTBase get(NBTTagList tag, int idx)
{
return idx >= 0 && idx < tag.tagList.size() ? (NBTBase)tag.tagList.get(idx) : null;
}
}
+81 -31
View File
@@ -1,11 +1,8 @@
package codechicken.nei.util;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagByte;
@@ -20,26 +17,21 @@ import net.minecraft.nbt.NBTTagLong;
import net.minecraft.nbt.NBTTagShort;
import net.minecraft.nbt.NBTTagString;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.IntStream;
public class NBTJson {
private static final Pattern numberPattern = Pattern.compile("^([-+]?[\\d]+\\.?[0-9]*)([bBsSlLfFdD]?)$");
private static final JsonParser parser = new JsonParser();
private static final Gson gson = new GsonBuilder().create();
private static final Pattern numberPattern = Pattern.compile("^([-+]?\\d+\\.?\\d*E*\\d*)([bBsSlLfFdD]?)$");
public static String toJson(NBTTagCompound tag) {
return toJson(toJsonObject(tag));
}
public static String toJson(JsonElement json) {
final String jsonString = json.toString();
return gson.toJson(parser.parse(jsonString));
return json.toString();
}
@SuppressWarnings("unchecked")
@@ -50,9 +42,11 @@ public class NBTJson {
final Map<String, NBTBase> tagMap = (Map<String, NBTBase>)nbtTagCompound.tagMap;
JsonObject root = new JsonObject();
for (Map.Entry<String, NBTBase> nbtEntry : tagMap.entrySet() ) {
for (Map.Entry<String, NBTBase> nbtEntry : tagMap.entrySet()) {
root.add(nbtEntry.getKey(), toJsonObject(nbtEntry.getValue()));
}
return root;
} else if (nbt instanceof NBTTagByte) {
// Number (byte)
@@ -80,23 +74,48 @@ public class NBTJson {
return new JsonPrimitive(((NBTTagString) nbt).func_150285_a_());
} else if (nbt instanceof NBTTagList) {
// Tag List
JsonArray arr = new JsonArray();
((NBTTagList) nbt).tagList.forEach(c -> arr.add(toJsonObject((NBTBase) c)));
return arr;
final NBTTagList list = (NBTTagList) nbt;
if (list.tagList.isEmpty()) {
return createEmptyList(list);
} else {
JsonArray arr = new JsonArray();
list.tagList.forEach(c -> arr.add(toJsonObject((NBTBase) c)));
return arr;
}
} else if (nbt instanceof NBTTagIntArray) {
// Int Array
JsonArray arr = new JsonArray();
for(int i : ((NBTTagIntArray) nbt).func_150302_c()) {
arr.add(new JsonPrimitive(i));
final NBTTagIntArray list = (NBTTagIntArray) nbt;
if (list.func_150302_c().length == 0) {
return createEmptyList(list);
} else {
JsonArray arr = new JsonArray();
for (int i : list.func_150302_c()) {
arr.add(new JsonPrimitive(i));
}
return arr;
}
return arr;
} else if (nbt instanceof NBTTagByteArray) {
// Byte Array
JsonArray arr = new JsonArray();
for(int i : ((NBTTagByteArray) nbt).func_150292_c()) {
arr.add(new JsonPrimitive(i));
final NBTTagByteArray list = (NBTTagByteArray) nbt;
if (list.func_150292_c().length == 0) {
return createEmptyList(list);
} else {
JsonArray arr = new JsonArray();
for (byte i : list.func_150292_c()) {
arr.add(new JsonPrimitive(Byte.toString(i) + 'B'));
}
return arr;
}
return arr;
} else {
throw new IllegalArgumentException("Unsupported NBT Tag: " + NBTBase.NBTTypes[nbt.getId()] + " - " + nbt);
}
@@ -108,7 +127,7 @@ public class NBTJson {
final JsonPrimitive jsonPrimitive = (JsonPrimitive) jsonElement;
final String jsonString = jsonPrimitive.getAsString();
final Matcher m = numberPattern.matcher(jsonString);
if(m.find()) {
if (m.find()) {
// Number
final String numberString = m.group(1);
if (m.groupCount() == 2 && m.group(2).length() > 0) {
@@ -152,7 +171,13 @@ public class NBTJson {
if (nbtList.stream().allMatch(n -> n instanceof NBTTagInt)) {
return new NBTTagIntArray(nbtList.stream().mapToInt(i -> ((NBTTagInt)i).func_150287_d() ).toArray());
} else if (nbtList.stream().allMatch(n -> n instanceof NBTTagByte)) {
return new NBTTagByteArray(toByteArray(nbtList.stream().mapToInt(i -> ((NBTTagInt)i).func_150287_d() )));
final byte[] abyte = new byte[nbtList.size()];
for (int i = 0; i < nbtList.size(); i++) {
abyte[i] = ((NBTTagByte) nbtList.get(i)).func_150290_f();
}
return new NBTTagByteArray(abyte);
} else {
NBTTagList nbtTagList = new NBTTagList();
nbtList.forEach(nbtTagList::appendTag);
@@ -163,18 +188,43 @@ public class NBTJson {
} else if (jsonElement instanceof JsonObject) {
// NBTTagCompound
final JsonObject jsonObject = (JsonObject) jsonElement;
NBTTagCompound nbtTagCompound = new NBTTagCompound();
for (Map.Entry<String, JsonElement> jsonEntry : jsonObject.entrySet()) {
nbtTagCompound.setTag(jsonEntry.getKey(), toNbt(jsonEntry.getValue()));
final NBTBase custom = restoreEmptyList(jsonObject);
if (custom == null) {
NBTTagCompound nbtTagCompound = new NBTTagCompound();
for (Map.Entry<String, JsonElement> jsonEntry : jsonObject.entrySet()) {
nbtTagCompound.setTag(jsonEntry.getKey(), toNbt(jsonEntry.getValue()));
}
return nbtTagCompound;
} else {
return custom;
}
return nbtTagCompound;
}
throw new IllegalArgumentException("Unhandled element " + jsonElement);
}
public static byte[] toByteArray(IntStream stream) {
return stream.collect(ByteArrayOutputStream::new, (baos, i) -> baos.write((byte) i), (baos1, baos2) -> baos1.write(baos2.toByteArray(), 0, baos2.size()))
.toByteArray();
protected static JsonObject createEmptyList(Object obj)
{
JsonObject empty = new JsonObject();
empty.add("__custom_type", new JsonPrimitive(obj.getClass().getName()));
return empty;
}
protected static NBTBase restoreEmptyList(JsonObject obj)
{
if (obj.has("__custom_type")) {
try {
final String className = obj.get("__custom_type").getAsString();
return (NBTBase)Class.forName(className).newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException th) {}
}
return null;
}
}
+329 -332
View File
@@ -79,8 +79,8 @@ net.bdew.gendustry.nei.ReplicatorHandler,gendustry:Replicator,,gendustry,TRUE,,,
net.bdew.gendustry.nei.SamplerHandler,gendustry:Sampler,,gendustry,TRUE,,,,,,
net.bdew.gendustry.nei.TransposerHandler,gendustry:Transposer,,gendustry,TRUE,,,,,,
smelting,IC2:blockMachine:1,,IC2,TRUE,,,,,,
smelting,IC2:blockMachine:2,,IC2,TRUE,,,,,,
smelting,IC2:blockMachine:13,,IC2,TRUE,,,,,,
smelting,IC2:blockMachine:2,,IC2,TRUE,dreamcraft,,,,,
smelting,IC2:blockMachine:13,,IC2,TRUE,dreamcraft,,,,,
ic2.neiIntegration.core.recipehandler.BlastFurnaceRecipeHandler,IC2:blockMachine3:1,,IC2,TRUE,,,,,,
ic2.neiIntegration.core.recipehandler.BlockCutterRecipeHandler,IC2:blockMachine3:2,,IC2,TRUE,,,,,,
ic2.neiIntegration.core.recipehandler.CentrifugeRecipeHandler,IC2:blockMachine2:3,,IC2,TRUE,,,,,,
@@ -323,19 +323,19 @@ exnihilo.compatibility.nei.RecipeHandlerSieve,exnihilo:sifting_table:2,,exnihilo
exnihilo.compatibility.nei.RecipeHandlerSieve,exnihilo:sifting_table:3,,exnihilo,TRUE,,,,,,
exnihilo.compatibility.nei.RecipeHandlerSieve,exnihilo:sifting_table:4,,exnihilo,TRUE,,,,,,
exnihilo.compatibility.nei.RecipeHandlerSieve,exnihilo:sifting_table:5,,exnihilo,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.AlloySmelterRecipeHandler,gregtech_addon:machine:56,,gregtech_addon,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.AssemblerRecipeHandler,gregtech_addon:machine:60,,gregtech_addon,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.BenderRecipeHandler,gregtech_addon:machine:59,,gregtech_addon,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.BlastRecipeHandler,gregtech_addon:machine:29,,gregtech_addon,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.BronzeBlastRecipeHandler,gregtech_addon:machine:136,,gregtech_addon,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.CannerRecipeHandler,gregtech_addon:machine:57,,gregtech_addon,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.CentrifugeRecipeHandler,gregtech_addon:machine:62,,gregtech_addon,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.ChemicalRecipeHandler,gregtech_addon:machine:41,,gregtech_addon,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.CutterRecipeHandler,gregtech_addon:machine:113,,gregtech_addon,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.DistillationRecipeHandler,gregtech_addon:machine:44,,gregtech_addon,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.ElectrolyzerRecipeHandler,gregtech_addon:machine:25,,gregtech_addon,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.ExtruderRecipeHandler,gregtech_addon:machine:115,,gregtech_addon,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.FusionRecipeHandler,gregtech_addon:machine:80,,gregtech_addon,TRUE,,,,,,
gregtech.Alloy,gregtech_addon:machine:56,,gregtech_addon,TRUE,,,,,,
gregtech.Assembler,gregtech_addon:machine:60,,gregtech_addon,TRUE,,,,,,
gregtech.Bender,gregtech_addon:machine:59,,gregtech_addon,TRUE,,,,,,
gregtech.Blast,gregtech_addon:machine:29,,gregtech_addon,TRUE,,,,,,
gregtech.BronzeBlast,gregtech_addon:machine:136,,gregtech_addon,TRUE,,,,,,
gregtech.Canner,gregtech_addon:machine:57,,gregtech_addon,TRUE,,,,,,
gregtech.centrifuge,gregtech_addon:machine:62,,gregtech_addon,TRUE,,,,,,
gregtech.chemicalreactor,gregtech_addon:machine:41,,gregtech_addon,TRUE,,,,,,
gregtech.Cutter,gregtech_addon:machine:113,,gregtech_addon,TRUE,,,,,,
gregtech.Distillation,gregtech_addon:machine:44,,gregtech_addon,TRUE,,,,,,
gregtech.electrolyzer,gregtech_addon:machine:25,,gregtech_addon,TRUE,,,,,,
gregtech.extruder,gregtech_addon:machine:115,,gregtech_addon,TRUE,,,,,,
gregtech.fusion,gregtech_addon:machine:80,,gregtech_addon,TRUE,,,,,,
gregtech.thermal_generator,gregtech_addon:machine:35,,gregtech_addon,TRUE,,,,,,
gregtech.diesel_generator,gregtech_addon:machine:33,,gregtech_addon,TRUE,,,,,,
gregtech.gas_turbine,gregtech_addon:machine:34,,gregtech_addon,TRUE,,,,,,
@@ -344,12 +344,12 @@ gregtech.semifluid_generator,gregtech_addon:machine:36,,gregtech_addon,TRUE,,,,,
gregtech.plasma_generator,gregtech_addon:machine:37,,gregtech_addon,TRUE,,,,,,
gregtech.plasma_generator,gregtech_addon:machine:117,,gregtech_addon,TRUE,,,,,,
gregtech.magic_generator,gregtech_addon:machine:42,,gregtech_addon,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.GrinderRecipeHandler,gregtech_addon:machine:28,,gregtech_addon,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.ImplosionRecipeHandler,gregtech_addon:machine:31,,gregtech_addon,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.LatheRecipeHandler,gregtech_addon:machine:111,,gregtech_addon,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.SawmillRecipeHandler,gregtech_addon:machine:32,,gregtech_addon,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.VacuumFreezerRecipeHandler,gregtech_addon:machine:38,,gregtech_addon,TRUE,,,,,,
gregtechmod.mistaqur.nei.handlers.WiremillRecipeHandler,gregtech_addon:machine:55,,gregtech_addon,TRUE,,,,,,
gregtech.Grinder,gregtech_addon:machine:28,,gregtech_addon,TRUE,,,,,,
gregtech.Implosion,gregtech_addon:machine:31,,gregtech_addon,TRUE,,,,,,
gregtech.Lathe,gregtech_addon:machine:111,,gregtech_addon,TRUE,,,,,,
gregtech.Sawmill,gregtech_addon:machine:32,,gregtech_addon,TRUE,,,,,,
gregtech.VacuumFreezer,gregtech_addon:machine:38,,gregtech_addon,TRUE,,,,,,
gregtech.Wiremill,gregtech_addon:machine:55,,gregtech_addon,TRUE,,,,,,
wanion.biggercraftingtables.nei.BigShapedRecipeHandler,biggercraftingtables:BiggerCraftingTables,,biggercraftingtables,TRUE,,,,,,this and below are not tested
wanion.biggercraftingtables.nei.BigShapedRecipeHandler,biggercraftingtables:AutoBiggerCraftingTables,,biggercraftingtables,TRUE,,,,,,
wanion.biggercraftingtables.nei.BigShapelessRecipeHandler,biggercraftingtables:BiggerCraftingTables,,biggercraftingtables,TRUE,,,,,,
@@ -383,306 +383,311 @@ nc.crafting.nei.RecyclerRecipeHandler,NuclearCraft:recyclerIdle,,NuclearCraft,TR
nc.crafting.nei.NuclearWorkspaceRecipeHandler,NuclearCraft:nuclearWorkspace,,NuclearCraft,TRUE,,,,,,
ganymedes01.etfuturum.NEI_EtFuturum_Config$NEI_Recipes_Smoker,etfuturum:smoker,,etfuturum,TRUE,,,,,,not working well
ganymedes01.etfuturum.NEI_EtFuturum_Config$NEI_Recipes_BlastFurnace,etfuturum:blast_furnace,,etfuturum,TRUE,,,,,,not working well
crafting,gregtech:gt.metaitem.01:32744,,gregtech,TRUE,,,,,,"GT5 start: for readability, keep all GTNH-related catalysts below"
gt.recipe.primitiveblastfurnace,gregtech:gt.blockmachines:140,,gregtech,TRUE,,,,,,
gt.recipe.primitiveblastfurnace,gregtech:gt.blockmachines:108,,gregtech,TRUE,,,,,,
smelting,gregtech:gt.blockmachines:103,,gregtech,TRUE,,,,,,
smelting,gregtech:gt.blockmachines:104,,gregtech,TRUE,,,,,,
gt.recipe.macerator,gregtech:gt.blockmachines:106,,gregtech,TRUE,,,,,,
gt.recipe.macerator,gregtech:gt.blockmachines:107,,gregtech,TRUE,,,,,,
gt.recipe.extractor,gregtech:gt.blockmachines:109,,gregtech,TRUE,,,,,,
gt.recipe.extractor,gregtech:gt.blockmachines:110,,gregtech,TRUE,,,,,,
gt.recipe.hammer,gregtech:gt.blockmachines:112,,gregtech,TRUE,,,,,,
gt.recipe.hammer,gregtech:gt.blockmachines:113,,gregtech,TRUE,,,,,,
gt.recipe.compressor,gregtech:gt.blockmachines:115,,gregtech,TRUE,,,,,,
gt.recipe.compressor,gregtech:gt.blockmachines:116,,gregtech,TRUE,,,,,,
gt.recipe.alloysmelter,gregtech:gt.blockmachines:118,,gregtech,TRUE,,,,,,
gt.recipe.alloysmelter,gregtech:gt.blockmachines:119,,gregtech,TRUE,,,,,,
gt.recipe.alloysmelter,gregtech:gt.blockmachines:201,,gregtech,TRUE,,,,,,
gt.recipe.alloysmelter,gregtech:gt.blockmachines:202,,gregtech,TRUE,,,,,,
gt.recipe.alloysmelter,gregtech:gt.blockmachines:203,,gregtech,TRUE,,,,,,
gt.recipe.alloysmelter,gregtech:gt.blockmachines:204,,gregtech,TRUE,,,,,,
gt.recipe.alloysmelter,gregtech:gt.blockmachines:205,,gregtech,TRUE,,,,,,
gt.recipe.assembler,gregtech:gt.blockmachines:211,,gregtech,TRUE,,,,,,
gt.recipe.assembler,gregtech:gt.blockmachines:212,,gregtech,TRUE,,,,,,
gt.recipe.assembler,gregtech:gt.blockmachines:213,,gregtech,TRUE,,,,,,
gt.recipe.assembler,gregtech:gt.blockmachines:214,,gregtech,TRUE,,,,,,
gt.recipe.assembler,gregtech:gt.blockmachines:215,,gregtech,TRUE,,,,,,
gt.recipe.metalbender,gregtech:gt.blockmachines:221,,gregtech,TRUE,,,,,,
gt.recipe.metalbender,gregtech:gt.blockmachines:222,,gregtech,TRUE,,,,,,
gt.recipe.metalbender,gregtech:gt.blockmachines:223,,gregtech,TRUE,,,,,,
gt.recipe.metalbender,gregtech:gt.blockmachines:224,,gregtech,TRUE,,,,,,
gt.recipe.metalbender,gregtech:gt.blockmachines:225,,gregtech,TRUE,,,,,,
gt.recipe.canner,gregtech:gt.blockmachines:231,,gregtech,TRUE,,,,,,
gt.recipe.canner,gregtech:gt.blockmachines:232,,gregtech,TRUE,,,,,,
gt.recipe.canner,gregtech:gt.blockmachines:233,,gregtech,TRUE,,,,,,
gt.recipe.canner,gregtech:gt.blockmachines:234,,gregtech,TRUE,,,,,,
gt.recipe.canner,gregtech:gt.blockmachines:235,,gregtech,TRUE,,,,,,
gt.recipe.compressor,gregtech:gt.blockmachines:241,,gregtech,TRUE,,,,,,
gt.recipe.compressor,gregtech:gt.blockmachines:242,,gregtech,TRUE,,,,,,
gt.recipe.compressor,gregtech:gt.blockmachines:243,,gregtech,TRUE,,,,,,
gt.recipe.compressor,gregtech:gt.blockmachines:244,,gregtech,TRUE,,,,,,
gt.recipe.compressor,gregtech:gt.blockmachines:245,,gregtech,TRUE,,,,,,
gt.recipe.cuttingsaw,gregtech:gt.blockmachines:251,,gregtech,TRUE,,,,,,
gt.recipe.cuttingsaw,gregtech:gt.blockmachines:252,,gregtech,TRUE,,,,,,
gt.recipe.cuttingsaw,gregtech:gt.blockmachines:253,,gregtech,TRUE,,,,,,
gt.recipe.cuttingsaw,gregtech:gt.blockmachines:254,,gregtech,TRUE,,,,,,
gt.recipe.cuttingsaw,gregtech:gt.blockmachines:255,,gregtech,TRUE,,,,,,
smelting,gregtech:gt.blockmachines:261,,gregtech,TRUE,,,,,,
smelting,gregtech:gt.blockmachines:262,,gregtech,TRUE,,,,,,
smelting,gregtech:gt.blockmachines:263,,gregtech,TRUE,,,,,,
smelting,gregtech:gt.blockmachines:264,,gregtech,TRUE,,,,,,
smelting,gregtech:gt.blockmachines:265,,gregtech,TRUE,,,,,,
gt.recipe.extractor,gregtech:gt.blockmachines:271,,gregtech,TRUE,,,,,,
gt.recipe.extractor,gregtech:gt.blockmachines:272,,gregtech,TRUE,,,,,,
gt.recipe.extractor,gregtech:gt.blockmachines:273,,gregtech,TRUE,,,,,,
gt.recipe.extractor,gregtech:gt.blockmachines:274,,gregtech,TRUE,,,,,,
gt.recipe.extractor,gregtech:gt.blockmachines:275,,gregtech,TRUE,,,,,,
gt.recipe.extruder,gregtech:gt.blockmachines:281,,gregtech,TRUE,,,,,,
gt.recipe.extruder,gregtech:gt.blockmachines:282,,gregtech,TRUE,,,,,,
gt.recipe.extruder,gregtech:gt.blockmachines:283,,gregtech,TRUE,,,,,,
gt.recipe.extruder,gregtech:gt.blockmachines:284,,gregtech,TRUE,,,,,,
gt.recipe.extruder,gregtech:gt.blockmachines:285,,gregtech,TRUE,,,,,,
gt.recipe.lathe,gregtech:gt.blockmachines:291,,gregtech,TRUE,,,,,,
gt.recipe.lathe,gregtech:gt.blockmachines:292,,gregtech,TRUE,,,,,,
gt.recipe.lathe,gregtech:gt.blockmachines:293,,gregtech,TRUE,,,,,,
gt.recipe.lathe,gregtech:gt.blockmachines:294,,gregtech,TRUE,,,,,,
gt.recipe.lathe,gregtech:gt.blockmachines:295,,gregtech,TRUE,,,,,,
gt.recipe.macerator,gregtech:gt.blockmachines:301,,gregtech,TRUE,,,,,,
gt.recipe.macerator,gregtech:gt.blockmachines:302,,gregtech,TRUE,,,,,,
gt.recipe.macerator,gregtech:gt.blockmachines:303,,gregtech,TRUE,,,,,,
gt.recipe.macerator,gregtech:gt.blockmachines:304,,gregtech,TRUE,,,,,,
gt.recipe.macerator,gregtech:gt.blockmachines:305,,gregtech,TRUE,,,,,,
smelting,gregtech:gt.blockmachines:311,,gregtech,TRUE,,,,,,
smelting,gregtech:gt.blockmachines:312,,gregtech,TRUE,,,,,,
smelting,gregtech:gt.blockmachines:313,,gregtech,TRUE,,,,,,
smelting,gregtech:gt.blockmachines:314,,gregtech,TRUE,,,,,,
smelting,gregtech:gt.blockmachines:315,,gregtech,TRUE,,,,,,
gt.recipe.printer,gregtech:gt.blockmachines:321,,gregtech,TRUE,,,,,,
gt.recipe.printer,gregtech:gt.blockmachines:322,,gregtech,TRUE,,,,,,
gt.recipe.printer,gregtech:gt.blockmachines:323,,gregtech,TRUE,,,,,,
gt.recipe.printer,gregtech:gt.blockmachines:324,,gregtech,TRUE,,,,,,
gt.recipe.printer,gregtech:gt.blockmachines:325,,gregtech,TRUE,,,,,,
gt.recipe.printer,gregtech:gt.blockmachines:326,,gregtech,TRUE,,,,,,
gt.recipe.printer,gregtech:gt.blockmachines:327,,gregtech,TRUE,,,,,,
gt.recipe.printer,gregtech:gt.blockmachines:328,,gregtech,TRUE,,,,,,
ic2.recycler,gregtech:gt.blockmachines:331,,gregtech,TRUE,,,,,,
ic2.recycler,gregtech:gt.blockmachines:332,,gregtech,TRUE,,,,,,
ic2.recycler,gregtech:gt.blockmachines:333,,gregtech,TRUE,,,,,,
ic2.recycler,gregtech:gt.blockmachines:334,,gregtech,TRUE,,,,,,
ic2.recycler,gregtech:gt.blockmachines:335,,gregtech,TRUE,,,,,,
gt.recipe.scanner,gregtech:gt.blockmachines:341,,gregtech,TRUE,,,,,,
gt.recipe.scanner,gregtech:gt.blockmachines:342,,gregtech,TRUE,,,,,,
gt.recipe.scanner,gregtech:gt.blockmachines:343,,gregtech,TRUE,,,,,,
gt.recipe.scanner,gregtech:gt.blockmachines:344,,gregtech,TRUE,,,,,,
gt.recipe.scanner,gregtech:gt.blockmachines:345,,gregtech,TRUE,,,,,,
gt.recipe.wiremill,gregtech:gt.blockmachines:351,,gregtech,TRUE,,,,,,
gt.recipe.wiremill,gregtech:gt.blockmachines:352,,gregtech,TRUE,,,,,,
gt.recipe.wiremill,gregtech:gt.blockmachines:353,,gregtech,TRUE,,,,,,
gt.recipe.wiremill,gregtech:gt.blockmachines:354,,gregtech,TRUE,,,,,,
gt.recipe.wiremill,gregtech:gt.blockmachines:355,,gregtech,TRUE,,,,,,
gt.recipe.centrifuge,gregtech:gt.blockmachines:361,,gregtech,TRUE,,,,,,
gt.recipe.centrifuge,gregtech:gt.blockmachines:362,,gregtech,TRUE,,,,,,
gt.recipe.centrifuge,gregtech:gt.blockmachines:363,,gregtech,TRUE,,,,,,
gt.recipe.centrifuge,gregtech:gt.blockmachines:364,,gregtech,TRUE,,,,,,
gt.recipe.centrifuge,gregtech:gt.blockmachines:365,,gregtech,TRUE,,,,,,
gt.recipe.electrolyzer,gregtech:gt.blockmachines:371,,gregtech,TRUE,,,,,,
gt.recipe.electrolyzer,gregtech:gt.blockmachines:372,,gregtech,TRUE,,,,,,
gt.recipe.electrolyzer,gregtech:gt.blockmachines:373,,gregtech,TRUE,,,,,,
gt.recipe.electrolyzer,gregtech:gt.blockmachines:374,,gregtech,TRUE,,,,,,
gt.recipe.electrolyzer,gregtech:gt.blockmachines:375,,gregtech,TRUE,,,,,,
gt.recipe.thermalcentrifuge,gregtech:gt.blockmachines:381,,gregtech,TRUE,,,,,,
gt.recipe.thermalcentrifuge,gregtech:gt.blockmachines:382,,gregtech,TRUE,,,,,,
gt.recipe.thermalcentrifuge,gregtech:gt.blockmachines:383,,gregtech,TRUE,,,,,,
gt.recipe.thermalcentrifuge,gregtech:gt.blockmachines:384,,gregtech,TRUE,,,,,,
gt.recipe.thermalcentrifuge,gregtech:gt.blockmachines:385,,gregtech,TRUE,,,,,,
gt.recipe.orewasher,gregtech:gt.blockmachines:391,,gregtech,TRUE,,,,,,
gt.recipe.orewasher,gregtech:gt.blockmachines:392,,gregtech,TRUE,,,,,,
gt.recipe.orewasher,gregtech:gt.blockmachines:393,,gregtech,TRUE,,,,,,
gt.recipe.orewasher,gregtech:gt.blockmachines:394,,gregtech,TRUE,,,,,,
gt.recipe.orewasher,gregtech:gt.blockmachines:395,,gregtech,TRUE,,,,,,
gt.recipe.packager,gregtech:gt.blockmachines:401,,gregtech,TRUE,,,,,,
gt.recipe.packager,gregtech:gt.blockmachines:402,,gregtech,TRUE,,,,,,
gt.recipe.packager,gregtech:gt.blockmachines:403,,gregtech,TRUE,,,,,,
gt.recipe.packager,gregtech:gt.blockmachines:404,,gregtech,TRUE,,,,,,
gt.recipe.packager,gregtech:gt.blockmachines:405,,gregtech,TRUE,,,,,,
gt.recipe.packager,gregtech:gt.blockmachines:406,,gregtech,TRUE,,,,,,
gt.recipe.packager,gregtech:gt.blockmachines:407,,gregtech,TRUE,,,,,,
gt.recipe.packager,gregtech:gt.blockmachines:408,,gregtech,TRUE,,,,,,
gt.recipe.unpackager,gregtech:gt.blockmachines:411,,gregtech,TRUE,,,,,,
gt.recipe.unpackager,gregtech:gt.blockmachines:412,,gregtech,TRUE,,,,,,
gt.recipe.unpackager,gregtech:gt.blockmachines:413,,gregtech,TRUE,,,,,,
gt.recipe.unpackager,gregtech:gt.blockmachines:414,,gregtech,TRUE,,,,,,
gt.recipe.unpackager,gregtech:gt.blockmachines:415,,gregtech,TRUE,,,,,,
gt.recipe.unpackager,gregtech:gt.blockmachines:416,,gregtech,TRUE,,,,,,
gt.recipe.unpackager,gregtech:gt.blockmachines:417,,gregtech,TRUE,,,,,,
gt.recipe.unpackager,gregtech:gt.blockmachines:418,,gregtech,TRUE,,,,,,
gt.recipe.chemicalreactor,gregtech:gt.blockmachines:421,,gregtech,TRUE,,,,,,
gt.recipe.chemicalreactor,gregtech:gt.blockmachines:422,,gregtech,TRUE,,,,,,
gt.recipe.chemicalreactor,gregtech:gt.blockmachines:423,,gregtech,TRUE,,,,,,
gt.recipe.chemicalreactor,gregtech:gt.blockmachines:424,,gregtech,TRUE,,,,,,
gt.recipe.chemicalreactor,gregtech:gt.blockmachines:425,,gregtech,TRUE,,,,,,
gt.recipe.fluidcanner,gregtech:gt.blockmachines:431,,gregtech,TRUE,,,,,,
gt.recipe.fluidcanner,gregtech:gt.blockmachines:432,,gregtech,TRUE,,,,,,
gt.recipe.fluidcanner,gregtech:gt.blockmachines:433,,gregtech,TRUE,,,,,,
gt.recipe.fluidcanner,gregtech:gt.blockmachines:434,,gregtech,TRUE,,,,,,
gt.recipe.fluidcanner,gregtech:gt.blockmachines:435,,gregtech,TRUE,,,,,,
gt.recipe.rockbreaker,gregtech:gt.blockmachines:441,,gregtech,TRUE,,,,,,
gt.recipe.rockbreaker,gregtech:gt.blockmachines:442,,gregtech,TRUE,,,,,,
gt.recipe.rockbreaker,gregtech:gt.blockmachines:443,,gregtech,TRUE,,,,,,
gt.recipe.rockbreaker,gregtech:gt.blockmachines:444,,gregtech,TRUE,,,,,,
gt.recipe.rockbreaker,gregtech:gt.blockmachines:445,,gregtech,TRUE,,,,,,
gt.recipe.massfab,gregtech:gt.blockmachines:461,,gregtech,TRUE,,,,,,
gt.recipe.massfab,gregtech:gt.blockmachines:462,,gregtech,TRUE,,,,,,
gt.recipe.massfab,gregtech:gt.blockmachines:463,,gregtech,TRUE,,,,,,
gt.recipe.massfab,gregtech:gt.blockmachines:464,,gregtech,TRUE,,,,,,
gt.recipe.massfab,gregtech:gt.blockmachines:465,,gregtech,TRUE,,,,,,
gt.recipe.uuamplifier,gregtech:gt.blockmachines:471,,gregtech,TRUE,,,,,,
gt.recipe.uuamplifier,gregtech:gt.blockmachines:472,,gregtech,TRUE,,,,,,
gt.recipe.uuamplifier,gregtech:gt.blockmachines:473,,gregtech,TRUE,,,,,,
gt.recipe.uuamplifier,gregtech:gt.blockmachines:474,,gregtech,TRUE,,,,,,
gt.recipe.uuamplifier,gregtech:gt.blockmachines:475,,gregtech,TRUE,,,,,,
gt.recipe.replicator,gregtech:gt.blockmachines:481,,gregtech,TRUE,,,,,,
gt.recipe.replicator,gregtech:gt.blockmachines:482,,gregtech,TRUE,,,,,,
gt.recipe.replicator,gregtech:gt.blockmachines:483,,gregtech,TRUE,,,,,,
gt.recipe.replicator,gregtech:gt.blockmachines:484,,gregtech,TRUE,,,,,,
gt.recipe.replicator,gregtech:gt.blockmachines:485,,gregtech,TRUE,,,,,,
gt.recipe.brewer,gregtech:gt.blockmachines:491,,gregtech,TRUE,,,,,,
gt.recipe.brewer,gregtech:gt.blockmachines:492,,gregtech,TRUE,,,,,,
gt.recipe.brewer,gregtech:gt.blockmachines:493,,gregtech,TRUE,,,,,,
gt.recipe.brewer,gregtech:gt.blockmachines:494,,gregtech,TRUE,,,,,,
gt.recipe.brewer,gregtech:gt.blockmachines:495,,gregtech,TRUE,,,,,,
gt.recipe.fermenter,gregtech:gt.blockmachines:501,,gregtech,TRUE,,,,,,
gt.recipe.fermenter,gregtech:gt.blockmachines:502,,gregtech,TRUE,,,,,,
gt.recipe.fermenter,gregtech:gt.blockmachines:503,,gregtech,TRUE,,,,,,
gt.recipe.fermenter,gregtech:gt.blockmachines:504,,gregtech,TRUE,,,,,,
gt.recipe.fermenter,gregtech:gt.blockmachines:505,,gregtech,TRUE,,,,,,
gt.recipe.fluidextractor,gregtech:gt.blockmachines:511,,gregtech,TRUE,,,,,,
gt.recipe.fluidextractor,gregtech:gt.blockmachines:512,,gregtech,TRUE,,,,,,
gt.recipe.fluidextractor,gregtech:gt.blockmachines:513,,gregtech,TRUE,,,,,,
gt.recipe.fluidextractor,gregtech:gt.blockmachines:514,,gregtech,TRUE,,,,,,
gt.recipe.fluidextractor,gregtech:gt.blockmachines:515,,gregtech,TRUE,,,,,,
gt.recipe.fluidsolidifier,gregtech:gt.blockmachines:521,,gregtech,TRUE,,,,,,
gt.recipe.fluidsolidifier,gregtech:gt.blockmachines:522,,gregtech,TRUE,,,,,,
gt.recipe.fluidsolidifier,gregtech:gt.blockmachines:523,,gregtech,TRUE,,,,,,
gt.recipe.fluidsolidifier,gregtech:gt.blockmachines:524,,gregtech,TRUE,,,,,,
gt.recipe.fluidsolidifier,gregtech:gt.blockmachines:525,,gregtech,TRUE,,,,,,
gt.recipe.distillery,gregtech:gt.blockmachines:531,,gregtech,TRUE,,,,,,
gt.recipe.distillery,gregtech:gt.blockmachines:532,,gregtech,TRUE,,,,,,
gt.recipe.distillery,gregtech:gt.blockmachines:533,,gregtech,TRUE,,,,,,
gt.recipe.distillery,gregtech:gt.blockmachines:534,,gregtech,TRUE,,,,,,
gt.recipe.distillery,gregtech:gt.blockmachines:535,,gregtech,TRUE,,,,,,
gt.recipe.chemicalbath,gregtech:gt.blockmachines:541,,gregtech,TRUE,,,,,,
gt.recipe.chemicalbath,gregtech:gt.blockmachines:542,,gregtech,TRUE,,,,,,
gt.recipe.chemicalbath,gregtech:gt.blockmachines:543,,gregtech,TRUE,,,,,,
gt.recipe.chemicalbath,gregtech:gt.blockmachines:544,,gregtech,TRUE,,,,,,
gt.recipe.chemicalbath,gregtech:gt.blockmachines:545,,gregtech,TRUE,,,,,,
gt.recipe.polarizer,gregtech:gt.blockmachines:551,,gregtech,TRUE,,,,,,
gt.recipe.polarizer,gregtech:gt.blockmachines:552,,gregtech,TRUE,,,,,,
gt.recipe.polarizer,gregtech:gt.blockmachines:553,,gregtech,TRUE,,,,,,
gt.recipe.polarizer,gregtech:gt.blockmachines:554,,gregtech,TRUE,,,,,,
gt.recipe.polarizer,gregtech:gt.blockmachines:555,,gregtech,TRUE,,,,,,
gt.recipe.electromagneticseparator,gregtech:gt.blockmachines:561,,gregtech,TRUE,,,,,,
gt.recipe.electromagneticseparator,gregtech:gt.blockmachines:562,,gregtech,TRUE,,,,,,
gt.recipe.electromagneticseparator,gregtech:gt.blockmachines:563,,gregtech,TRUE,,,,,,
gt.recipe.electromagneticseparator,gregtech:gt.blockmachines:564,,gregtech,TRUE,,,,,,
gt.recipe.electromagneticseparator,gregtech:gt.blockmachines:565,,gregtech,TRUE,,,,,,
gt.recipe.autoclave,gregtech:gt.blockmachines:571,,gregtech,TRUE,,,,,,
gt.recipe.autoclave,gregtech:gt.blockmachines:572,,gregtech,TRUE,,,,,,
gt.recipe.autoclave,gregtech:gt.blockmachines:573,,gregtech,TRUE,,,,,,
gt.recipe.autoclave,gregtech:gt.blockmachines:574,,gregtech,TRUE,,,,,,
gt.recipe.autoclave,gregtech:gt.blockmachines:575,,gregtech,TRUE,,,,,,
gt.recipe.mixer,gregtech:gt.blockmachines:581,,gregtech,TRUE,,,,,,
gt.recipe.mixer,gregtech:gt.blockmachines:582,,gregtech,TRUE,,,,,,
gt.recipe.mixer,gregtech:gt.blockmachines:583,,gregtech,TRUE,,,,,,
gt.recipe.mixer,gregtech:gt.blockmachines:584,,gregtech,TRUE,,,,,,
gt.recipe.mixer,gregtech:gt.blockmachines:585,,gregtech,TRUE,,,,,,
gt.recipe.laserengraver,gregtech:gt.blockmachines:591,,gregtech,TRUE,,,,,,
gt.recipe.laserengraver,gregtech:gt.blockmachines:592,,gregtech,TRUE,,,,,,
gt.recipe.laserengraver,gregtech:gt.blockmachines:593,,gregtech,TRUE,,,,,,
gt.recipe.laserengraver,gregtech:gt.blockmachines:594,,gregtech,TRUE,,,,,,
gt.recipe.laserengraver,gregtech:gt.blockmachines:595,,gregtech,TRUE,,,,,,
gt.recipe.press,gregtech:gt.blockmachines:601,,gregtech,TRUE,,,,,,
gt.recipe.press,gregtech:gt.blockmachines:602,,gregtech,TRUE,,,,,,
gt.recipe.press,gregtech:gt.blockmachines:603,,gregtech,TRUE,,,,,,
gt.recipe.press,gregtech:gt.blockmachines:604,,gregtech,TRUE,,,,,,
gt.recipe.press,gregtech:gt.blockmachines:605,,gregtech,TRUE,,,,,,
gt.recipe.hammer,gregtech:gt.blockmachines:611,,gregtech,TRUE,,,,,,
gt.recipe.hammer,gregtech:gt.blockmachines:612,,gregtech,TRUE,,,,,,
gt.recipe.hammer,gregtech:gt.blockmachines:613,,gregtech,TRUE,,,,,,
gt.recipe.hammer,gregtech:gt.blockmachines:614,,gregtech,TRUE,,,,,,
gt.recipe.hammer,gregtech:gt.blockmachines:615,,gregtech,TRUE,,,,,,
gt.recipe.fluidheater,gregtech:gt.blockmachines:621,,gregtech,TRUE,,,,,,
gt.recipe.fluidheater,gregtech:gt.blockmachines:622,,gregtech,TRUE,,,,,,
gt.recipe.fluidheater,gregtech:gt.blockmachines:623,,gregtech,TRUE,,,,,,
gt.recipe.fluidheater,gregtech:gt.blockmachines:624,,gregtech,TRUE,,,,,,
gt.recipe.fluidheater,gregtech:gt.blockmachines:625,,gregtech,TRUE,,,,,,
gt.recipe.slicer,gregtech:gt.blockmachines:631,,gregtech,TRUE,,,,,,
gt.recipe.slicer,gregtech:gt.blockmachines:632,,gregtech,TRUE,,,,,,
gt.recipe.slicer,gregtech:gt.blockmachines:633,,gregtech,TRUE,,,,,,
gt.recipe.slicer,gregtech:gt.blockmachines:634,,gregtech,TRUE,,,,,,
gt.recipe.slicer,gregtech:gt.blockmachines:635,,gregtech,TRUE,,,,,,
gt.recipe.sifter,gregtech:gt.blockmachines:641,,gregtech,TRUE,,,,,,
gt.recipe.sifter,gregtech:gt.blockmachines:642,,gregtech,TRUE,,,,,,
gt.recipe.sifter,gregtech:gt.blockmachines:643,,gregtech,TRUE,,,,,,
gt.recipe.sifter,gregtech:gt.blockmachines:644,,gregtech,TRUE,,,,,,
gt.recipe.sifter,gregtech:gt.blockmachines:645,,gregtech,TRUE,,,,,,
gt.recipe.arcfurnace,gregtech:gt.blockmachines:651,,gregtech,TRUE,,,,,,
gt.recipe.arcfurnace,gregtech:gt.blockmachines:652,,gregtech,TRUE,,,,,,
gt.recipe.arcfurnace,gregtech:gt.blockmachines:653,,gregtech,TRUE,,,,,,
gt.recipe.arcfurnace,gregtech:gt.blockmachines:654,,gregtech,TRUE,,,,,,
gt.recipe.arcfurnace,gregtech:gt.blockmachines:655,,gregtech,TRUE,,,,,,
gt.recipe.plasmaarcfurnace,gregtech:gt.blockmachines:661,,gregtech,TRUE,,,,,,
gt.recipe.plasmaarcfurnace,gregtech:gt.blockmachines:662,,gregtech,TRUE,,,,,,
gt.recipe.plasmaarcfurnace,gregtech:gt.blockmachines:663,,gregtech,TRUE,,,,,,
gt.recipe.plasmaarcfurnace,gregtech:gt.blockmachines:664,,gregtech,TRUE,,,,,,
gt.recipe.plasmaarcfurnace,gregtech:gt.blockmachines:665,,gregtech,TRUE,,,,,,
smelting,gregtech:gt.blockmachines:671,,gregtech,TRUE,,,,,,
smelting,gregtech:gt.blockmachines:672,,gregtech,TRUE,,,,,,
smelting,gregtech:gt.blockmachines:673,,gregtech,TRUE,,,,,,
smelting,gregtech:gt.blockmachines:674,,gregtech,TRUE,,,,,,
smelting,gregtech:gt.blockmachines:675,,gregtech,TRUE,,,,,,
gt.recipe.blastfurnace,gregtech:gt.blockmachines:1000,,gregtech,TRUE,,,,,,
gt.recipe.implosioncompressor,gregtech:gt.blockmachines:1001,,gregtech,TRUE,,,,,,
gt.recipe.vacuumfreezer,gregtech:gt.blockmachines:1002,,gregtech,TRUE,,,,,,
smelting,gregtech:gt.blockmachines:1003,,gregtech,TRUE,,,,,,
gt.recipe.dieselgeneratorfuel,gregtech:gt.blockmachines:1110,,gregtech,TRUE,,,,,,
gt.recipe.dieselgeneratorfuel,gregtech:gt.blockmachines:1111,,gregtech,TRUE,,,,,,
gt.recipe.dieselgeneratorfuel,gregtech:gt.blockmachines:1112,,gregtech,TRUE,,,,,,
gt.recipe.gasturbinefuel,gregtech:gt.blockmachines:1115,,gregtech,TRUE,,,,,,
gt.recipe.gasturbinefuel,gregtech:gt.blockmachines:1116,,gregtech,TRUE,,,,,,
gt.recipe.gasturbinefuel,gregtech:gt.blockmachines:1117,,gregtech,TRUE,,,,,,
gt.recipe.fluidnaquadahreactor,gregtech:gt.blockmachines:1190,,gregtech,TRUE,,,,,,
gt.recipe.fluidnaquadahreactor,gregtech:gt.blockmachines:1191,,gregtech,TRUE,,,,,,
gt.recipe.fluidnaquadahreactor,gregtech:gt.blockmachines:1192,,gregtech,TRUE,,,,,,
gt.recipe.fluidnaquadahreactor,gregtech:gt.blockmachines:1188,,gregtech,TRUE,,,,,,
gt.recipe.fluidnaquadahreactor,gregtech:gt.blockmachines:1189,,gregtech,TRUE,,,,,,
gt.recipe.magicfuels,gregtech:gt.blockmachines:1123,,gregtech,TRUE,,,,,,
gt.recipe.magicfuels,gregtech:gt.blockmachines:1124,,gregtech,TRUE,,,,,,
gt.recipe.magicfuels,gregtech:gt.blockmachines:1125,,gregtech,TRUE,,,,,,
gt.recipe.fusionreactor,gregtech:gt.blockmachines:1193,,gregtech,TRUE,,,,,,
gt.recipe.fusionreactor,gregtech:gt.blockmachines:1194,,gregtech,TRUE,,,,,,
gt.recipe.fusionreactor,gregtech:gt.blockmachines:1195,,gregtech,TRUE,,,,,,
gt.recipe.plasmageneratorfuels,gregtech:gt.blockmachines:1196,,gregtech,TRUE,,,,,,
gt.recipe.plasmageneratorfuels,gregtech:gt.blockmachines:1197,,gregtech,TRUE,,,,,,
gt.recipe.plasmageneratorfuels,gregtech:gt.blockmachines:1198,,gregtech,TRUE,,,,,,
gt.recipe.distillationtower,gregtech:gt.blockmachines:1126,,gregtech,TRUE,,,,,,
gt.recipe.gasturbinefuel,gregtech:gt.blockmachines:1151,,gregtech,TRUE,,,,,,
gt.recipe.plasmageneratorfuels,gregtech:gt.blockmachines:1153,,gregtech,TRUE,,-10,,,,
gt.recipe.pyro,gregtech:gt.blockmachines:1159,,gregtech,TRUE,,,,,,
gt.recipe.craker,gregtech:gt.blockmachines:1160,,gregtech,TRUE,,,,,,
gt.recipe.fakeAssemblylineProcess,gregtech:gt.blockmachines:1170,,gregtech,TRUE,,,,,,
gt.recipe.dieselgeneratorfuel,gregtech:gt.blockmachines:1171,,gregtech,TRUE,,-5,,,,
gt.recipe.extremedieselgeneratorfuel,gregtech:gt.blockmachines:2105,,gregtech,TRUE,,,,,,
gt.recipe.circuitassembler,gregtech:gt.blockmachines:1180,,gregtech,TRUE,,,,,,
gt.recipe.circuitassembler,gregtech:gt.blockmachines:1181,,gregtech,TRUE,,,,,,
gt.recipe.circuitassembler,gregtech:gt.blockmachines:1182,,gregtech,TRUE,,,,,,
gt.recipe.circuitassembler,gregtech:gt.blockmachines:1183,,gregtech,TRUE,,,,,,
gt.recipe.circuitassembler,gregtech:gt.blockmachines:1184,,gregtech,TRUE,,,,,,
gt.recipe.circuitassembler,gregtech:gt.blockmachines:1185,,gregtech,TRUE,,,,,,
gt.recipe.circuitassembler,gregtech:gt.blockmachines:1186,,gregtech,TRUE,,,,,,
gt.recipe.circuitassembler,gregtech:gt.blockmachines:1187,,gregtech,TRUE,,,,,,
gt.recipe.largechemicalreactor,gregtech:gt.blockmachines:1169,,gregtech,TRUE,,,,,,
connor135246.campfirebackport.client.compat.nei.NEICampfireRecipeHandler,campfirebackport:campfire,,campfirebackport,TRUE,,,,,,
connor135246.campfirebackport.client.compat.nei.NEICampfireRecipeHandler,campfirebackport:soul_campfire,,campfirebackport,TRUE,,,,,,
connor135246.campfirebackport.client.compat.nei.NEICampfireStateChangerHandler,campfirebackport:campfire,,campfirebackport,TRUE,,,,,,
connor135246.campfirebackport.client.compat.nei.NEICampfireStateChangerHandler,campfirebackport:soul_campfire,,campfirebackport,TRUE,,,,,,
smelting,Natura:NetherFurnace,,Natura,TRUE,,,,,,
crafting,gregtech:gt.metaitem.01:32744,,gregtech,TRUE,gregapi_post,,,,,"GT5 start: for readability, keep all GTNH-related catalysts below"
gt.recipe.primitiveblastfurnace,gregtech:gt.blockmachines:140,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.primitiveblastfurnace,gregtech:gt.blockmachines:108,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:103,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:104,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.macerator,gregtech:gt.blockmachines:106,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.macerator,gregtech:gt.blockmachines:107,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.extractor,gregtech:gt.blockmachines:109,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.extractor,gregtech:gt.blockmachines:110,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.hammer,gregtech:gt.blockmachines:112,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.hammer,gregtech:gt.blockmachines:113,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.compressor,gregtech:gt.blockmachines:115,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.compressor,gregtech:gt.blockmachines:116,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.alloysmelter,gregtech:gt.blockmachines:118,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.alloysmelter,gregtech:gt.blockmachines:119,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.alloysmelter,gregtech:gt.blockmachines:201,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.alloysmelter,gregtech:gt.blockmachines:202,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.alloysmelter,gregtech:gt.blockmachines:203,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.alloysmelter,gregtech:gt.blockmachines:204,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.alloysmelter,gregtech:gt.blockmachines:205,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.assembler,gregtech:gt.blockmachines:211,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.assembler,gregtech:gt.blockmachines:212,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.assembler,gregtech:gt.blockmachines:213,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.assembler,gregtech:gt.blockmachines:214,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.assembler,gregtech:gt.blockmachines:215,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.metalbender,gregtech:gt.blockmachines:221,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.metalbender,gregtech:gt.blockmachines:222,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.metalbender,gregtech:gt.blockmachines:223,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.metalbender,gregtech:gt.blockmachines:224,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.metalbender,gregtech:gt.blockmachines:225,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.canner,gregtech:gt.blockmachines:231,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.canner,gregtech:gt.blockmachines:232,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.canner,gregtech:gt.blockmachines:233,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.canner,gregtech:gt.blockmachines:234,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.canner,gregtech:gt.blockmachines:235,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.compressor,gregtech:gt.blockmachines:241,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.compressor,gregtech:gt.blockmachines:242,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.compressor,gregtech:gt.blockmachines:243,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.compressor,gregtech:gt.blockmachines:244,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.compressor,gregtech:gt.blockmachines:245,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.cuttingsaw,gregtech:gt.blockmachines:251,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.cuttingsaw,gregtech:gt.blockmachines:252,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.cuttingsaw,gregtech:gt.blockmachines:253,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.cuttingsaw,gregtech:gt.blockmachines:254,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.cuttingsaw,gregtech:gt.blockmachines:255,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:261,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:262,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:263,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:264,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:265,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.extractor,gregtech:gt.blockmachines:271,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.extractor,gregtech:gt.blockmachines:272,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.extractor,gregtech:gt.blockmachines:273,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.extractor,gregtech:gt.blockmachines:274,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.extractor,gregtech:gt.blockmachines:275,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.extruder,gregtech:gt.blockmachines:281,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.extruder,gregtech:gt.blockmachines:282,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.extruder,gregtech:gt.blockmachines:283,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.extruder,gregtech:gt.blockmachines:284,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.extruder,gregtech:gt.blockmachines:285,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.lathe,gregtech:gt.blockmachines:291,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.lathe,gregtech:gt.blockmachines:292,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.lathe,gregtech:gt.blockmachines:293,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.lathe,gregtech:gt.blockmachines:294,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.lathe,gregtech:gt.blockmachines:295,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.macerator,gregtech:gt.blockmachines:301,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.macerator,gregtech:gt.blockmachines:302,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.macerator,gregtech:gt.blockmachines:303,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.macerator,gregtech:gt.blockmachines:304,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.macerator,gregtech:gt.blockmachines:305,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:311,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:312,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:313,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:314,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:315,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.printer,gregtech:gt.blockmachines:321,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.printer,gregtech:gt.blockmachines:322,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.printer,gregtech:gt.blockmachines:323,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.printer,gregtech:gt.blockmachines:324,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.printer,gregtech:gt.blockmachines:325,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.printer,gregtech:gt.blockmachines:326,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.printer,gregtech:gt.blockmachines:327,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.printer,gregtech:gt.blockmachines:328,,gregtech,TRUE,gregapi_post,,,,,
ic2.recycler,gregtech:gt.blockmachines:331,,gregtech,TRUE,gregapi_post,,,,,
ic2.recycler,gregtech:gt.blockmachines:332,,gregtech,TRUE,gregapi_post,,,,,
ic2.recycler,gregtech:gt.blockmachines:333,,gregtech,TRUE,gregapi_post,,,,,
ic2.recycler,gregtech:gt.blockmachines:334,,gregtech,TRUE,gregapi_post,,,,,
ic2.recycler,gregtech:gt.blockmachines:335,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.scanner,gregtech:gt.blockmachines:341,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.scanner,gregtech:gt.blockmachines:342,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.scanner,gregtech:gt.blockmachines:343,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.scanner,gregtech:gt.blockmachines:344,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.scanner,gregtech:gt.blockmachines:345,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.wiremill,gregtech:gt.blockmachines:351,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.wiremill,gregtech:gt.blockmachines:352,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.wiremill,gregtech:gt.blockmachines:353,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.wiremill,gregtech:gt.blockmachines:354,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.wiremill,gregtech:gt.blockmachines:355,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.centrifuge,gregtech:gt.blockmachines:361,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.centrifuge,gregtech:gt.blockmachines:362,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.centrifuge,gregtech:gt.blockmachines:363,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.centrifuge,gregtech:gt.blockmachines:364,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.centrifuge,gregtech:gt.blockmachines:365,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.electrolyzer,gregtech:gt.blockmachines:371,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.electrolyzer,gregtech:gt.blockmachines:372,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.electrolyzer,gregtech:gt.blockmachines:373,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.electrolyzer,gregtech:gt.blockmachines:374,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.electrolyzer,gregtech:gt.blockmachines:375,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.thermalcentrifuge,gregtech:gt.blockmachines:381,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.thermalcentrifuge,gregtech:gt.blockmachines:382,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.thermalcentrifuge,gregtech:gt.blockmachines:383,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.thermalcentrifuge,gregtech:gt.blockmachines:384,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.thermalcentrifuge,gregtech:gt.blockmachines:385,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.orewasher,gregtech:gt.blockmachines:391,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.orewasher,gregtech:gt.blockmachines:392,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.orewasher,gregtech:gt.blockmachines:393,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.orewasher,gregtech:gt.blockmachines:394,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.orewasher,gregtech:gt.blockmachines:395,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.packager,gregtech:gt.blockmachines:401,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.packager,gregtech:gt.blockmachines:402,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.packager,gregtech:gt.blockmachines:403,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.packager,gregtech:gt.blockmachines:404,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.packager,gregtech:gt.blockmachines:405,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.packager,gregtech:gt.blockmachines:406,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.packager,gregtech:gt.blockmachines:407,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.packager,gregtech:gt.blockmachines:408,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.unpackager,gregtech:gt.blockmachines:411,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.unpackager,gregtech:gt.blockmachines:412,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.unpackager,gregtech:gt.blockmachines:413,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.unpackager,gregtech:gt.blockmachines:414,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.unpackager,gregtech:gt.blockmachines:415,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.unpackager,gregtech:gt.blockmachines:416,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.unpackager,gregtech:gt.blockmachines:417,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.unpackager,gregtech:gt.blockmachines:418,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.chemicalreactor,gregtech:gt.blockmachines:421,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.chemicalreactor,gregtech:gt.blockmachines:422,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.chemicalreactor,gregtech:gt.blockmachines:423,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.chemicalreactor,gregtech:gt.blockmachines:424,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.chemicalreactor,gregtech:gt.blockmachines:425,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidcanner,gregtech:gt.blockmachines:431,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidcanner,gregtech:gt.blockmachines:432,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidcanner,gregtech:gt.blockmachines:433,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidcanner,gregtech:gt.blockmachines:434,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidcanner,gregtech:gt.blockmachines:435,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.rockbreaker,gregtech:gt.blockmachines:441,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.rockbreaker,gregtech:gt.blockmachines:442,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.rockbreaker,gregtech:gt.blockmachines:443,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.rockbreaker,gregtech:gt.blockmachines:444,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.rockbreaker,gregtech:gt.blockmachines:445,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.massfab,gregtech:gt.blockmachines:461,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.massfab,gregtech:gt.blockmachines:462,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.massfab,gregtech:gt.blockmachines:463,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.massfab,gregtech:gt.blockmachines:464,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.massfab,gregtech:gt.blockmachines:465,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.uuamplifier,gregtech:gt.blockmachines:471,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.uuamplifier,gregtech:gt.blockmachines:472,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.uuamplifier,gregtech:gt.blockmachines:473,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.uuamplifier,gregtech:gt.blockmachines:474,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.uuamplifier,gregtech:gt.blockmachines:475,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.replicator,gregtech:gt.blockmachines:481,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.replicator,gregtech:gt.blockmachines:482,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.replicator,gregtech:gt.blockmachines:483,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.replicator,gregtech:gt.blockmachines:484,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.replicator,gregtech:gt.blockmachines:485,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.brewer,gregtech:gt.blockmachines:491,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.brewer,gregtech:gt.blockmachines:492,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.brewer,gregtech:gt.blockmachines:493,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.brewer,gregtech:gt.blockmachines:494,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.brewer,gregtech:gt.blockmachines:495,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fermenter,gregtech:gt.blockmachines:501,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fermenter,gregtech:gt.blockmachines:502,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fermenter,gregtech:gt.blockmachines:503,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fermenter,gregtech:gt.blockmachines:504,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fermenter,gregtech:gt.blockmachines:505,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidextractor,gregtech:gt.blockmachines:511,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidextractor,gregtech:gt.blockmachines:512,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidextractor,gregtech:gt.blockmachines:513,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidextractor,gregtech:gt.blockmachines:514,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidextractor,gregtech:gt.blockmachines:515,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidsolidifier,gregtech:gt.blockmachines:521,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidsolidifier,gregtech:gt.blockmachines:522,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidsolidifier,gregtech:gt.blockmachines:523,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidsolidifier,gregtech:gt.blockmachines:524,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidsolidifier,gregtech:gt.blockmachines:525,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.distillery,gregtech:gt.blockmachines:531,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.distillery,gregtech:gt.blockmachines:532,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.distillery,gregtech:gt.blockmachines:533,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.distillery,gregtech:gt.blockmachines:534,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.distillery,gregtech:gt.blockmachines:535,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.chemicalbath,gregtech:gt.blockmachines:541,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.chemicalbath,gregtech:gt.blockmachines:542,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.chemicalbath,gregtech:gt.blockmachines:543,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.chemicalbath,gregtech:gt.blockmachines:544,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.chemicalbath,gregtech:gt.blockmachines:545,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.polarizer,gregtech:gt.blockmachines:551,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.polarizer,gregtech:gt.blockmachines:552,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.polarizer,gregtech:gt.blockmachines:553,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.polarizer,gregtech:gt.blockmachines:554,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.polarizer,gregtech:gt.blockmachines:555,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.electromagneticseparator,gregtech:gt.blockmachines:561,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.electromagneticseparator,gregtech:gt.blockmachines:562,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.electromagneticseparator,gregtech:gt.blockmachines:563,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.electromagneticseparator,gregtech:gt.blockmachines:564,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.electromagneticseparator,gregtech:gt.blockmachines:565,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.autoclave,gregtech:gt.blockmachines:571,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.autoclave,gregtech:gt.blockmachines:572,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.autoclave,gregtech:gt.blockmachines:573,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.autoclave,gregtech:gt.blockmachines:574,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.autoclave,gregtech:gt.blockmachines:575,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.mixer,gregtech:gt.blockmachines:581,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.mixer,gregtech:gt.blockmachines:582,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.mixer,gregtech:gt.blockmachines:583,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.mixer,gregtech:gt.blockmachines:584,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.mixer,gregtech:gt.blockmachines:585,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.laserengraver,gregtech:gt.blockmachines:591,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.laserengraver,gregtech:gt.blockmachines:592,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.laserengraver,gregtech:gt.blockmachines:593,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.laserengraver,gregtech:gt.blockmachines:594,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.laserengraver,gregtech:gt.blockmachines:595,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.press,gregtech:gt.blockmachines:601,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.press,gregtech:gt.blockmachines:602,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.press,gregtech:gt.blockmachines:603,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.press,gregtech:gt.blockmachines:604,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.press,gregtech:gt.blockmachines:605,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.hammer,gregtech:gt.blockmachines:611,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.hammer,gregtech:gt.blockmachines:612,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.hammer,gregtech:gt.blockmachines:613,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.hammer,gregtech:gt.blockmachines:614,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.hammer,gregtech:gt.blockmachines:615,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidheater,gregtech:gt.blockmachines:621,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidheater,gregtech:gt.blockmachines:622,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidheater,gregtech:gt.blockmachines:623,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidheater,gregtech:gt.blockmachines:624,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidheater,gregtech:gt.blockmachines:625,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.slicer,gregtech:gt.blockmachines:631,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.slicer,gregtech:gt.blockmachines:632,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.slicer,gregtech:gt.blockmachines:633,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.slicer,gregtech:gt.blockmachines:634,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.slicer,gregtech:gt.blockmachines:635,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.sifter,gregtech:gt.blockmachines:641,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.sifter,gregtech:gt.blockmachines:642,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.sifter,gregtech:gt.blockmachines:643,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.sifter,gregtech:gt.blockmachines:644,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.sifter,gregtech:gt.blockmachines:645,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.arcfurnace,gregtech:gt.blockmachines:651,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.arcfurnace,gregtech:gt.blockmachines:652,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.arcfurnace,gregtech:gt.blockmachines:653,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.arcfurnace,gregtech:gt.blockmachines:654,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.arcfurnace,gregtech:gt.blockmachines:655,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.plasmaarcfurnace,gregtech:gt.blockmachines:661,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.plasmaarcfurnace,gregtech:gt.blockmachines:662,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.plasmaarcfurnace,gregtech:gt.blockmachines:663,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.plasmaarcfurnace,gregtech:gt.blockmachines:664,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.plasmaarcfurnace,gregtech:gt.blockmachines:665,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:671,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:672,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:673,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:674,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:675,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.blastfurnace,gregtech:gt.blockmachines:1000,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.implosioncompressor,gregtech:gt.blockmachines:1001,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.vacuumfreezer,gregtech:gt.blockmachines:1002,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:1003,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.dieselgeneratorfuel,gregtech:gt.blockmachines:1110,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.dieselgeneratorfuel,gregtech:gt.blockmachines:1111,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.dieselgeneratorfuel,gregtech:gt.blockmachines:1112,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.gasturbinefuel,gregtech:gt.blockmachines:1115,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.gasturbinefuel,gregtech:gt.blockmachines:1116,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.gasturbinefuel,gregtech:gt.blockmachines:1117,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidnaquadahreactor,gregtech:gt.blockmachines:1190,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidnaquadahreactor,gregtech:gt.blockmachines:1191,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidnaquadahreactor,gregtech:gt.blockmachines:1192,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidnaquadahreactor,gregtech:gt.blockmachines:1188,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fluidnaquadahreactor,gregtech:gt.blockmachines:1189,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.magicfuels,gregtech:gt.blockmachines:1123,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.magicfuels,gregtech:gt.blockmachines:1124,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.magicfuels,gregtech:gt.blockmachines:1125,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fusionreactor,gregtech:gt.blockmachines:1193,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fusionreactor,gregtech:gt.blockmachines:1194,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fusionreactor,gregtech:gt.blockmachines:1195,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.plasmageneratorfuels,gregtech:gt.blockmachines:1196,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.plasmageneratorfuels,gregtech:gt.blockmachines:1197,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.plasmageneratorfuels,gregtech:gt.blockmachines:1198,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.distillationtower,gregtech:gt.blockmachines:1126,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.gasturbinefuel,gregtech:gt.blockmachines:1151,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.plasmageneratorfuels,gregtech:gt.blockmachines:1153,,gregtech,TRUE,gregapi_post,-10,,,,
gt.recipe.pyro,gregtech:gt.blockmachines:1159,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.craker,gregtech:gt.blockmachines:1160,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.fakeAssemblylineProcess,gregtech:gt.blockmachines:1170,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.dieselgeneratorfuel,gregtech:gt.blockmachines:1171,,gregtech,TRUE,gregapi_post,-5,,,,
gt.recipe.extremedieselgeneratorfuel,gregtech:gt.blockmachines:2105,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.circuitassembler,gregtech:gt.blockmachines:1180,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.circuitassembler,gregtech:gt.blockmachines:1181,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.circuitassembler,gregtech:gt.blockmachines:1182,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.circuitassembler,gregtech:gt.blockmachines:1183,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.circuitassembler,gregtech:gt.blockmachines:1184,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.circuitassembler,gregtech:gt.blockmachines:1185,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.circuitassembler,gregtech:gt.blockmachines:1186,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.circuitassembler,gregtech:gt.blockmachines:1187,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.largechemicalreactor,gregtech:gt.blockmachines:1169,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.plasmageneratorfuels,gregtech:gt.blockmachines:10752,,dreamcraft,TRUE,,,,,,
gt.recipe.plasmageneratorfuels,gregtech:gt.blockmachines:10753,,dreamcraft,TRUE,,,,,,
gt.recipe.alloysmelter,gregtech:gt.blockmachines:10760,,dreamcraft,TRUE,,,,,,
@@ -1033,14 +1038,6 @@ gtpp.recipe.chemicaldehydrator,gregtech:gt.blockmachines:814,,miscutils,TRUE,,,,
gtpp.recipe.chemicaldehydrator,gregtech:gt.blockmachines:815,,miscutils,TRUE,,,,,,
gtpp.recipe.chemicaldehydrator,gregtech:gt.blockmachines:816,,miscutils,TRUE,,,,,,
gtpp.recipe.chemicaldehydrator,gregtech:gt.blockmachines:995,,miscutils,TRUE,,,,,,
gt.recipe.mixer,gregtech:gt.blockmachines:851,,miscutils,TRUE,,,,,,
gt.recipe.mixer,gregtech:gt.blockmachines:852,,miscutils,TRUE,,,,,,
gt.recipe.mixer,gregtech:gt.blockmachines:853,,miscutils,TRUE,,,,,,
gt.recipe.mixer,gregtech:gt.blockmachines:854,,miscutils,TRUE,,,,,,
gt.recipe.mixer,gregtech:gt.blockmachines:855,,miscutils,TRUE,,,,,,
gt.recipe.mixer,gregtech:gt.blockmachines:856,,miscutils,TRUE,,,,,,
gt.recipe.mixer,gregtech:gt.blockmachines:857,,miscutils,TRUE,,,,,,
gt.recipe.mixer,gregtech:gt.blockmachines:858,,miscutils,TRUE,,,,,,
gt.recipe.fusionreactor,gregtech:gt.blockmachines:965,,miscutils,TRUE,,,,,,
gtpp.recipe.alloyblastsmelter,gregtech:gt.blockmachines:810,,miscutils,TRUE,,,,,,
gtpp.recipe.rocketenginefuel,gregtech:gt.blockmachines:793,,miscutils,TRUE,,,,,,
@@ -1072,9 +1069,9 @@ gtpp.recipe.simplewasher,gregtech:gt.blockmachines:31018,,miscutils,TRUE,,,,,,
gtpp.recipe.simplewasher,gregtech:gt.blockmachines:31019,,miscutils,TRUE,,,,,,
gtpp.recipe.simplewasher,gregtech:gt.blockmachines:31020,,miscutils,TRUE,,,,,,
gtpp.recipe.vacfurnace,gregtech:gt.blockmachines:995,,miscutils,TRUE,,,,,,
gtPlusPlus.nei.GT_NEI_FlotationCell,gregtech:gt.blockmachines:31028,,miscutils,TRUE,,,,,,
gtPlusPlus.nei.GT_NEI_FluidReactor,gregtech:gt.blockmachines:998,,miscutils,TRUE,,,,,,
gtPlusPlus.nei.GT_NEI_MillingMachine,gregtech:gt.blockmachines:31027,,miscutils,TRUE,,,,,,
gtpp.recipe.flotationcell,gregtech:gt.blockmachines:31028,,miscutils,TRUE,,,,,,
gtpp.recipe.fluidchemicaleactor,gregtech:gt.blockmachines:998,,miscutils,TRUE,,,,,,
gtpp.recipe.oremill,gregtech:gt.blockmachines:31027,,miscutils,TRUE,,,,,,
team.chisel.compat.nei.RecipeHandlerChisel,gregtech:gt.blockmachines:31066,,miscutils,TRUE,,,,,,
team.chisel.compat.nei.RecipeHandlerChisel,gregtech:gt.blockmachines:31067,,miscutils,TRUE,,,,,,
team.chisel.compat.nei.RecipeHandlerChisel,gregtech:gt.blockmachines:31068,,miscutils,TRUE,,,,,,
1 handler itemName nbtInfo modId modRequired excludedModId priority minVersion maxVersion forceClassName itemNotes
79 net.bdew.gendustry.nei.SamplerHandler gendustry:Sampler gendustry TRUE
80 net.bdew.gendustry.nei.TransposerHandler gendustry:Transposer gendustry TRUE
81 smelting IC2:blockMachine:1 IC2 TRUE
82 smelting IC2:blockMachine:2 IC2 TRUE dreamcraft
83 smelting IC2:blockMachine:13 IC2 TRUE dreamcraft
84 ic2.neiIntegration.core.recipehandler.BlastFurnaceRecipeHandler IC2:blockMachine3:1 IC2 TRUE
85 ic2.neiIntegration.core.recipehandler.BlockCutterRecipeHandler IC2:blockMachine3:2 IC2 TRUE
86 ic2.neiIntegration.core.recipehandler.CentrifugeRecipeHandler IC2:blockMachine2:3 IC2 TRUE
323 exnihilo.compatibility.nei.RecipeHandlerSieve exnihilo:sifting_table:3 exnihilo TRUE
324 exnihilo.compatibility.nei.RecipeHandlerSieve exnihilo:sifting_table:4 exnihilo TRUE
325 exnihilo.compatibility.nei.RecipeHandlerSieve exnihilo:sifting_table:5 exnihilo TRUE
326 gregtechmod.mistaqur.nei.handlers.AlloySmelterRecipeHandler gregtech.Alloy gregtech_addon:machine:56 gregtech_addon TRUE
327 gregtechmod.mistaqur.nei.handlers.AssemblerRecipeHandler gregtech.Assembler gregtech_addon:machine:60 gregtech_addon TRUE
328 gregtechmod.mistaqur.nei.handlers.BenderRecipeHandler gregtech.Bender gregtech_addon:machine:59 gregtech_addon TRUE
329 gregtechmod.mistaqur.nei.handlers.BlastRecipeHandler gregtech.Blast gregtech_addon:machine:29 gregtech_addon TRUE
330 gregtechmod.mistaqur.nei.handlers.BronzeBlastRecipeHandler gregtech.BronzeBlast gregtech_addon:machine:136 gregtech_addon TRUE
331 gregtechmod.mistaqur.nei.handlers.CannerRecipeHandler gregtech.Canner gregtech_addon:machine:57 gregtech_addon TRUE
332 gregtechmod.mistaqur.nei.handlers.CentrifugeRecipeHandler gregtech.centrifuge gregtech_addon:machine:62 gregtech_addon TRUE
333 gregtechmod.mistaqur.nei.handlers.ChemicalRecipeHandler gregtech.chemicalreactor gregtech_addon:machine:41 gregtech_addon TRUE
334 gregtechmod.mistaqur.nei.handlers.CutterRecipeHandler gregtech.Cutter gregtech_addon:machine:113 gregtech_addon TRUE
335 gregtechmod.mistaqur.nei.handlers.DistillationRecipeHandler gregtech.Distillation gregtech_addon:machine:44 gregtech_addon TRUE
336 gregtechmod.mistaqur.nei.handlers.ElectrolyzerRecipeHandler gregtech.electrolyzer gregtech_addon:machine:25 gregtech_addon TRUE
337 gregtechmod.mistaqur.nei.handlers.ExtruderRecipeHandler gregtech.extruder gregtech_addon:machine:115 gregtech_addon TRUE
338 gregtechmod.mistaqur.nei.handlers.FusionRecipeHandler gregtech.fusion gregtech_addon:machine:80 gregtech_addon TRUE
339 gregtech.thermal_generator gregtech_addon:machine:35 gregtech_addon TRUE
340 gregtech.diesel_generator gregtech_addon:machine:33 gregtech_addon TRUE
341 gregtech.gas_turbine gregtech_addon:machine:34 gregtech_addon TRUE
344 gregtech.plasma_generator gregtech_addon:machine:37 gregtech_addon TRUE
345 gregtech.plasma_generator gregtech_addon:machine:117 gregtech_addon TRUE
346 gregtech.magic_generator gregtech_addon:machine:42 gregtech_addon TRUE
347 gregtechmod.mistaqur.nei.handlers.GrinderRecipeHandler gregtech.Grinder gregtech_addon:machine:28 gregtech_addon TRUE
348 gregtechmod.mistaqur.nei.handlers.ImplosionRecipeHandler gregtech.Implosion gregtech_addon:machine:31 gregtech_addon TRUE
349 gregtechmod.mistaqur.nei.handlers.LatheRecipeHandler gregtech.Lathe gregtech_addon:machine:111 gregtech_addon TRUE
350 gregtechmod.mistaqur.nei.handlers.SawmillRecipeHandler gregtech.Sawmill gregtech_addon:machine:32 gregtech_addon TRUE
351 gregtechmod.mistaqur.nei.handlers.VacuumFreezerRecipeHandler gregtech.VacuumFreezer gregtech_addon:machine:38 gregtech_addon TRUE
352 gregtechmod.mistaqur.nei.handlers.WiremillRecipeHandler gregtech.Wiremill gregtech_addon:machine:55 gregtech_addon TRUE
353 wanion.biggercraftingtables.nei.BigShapedRecipeHandler biggercraftingtables:BiggerCraftingTables biggercraftingtables TRUE this and below are not tested
354 wanion.biggercraftingtables.nei.BigShapedRecipeHandler biggercraftingtables:AutoBiggerCraftingTables biggercraftingtables TRUE
355 wanion.biggercraftingtables.nei.BigShapelessRecipeHandler biggercraftingtables:BiggerCraftingTables biggercraftingtables TRUE
383 nc.crafting.nei.NuclearWorkspaceRecipeHandler NuclearCraft:nuclearWorkspace NuclearCraft TRUE
384 ganymedes01.etfuturum.NEI_EtFuturum_Config$NEI_Recipes_Smoker etfuturum:smoker etfuturum TRUE not working well
385 ganymedes01.etfuturum.NEI_EtFuturum_Config$NEI_Recipes_BlastFurnace etfuturum:blast_furnace etfuturum TRUE not working well
386 crafting connor135246.campfirebackport.client.compat.nei.NEICampfireRecipeHandler gregtech:gt.metaitem.01:32744 campfirebackport:campfire gregtech campfirebackport TRUE GT5 start: for readability, keep all GTNH-related catalysts below
387 gt.recipe.primitiveblastfurnace connor135246.campfirebackport.client.compat.nei.NEICampfireRecipeHandler gregtech:gt.blockmachines:140 campfirebackport:soul_campfire gregtech campfirebackport TRUE
388 gt.recipe.primitiveblastfurnace connor135246.campfirebackport.client.compat.nei.NEICampfireStateChangerHandler gregtech:gt.blockmachines:108 campfirebackport:campfire gregtech campfirebackport TRUE
389 smelting connor135246.campfirebackport.client.compat.nei.NEICampfireStateChangerHandler gregtech:gt.blockmachines:103 campfirebackport:soul_campfire gregtech campfirebackport TRUE
390 smelting gregtech:gt.blockmachines:104 Natura:NetherFurnace gregtech Natura TRUE
391 gt.recipe.macerator crafting gregtech:gt.blockmachines:106 gregtech:gt.metaitem.01:32744 gregtech TRUE gregapi_post GT5 start: for readability, keep all GTNH-related catalysts below
392 gt.recipe.macerator gt.recipe.primitiveblastfurnace gregtech:gt.blockmachines:107 gregtech:gt.blockmachines:140 gregtech TRUE gregapi_post
393 gt.recipe.extractor gt.recipe.primitiveblastfurnace gregtech:gt.blockmachines:109 gregtech:gt.blockmachines:108 gregtech TRUE gregapi_post
394 gt.recipe.extractor smelting gregtech:gt.blockmachines:110 gregtech:gt.blockmachines:103 gregtech TRUE gregapi_post
395 gt.recipe.hammer smelting gregtech:gt.blockmachines:112 gregtech:gt.blockmachines:104 gregtech TRUE gregapi_post
396 gt.recipe.hammer gt.recipe.macerator gregtech:gt.blockmachines:113 gregtech:gt.blockmachines:106 gregtech TRUE gregapi_post
397 gt.recipe.compressor gt.recipe.macerator gregtech:gt.blockmachines:115 gregtech:gt.blockmachines:107 gregtech TRUE gregapi_post
398 gt.recipe.compressor gt.recipe.extractor gregtech:gt.blockmachines:116 gregtech:gt.blockmachines:109 gregtech TRUE gregapi_post
399 gt.recipe.alloysmelter gt.recipe.extractor gregtech:gt.blockmachines:118 gregtech:gt.blockmachines:110 gregtech TRUE gregapi_post
400 gt.recipe.alloysmelter gt.recipe.hammer gregtech:gt.blockmachines:119 gregtech:gt.blockmachines:112 gregtech TRUE gregapi_post
401 gt.recipe.alloysmelter gt.recipe.hammer gregtech:gt.blockmachines:201 gregtech:gt.blockmachines:113 gregtech TRUE gregapi_post
402 gt.recipe.alloysmelter gt.recipe.compressor gregtech:gt.blockmachines:202 gregtech:gt.blockmachines:115 gregtech TRUE gregapi_post
403 gt.recipe.alloysmelter gt.recipe.compressor gregtech:gt.blockmachines:203 gregtech:gt.blockmachines:116 gregtech TRUE gregapi_post
404 gt.recipe.alloysmelter gregtech:gt.blockmachines:204 gregtech:gt.blockmachines:118 gregtech TRUE gregapi_post
405 gt.recipe.alloysmelter gregtech:gt.blockmachines:205 gregtech:gt.blockmachines:119 gregtech TRUE gregapi_post
406 gt.recipe.assembler gt.recipe.alloysmelter gregtech:gt.blockmachines:211 gregtech:gt.blockmachines:201 gregtech TRUE gregapi_post
407 gt.recipe.assembler gt.recipe.alloysmelter gregtech:gt.blockmachines:212 gregtech:gt.blockmachines:202 gregtech TRUE gregapi_post
408 gt.recipe.assembler gt.recipe.alloysmelter gregtech:gt.blockmachines:213 gregtech:gt.blockmachines:203 gregtech TRUE gregapi_post
409 gt.recipe.assembler gt.recipe.alloysmelter gregtech:gt.blockmachines:214 gregtech:gt.blockmachines:204 gregtech TRUE gregapi_post
410 gt.recipe.assembler gt.recipe.alloysmelter gregtech:gt.blockmachines:215 gregtech:gt.blockmachines:205 gregtech TRUE gregapi_post
411 gt.recipe.metalbender gt.recipe.assembler gregtech:gt.blockmachines:221 gregtech:gt.blockmachines:211 gregtech TRUE gregapi_post
412 gt.recipe.metalbender gt.recipe.assembler gregtech:gt.blockmachines:222 gregtech:gt.blockmachines:212 gregtech TRUE gregapi_post
413 gt.recipe.metalbender gt.recipe.assembler gregtech:gt.blockmachines:223 gregtech:gt.blockmachines:213 gregtech TRUE gregapi_post
414 gt.recipe.metalbender gt.recipe.assembler gregtech:gt.blockmachines:224 gregtech:gt.blockmachines:214 gregtech TRUE gregapi_post
415 gt.recipe.metalbender gt.recipe.assembler gregtech:gt.blockmachines:225 gregtech:gt.blockmachines:215 gregtech TRUE gregapi_post
416 gt.recipe.canner gt.recipe.metalbender gregtech:gt.blockmachines:231 gregtech:gt.blockmachines:221 gregtech TRUE gregapi_post
417 gt.recipe.canner gt.recipe.metalbender gregtech:gt.blockmachines:232 gregtech:gt.blockmachines:222 gregtech TRUE gregapi_post
418 gt.recipe.canner gt.recipe.metalbender gregtech:gt.blockmachines:233 gregtech:gt.blockmachines:223 gregtech TRUE gregapi_post
419 gt.recipe.canner gt.recipe.metalbender gregtech:gt.blockmachines:234 gregtech:gt.blockmachines:224 gregtech TRUE gregapi_post
420 gt.recipe.canner gt.recipe.metalbender gregtech:gt.blockmachines:235 gregtech:gt.blockmachines:225 gregtech TRUE gregapi_post
421 gt.recipe.compressor gt.recipe.canner gregtech:gt.blockmachines:241 gregtech:gt.blockmachines:231 gregtech TRUE gregapi_post
422 gt.recipe.compressor gt.recipe.canner gregtech:gt.blockmachines:242 gregtech:gt.blockmachines:232 gregtech TRUE gregapi_post
423 gt.recipe.compressor gt.recipe.canner gregtech:gt.blockmachines:243 gregtech:gt.blockmachines:233 gregtech TRUE gregapi_post
424 gt.recipe.compressor gt.recipe.canner gregtech:gt.blockmachines:244 gregtech:gt.blockmachines:234 gregtech TRUE gregapi_post
425 gt.recipe.compressor gt.recipe.canner gregtech:gt.blockmachines:245 gregtech:gt.blockmachines:235 gregtech TRUE gregapi_post
426 gt.recipe.cuttingsaw gt.recipe.compressor gregtech:gt.blockmachines:251 gregtech:gt.blockmachines:241 gregtech TRUE gregapi_post
427 gt.recipe.cuttingsaw gt.recipe.compressor gregtech:gt.blockmachines:252 gregtech:gt.blockmachines:242 gregtech TRUE gregapi_post
428 gt.recipe.cuttingsaw gt.recipe.compressor gregtech:gt.blockmachines:253 gregtech:gt.blockmachines:243 gregtech TRUE gregapi_post
429 gt.recipe.cuttingsaw gt.recipe.compressor gregtech:gt.blockmachines:254 gregtech:gt.blockmachines:244 gregtech TRUE gregapi_post
430 gt.recipe.cuttingsaw gt.recipe.compressor gregtech:gt.blockmachines:255 gregtech:gt.blockmachines:245 gregtech TRUE gregapi_post
431 smelting gt.recipe.cuttingsaw gregtech:gt.blockmachines:261 gregtech:gt.blockmachines:251 gregtech TRUE gregapi_post
432 smelting gt.recipe.cuttingsaw gregtech:gt.blockmachines:262 gregtech:gt.blockmachines:252 gregtech TRUE gregapi_post
433 smelting gt.recipe.cuttingsaw gregtech:gt.blockmachines:263 gregtech:gt.blockmachines:253 gregtech TRUE gregapi_post
434 smelting gt.recipe.cuttingsaw gregtech:gt.blockmachines:264 gregtech:gt.blockmachines:254 gregtech TRUE gregapi_post
435 smelting gt.recipe.cuttingsaw gregtech:gt.blockmachines:265 gregtech:gt.blockmachines:255 gregtech TRUE gregapi_post
436 gt.recipe.extractor smelting gregtech:gt.blockmachines:271 gregtech:gt.blockmachines:261 gregtech TRUE gregapi_post
437 gt.recipe.extractor smelting gregtech:gt.blockmachines:272 gregtech:gt.blockmachines:262 gregtech TRUE gregapi_post
438 gt.recipe.extractor smelting gregtech:gt.blockmachines:273 gregtech:gt.blockmachines:263 gregtech TRUE gregapi_post
439 gt.recipe.extractor smelting gregtech:gt.blockmachines:274 gregtech:gt.blockmachines:264 gregtech TRUE gregapi_post
440 gt.recipe.extractor smelting gregtech:gt.blockmachines:275 gregtech:gt.blockmachines:265 gregtech TRUE gregapi_post
441 gt.recipe.extruder gt.recipe.extractor gregtech:gt.blockmachines:281 gregtech:gt.blockmachines:271 gregtech TRUE gregapi_post
442 gt.recipe.extruder gt.recipe.extractor gregtech:gt.blockmachines:282 gregtech:gt.blockmachines:272 gregtech TRUE gregapi_post
443 gt.recipe.extruder gt.recipe.extractor gregtech:gt.blockmachines:283 gregtech:gt.blockmachines:273 gregtech TRUE gregapi_post
444 gt.recipe.extruder gt.recipe.extractor gregtech:gt.blockmachines:284 gregtech:gt.blockmachines:274 gregtech TRUE gregapi_post
445 gt.recipe.extruder gt.recipe.extractor gregtech:gt.blockmachines:285 gregtech:gt.blockmachines:275 gregtech TRUE gregapi_post
446 gt.recipe.lathe gt.recipe.extruder gregtech:gt.blockmachines:291 gregtech:gt.blockmachines:281 gregtech TRUE gregapi_post
447 gt.recipe.lathe gt.recipe.extruder gregtech:gt.blockmachines:292 gregtech:gt.blockmachines:282 gregtech TRUE gregapi_post
448 gt.recipe.lathe gt.recipe.extruder gregtech:gt.blockmachines:293 gregtech:gt.blockmachines:283 gregtech TRUE gregapi_post
449 gt.recipe.lathe gt.recipe.extruder gregtech:gt.blockmachines:294 gregtech:gt.blockmachines:284 gregtech TRUE gregapi_post
450 gt.recipe.lathe gt.recipe.extruder gregtech:gt.blockmachines:295 gregtech:gt.blockmachines:285 gregtech TRUE gregapi_post
451 gt.recipe.macerator gt.recipe.lathe gregtech:gt.blockmachines:301 gregtech:gt.blockmachines:291 gregtech TRUE gregapi_post
452 gt.recipe.macerator gt.recipe.lathe gregtech:gt.blockmachines:302 gregtech:gt.blockmachines:292 gregtech TRUE gregapi_post
453 gt.recipe.macerator gt.recipe.lathe gregtech:gt.blockmachines:303 gregtech:gt.blockmachines:293 gregtech TRUE gregapi_post
454 gt.recipe.macerator gt.recipe.lathe gregtech:gt.blockmachines:304 gregtech:gt.blockmachines:294 gregtech TRUE gregapi_post
455 gt.recipe.macerator gt.recipe.lathe gregtech:gt.blockmachines:305 gregtech:gt.blockmachines:295 gregtech TRUE gregapi_post
456 smelting gt.recipe.macerator gregtech:gt.blockmachines:311 gregtech:gt.blockmachines:301 gregtech TRUE gregapi_post
457 smelting gt.recipe.macerator gregtech:gt.blockmachines:312 gregtech:gt.blockmachines:302 gregtech TRUE gregapi_post
458 smelting gt.recipe.macerator gregtech:gt.blockmachines:313 gregtech:gt.blockmachines:303 gregtech TRUE gregapi_post
459 smelting gt.recipe.macerator gregtech:gt.blockmachines:314 gregtech:gt.blockmachines:304 gregtech TRUE gregapi_post
460 smelting gt.recipe.macerator gregtech:gt.blockmachines:315 gregtech:gt.blockmachines:305 gregtech TRUE gregapi_post
461 gt.recipe.printer smelting gregtech:gt.blockmachines:321 gregtech:gt.blockmachines:311 gregtech TRUE gregapi_post
462 gt.recipe.printer smelting gregtech:gt.blockmachines:322 gregtech:gt.blockmachines:312 gregtech TRUE gregapi_post
463 gt.recipe.printer smelting gregtech:gt.blockmachines:323 gregtech:gt.blockmachines:313 gregtech TRUE gregapi_post
464 gt.recipe.printer smelting gregtech:gt.blockmachines:324 gregtech:gt.blockmachines:314 gregtech TRUE gregapi_post
465 gt.recipe.printer smelting gregtech:gt.blockmachines:325 gregtech:gt.blockmachines:315 gregtech TRUE gregapi_post
466 gt.recipe.printer gregtech:gt.blockmachines:326 gregtech:gt.blockmachines:321 gregtech TRUE gregapi_post
467 gt.recipe.printer gregtech:gt.blockmachines:327 gregtech:gt.blockmachines:322 gregtech TRUE gregapi_post
468 gt.recipe.printer gregtech:gt.blockmachines:328 gregtech:gt.blockmachines:323 gregtech TRUE gregapi_post
469 ic2.recycler gt.recipe.printer gregtech:gt.blockmachines:331 gregtech:gt.blockmachines:324 gregtech TRUE gregapi_post
470 ic2.recycler gt.recipe.printer gregtech:gt.blockmachines:332 gregtech:gt.blockmachines:325 gregtech TRUE gregapi_post
471 ic2.recycler gt.recipe.printer gregtech:gt.blockmachines:333 gregtech:gt.blockmachines:326 gregtech TRUE gregapi_post
472 ic2.recycler gt.recipe.printer gregtech:gt.blockmachines:334 gregtech:gt.blockmachines:327 gregtech TRUE gregapi_post
473 ic2.recycler gt.recipe.printer gregtech:gt.blockmachines:335 gregtech:gt.blockmachines:328 gregtech TRUE gregapi_post
474 gt.recipe.scanner ic2.recycler gregtech:gt.blockmachines:341 gregtech:gt.blockmachines:331 gregtech TRUE gregapi_post
475 gt.recipe.scanner ic2.recycler gregtech:gt.blockmachines:342 gregtech:gt.blockmachines:332 gregtech TRUE gregapi_post
476 gt.recipe.scanner ic2.recycler gregtech:gt.blockmachines:343 gregtech:gt.blockmachines:333 gregtech TRUE gregapi_post
477 gt.recipe.scanner ic2.recycler gregtech:gt.blockmachines:344 gregtech:gt.blockmachines:334 gregtech TRUE gregapi_post
478 gt.recipe.scanner ic2.recycler gregtech:gt.blockmachines:345 gregtech:gt.blockmachines:335 gregtech TRUE gregapi_post
479 gt.recipe.wiremill gt.recipe.scanner gregtech:gt.blockmachines:351 gregtech:gt.blockmachines:341 gregtech TRUE gregapi_post
480 gt.recipe.wiremill gt.recipe.scanner gregtech:gt.blockmachines:352 gregtech:gt.blockmachines:342 gregtech TRUE gregapi_post
481 gt.recipe.wiremill gt.recipe.scanner gregtech:gt.blockmachines:353 gregtech:gt.blockmachines:343 gregtech TRUE gregapi_post
482 gt.recipe.wiremill gt.recipe.scanner gregtech:gt.blockmachines:354 gregtech:gt.blockmachines:344 gregtech TRUE gregapi_post
483 gt.recipe.wiremill gt.recipe.scanner gregtech:gt.blockmachines:355 gregtech:gt.blockmachines:345 gregtech TRUE gregapi_post
484 gt.recipe.centrifuge gt.recipe.wiremill gregtech:gt.blockmachines:361 gregtech:gt.blockmachines:351 gregtech TRUE gregapi_post
485 gt.recipe.centrifuge gt.recipe.wiremill gregtech:gt.blockmachines:362 gregtech:gt.blockmachines:352 gregtech TRUE gregapi_post
486 gt.recipe.centrifuge gt.recipe.wiremill gregtech:gt.blockmachines:363 gregtech:gt.blockmachines:353 gregtech TRUE gregapi_post
487 gt.recipe.centrifuge gt.recipe.wiremill gregtech:gt.blockmachines:364 gregtech:gt.blockmachines:354 gregtech TRUE gregapi_post
488 gt.recipe.centrifuge gt.recipe.wiremill gregtech:gt.blockmachines:365 gregtech:gt.blockmachines:355 gregtech TRUE gregapi_post
489 gt.recipe.electrolyzer gt.recipe.centrifuge gregtech:gt.blockmachines:371 gregtech:gt.blockmachines:361 gregtech TRUE gregapi_post
490 gt.recipe.electrolyzer gt.recipe.centrifuge gregtech:gt.blockmachines:372 gregtech:gt.blockmachines:362 gregtech TRUE gregapi_post
491 gt.recipe.electrolyzer gt.recipe.centrifuge gregtech:gt.blockmachines:373 gregtech:gt.blockmachines:363 gregtech TRUE gregapi_post
492 gt.recipe.electrolyzer gt.recipe.centrifuge gregtech:gt.blockmachines:374 gregtech:gt.blockmachines:364 gregtech TRUE gregapi_post
493 gt.recipe.electrolyzer gt.recipe.centrifuge gregtech:gt.blockmachines:375 gregtech:gt.blockmachines:365 gregtech TRUE gregapi_post
494 gt.recipe.thermalcentrifuge gt.recipe.electrolyzer gregtech:gt.blockmachines:381 gregtech:gt.blockmachines:371 gregtech TRUE gregapi_post
495 gt.recipe.thermalcentrifuge gt.recipe.electrolyzer gregtech:gt.blockmachines:382 gregtech:gt.blockmachines:372 gregtech TRUE gregapi_post
496 gt.recipe.thermalcentrifuge gt.recipe.electrolyzer gregtech:gt.blockmachines:383 gregtech:gt.blockmachines:373 gregtech TRUE gregapi_post
497 gt.recipe.thermalcentrifuge gt.recipe.electrolyzer gregtech:gt.blockmachines:384 gregtech:gt.blockmachines:374 gregtech TRUE gregapi_post
498 gt.recipe.thermalcentrifuge gt.recipe.electrolyzer gregtech:gt.blockmachines:385 gregtech:gt.blockmachines:375 gregtech TRUE gregapi_post
499 gt.recipe.orewasher gt.recipe.thermalcentrifuge gregtech:gt.blockmachines:391 gregtech:gt.blockmachines:381 gregtech TRUE gregapi_post
500 gt.recipe.orewasher gt.recipe.thermalcentrifuge gregtech:gt.blockmachines:392 gregtech:gt.blockmachines:382 gregtech TRUE gregapi_post
501 gt.recipe.orewasher gt.recipe.thermalcentrifuge gregtech:gt.blockmachines:393 gregtech:gt.blockmachines:383 gregtech TRUE gregapi_post
502 gt.recipe.orewasher gt.recipe.thermalcentrifuge gregtech:gt.blockmachines:394 gregtech:gt.blockmachines:384 gregtech TRUE gregapi_post
503 gt.recipe.orewasher gt.recipe.thermalcentrifuge gregtech:gt.blockmachines:395 gregtech:gt.blockmachines:385 gregtech TRUE gregapi_post
504 gt.recipe.packager gt.recipe.orewasher gregtech:gt.blockmachines:401 gregtech:gt.blockmachines:391 gregtech TRUE gregapi_post
505 gt.recipe.packager gt.recipe.orewasher gregtech:gt.blockmachines:402 gregtech:gt.blockmachines:392 gregtech TRUE gregapi_post
506 gt.recipe.packager gt.recipe.orewasher gregtech:gt.blockmachines:403 gregtech:gt.blockmachines:393 gregtech TRUE gregapi_post
507 gt.recipe.packager gt.recipe.orewasher gregtech:gt.blockmachines:404 gregtech:gt.blockmachines:394 gregtech TRUE gregapi_post
508 gt.recipe.packager gt.recipe.orewasher gregtech:gt.blockmachines:405 gregtech:gt.blockmachines:395 gregtech TRUE gregapi_post
509 gt.recipe.packager gregtech:gt.blockmachines:406 gregtech:gt.blockmachines:401 gregtech TRUE gregapi_post
510 gt.recipe.packager gregtech:gt.blockmachines:407 gregtech:gt.blockmachines:402 gregtech TRUE gregapi_post
511 gt.recipe.packager gregtech:gt.blockmachines:408 gregtech:gt.blockmachines:403 gregtech TRUE gregapi_post
512 gt.recipe.unpackager gt.recipe.packager gregtech:gt.blockmachines:411 gregtech:gt.blockmachines:404 gregtech TRUE gregapi_post
513 gt.recipe.unpackager gt.recipe.packager gregtech:gt.blockmachines:412 gregtech:gt.blockmachines:405 gregtech TRUE gregapi_post
514 gt.recipe.unpackager gt.recipe.packager gregtech:gt.blockmachines:413 gregtech:gt.blockmachines:406 gregtech TRUE gregapi_post
515 gt.recipe.unpackager gt.recipe.packager gregtech:gt.blockmachines:414 gregtech:gt.blockmachines:407 gregtech TRUE gregapi_post
516 gt.recipe.unpackager gt.recipe.packager gregtech:gt.blockmachines:415 gregtech:gt.blockmachines:408 gregtech TRUE gregapi_post
517 gt.recipe.unpackager gregtech:gt.blockmachines:416 gregtech:gt.blockmachines:411 gregtech TRUE gregapi_post
518 gt.recipe.unpackager gregtech:gt.blockmachines:417 gregtech:gt.blockmachines:412 gregtech TRUE gregapi_post
519 gt.recipe.unpackager gregtech:gt.blockmachines:418 gregtech:gt.blockmachines:413 gregtech TRUE gregapi_post
520 gt.recipe.chemicalreactor gt.recipe.unpackager gregtech:gt.blockmachines:421 gregtech:gt.blockmachines:414 gregtech TRUE gregapi_post
521 gt.recipe.chemicalreactor gt.recipe.unpackager gregtech:gt.blockmachines:422 gregtech:gt.blockmachines:415 gregtech TRUE gregapi_post
522 gt.recipe.chemicalreactor gt.recipe.unpackager gregtech:gt.blockmachines:423 gregtech:gt.blockmachines:416 gregtech TRUE gregapi_post
523 gt.recipe.chemicalreactor gt.recipe.unpackager gregtech:gt.blockmachines:424 gregtech:gt.blockmachines:417 gregtech TRUE gregapi_post
524 gt.recipe.chemicalreactor gt.recipe.unpackager gregtech:gt.blockmachines:425 gregtech:gt.blockmachines:418 gregtech TRUE gregapi_post
525 gt.recipe.fluidcanner gt.recipe.chemicalreactor gregtech:gt.blockmachines:431 gregtech:gt.blockmachines:421 gregtech TRUE gregapi_post
526 gt.recipe.fluidcanner gt.recipe.chemicalreactor gregtech:gt.blockmachines:432 gregtech:gt.blockmachines:422 gregtech TRUE gregapi_post
527 gt.recipe.fluidcanner gt.recipe.chemicalreactor gregtech:gt.blockmachines:433 gregtech:gt.blockmachines:423 gregtech TRUE gregapi_post
528 gt.recipe.fluidcanner gt.recipe.chemicalreactor gregtech:gt.blockmachines:434 gregtech:gt.blockmachines:424 gregtech TRUE gregapi_post
529 gt.recipe.fluidcanner gt.recipe.chemicalreactor gregtech:gt.blockmachines:435 gregtech:gt.blockmachines:425 gregtech TRUE gregapi_post
530 gt.recipe.rockbreaker gt.recipe.fluidcanner gregtech:gt.blockmachines:441 gregtech:gt.blockmachines:431 gregtech TRUE gregapi_post
531 gt.recipe.rockbreaker gt.recipe.fluidcanner gregtech:gt.blockmachines:442 gregtech:gt.blockmachines:432 gregtech TRUE gregapi_post
532 gt.recipe.rockbreaker gt.recipe.fluidcanner gregtech:gt.blockmachines:443 gregtech:gt.blockmachines:433 gregtech TRUE gregapi_post
533 gt.recipe.rockbreaker gt.recipe.fluidcanner gregtech:gt.blockmachines:444 gregtech:gt.blockmachines:434 gregtech TRUE gregapi_post
534 gt.recipe.rockbreaker gt.recipe.fluidcanner gregtech:gt.blockmachines:445 gregtech:gt.blockmachines:435 gregtech TRUE gregapi_post
535 gt.recipe.massfab gt.recipe.rockbreaker gregtech:gt.blockmachines:461 gregtech:gt.blockmachines:441 gregtech TRUE gregapi_post
536 gt.recipe.massfab gt.recipe.rockbreaker gregtech:gt.blockmachines:462 gregtech:gt.blockmachines:442 gregtech TRUE gregapi_post
537 gt.recipe.massfab gt.recipe.rockbreaker gregtech:gt.blockmachines:463 gregtech:gt.blockmachines:443 gregtech TRUE gregapi_post
538 gt.recipe.massfab gt.recipe.rockbreaker gregtech:gt.blockmachines:464 gregtech:gt.blockmachines:444 gregtech TRUE gregapi_post
539 gt.recipe.massfab gt.recipe.rockbreaker gregtech:gt.blockmachines:465 gregtech:gt.blockmachines:445 gregtech TRUE gregapi_post
540 gt.recipe.uuamplifier gt.recipe.massfab gregtech:gt.blockmachines:471 gregtech:gt.blockmachines:461 gregtech TRUE gregapi_post
541 gt.recipe.uuamplifier gt.recipe.massfab gregtech:gt.blockmachines:472 gregtech:gt.blockmachines:462 gregtech TRUE gregapi_post
542 gt.recipe.uuamplifier gt.recipe.massfab gregtech:gt.blockmachines:473 gregtech:gt.blockmachines:463 gregtech TRUE gregapi_post
543 gt.recipe.uuamplifier gt.recipe.massfab gregtech:gt.blockmachines:474 gregtech:gt.blockmachines:464 gregtech TRUE gregapi_post
544 gt.recipe.uuamplifier gt.recipe.massfab gregtech:gt.blockmachines:475 gregtech:gt.blockmachines:465 gregtech TRUE gregapi_post
545 gt.recipe.replicator gt.recipe.uuamplifier gregtech:gt.blockmachines:481 gregtech:gt.blockmachines:471 gregtech TRUE gregapi_post
546 gt.recipe.replicator gt.recipe.uuamplifier gregtech:gt.blockmachines:482 gregtech:gt.blockmachines:472 gregtech TRUE gregapi_post
547 gt.recipe.replicator gt.recipe.uuamplifier gregtech:gt.blockmachines:483 gregtech:gt.blockmachines:473 gregtech TRUE gregapi_post
548 gt.recipe.replicator gt.recipe.uuamplifier gregtech:gt.blockmachines:484 gregtech:gt.blockmachines:474 gregtech TRUE gregapi_post
549 gt.recipe.replicator gt.recipe.uuamplifier gregtech:gt.blockmachines:485 gregtech:gt.blockmachines:475 gregtech TRUE gregapi_post
550 gt.recipe.brewer gt.recipe.replicator gregtech:gt.blockmachines:491 gregtech:gt.blockmachines:481 gregtech TRUE gregapi_post
551 gt.recipe.brewer gt.recipe.replicator gregtech:gt.blockmachines:492 gregtech:gt.blockmachines:482 gregtech TRUE gregapi_post
552 gt.recipe.brewer gt.recipe.replicator gregtech:gt.blockmachines:493 gregtech:gt.blockmachines:483 gregtech TRUE gregapi_post
553 gt.recipe.brewer gt.recipe.replicator gregtech:gt.blockmachines:494 gregtech:gt.blockmachines:484 gregtech TRUE gregapi_post
554 gt.recipe.brewer gt.recipe.replicator gregtech:gt.blockmachines:495 gregtech:gt.blockmachines:485 gregtech TRUE gregapi_post
555 gt.recipe.fermenter gt.recipe.brewer gregtech:gt.blockmachines:501 gregtech:gt.blockmachines:491 gregtech TRUE gregapi_post
556 gt.recipe.fermenter gt.recipe.brewer gregtech:gt.blockmachines:502 gregtech:gt.blockmachines:492 gregtech TRUE gregapi_post
557 gt.recipe.fermenter gt.recipe.brewer gregtech:gt.blockmachines:503 gregtech:gt.blockmachines:493 gregtech TRUE gregapi_post
558 gt.recipe.fermenter gt.recipe.brewer gregtech:gt.blockmachines:504 gregtech:gt.blockmachines:494 gregtech TRUE gregapi_post
559 gt.recipe.fermenter gt.recipe.brewer gregtech:gt.blockmachines:505 gregtech:gt.blockmachines:495 gregtech TRUE gregapi_post
560 gt.recipe.fluidextractor gt.recipe.fermenter gregtech:gt.blockmachines:511 gregtech:gt.blockmachines:501 gregtech TRUE gregapi_post
561 gt.recipe.fluidextractor gt.recipe.fermenter gregtech:gt.blockmachines:512 gregtech:gt.blockmachines:502 gregtech TRUE gregapi_post
562 gt.recipe.fluidextractor gt.recipe.fermenter gregtech:gt.blockmachines:513 gregtech:gt.blockmachines:503 gregtech TRUE gregapi_post
563 gt.recipe.fluidextractor gt.recipe.fermenter gregtech:gt.blockmachines:514 gregtech:gt.blockmachines:504 gregtech TRUE gregapi_post
564 gt.recipe.fluidextractor gt.recipe.fermenter gregtech:gt.blockmachines:515 gregtech:gt.blockmachines:505 gregtech TRUE gregapi_post
565 gt.recipe.fluidsolidifier gt.recipe.fluidextractor gregtech:gt.blockmachines:521 gregtech:gt.blockmachines:511 gregtech TRUE gregapi_post
566 gt.recipe.fluidsolidifier gt.recipe.fluidextractor gregtech:gt.blockmachines:522 gregtech:gt.blockmachines:512 gregtech TRUE gregapi_post
567 gt.recipe.fluidsolidifier gt.recipe.fluidextractor gregtech:gt.blockmachines:523 gregtech:gt.blockmachines:513 gregtech TRUE gregapi_post
568 gt.recipe.fluidsolidifier gt.recipe.fluidextractor gregtech:gt.blockmachines:524 gregtech:gt.blockmachines:514 gregtech TRUE gregapi_post
569 gt.recipe.fluidsolidifier gt.recipe.fluidextractor gregtech:gt.blockmachines:525 gregtech:gt.blockmachines:515 gregtech TRUE gregapi_post
570 gt.recipe.distillery gt.recipe.fluidsolidifier gregtech:gt.blockmachines:531 gregtech:gt.blockmachines:521 gregtech TRUE gregapi_post
571 gt.recipe.distillery gt.recipe.fluidsolidifier gregtech:gt.blockmachines:532 gregtech:gt.blockmachines:522 gregtech TRUE gregapi_post
572 gt.recipe.distillery gt.recipe.fluidsolidifier gregtech:gt.blockmachines:533 gregtech:gt.blockmachines:523 gregtech TRUE gregapi_post
573 gt.recipe.distillery gt.recipe.fluidsolidifier gregtech:gt.blockmachines:534 gregtech:gt.blockmachines:524 gregtech TRUE gregapi_post
574 gt.recipe.distillery gt.recipe.fluidsolidifier gregtech:gt.blockmachines:535 gregtech:gt.blockmachines:525 gregtech TRUE gregapi_post
575 gt.recipe.chemicalbath gt.recipe.distillery gregtech:gt.blockmachines:541 gregtech:gt.blockmachines:531 gregtech TRUE gregapi_post
576 gt.recipe.chemicalbath gt.recipe.distillery gregtech:gt.blockmachines:542 gregtech:gt.blockmachines:532 gregtech TRUE gregapi_post
577 gt.recipe.chemicalbath gt.recipe.distillery gregtech:gt.blockmachines:543 gregtech:gt.blockmachines:533 gregtech TRUE gregapi_post
578 gt.recipe.chemicalbath gt.recipe.distillery gregtech:gt.blockmachines:544 gregtech:gt.blockmachines:534 gregtech TRUE gregapi_post
579 gt.recipe.chemicalbath gt.recipe.distillery gregtech:gt.blockmachines:545 gregtech:gt.blockmachines:535 gregtech TRUE gregapi_post
580 gt.recipe.polarizer gt.recipe.chemicalbath gregtech:gt.blockmachines:551 gregtech:gt.blockmachines:541 gregtech TRUE gregapi_post
581 gt.recipe.polarizer gt.recipe.chemicalbath gregtech:gt.blockmachines:552 gregtech:gt.blockmachines:542 gregtech TRUE gregapi_post
582 gt.recipe.polarizer gt.recipe.chemicalbath gregtech:gt.blockmachines:553 gregtech:gt.blockmachines:543 gregtech TRUE gregapi_post
583 gt.recipe.polarizer gt.recipe.chemicalbath gregtech:gt.blockmachines:554 gregtech:gt.blockmachines:544 gregtech TRUE gregapi_post
584 gt.recipe.polarizer gt.recipe.chemicalbath gregtech:gt.blockmachines:555 gregtech:gt.blockmachines:545 gregtech TRUE gregapi_post
585 gt.recipe.electromagneticseparator gt.recipe.polarizer gregtech:gt.blockmachines:561 gregtech:gt.blockmachines:551 gregtech TRUE gregapi_post
586 gt.recipe.electromagneticseparator gt.recipe.polarizer gregtech:gt.blockmachines:562 gregtech:gt.blockmachines:552 gregtech TRUE gregapi_post
587 gt.recipe.electromagneticseparator gt.recipe.polarizer gregtech:gt.blockmachines:563 gregtech:gt.blockmachines:553 gregtech TRUE gregapi_post
588 gt.recipe.electromagneticseparator gt.recipe.polarizer gregtech:gt.blockmachines:564 gregtech:gt.blockmachines:554 gregtech TRUE gregapi_post
589 gt.recipe.electromagneticseparator gt.recipe.polarizer gregtech:gt.blockmachines:565 gregtech:gt.blockmachines:555 gregtech TRUE gregapi_post
590 gt.recipe.autoclave gt.recipe.electromagneticseparator gregtech:gt.blockmachines:571 gregtech:gt.blockmachines:561 gregtech TRUE gregapi_post
591 gt.recipe.autoclave gt.recipe.electromagneticseparator gregtech:gt.blockmachines:572 gregtech:gt.blockmachines:562 gregtech TRUE gregapi_post
592 gt.recipe.autoclave gt.recipe.electromagneticseparator gregtech:gt.blockmachines:573 gregtech:gt.blockmachines:563 gregtech TRUE gregapi_post
593 gt.recipe.autoclave gt.recipe.electromagneticseparator gregtech:gt.blockmachines:574 gregtech:gt.blockmachines:564 gregtech TRUE gregapi_post
594 gt.recipe.autoclave gt.recipe.electromagneticseparator gregtech:gt.blockmachines:575 gregtech:gt.blockmachines:565 gregtech TRUE gregapi_post
595 gt.recipe.mixer gt.recipe.autoclave gregtech:gt.blockmachines:581 gregtech:gt.blockmachines:571 gregtech TRUE gregapi_post
596 gt.recipe.mixer gt.recipe.autoclave gregtech:gt.blockmachines:582 gregtech:gt.blockmachines:572 gregtech TRUE gregapi_post
597 gt.recipe.mixer gt.recipe.autoclave gregtech:gt.blockmachines:583 gregtech:gt.blockmachines:573 gregtech TRUE gregapi_post
598 gt.recipe.mixer gt.recipe.autoclave gregtech:gt.blockmachines:584 gregtech:gt.blockmachines:574 gregtech TRUE gregapi_post
599 gt.recipe.mixer gt.recipe.autoclave gregtech:gt.blockmachines:585 gregtech:gt.blockmachines:575 gregtech TRUE gregapi_post
600 gt.recipe.laserengraver gt.recipe.mixer gregtech:gt.blockmachines:591 gregtech:gt.blockmachines:581 gregtech TRUE gregapi_post
601 gt.recipe.laserengraver gt.recipe.mixer gregtech:gt.blockmachines:592 gregtech:gt.blockmachines:582 gregtech TRUE gregapi_post
602 gt.recipe.laserengraver gt.recipe.mixer gregtech:gt.blockmachines:593 gregtech:gt.blockmachines:583 gregtech TRUE gregapi_post
603 gt.recipe.laserengraver gt.recipe.mixer gregtech:gt.blockmachines:594 gregtech:gt.blockmachines:584 gregtech TRUE gregapi_post
604 gt.recipe.laserengraver gt.recipe.mixer gregtech:gt.blockmachines:595 gregtech:gt.blockmachines:585 gregtech TRUE gregapi_post
605 gt.recipe.press gt.recipe.laserengraver gregtech:gt.blockmachines:601 gregtech:gt.blockmachines:591 gregtech TRUE gregapi_post
606 gt.recipe.press gt.recipe.laserengraver gregtech:gt.blockmachines:602 gregtech:gt.blockmachines:592 gregtech TRUE gregapi_post
607 gt.recipe.press gt.recipe.laserengraver gregtech:gt.blockmachines:603 gregtech:gt.blockmachines:593 gregtech TRUE gregapi_post
608 gt.recipe.press gt.recipe.laserengraver gregtech:gt.blockmachines:604 gregtech:gt.blockmachines:594 gregtech TRUE gregapi_post
609 gt.recipe.press gt.recipe.laserengraver gregtech:gt.blockmachines:605 gregtech:gt.blockmachines:595 gregtech TRUE gregapi_post
610 gt.recipe.hammer gt.recipe.press gregtech:gt.blockmachines:611 gregtech:gt.blockmachines:601 gregtech TRUE gregapi_post
611 gt.recipe.hammer gt.recipe.press gregtech:gt.blockmachines:612 gregtech:gt.blockmachines:602 gregtech TRUE gregapi_post
612 gt.recipe.hammer gt.recipe.press gregtech:gt.blockmachines:613 gregtech:gt.blockmachines:603 gregtech TRUE gregapi_post
613 gt.recipe.hammer gt.recipe.press gregtech:gt.blockmachines:614 gregtech:gt.blockmachines:604 gregtech TRUE gregapi_post
614 gt.recipe.hammer gt.recipe.press gregtech:gt.blockmachines:615 gregtech:gt.blockmachines:605 gregtech TRUE gregapi_post
615 gt.recipe.fluidheater gt.recipe.hammer gregtech:gt.blockmachines:621 gregtech:gt.blockmachines:611 gregtech TRUE gregapi_post
616 gt.recipe.fluidheater gt.recipe.hammer gregtech:gt.blockmachines:622 gregtech:gt.blockmachines:612 gregtech TRUE gregapi_post
617 gt.recipe.fluidheater gt.recipe.hammer gregtech:gt.blockmachines:623 gregtech:gt.blockmachines:613 gregtech TRUE gregapi_post
618 gt.recipe.fluidheater gt.recipe.hammer gregtech:gt.blockmachines:624 gregtech:gt.blockmachines:614 gregtech TRUE gregapi_post
619 gt.recipe.fluidheater gt.recipe.hammer gregtech:gt.blockmachines:625 gregtech:gt.blockmachines:615 gregtech TRUE gregapi_post
620 gt.recipe.slicer gt.recipe.fluidheater gregtech:gt.blockmachines:631 gregtech:gt.blockmachines:621 gregtech TRUE gregapi_post
621 gt.recipe.slicer gt.recipe.fluidheater gregtech:gt.blockmachines:632 gregtech:gt.blockmachines:622 gregtech TRUE gregapi_post
622 gt.recipe.slicer gt.recipe.fluidheater gregtech:gt.blockmachines:633 gregtech:gt.blockmachines:623 gregtech TRUE gregapi_post
623 gt.recipe.slicer gt.recipe.fluidheater gregtech:gt.blockmachines:634 gregtech:gt.blockmachines:624 gregtech TRUE gregapi_post
624 gt.recipe.slicer gt.recipe.fluidheater gregtech:gt.blockmachines:635 gregtech:gt.blockmachines:625 gregtech TRUE gregapi_post
625 gt.recipe.sifter gt.recipe.slicer gregtech:gt.blockmachines:641 gregtech:gt.blockmachines:631 gregtech TRUE gregapi_post
626 gt.recipe.sifter gt.recipe.slicer gregtech:gt.blockmachines:642 gregtech:gt.blockmachines:632 gregtech TRUE gregapi_post
627 gt.recipe.sifter gt.recipe.slicer gregtech:gt.blockmachines:643 gregtech:gt.blockmachines:633 gregtech TRUE gregapi_post
628 gt.recipe.sifter gt.recipe.slicer gregtech:gt.blockmachines:644 gregtech:gt.blockmachines:634 gregtech TRUE gregapi_post
629 gt.recipe.sifter gt.recipe.slicer gregtech:gt.blockmachines:645 gregtech:gt.blockmachines:635 gregtech TRUE gregapi_post
630 gt.recipe.arcfurnace gt.recipe.sifter gregtech:gt.blockmachines:651 gregtech:gt.blockmachines:641 gregtech TRUE gregapi_post
631 gt.recipe.arcfurnace gt.recipe.sifter gregtech:gt.blockmachines:652 gregtech:gt.blockmachines:642 gregtech TRUE gregapi_post
632 gt.recipe.arcfurnace gt.recipe.sifter gregtech:gt.blockmachines:653 gregtech:gt.blockmachines:643 gregtech TRUE gregapi_post
633 gt.recipe.arcfurnace gt.recipe.sifter gregtech:gt.blockmachines:654 gregtech:gt.blockmachines:644 gregtech TRUE gregapi_post
634 gt.recipe.arcfurnace gt.recipe.sifter gregtech:gt.blockmachines:655 gregtech:gt.blockmachines:645 gregtech TRUE gregapi_post
635 gt.recipe.plasmaarcfurnace gt.recipe.arcfurnace gregtech:gt.blockmachines:661 gregtech:gt.blockmachines:651 gregtech TRUE gregapi_post
636 gt.recipe.plasmaarcfurnace gt.recipe.arcfurnace gregtech:gt.blockmachines:662 gregtech:gt.blockmachines:652 gregtech TRUE gregapi_post
637 gt.recipe.plasmaarcfurnace gt.recipe.arcfurnace gregtech:gt.blockmachines:663 gregtech:gt.blockmachines:653 gregtech TRUE gregapi_post
638 gt.recipe.plasmaarcfurnace gt.recipe.arcfurnace gregtech:gt.blockmachines:664 gregtech:gt.blockmachines:654 gregtech TRUE gregapi_post
639 gt.recipe.plasmaarcfurnace gt.recipe.arcfurnace gregtech:gt.blockmachines:665 gregtech:gt.blockmachines:655 gregtech TRUE gregapi_post
640 smelting gt.recipe.plasmaarcfurnace gregtech:gt.blockmachines:671 gregtech:gt.blockmachines:661 gregtech TRUE gregapi_post
641 smelting gt.recipe.plasmaarcfurnace gregtech:gt.blockmachines:672 gregtech:gt.blockmachines:662 gregtech TRUE gregapi_post
642 smelting gt.recipe.plasmaarcfurnace gregtech:gt.blockmachines:673 gregtech:gt.blockmachines:663 gregtech TRUE gregapi_post
643 smelting gt.recipe.plasmaarcfurnace gregtech:gt.blockmachines:674 gregtech:gt.blockmachines:664 gregtech TRUE gregapi_post
644 smelting gt.recipe.plasmaarcfurnace gregtech:gt.blockmachines:675 gregtech:gt.blockmachines:665 gregtech TRUE gregapi_post
645 gt.recipe.blastfurnace smelting gregtech:gt.blockmachines:1000 gregtech:gt.blockmachines:671 gregtech TRUE gregapi_post
646 gt.recipe.implosioncompressor smelting gregtech:gt.blockmachines:1001 gregtech:gt.blockmachines:672 gregtech TRUE gregapi_post
647 gt.recipe.vacuumfreezer smelting gregtech:gt.blockmachines:1002 gregtech:gt.blockmachines:673 gregtech TRUE gregapi_post
648 smelting gregtech:gt.blockmachines:1003 gregtech:gt.blockmachines:674 gregtech TRUE gregapi_post
649 gt.recipe.dieselgeneratorfuel smelting gregtech:gt.blockmachines:1110 gregtech:gt.blockmachines:675 gregtech TRUE gregapi_post
650 gt.recipe.dieselgeneratorfuel gt.recipe.blastfurnace gregtech:gt.blockmachines:1111 gregtech:gt.blockmachines:1000 gregtech TRUE gregapi_post
651 gt.recipe.dieselgeneratorfuel gt.recipe.implosioncompressor gregtech:gt.blockmachines:1112 gregtech:gt.blockmachines:1001 gregtech TRUE gregapi_post
652 gt.recipe.gasturbinefuel gt.recipe.vacuumfreezer gregtech:gt.blockmachines:1115 gregtech:gt.blockmachines:1002 gregtech TRUE gregapi_post
653 gt.recipe.gasturbinefuel smelting gregtech:gt.blockmachines:1116 gregtech:gt.blockmachines:1003 gregtech TRUE gregapi_post
654 gt.recipe.gasturbinefuel gt.recipe.dieselgeneratorfuel gregtech:gt.blockmachines:1117 gregtech:gt.blockmachines:1110 gregtech TRUE gregapi_post
655 gt.recipe.fluidnaquadahreactor gt.recipe.dieselgeneratorfuel gregtech:gt.blockmachines:1190 gregtech:gt.blockmachines:1111 gregtech TRUE gregapi_post
656 gt.recipe.fluidnaquadahreactor gt.recipe.dieselgeneratorfuel gregtech:gt.blockmachines:1191 gregtech:gt.blockmachines:1112 gregtech TRUE gregapi_post
657 gt.recipe.fluidnaquadahreactor gt.recipe.gasturbinefuel gregtech:gt.blockmachines:1192 gregtech:gt.blockmachines:1115 gregtech TRUE gregapi_post
658 gt.recipe.fluidnaquadahreactor gt.recipe.gasturbinefuel gregtech:gt.blockmachines:1188 gregtech:gt.blockmachines:1116 gregtech TRUE gregapi_post
659 gt.recipe.fluidnaquadahreactor gt.recipe.gasturbinefuel gregtech:gt.blockmachines:1189 gregtech:gt.blockmachines:1117 gregtech TRUE gregapi_post
660 gt.recipe.magicfuels gt.recipe.fluidnaquadahreactor gregtech:gt.blockmachines:1123 gregtech:gt.blockmachines:1190 gregtech TRUE gregapi_post
661 gt.recipe.magicfuels gt.recipe.fluidnaquadahreactor gregtech:gt.blockmachines:1124 gregtech:gt.blockmachines:1191 gregtech TRUE gregapi_post
662 gt.recipe.magicfuels gt.recipe.fluidnaquadahreactor gregtech:gt.blockmachines:1125 gregtech:gt.blockmachines:1192 gregtech TRUE gregapi_post
663 gt.recipe.fusionreactor gt.recipe.fluidnaquadahreactor gregtech:gt.blockmachines:1193 gregtech:gt.blockmachines:1188 gregtech TRUE gregapi_post
664 gt.recipe.fusionreactor gt.recipe.fluidnaquadahreactor gregtech:gt.blockmachines:1194 gregtech:gt.blockmachines:1189 gregtech TRUE gregapi_post
665 gt.recipe.fusionreactor gt.recipe.magicfuels gregtech:gt.blockmachines:1195 gregtech:gt.blockmachines:1123 gregtech TRUE gregapi_post
666 gt.recipe.plasmageneratorfuels gt.recipe.magicfuels gregtech:gt.blockmachines:1196 gregtech:gt.blockmachines:1124 gregtech TRUE gregapi_post
667 gt.recipe.plasmageneratorfuels gt.recipe.magicfuels gregtech:gt.blockmachines:1197 gregtech:gt.blockmachines:1125 gregtech TRUE gregapi_post
668 gt.recipe.plasmageneratorfuels gt.recipe.fusionreactor gregtech:gt.blockmachines:1198 gregtech:gt.blockmachines:1193 gregtech TRUE gregapi_post
669 gt.recipe.distillationtower gt.recipe.fusionreactor gregtech:gt.blockmachines:1126 gregtech:gt.blockmachines:1194 gregtech TRUE gregapi_post
670 gt.recipe.gasturbinefuel gt.recipe.fusionreactor gregtech:gt.blockmachines:1151 gregtech:gt.blockmachines:1195 gregtech TRUE gregapi_post
671 gt.recipe.plasmageneratorfuels gregtech:gt.blockmachines:1153 gregtech:gt.blockmachines:1196 gregtech TRUE gregapi_post -10
672 gt.recipe.pyro gt.recipe.plasmageneratorfuels gregtech:gt.blockmachines:1159 gregtech:gt.blockmachines:1197 gregtech TRUE gregapi_post
673 gt.recipe.craker gt.recipe.plasmageneratorfuels gregtech:gt.blockmachines:1160 gregtech:gt.blockmachines:1198 gregtech TRUE gregapi_post
674 gt.recipe.fakeAssemblylineProcess gt.recipe.distillationtower gregtech:gt.blockmachines:1170 gregtech:gt.blockmachines:1126 gregtech TRUE gregapi_post
675 gt.recipe.dieselgeneratorfuel gt.recipe.gasturbinefuel gregtech:gt.blockmachines:1171 gregtech:gt.blockmachines:1151 gregtech TRUE gregapi_post -5
676 gt.recipe.extremedieselgeneratorfuel gt.recipe.plasmageneratorfuels gregtech:gt.blockmachines:2105 gregtech:gt.blockmachines:1153 gregtech TRUE gregapi_post -10
677 gt.recipe.circuitassembler gt.recipe.pyro gregtech:gt.blockmachines:1180 gregtech:gt.blockmachines:1159 gregtech TRUE gregapi_post
678 gt.recipe.circuitassembler gt.recipe.craker gregtech:gt.blockmachines:1181 gregtech:gt.blockmachines:1160 gregtech TRUE gregapi_post
679 gt.recipe.circuitassembler gt.recipe.fakeAssemblylineProcess gregtech:gt.blockmachines:1182 gregtech:gt.blockmachines:1170 gregtech TRUE gregapi_post
680 gt.recipe.circuitassembler gt.recipe.dieselgeneratorfuel gregtech:gt.blockmachines:1183 gregtech:gt.blockmachines:1171 gregtech TRUE gregapi_post -5
681 gt.recipe.circuitassembler gt.recipe.extremedieselgeneratorfuel gregtech:gt.blockmachines:1184 gregtech:gt.blockmachines:2105 gregtech TRUE gregapi_post
682 gt.recipe.circuitassembler gregtech:gt.blockmachines:1185 gregtech:gt.blockmachines:1180 gregtech TRUE gregapi_post
683 gt.recipe.circuitassembler gregtech:gt.blockmachines:1186 gregtech:gt.blockmachines:1181 gregtech TRUE gregapi_post
684 gt.recipe.circuitassembler gregtech:gt.blockmachines:1187 gregtech:gt.blockmachines:1182 gregtech TRUE gregapi_post
685 gt.recipe.largechemicalreactor gt.recipe.circuitassembler gregtech:gt.blockmachines:1169 gregtech:gt.blockmachines:1183 gregtech TRUE gregapi_post
686 gt.recipe.circuitassembler gregtech:gt.blockmachines:1184 gregtech TRUE gregapi_post
687 gt.recipe.circuitassembler gregtech:gt.blockmachines:1185 gregtech TRUE gregapi_post
688 gt.recipe.circuitassembler gregtech:gt.blockmachines:1186 gregtech TRUE gregapi_post
689 gt.recipe.circuitassembler gregtech:gt.blockmachines:1187 gregtech TRUE gregapi_post
690 gt.recipe.largechemicalreactor gregtech:gt.blockmachines:1169 gregtech TRUE gregapi_post
691 gt.recipe.plasmageneratorfuels gregtech:gt.blockmachines:10752 dreamcraft TRUE
692 gt.recipe.plasmageneratorfuels gregtech:gt.blockmachines:10753 dreamcraft TRUE
693 gt.recipe.alloysmelter gregtech:gt.blockmachines:10760 dreamcraft TRUE
1038 gtpp.recipe.chemicaldehydrator gregtech:gt.blockmachines:815 miscutils TRUE
1039 gtpp.recipe.chemicaldehydrator gregtech:gt.blockmachines:816 miscutils TRUE
1040 gtpp.recipe.chemicaldehydrator gregtech:gt.blockmachines:995 miscutils TRUE
gt.recipe.mixer gregtech:gt.blockmachines:851 miscutils TRUE
gt.recipe.mixer gregtech:gt.blockmachines:852 miscutils TRUE
gt.recipe.mixer gregtech:gt.blockmachines:853 miscutils TRUE
gt.recipe.mixer gregtech:gt.blockmachines:854 miscutils TRUE
gt.recipe.mixer gregtech:gt.blockmachines:855 miscutils TRUE
gt.recipe.mixer gregtech:gt.blockmachines:856 miscutils TRUE
gt.recipe.mixer gregtech:gt.blockmachines:857 miscutils TRUE
gt.recipe.mixer gregtech:gt.blockmachines:858 miscutils TRUE
1041 gt.recipe.fusionreactor gregtech:gt.blockmachines:965 miscutils TRUE
1042 gtpp.recipe.alloyblastsmelter gregtech:gt.blockmachines:810 miscutils TRUE
1043 gtpp.recipe.rocketenginefuel gregtech:gt.blockmachines:793 miscutils TRUE
1069 gtpp.recipe.simplewasher gregtech:gt.blockmachines:31019 miscutils TRUE
1070 gtpp.recipe.simplewasher gregtech:gt.blockmachines:31020 miscutils TRUE
1071 gtpp.recipe.vacfurnace gregtech:gt.blockmachines:995 miscutils TRUE
1072 gtPlusPlus.nei.GT_NEI_FlotationCell gtpp.recipe.flotationcell gregtech:gt.blockmachines:31028 miscutils TRUE
1073 gtPlusPlus.nei.GT_NEI_FluidReactor gtpp.recipe.fluidchemicaleactor gregtech:gt.blockmachines:998 miscutils TRUE
1074 gtPlusPlus.nei.GT_NEI_MillingMachine gtpp.recipe.oremill gregtech:gt.blockmachines:31027 miscutils TRUE
1075 team.chisel.compat.nei.RecipeHandlerChisel gregtech:gt.blockmachines:31066 miscutils TRUE
1076 team.chisel.compat.nei.RecipeHandlerChisel gregtech:gt.blockmachines:31067 miscutils TRUE
1077 team.chisel.compat.nei.RecipeHandlerChisel gregtech:gt.blockmachines:31068 miscutils TRUE
+28 -21
View File
@@ -424,26 +424,31 @@ mekanism.client.nei.SolarNeutronRecipeHandler,Mekanism,Mekanism:MachineBlock3:1,
mekanism.client.nei.ThermalEvaporationRecipeHandler,Mekanism,Mekanism:BasicBlock:14,,Mekanism,TRUE,,,62,,5,,,,,,
exnihilo.compatibility.nei.RecipeHandlerHammer,Ex Nihilo,exnihilo:hammer_iron,,exnihilo,TRUE,,,58,,5,,,,,,
exnihilo.compatibility.nei.RecipeHandlerSieve,Ex Nihilo,exnihilo:sifting_table,,exnihilo,TRUE,,,130,,2,,,,,,
gregtechmod.mistaqur.nei.handlers.AlloySmelterRecipeHandler,GregTech-Addon,gregtech_addon:machine:56,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.AssemblerRecipeHandler,GregTech-Addon,gregtech_addon:machine:60,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.BenderRecipeHandler,GregTech-Addon,gregtech_addon:machine:59,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.BlastRecipeHandler,GregTech-Addon,gregtech_addon:machine:29,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.BronzeBlastRecipeHandler,GregTech-Addon,gregtech_addon:machine:136,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.CannerRecipeHandler,GregTech-Addon,gregtech_addon:machine:57,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.CentrifugeRecipeHandler,GregTech-Addon,gregtech_addon:machine:62,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.ChemicalRecipeHandler,GregTech-Addon,gregtech_addon:machine:41,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.CutterRecipeHandler,GregTech-Addon,gregtech_addon:machine:113,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.DistillationRecipeHandler,GregTech-Addon,gregtech_addon:machine:44,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.ElectrolyzerRecipeHandler,GregTech-Addon,gregtech_addon:machine:25,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.ExtruderRecipeHandler,GregTech-Addon,gregtech_addon:machine:115,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.FusionRecipeHandler,GregTech-Addon,gregtech_addon:machine:80,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.GeneratorHandler,GregTech-Addon,,,gregtech_addon,TRUE,,15,145,166,2,nei:textures/nei_tabbed_sprites.png,80,0,14,14,
gregtechmod.mistaqur.nei.handlers.GrinderRecipeHandler,GregTech-Addon,gregtech_addon:machine:28,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.ImplosionRecipeHandler,GregTech-Addon,gregtech_addon:machine:31,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.LatheRecipeHandler,GregTech-Addon,gregtech_addon:machine:111,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.SawmillRecipeHandler,GregTech-Addon,gregtech_addon:machine:32,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.VacuumFreezerRecipeHandler,GregTech-Addon,gregtech_addon:machine:38,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtechmod.mistaqur.nei.handlers.WiremillRecipeHandler,GregTech-Addon,gregtech_addon:machine:55,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.Alloy,GregTech-Addon,gregtech_addon:machine:56,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.Assembler,GregTech-Addon,gregtech_addon:machine:60,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.Bender,GregTech-Addon,gregtech_addon:machine:59,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.Blast,GregTech-Addon,gregtech_addon:machine:29,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.BronzeBlast,GregTech-Addon,gregtech_addon:machine:136,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.Canner,GregTech-Addon,gregtech_addon:machine:57,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.centrifuge,GregTech-Addon,gregtech_addon:machine:62,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.chemicalreactor,GregTech-Addon,gregtech_addon:machine:41,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.Cutter,GregTech-Addon,gregtech_addon:machine:113,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.Distillation,GregTech-Addon,gregtech_addon:machine:44,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.electrolyzer,GregTech-Addon,gregtech_addon:machine:25,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.extruder,GregTech-Addon,gregtech_addon:machine:115,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.fusion,GregTech-Addon,gregtech_addon:machine:80,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.thermal_generator,GregTech-Addon,gregtech_addon:machine:35,,gregtech_addon,TRUE,,15,145,166,2,,80,0,14,14,
gregtech.diesel_generator,GregTech-Addon,gregtech_addon:machine:33,,gregtech_addon,TRUE,,15,145,166,2,,80,0,14,14,
gregtech.gas_turbine,GregTech-Addon,gregtech_addon:machine:108,,gregtech_addon,TRUE,,15,145,166,2,,80,0,14,14,
gregtech.semifluid_generator,GregTech-Addon,gregtech_addon:machine:36,,gregtech_addon,TRUE,,15,145,166,2,,80,0,14,14,
gregtech.plasma_generator,GregTech-Addon,gregtech_addon:machine:37,,gregtech_addon,TRUE,,15,145,166,2,,80,0,14,14,
gregtech.magic_generator,GregTech-Addon,gregtech_addon:machine:42,,gregtech_addon,TRUE,,15,145,166,2,,80,0,14,14,
gregtech.Grinder,GregTech-Addon,gregtech_addon:machine:28,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.Implosion,GregTech-Addon,gregtech_addon:machine:31,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.Lathe,GregTech-Addon,gregtech_addon:machine:111,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.Sawmill,GregTech-Addon,gregtech_addon:machine:32,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.VacuumFreezer,GregTech-Addon,gregtech_addon:machine:38,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
gregtech.Wiremill,GregTech-Addon,gregtech_addon:machine:55,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
cofh.thermaldynamics.plugins.nei.RecipeHandlerCover,Thermal Dynamics,ThermalDynamics:cover,"{Block:""minecraft:glass"",Meta:0b}",ThermalDynamics,TRUE,,,65,166,5,,,,,,
neresources.nei.NEIAdvSeedHandler,Not Enough Resources,minecraft:wheat,,neresources,TRUE,,,65,166,5,,,,,,
neresources.nei.NEIDungeonHandler,Not Enough Resources,minecraft:chest,,neresources,TRUE,,,130,166,2,,,,,,
@@ -473,4 +478,6 @@ nc.crafting.nei.HeliumExtractorRecipeHandler,NuclearCraft,NuclearCraft:heliumExt
nc.crafting.nei.RecyclerRecipeHandler,NuclearCraft,NuclearCraft:recyclerIdle,,NuclearCraft,TRUE,,,65,166,5,,,,,,
nc.crafting.nei.NuclearWorkspaceRecipeHandler,NuclearCraft,NuclearCraft:nuclearWorkspace,,NuclearCraft,TRUE,,,130,,2,,,,,,
ganymedes01.etfuturum.NEI_EtFuturum_Config$NEI_Recipes_Smoker,EtFuturum Requiem,etfuturum:lit_smoker,,etfuturum,TRUE,,,65,166,5,,,,,,
ganymedes01.etfuturum.NEI_EtFuturum_Config$NEI_Recipes_BlastFurnace,EtFuturum Requiem,etfuturum:lit_blast_furnace,,etfuturum,TRUE,,,65,166,5,,,,,,
ganymedes01.etfuturum.NEI_EtFuturum_Config$NEI_Recipes_BlastFurnace,EtFuturum Requiem,etfuturum:lit_blast_furnace,,etfuturum,TRUE,,,65,166,5,,,,,,
connor135246.campfirebackport.client.compat.nei.NEICampfireRecipeHandler,Campfire Backport,campfirebackport:campfire,,campfirebackport,TRUE,,,65,166,5,,,,,,
connor135246.campfirebackport.client.compat.nei.NEICampfireStateChangerHandler,Campfire Backport,campfirebackport:campfire_base,,campfirebackport,TRUE,,,65,166,5,,,,,,
1 handler modName itemName nbtInfo modId modRequired excludedModId yShift handlerHeight handlerWidth maxRecipesPerPage imageResource imageX imageY imageWidth imageHeight itemNotes
424 mekanism.client.nei.ThermalEvaporationRecipeHandler Mekanism Mekanism:BasicBlock:14 Mekanism TRUE 62 5
425 exnihilo.compatibility.nei.RecipeHandlerHammer Ex Nihilo exnihilo:hammer_iron exnihilo TRUE 58 5
426 exnihilo.compatibility.nei.RecipeHandlerSieve Ex Nihilo exnihilo:sifting_table exnihilo TRUE 130 2
427 gregtechmod.mistaqur.nei.handlers.AlloySmelterRecipeHandler gregtech.Alloy GregTech-Addon gregtech_addon:machine:56 gregtech_addon TRUE 15 145 166 2
428 gregtechmod.mistaqur.nei.handlers.AssemblerRecipeHandler gregtech.Assembler GregTech-Addon gregtech_addon:machine:60 gregtech_addon TRUE 15 145 166 2
429 gregtechmod.mistaqur.nei.handlers.BenderRecipeHandler gregtech.Bender GregTech-Addon gregtech_addon:machine:59 gregtech_addon TRUE 15 145 166 2
430 gregtechmod.mistaqur.nei.handlers.BlastRecipeHandler gregtech.Blast GregTech-Addon gregtech_addon:machine:29 gregtech_addon TRUE 15 145 166 2
431 gregtechmod.mistaqur.nei.handlers.BronzeBlastRecipeHandler gregtech.BronzeBlast GregTech-Addon gregtech_addon:machine:136 gregtech_addon TRUE 15 145 166 2
432 gregtechmod.mistaqur.nei.handlers.CannerRecipeHandler gregtech.Canner GregTech-Addon gregtech_addon:machine:57 gregtech_addon TRUE 15 145 166 2
433 gregtechmod.mistaqur.nei.handlers.CentrifugeRecipeHandler gregtech.centrifuge GregTech-Addon gregtech_addon:machine:62 gregtech_addon TRUE 15 145 166 2
434 gregtechmod.mistaqur.nei.handlers.ChemicalRecipeHandler gregtech.chemicalreactor GregTech-Addon gregtech_addon:machine:41 gregtech_addon TRUE 15 145 166 2
435 gregtechmod.mistaqur.nei.handlers.CutterRecipeHandler gregtech.Cutter GregTech-Addon gregtech_addon:machine:113 gregtech_addon TRUE 15 145 166 2
436 gregtechmod.mistaqur.nei.handlers.DistillationRecipeHandler gregtech.Distillation GregTech-Addon gregtech_addon:machine:44 gregtech_addon TRUE 15 145 166 2
437 gregtechmod.mistaqur.nei.handlers.ElectrolyzerRecipeHandler gregtech.electrolyzer GregTech-Addon gregtech_addon:machine:25 gregtech_addon TRUE 15 145 166 2
438 gregtechmod.mistaqur.nei.handlers.ExtruderRecipeHandler gregtech.extruder GregTech-Addon gregtech_addon:machine:115 gregtech_addon TRUE 15 145 166 2
439 gregtechmod.mistaqur.nei.handlers.FusionRecipeHandler gregtech.fusion GregTech-Addon gregtech_addon:machine:80 gregtech_addon TRUE 15 145 166 2
440 gregtechmod.mistaqur.nei.handlers.GeneratorHandler gregtech.thermal_generator GregTech-Addon gregtech_addon:machine:35 gregtech_addon TRUE 15 145 166 2 nei:textures/nei_tabbed_sprites.png 80 0 14 14
441 gregtechmod.mistaqur.nei.handlers.GrinderRecipeHandler gregtech.diesel_generator GregTech-Addon gregtech_addon:machine:28 gregtech_addon:machine:33 gregtech_addon TRUE 15 145 166 2 80 0 14 14
442 gregtechmod.mistaqur.nei.handlers.ImplosionRecipeHandler gregtech.gas_turbine GregTech-Addon gregtech_addon:machine:31 gregtech_addon:machine:108 gregtech_addon TRUE 15 145 166 2 80 0 14 14
443 gregtechmod.mistaqur.nei.handlers.LatheRecipeHandler gregtech.semifluid_generator GregTech-Addon gregtech_addon:machine:111 gregtech_addon:machine:36 gregtech_addon TRUE 15 145 166 2 80 0 14 14
444 gregtechmod.mistaqur.nei.handlers.SawmillRecipeHandler gregtech.plasma_generator GregTech-Addon gregtech_addon:machine:32 gregtech_addon:machine:37 gregtech_addon TRUE 15 145 166 2 80 0 14 14
445 gregtechmod.mistaqur.nei.handlers.VacuumFreezerRecipeHandler gregtech.magic_generator GregTech-Addon gregtech_addon:machine:38 gregtech_addon:machine:42 gregtech_addon TRUE 15 145 166 2 80 0 14 14
446 gregtechmod.mistaqur.nei.handlers.WiremillRecipeHandler gregtech.Grinder GregTech-Addon gregtech_addon:machine:55 gregtech_addon:machine:28 gregtech_addon TRUE 15 145 166 2
447 gregtech.Implosion GregTech-Addon gregtech_addon:machine:31 gregtech_addon TRUE 15 145 166 2
448 gregtech.Lathe GregTech-Addon gregtech_addon:machine:111 gregtech_addon TRUE 15 145 166 2
449 gregtech.Sawmill GregTech-Addon gregtech_addon:machine:32 gregtech_addon TRUE 15 145 166 2
450 gregtech.VacuumFreezer GregTech-Addon gregtech_addon:machine:38 gregtech_addon TRUE 15 145 166 2
451 gregtech.Wiremill GregTech-Addon gregtech_addon:machine:55 gregtech_addon TRUE 15 145 166 2
452 cofh.thermaldynamics.plugins.nei.RecipeHandlerCover Thermal Dynamics ThermalDynamics:cover {Block:"minecraft:glass",Meta:0b} ThermalDynamics TRUE 65 166 5
453 neresources.nei.NEIAdvSeedHandler Not Enough Resources minecraft:wheat neresources TRUE 65 166 5
454 neresources.nei.NEIDungeonHandler Not Enough Resources minecraft:chest neresources TRUE 130 166 2
478 nc.crafting.nei.RecyclerRecipeHandler NuclearCraft NuclearCraft:recyclerIdle NuclearCraft TRUE 65 166 5
479 nc.crafting.nei.NuclearWorkspaceRecipeHandler NuclearCraft NuclearCraft:nuclearWorkspace NuclearCraft TRUE 130 2
480 ganymedes01.etfuturum.NEI_EtFuturum_Config$NEI_Recipes_Smoker EtFuturum Requiem etfuturum:lit_smoker etfuturum TRUE 65 166 5
481 ganymedes01.etfuturum.NEI_EtFuturum_Config$NEI_Recipes_BlastFurnace EtFuturum Requiem etfuturum:lit_blast_furnace etfuturum TRUE 65 166 5
482 connor135246.campfirebackport.client.compat.nei.NEICampfireRecipeHandler Campfire Backport campfirebackport:campfire campfirebackport TRUE 65 166 5
483 connor135246.campfirebackport.client.compat.nei.NEICampfireStateChangerHandler Campfire Backport campfirebackport:campfire_base campfirebackport TRUE 65 166 5
@@ -0,0 +1,56 @@
AdvancedSolarPanel:hybrid_solar_helmet,Damage
BuildCraft|Transport:pipeFacade
DraconicEvolution:draconicAxe,tag.Energy
DraconicEvolution:draconicPickaxe,tag.Energy
DraconicEvolution:wyvernPickaxe,tag.Energy
ExtraUtilities:microblocks,Damage
Forestry:beePrincessGE,tag.Genome.Chromosomes
ForgeMicroblock:microblock,Damage
Genetics:serumArray,tag.genes
GraviSuite:itemPlasmaCell,tag.Fluid.FluidName
IC2:itemCropSeed,tag.name
IC2:itemFluidCell,tag.Fluid.FluidName
NodalMechanics:item.nodalmechanics.matrix,tag.Aspects.0.key
TConstruct:ArrowAmmo,tag.InfiTool
TConstruct:BoltAmmo,tag.InfiTool
TConstruct:Crossbow,tag.InfiTool
TConstruct:Javelin,tag.InfiTool
TConstruct:LongBow,tag.InfiTool
TConstruct:ShortBow,tag.InfiTool
TConstruct:Shuriken,tag.InfiTool
TConstruct:ThrowingKnife,tag.InfiTool
TConstruct:battleaxe,tag.InfiTool
TConstruct:battlesign,tag.InfiTool
TConstruct:broadsword,tag.InfiTool
TConstruct:chisel,tag.InfiTool
TConstruct:cleaver,tag.InfiTool
TConstruct:cutlass,tag.InfiTool
TConstruct:dagger,tag.InfiTool
TConstruct:excavator,tag.InfiTool
TConstruct:frypan,tag.InfiTool
TConstruct:hammer,tag.InfiTool
TConstruct:hatchet,tag.InfiTool
TConstruct:longsword,tag.InfiTool
TConstruct:lumberaxe,tag.InfiTool
TConstruct:mattock,tag.InfiTool
TConstruct:pickaxe,tag.InfiTool
TConstruct:potionLauncher
TConstruct:rapier,tag.InfiTool
TConstruct:scythe,tag.InfiTool
TConstruct:shovel,tag.InfiTool
Thaumcraft:ItemEssence,tag.Aspects.0.key
Thaumcraft:ItemWispEssence,tag.Aspects.0.key
WitchingGadgets:item.WG_InfusedGem,tag.Aspect
adventurebackpack:adventureBackpack,Damage
appliedenergistics2:item.ItemFacade
bartworks:BioLabParts,Damage,tag.Name
battlegear2:knights_armour.boots
battlegear2:knights_armour.helmet
battlegear2:knights_armour.legs
battlegear2:knights_armour.plate
miscutils:itemBlueprint
miscutils:particleIon,Damage
miscutils:personalHealingDevice
tectech:item.em.debugContainer,tag.symbols
tinkersdefense:Heater Shield,tag.InfiTool
tinkersdefense:Round Shield,tag.InfiTool
+27 -1
View File
@@ -66,6 +66,7 @@ nei.chat.rain.on=Rain turned on
nei.chat.rain.off=Rain turned off
nei.chat.time=Day %d. %d:00
nei.chat.give.noitem=No such item.
nei.chat.recipe.error=There was error during loading recipe. Please check log for details.
nei.options=NEI Options
nei.options.back=Back
@@ -94,6 +95,7 @@ nei.options.keys.gui.prev_machine=Prev Machine
nei.options.keys.gui.search=Focus Search Bar
nei.options.keys.gui.bookmark=Add Bookmark
nei.options.keys.gui.hide_bookmarks=Toggle Bookmark Panel Visibility
nei.options.keys.gui.overlay=Overlay Recipe
nei.options.keys.world=World
nei.options.keys.world.chunkoverlay=Chunk Boundary Overlay
nei.options.keys.world.moboverlay=Mob Spawn Overlay
@@ -111,6 +113,9 @@ nei.options.inventory=Inventory
nei.options.inventory.worldSpecificBookmarks=World Specific Bookmarks
nei.options.inventory.worldSpecificBookmarks.true=Yes
nei.options.inventory.worldSpecificBookmarks.false=No
nei.options.inventory.worldSpecificPresets=World Specific Presets
nei.options.inventory.worldSpecificPresets.true=Yes
nei.options.inventory.worldSpecificPresets.false=No
nei.options.inventory.bookmarksEnabled=Bookmarks Panel Visibility
nei.options.inventory.bookmarksEnabled.true=Visible
nei.options.inventory.bookmarksEnabled.false=Hidden
@@ -129,6 +134,9 @@ nei.options.inventory.saveCurrentRecipeInBookmarksEnabled.false=Disabled
nei.options.inventory.useNBTInBookmarks=Use NBT in Bookmarks
nei.options.inventory.useNBTInBookmarks.true=Yes
nei.options.inventory.useNBTInBookmarks.false=No
nei.options.inventory.showRecipeMarker=Show Recipe Marker
nei.options.inventory.showRecipeMarker.true=Yes
nei.options.inventory.showRecipeMarker.false=No
nei.options.inventory.creative_tab_style=Creative or JEI tab style
nei.options.inventory.creative_tab_style.true=Creative
nei.options.inventory.creative_tab_style.false=JEI
@@ -171,6 +179,9 @@ nei.options.inventory.disableMouseScrollTransfer.false=False
nei.options.inventory.invertMouseScrollTransfer=Invert Mouse Wheel Transfer Direction
nei.options.inventory.invertMouseScrollTransfer.true=True
nei.options.inventory.invertMouseScrollTransfer.false=False
nei.options.inventory.cacheItemRendering=Cache Item Rendering
nei.options.inventory.cacheItemRendering.true=True
nei.options.inventory.cacheItemRendering.false=False
nei.options.command=Commands
nei.options.command.creative=Gamemode
@@ -189,6 +200,8 @@ nei.options.world.highlight_tips.hide=Hidden
nei.options.world.highlight_tips.show=Shown
nei.options.world.highlight_tips.sample=Sample
nei.options.world.panels=Panels Settings
nei.options.tools=Tools
nei.options.tools.handler_load_from_config=Load handlers from Config
nei.options.tools.handler_load_from_config.true=Config
@@ -231,8 +244,12 @@ nei.recipe.shaped=Shaped Crafting
nei.recipe.shapeless=Shapeless Crafting
nei.recipe.furnace=Smelting
nei.recipe.fuel=Fuel
nei.recipe.fuel.smeltCount=Smelts %s items
# Deprecated
nei.recipe.fuel.required=%s required
# Deprecated
nei.recipe.fuel.processed=%s processed
# Deprecated
nei.recipe.fuel.produced=%s produced
nei.recipe.firework=Fireworks
nei.recipe.firework.tooltip0=Dyes add colours to the charges
@@ -277,4 +294,13 @@ nei.subsets.Items.Tools.Shovels=Shovels
nei.subsets.Items.Weapons=Weapons
nei.subsets.Items.Weapons.Ranged=Ranged
nei.subsets.Items.Weapons.Swords=Swords
nei.subsets.Mod=Mod
nei.subsets.Mod=Mod
nei.presets.blacklist.label=B
nei.presets.blacklist.tooltip=Blacklist
nei.presets.whitelist.label=W
nei.presets.whitelist.tooltip=Whitelist
nei.presets.textfield.tooltip.1=Enter - save
nei.presets.textfield.tooltip.2=Escape - cancel
nei.presets.label.tooltip=Double click to edit
nei.presets.label.selected=%s Presets
@@ -174,14 +174,14 @@ nei.recipe.fuel.processed=Обработано: %s
nei.recipe.fuel.produced=Произведено: %s
nei.recipe.firework=Фейерверки
nei.recipe.firework.tooltip0=Красители добавляют цвета на звёздочку
nei.recipe.firework.tooltip1=Recolouring adds fade colours to the charge
nei.recipe.firework.tooltip2=Multiple charges can be spawned from one rocket
nei.recipe.firework.tooltip1=Перекрашивание добавляет исчезающие цвета к заряду
nei.recipe.firework.tooltip2=Одна ракета может выпустить несколько зарядов
nei.recipe.brewing=Зельеварение
nei.recipe.profiler.crafting=Профилирование создания
nei.recipe.profiler.usage=Использование профилирования
nei.itemsort.minecraft=Minecraft
nei.itemsort.minecraft.tip=Сортирует предметы сначало из оригинального Minecraft
nei.itemsort.minecraft.tip=Сортирует предметы сначала из оригинального Minecraft
nei.itemsort.mod=По модификации
nei.itemsort.mod.tip=Группирует предметы в один мод, на основе имени мода
nei.itemsort.id=ID предмета
@@ -215,4 +215,4 @@ nei.subsets.Items.Tools.Shovels=Лопаты
nei.subsets.Items.Weapons=Оружие
nei.subsets.Items.Weapons.Ranged=Дальнего боя
nei.subsets.Items.Weapons.Swords=Мечи
nei.subsets.Mod=Модификации
nei.subsets.Mod=Модификации
+26 -1
View File
@@ -108,6 +108,12 @@ nei.options.keys.world.creative=游戏模式
nei.options.keys.world.creative.tip=循环游戏模式
nei.options.inventory=物品栏
nei.options.inventory.worldSpecificBookmarks=书签存储位置
nei.options.inventory.worldSpecificBookmarks.true=存档内
nei.options.inventory.worldSpecificBookmarks.false=全局
nei.options.inventory.worldSpecificPresets=预设存储位置
nei.options.inventory.worldSpecificPresets.true=存档内
nei.options.inventory.worldSpecificPresets.false=全局
nei.options.inventory.bookmarksEnabled=显示/隐藏书签页
nei.options.inventory.bookmarksEnabled.true=显示
nei.options.inventory.bookmarksEnabled.false=隐藏
@@ -117,6 +123,9 @@ nei.options.inventory.jei_style_tabs.false=否 [不会吧]
nei.options.inventory.jei_style_item_presence_overlay=JEI风格物品覆盖?-悬停
nei.options.inventory.jei_style_item_presence_overlay.true=是
nei.options.inventory.jei_style_item_presence_overlay.false=否
nei.options.inventory.jei_style_recipe_catalyst=JEI风格可执行合成表机器显示[测试中]
nei.options.inventory.jei_style_recipe_catalyst.true=是
nei.options.inventory.jei_style_recipe_catalyst.false=否
nei.options.inventory.saveCurrentRecipeInBookmarksEnabled=保存书签中的当前合成表
nei.options.inventory.saveCurrentRecipeInBookmarksEnabled.true=启用
nei.options.inventory.saveCurrentRecipeInBookmarksEnabled.false=禁用
@@ -184,9 +193,12 @@ nei.options.world.highlight_tips.show=显示
nei.options.world.highlight_tips.sample=样本
nei.options.tools=工具
nei.options.tools.handler_load_from_config=从Config加载预设(handler)
nei.options.tools.handler_load_from_config=从Config加载handler(加工所使用的机器类别)
nei.options.tools.handler_load_from_config.true=Config
nei.options.tools.handler_load_from_config.false=JAR
nei.options.tools.catalyst_load_from_config=从Config加载catalysts(加工所使用的具体机器等)
nei.options.tools.catalyst_load_from_config.true=Config
nei.options.tools.catalyst_load_from_config.false=JAR
nei.options.tools.dump=数据存储
nei.options.tools.dump.dump=存储
nei.options.tools.dump.dumped=%s ID已保存到.minecraft/%s
@@ -222,8 +234,12 @@ nei.recipe.shaped=有序合成
nei.recipe.shapeless=无序合成
nei.recipe.furnace=烧制
nei.recipe.fuel=燃料
nei.recipe.fuel.smeltCount=可冶炼%s个物品
# Deprecated
nei.recipe.fuel.required=需要%s个
# Deprecated
nei.recipe.fuel.processed=可烧制%s个
# Deprecated
nei.recipe.fuel.produced=可制作%s个
nei.recipe.firework=烟花
nei.recipe.firework.tooltip0=添加多种染料可增加烟火之星的颜色
@@ -269,3 +285,12 @@ nei.subsets.Items.Weapons=武器
nei.subsets.Items.Weapons.Ranged=远程
nei.subsets.Items.Weapons.Swords=剑
nei.subsets.Mod=Mod
nei.presets.blacklist.label=黑
nei.presets.blacklist.tooltip=黑名单
nei.presets.whitelist.label=白
nei.presets.whitelist.tooltip=白名单
nei.presets.textfield.tooltip.1=Enter - 保存
nei.presets.textfield.tooltip.2=Esc - 取消
nei.presets.label.tooltip=双击编辑
nei.presets.label.selected=%s 预设
+3 -3
View File
@@ -1,7 +1,7 @@
{
"repo": "https://github.com/GTNewHorizons/CodeChickenLib/releases/download/1.1.4.1/",
"file": "CodeChickenLib-1.7.10-1.1.4.1.jar",
"dev": "CodeChickenLib-1.7.10-1.1.4.1-dev.jar",
"repo": "https://github.com/GTNewHorizons/CodeChickenLib/releases/download/1.1.5.3/",
"file": "CodeChickenLib-1.7.10-1.1.5.3.jar",
"dev": "CodeChickenLib-1.7.10-1.1.5.3-dev.jar",
"class": "codechicken.lib.asm.ASMHelper",
"coreLib": true
}
+2 -7
View File
@@ -4,13 +4,8 @@
"name": "${modName}",
"version": "${modVersion}",
"mcversion": "${minecraftVersion}",
"description": "Recipe Viewer, Inventory Manager, Item Spawner, Cheats and more; GTNH Version
<plugins>
Supporters: EmuCraft Team, Victor Zimmer, lexi85, Ace_Trainer_Tullius, Bacon_Donut, Iarinu",
"url": "http://www.minecraftforum.net/topic/909223",
"description": "Recipe Viewer, Inventory Manager, Item Spawner, Cheats and more; GTNH Version includes many enhancements.",
"url": "https://github.com/GTNewHorizons/NotEnoughItems",
"credits": "Alexandria - original idea",
"license": "LGPL-3.0",
"authorList": [ "ChickenBones", "mitchej123" ],