Compare commits

...
27 Commits
Author SHA1 Message Date
Wilhelm Schuster 5b9c27e253 Fix potential NPE when calling ItemMobSpawner#loadSpawners. (#405) 2023-07-16 14:29:31 +02:00
Raven Szewczyk d613d06471 Attempt to fix CME when opening recipes immediately after load (#403) 2023-07-16 09:00:35 +01:00
65ffbad491 Show a full recipe widget in item tooltips for bookmarked recipes (#398)
* Update buildscript

* Show a full recipe widget in item tooltips for bookmarked recipes

* Make recipe tooltips configurable and only show in the bookmarks panel

* Fix layout relative to tooltip boxes

* Fix wildcard import

* spotlessApply (#401)

Co-authored-by: GitHub GTNH Actions <>

* Fix handler tooltip offsets for new&legacy handlers

* Fix render order to draw crafting tooltips on top of container manager buttons

* Fix wrong mouse Y half-point calculation

* Allow saving recipes with empty item ingredient lists to bookmarks (e.g. fluid-only)

* Fix waila vs. non-waila tooltip offsets

Co-authored-by: Wilhelm Schuster <[email protected]>

---------

Co-authored-by: Wilhelm Schuster <[email protected]>
2023-07-10 17:38:07 +01:00
Wilhelm Schuster 885609720e Extend height hack for legacy recipe handlers (#395)
* Store heighthackhandlers.cfg as an internal asset instead of an array of strings

Is copied into the config directory upon first launch. Also, comments
are now allowed (only from the beginning of the file).

* Store serialhandlers.cfg as an internal asset instead of an array of strings

Is copied into the config directory upon first launch. Also, comments
are now allowed (only from the beginning of the file).

Removes GTNH-specific code to be replaced with a configuration file.

* Extend the height hack to also cover guiTop and getRecipePosition

Certain legacy recipe handlers hardcode even more of the NEI recipe
screen layout, requiring only the singular recipe handler switcher
widget at the top, whereas this improved NEI moves the recipe pager to
the top as well expecting recipe handler to move down another 16px. One
such mod that breaks is Immersive Engineering. To fix it we move the top
edge of the gui (guiTop) down by 16px so that the old gap calculation
works correctly. This required special handling in getRecipePosition()
and refreshSlots().

* Fix Immersive Engineering recipe handlers

* Fix Ex Nihilo recipe handlers

* Fix Thermal Expansion recipe handlers

These handlers expect only two recipes to be displayed at a time. This can only be fixed through asm AFAICT.
2023-07-08 23:23:19 +02:00
chochemandglowredman bacf246504 Adjust nei overlay to gt oregen changes (#391)
* adjust to oregen changes

* add compat for old worlds

* remove testing debug

* Update buildscript

* Adjust to changed oregenPattern API

* fix fieldname

---------

Co-authored-by: glowredman <[email protected]>
2023-07-04 18:36:35 +02:00
Wilhelm Schuster 1ab3350eb8 Adjust recipe handler scrolling again (#393)
* Update buildscript

* Rework recipe handler tab scrolling again

Move the recipe handler tab scrolling before the handler-specific
scrolling again. This ensures that tab scrolling while hovering over the
tab bar will always be possible, regardless of how a recipe handler
handles scrolling itself. This mostly reverts back to how this feature
was implemented originally with one change: the Shift-scrolling behavior
is moved outside the recipe tabs scroll handler after the recipe
handler-specific scroll handling to prevent this from overwriting any
other behavior.
2023-06-24 12:01:21 +02:00
Wilhelm Schuster f3aa12483d Expand the tooltips for the time manipulation action buttons (#392) 2023-06-15 23:19:57 +02:00
miozune d86c472790 Fix crash with IC2 setItemDamage (#387)
* Ducttape fix for crash with IC2 setItemDamage

* Use Items.feather
2023-06-01 07:20:24 +02:00
Wilhelm Schuster 4124151208 Prevent recipe handler tab scrolling from overwriting recipe handler-specific scrolling (#384)
* Rename variable in GuiRecipeTabs to avoid confusion

Based on feedback in a previous PR review.

* Make sure recipe handler-specific scrolling behavior takes precedence over recipe handler tab scrolling
2023-05-13 17:40:08 +02:00
miozune 68ad800620 Remove handlers for Et Futurum Requiem (#383)
* Update dependencies

* updateBuildScript

* Remove handlers for Et Futurum Requiem
2023-05-13 14:12:22 +02:00
Wilhelm Schuster 2c7207485d Ensure the NEI config is really only initialized once (#381)
bootNEI() is supposed to only be called once during the client's
lifetime. Turns out, if your pack has 800 mods, bootNEI() might be
called a second time before configLoaded is set to true at the end of
the plugin loading thread. This introduces a second variable that is
set at the end of the single threaded portion of bootNEI() so that it
truly can only be called once, but we can still retain the ability to
check if the plugin loading thread has finished.
2023-05-10 23:55:45 +02:00
Wilhelm Schuster e8094794c3 Allow scrolling through recipe handlers (#379)
In addition to scrolling through all recipes of a single handler, you
can now scroll through all the recipe handlers while hovering over the
handler tab bar (or anywhere in the recipe area while holding left
shift).
2023-05-09 21:57:27 +02:00
miozune ad86d8f9c5 Separate logic to get detailed string of fluid amount (#378)
* Separate logic to get detailed string of fluid amount

* updateBuildScript & spotlessApply

* probably better way
2023-05-07 20:10:18 +02:00
Wilhelm Schuster 30c87e9160 Make sure NEI plugins are loaded before processing keybindings (#375)
NEI plugins are initialized in a separate thread. If this takes too long,
the client tick handler might already be running checking the keybindings
in KeyManager while a plugin calls API.addKeyBind() which can lead to a
CME.

Reported in https://github.com/GTNewHorizons/GT-New-Horizons-Modpack/issues/13292
Thanks to @Denostrov for helping me track this down.
2023-05-05 21:01:50 +02:00
chill 5eeb001534 Readme: fix wording (#374) 2023-05-05 12:16:22 +02:00
MalTeeez 962754ee10 Create handlers for Fusion Crafting (DE-), Techguns and some missing NC recipes (#372)
* Add Fusion Crafting catalyst.csv

* Add Fusion Crafter handler.csv

* Add Techguns handlers & some missing NuclearCraft handlers

* Add Techguns catalysts & some missing NuclearCraft catalysts

* Fix typo

* Add heights to handlers and fix typo

* Small height increase

* Group NC catalysts

* Group NC handlers
2023-04-28 08:24:58 +02:00
Jason Mitchell 0e34840c21 More robust IMC handling (#371)
* Complain if IMC adds a handler/catalyst for a handlerID that doesn't exist.

* Look at the right maps this time

* Don't show matches, only misses
2023-04-16 21:22:09 +02:00
CaedisandMartin Robertz a12fadb10d Add option to have the search widget under item panel (#364)
* Add option to have the search widget under item panel

* update bs+sa

* Make heights consistent

---------

Co-authored-by: Martin Robertz <[email protected]>
2023-04-01 23:16:18 +02:00
Raven Szewczyk 9218e233aa Ignore nonstackables in max overlaid recipe count calculation (#365)
* Update buildscript

* Ignore nonstackables in max overlaid recipe count calculation
2023-03-30 21:47:33 +02:00
theOnly1iKnow 23e16abae6 Add handlers of Reikas mods plus fixes (#362)
* Added Handlers for some of Reikas mods aswell as:
 - a fix for the Industrialcraft Fluid/Solid Canning Machine
 - Tiling for all MFR machines with multiple recipes 
 - Added Cyanite Reporcessor from Big Reactors

* Bring metalformer in line with other IC2 machines
2023-03-20 08:30:15 -07:00
theOnly1iKnow b3cb4db9ca Added handlers for Factorization plus a missing MFR handler (#359)
* Added Handlers for Factorization
as well as a missing MFR Handler

* Added three more MFR handlers
2023-03-06 13:10:28 +01:00
Raven Szewczyk 45fea43a4b Fix MissingFileException in <https://github.com/GTNewHorizons/GT-New-Horizons-Modpack/issues/12791> (#360) 2023-03-05 14:11:45 +01:00
miozune 088d9c08a8 Prevent NPE with null value for keybind (#358) 2023-03-03 11:15:13 +01:00
miozune 98547c2bcf Prevent NPE with null overlayHandler (#357) 2023-03-03 11:14:56 +01:00
Raven Szewczyk 02fa633043 Fix mob spawn spots sometimes showing as gray (#355) 2023-03-01 13:39:08 +01:00
r1tsuu 9df6ab0232 MacOS Command key accessibility (#354)
* MacOS Command key accessibility

* MacOS Command key accessibility

* Fixed spotless violation build error

* Fixed RMENU key to RMETA as CTRL on MacOS
2023-02-28 15:53:59 +01:00
Raven Szewczyk 89cc203875 Light/chunk overlay fixes (#353)
* Update buildscript

* Fix mob/chunk overlay rendering at very far x/z coordinates

Closes <https://github.com/GTNewHorizons/GT-New-Horizons-Modpack/issues/12680>

* Use Tesselator for mob spawn overlay drawing for a minor performance boost

* Missed a couple of offsets in the other chunk overlay modes
2023-02-27 13:31:44 +01:00
45 changed files with 1107 additions and 420 deletions

No files matched your search

+1 -8
View File
@@ -12,7 +12,7 @@ If you have issues with NEI outside of the GTNH modpack you may report them in t
- Uses a parallel stream to search the item list over multiple cores, resulting in 2-6x faster searches on average
- Loads the recipe handlers in parallel
* A textbox for search with most of the features you'd expect - moving forward, backwards, selection, etc
* Bookmarks! What are you in the process of crafting? Bookmark it using either 'A' or configure your own key.
* Bookmarks! Are you in the process of crafting? Bookmark it using either 'A' or configure your own key.
* Toggle bookmark pane. Default shortcut key `B`. Item Subsets menu is only available if bookmarks are not visible.
* Utility/Cheat buttons line up and wrap based on GUI size
* ItemList is no longer regenerated from the ItemRegistry on every inventory load
@@ -27,13 +27,6 @@ If you have issues with NEI outside of the GTNH modpack you may report them in t
* Remove TMI style
* Removed inventory Load/Save state
## Development
Before launching, you need to add
```
-Dfml.coreMods.load=codechicken.nei.asm.NEICorePlugin
```
as a command line argument to the VM.
## License
GTNH Modifications Copyright (c) 2019-2022 mitchej123 and the GTNH Team
+226 -138
View File
@@ -1,4 +1,4 @@
//version: 1675859611
//version: 1685785062
/*
DO NOT CHANGE THIS FILE!
Also, you may replace this file at any time if there is an update available.
@@ -6,31 +6,28 @@
*/
import com.diffplug.blowdryer.Blowdryer
import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import com.gtnewhorizons.retrofuturagradle.ObfuscationAttribute
import com.gtnewhorizons.retrofuturagradle.mcp.ReobfuscatedJar
import com.gtnewhorizons.retrofuturagradle.minecraft.RunMinecraftTask
import com.gtnewhorizons.retrofuturagradle.util.Distribution
import com.matthewprenger.cursegradle.CurseArtifact
import com.matthewprenger.cursegradle.CurseRelation
import com.modrinth.minotaur.dependencies.ModDependency
import com.modrinth.minotaur.dependencies.VersionDependency
import cpw.mods.fml.relauncher.Side
import org.gradle.api.tasks.options.Option;
import org.gradle.internal.logging.text.StyledTextOutput.Style
import org.gradle.internal.logging.text.StyledTextOutputFactory
import org.jetbrains.gradle.ext.*
import org.gradle.internal.xml.XmlTransformer
import org.jetbrains.gradle.ext.Application
import org.jetbrains.gradle.ext.Gradle
import javax.inject.Inject
import java.nio.file.Files
import java.nio.file.Paths
import java.util.concurrent.TimeUnit
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
import javax.inject.Inject
buildscript {
repositories {
mavenLocal()
mavenCentral()
maven {
@@ -51,6 +48,8 @@ buildscript {
name 'Scala CI dependencies'
url 'https://repo1.maven.org/maven2/'
}
mavenLocal()
}
}
plugins {
@@ -62,22 +61,26 @@ plugins {
id 'org.jetbrains.kotlin.jvm' version '1.8.0' apply false
id 'org.jetbrains.kotlin.kapt' version '1.8.0' apply false
id 'com.google.devtools.ksp' version '1.8.0-1.0.9' apply false
id 'org.ajoberstar.grgit' version '4.1.1' // 4.1.1 is the last jvm8 supporting version ,unused, available for addon.gradle
id 'com.github.johnrengelman.shadow' version '7.1.2' apply false
id 'com.palantir.git-version' version '0.13.0' apply false // 0.13.0 is the last jvm8 supporting version
id 'de.undercouch.download' version '5.3.0'
id 'org.ajoberstar.grgit' version '4.1.1' // 4.1.1 is the last jvm8 supporting version, unused, available for addon.gradle
id 'com.github.johnrengelman.shadow' version '8.1.1' apply false
id 'com.palantir.git-version' version '3.0.0' apply false
id 'de.undercouch.download' version '5.4.0'
id 'com.github.gmazzo.buildconfig' version '3.1.0' apply false // Unused, available for addon.gradle
id 'com.diffplug.spotless' version '6.7.2' apply false
id 'com.diffplug.spotless' version '6.13.0' apply false // 6.13.0 is the last jvm8 supporting version
id 'com.modrinth.minotaur' version '2.+' apply false
id 'com.matthewprenger.cursegradle' version '1.4.0' apply false
id 'com.gtnewhorizons.retrofuturagradle' version '1.1.5'
id 'com.gtnewhorizons.retrofuturagradle' version '1.3.14'
}
print("You might want to check out './gradlew :faq' if your build fails.\n")
boolean settingsupdated = verifySettingsGradle()
settingsupdated = verifyGitAttributes() || settingsupdated
if (settingsupdated)
throw new GradleException("Settings has been updated, please re-run task.")
if (project.file('.git/HEAD').isFile()) {
// In submodules, .git is a file pointing to the real git dir
if (project.file('.git/HEAD').isFile() || project.file('.git').isFile()) {
apply plugin: 'com.palantir.git-version'
}
@@ -126,7 +129,10 @@ propertyDefaultIfUnset("gradleTokenGroupName", "")
propertyDefaultIfUnset("enableModernJavaSyntax", false) // On by default for new projects only
propertyDefaultIfUnset("enableGenericInjection", false) // On by default for new projects only
project.extensions.add(Blowdryer, "Blowdryer", Blowdryer) // Make blowdryer available in "apply from:" scripts
// this is meant to be set using the user wide property file. by default we do nothing.
propertyDefaultIfUnset("ideaOverrideBuildType", "") // Can be nothing, "gradle" or "idea"
project.extensions.add(com.diffplug.blowdryer.Blowdryer, "Blowdryer", com.diffplug.blowdryer.Blowdryer) // Make blowdryer available in "apply from:" scripts
if (!disableSpotless) {
apply plugin: 'com.diffplug.spotless'
apply from: Blowdryer.file('spotless.gradle')
@@ -147,13 +153,21 @@ java {
} else {
languageVersion.set(projectJavaVersion)
}
vendor.set(JvmVendorSpec.ADOPTIUM)
vendor.set(JvmVendorSpec.AZUL)
}
if (!noPublishedSources) {
withSourcesJar()
}
}
tasks.withType(JavaCompile).configureEach {
options.encoding = "UTF-8"
}
tasks.withType(ScalaCompile).configureEach {
options.encoding = "UTF-8"
}
pluginManager.withPlugin('org.jetbrains.kotlin.jvm') {
// If Kotlin is enabled in the project
kotlin {
@@ -187,6 +201,14 @@ configurations {
canBeConsumed = false
canBeResolved = false
}
create("devOnlyNonPublishable") {
description = "Runtime and compiletime dependencies that are not published alongside the jar (compileOnly + runtimeOnlyNonPublishable)"
canBeConsumed = false
canBeResolved = false
}
compileOnly.extendsFrom(devOnlyNonPublishable)
runtimeOnlyNonPublishable.extendsFrom(devOnlyNonPublishable)
}
if (enableModernJavaSyntax.toBoolean()) {
@@ -200,6 +222,8 @@ if (enableModernJavaSyntax.toBoolean()) {
dependencies {
annotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.0'
// workaround for https://github.com/bsideup/jabel/issues/174
annotationProcessor 'net.java.dev.jna:jna-platform:5.13.0'
compileOnly('com.github.bsideup.jabel:jabel-javac-plugin:1.0.0') {
transitive = false // We only care about the 1 annotation class
}
@@ -216,7 +240,7 @@ if (enableModernJavaSyntax.toBoolean()) {
javaCompiler.set(javaToolchains.compilerFor {
languageVersion.set(JavaLanguageVersion.of(17))
vendor.set(JvmVendorSpec.ADOPTIUM)
vendor.set(JvmVendorSpec.AZUL)
})
}
}
@@ -248,12 +272,14 @@ if (apiPackage) {
}
if (accessTransformersFile) {
String targetFile = "src/main/resources/META-INF/" + accessTransformersFile
if (!getFile(targetFile).exists()) {
throw new GradleException("Could not resolve \"accessTransformersFile\"! Could not find " + targetFile)
for (atFile in accessTransformersFile.split(",")) {
String targetFile = "src/main/resources/META-INF/" + atFile.trim()
if (!getFile(targetFile).exists()) {
throw new GradleException("Could not resolve \"accessTransformersFile\"! Could not find " + targetFile)
}
tasks.deobfuscateMergedJarToSrg.accessTransformerFiles.from(targetFile)
tasks.srgifyBinpatchedJar.accessTransformerFiles.from(targetFile)
}
tasks.deobfuscateMergedJarToSrg.accessTransformerFiles.from(targetFile)
tasks.srgifyBinpatchedJar.accessTransformerFiles.from(targetFile)
} else {
boolean atsFound = false
for (File at : sourceSets.getByName("main").resources.files) {
@@ -381,12 +407,14 @@ minecraft {
injectMissingGenerics.set(true)
}
username = developmentEnvironmentUserName.toString()
lwjgl3Version = "3.3.2"
// Enable assertions in the current mod
extraRunJvmArguments.add("-ea:${modGroup}")
if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) {
extraTweakClasses.add("org.spongepowered.asm.launch.MixinTweaker")
if (usesMixinDebug.toBoolean()) {
extraRunJvmArguments.addAll([
"-Dmixin.debug.countInjections=true",
@@ -415,6 +443,16 @@ configurations.configureEach {
}
}
}
def obfuscationAttr = it.attributes.getAttribute(ObfuscationAttribute.OBFUSCATION_ATTRIBUTE)
if (obfuscationAttr != null && obfuscationAttr.name == ObfuscationAttribute.SRG) {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
// Remap CoFH core cursemaven dev jar to the obfuscated version for runObfClient/Server
if (details.requested.group == 'curse.maven' && details.requested.name.endsWith('-69162') && details.requested.version == '2388751') {
details.useVersion '2388750'
details.because 'Pick obfuscated jar'
}
}
}
}
// Ensure tests have access to minecraft classes
@@ -444,8 +482,9 @@ repositories.configureEach { repo ->
apply from: 'repositories.gradle'
configurations {
runtimeClasspath.extendsFrom(runtimeOnlyNonPublishable)
testRuntimeClasspath.extendsFrom(runtimeOnlyNonPublishable)
for (config in [compileClasspath, runtimeClasspath, testCompileClasspath, testRuntimeClasspath]) {
config.extendsFrom(runtimeOnlyNonPublishable)
if (usesShadowedDependencies.toBoolean()) {
config.extendsFrom(shadowImplementation)
// TODO: remove Compile after all uses are refactored to Implementation
@@ -490,12 +529,11 @@ repositories {
url = "http://jenkins.usrv.eu:8081/nexus/content/groups/public/"
allowInsecureProtocol = true
}
if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) {
if (usesMixinDebug.toBoolean()) {
maven {
name = "Fabric Maven"
url = "https://maven.fabricmc.net/"
}
maven {
name 'sonatype'
url 'https://oss.sonatype.org/content/repositories/snapshots/'
content {
includeGroup "org.lwjgl"
}
}
if (includeWellKnownRepositories.toBoolean()) {
@@ -529,29 +567,50 @@ repositories {
}
}
def mixinProviderGroup = "io.github.legacymoddingmc"
def mixinProviderModule = "unimixins"
def mixinProviderVersion = "0.1.7.1"
def mixinProviderSpecNoClassifer = "${mixinProviderGroup}:${mixinProviderModule}:${mixinProviderVersion}"
def mixinProviderSpec = "${mixinProviderSpecNoClassifer}:dev"
ext.mixinProviderSpec = mixinProviderSpec
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('com.gtnewhorizon:gtnhmixins:2.1.12:processor')
annotationProcessor(mixinProviderSpec)
if (usesMixinDebug.toBoolean()) {
runtimeOnlyNonPublishable('org.jetbrains:intellij-fernflower:1.2.1.16')
}
}
if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) {
implementation('com.gtnewhorizon:gtnhmixins:2.1.12')
if (usesMixins.toBoolean()) {
implementation(mixinProviderSpec)
} else if (forceEnableMixins.toBoolean()) {
runtimeOnlyNonPublishable(mixinProviderSpec)
}
}
pluginManager.withPlugin('org.jetbrains.kotlin.kapt') {
if (usesMixins.toBoolean()) {
dependencies {
kapt('com.gtnewhorizon:gtnhmixins:2.1.12:processor')
kapt(mixinProviderSpec)
}
}
}
// Replace old mixin mods with unimixins
// https://docs.gradle.org/8.0.2/userguide/resolution_rules.html#sec:substitution_with_classifier
configurations.all {
resolutionStrategy.dependencySubstitution {
substitute module('com.gtnewhorizon:gtnhmixins') using module(mixinProviderSpecNoClassifer) withClassifier("dev") because("Unimixins replaces other mixin mods")
substitute module('com.github.GTNewHorizons:Mixingasm') using module(mixinProviderSpecNoClassifer) withClassifier("dev") because("Unimixins replaces other mixin mods")
substitute module('com.github.GTNewHorizons:SpongePoweredMixin') using module(mixinProviderSpecNoClassifer) withClassifier("dev") because("Unimixins replaces other mixin mods")
substitute module('com.github.GTNewHorizons:SpongeMixins') using module(mixinProviderSpecNoClassifer) withClassifier("dev") because("Unimixins replaces other mixin mods")
substitute module('io.github.legacymoddingmc:unimixins') using module(mixinProviderSpecNoClassifer) withClassifier("dev") because("Our previous unimixins upload was missing the dev classifier")
}
}
apply from: 'dependencies.gradle'
def mixingConfigRefMap = 'mixins.' + modId + '.refmap.json'
@@ -656,17 +715,22 @@ ext.java17Toolchain = (JavaToolchainSpec spec) -> {
spec.vendor.set(JvmVendorSpec.matching("jetbrains"))
}
ext.java17DependenciesCfg = configurations.create("java17Dependencies")
ext.java17PatchDependenciesCfg = configurations.create("java17PatchDependencies")
ext.java17DependenciesCfg = configurations.create("java17Dependencies") {
extendsFrom(configurations.getByName("runtimeClasspath")) // Ensure consistent transitive dependency resolution
canBeConsumed = false
}
ext.java17PatchDependenciesCfg = configurations.create("java17PatchDependencies") {
canBeConsumed = false
}
dependencies {
def lwjgl3ifyVersion = '1.1.21'
def lwjgl3ifyVersion = '1.3.5'
def asmVersion = '9.4'
if (modId != 'lwjgl3ify') {
java17Dependencies("com.github.GTNewHorizons:lwjgl3ify:${lwjgl3ifyVersion}")
}
if (modId != 'hodgepodge') {
java17Dependencies('com.github.GTNewHorizons:Hodgepodge:2.0.31')
java17Dependencies('com.github.GTNewHorizons:Hodgepodge:2.2.13')
}
java17PatchDependencies('net.minecraft:launchwrapper:1.15') {transitive = false}
@@ -677,14 +741,14 @@ dependencies {
java17PatchDependencies("org.ow2.asm:asm-util:${asmVersion}")
java17PatchDependencies('org.ow2.asm:asm-deprecated:7.1')
java17PatchDependencies("org.apache.commons:commons-lang3:3.12.0")
java17PatchDependencies("com.github.GTNewHorizons:lwjgl3ify:${lwjgl3ifyVersion}:forgePatches")
java17PatchDependencies("com.github.GTNewHorizons:lwjgl3ify:${lwjgl3ifyVersion}:forgePatches") {transitive = false}
}
ext.java17JvmArgs = [
// Java 9+ support
"--illegal-access=warn",
"-Dfile.encoding=UTF-8",
"-Djava.security.manager=allow",
"-Dfile.encoding=UTF-8",
"--add-opens", "java.base/jdk.internal.loader=ALL-UNNAMED",
"--add-opens", "java.base/java.net=ALL-UNNAMED",
"--add-opens", "java.base/java.nio=ALL-UNNAMED",
@@ -695,6 +759,7 @@ ext.java17JvmArgs = [
"--add-opens", "java.base/java.util=ALL-UNNAMED",
"--add-opens", "java.base/jdk.internal.reflect=ALL-UNNAMED",
"--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED",
"--add-opens", "jdk.naming.dns/com.sun.jndi.dns=ALL-UNNAMED,java.naming",
"--add-opens", "java.desktop/sun.awt.image=ALL-UNNAMED",
"--add-modules", "jdk.dynalink",
"--add-opens", "jdk.dynalink/jdk.dynalink.beans=ALL-UNNAMED",
@@ -739,8 +804,8 @@ public abstract class RunHotswappableMinecraftTask extends RunMinecraftTask {
public boolean setEnableHotswap(boolean enable) { enableHotswap = enable }
@Inject
public RunHotswappableMinecraftTask(Side side, String superTask) {
super(side)
public RunHotswappableMinecraftTask(Distribution side, String superTask, org.gradle.api.invocation.Gradle gradle) {
super(side, gradle)
this.lwjglVersion = 3
this.javaLauncher = project.javaToolchains.launcherFor(project.java17Toolchain)
@@ -748,7 +813,7 @@ public abstract class RunHotswappableMinecraftTask extends RunMinecraftTask {
this.extraJvmArgs.addAll(project.provider(() -> enableHotswap ? project.hotswapJvmArgs : []))
this.classpath(project.java17PatchDependenciesCfg)
if (side == Side.CLIENT) {
if (side == Distribution.CLIENT) {
this.classpath(project.minecraftTasks.lwjgl3Configuration)
}
// Use a raw provider instead of map to not create a dependency on the task
@@ -757,23 +822,33 @@ public abstract class RunHotswappableMinecraftTask extends RunMinecraftTask {
!file.path.contains("2.9.4-nightly-20150209") // Remove lwjgl2
}
this.classpath(project.java17DependenciesCfg)
}
if (!(project.usesMixins.toBoolean() || project.forceEnableMixins.toBoolean())) {
this.extraArgs.addAll("--tweakClass", "org.spongepowered.asm.launch.MixinTweaker")
public void setup(Project project) {
super.setup(project)
if (project.usesMixins.toBoolean()) {
this.extraJvmArgs.addAll(project.provider(() -> {
def mixinCfg = project.configurations.detachedConfiguration(project.dependencies.create(project.mixinProviderSpec))
mixinCfg.canBeConsumed = false
mixinCfg.transitive = false
enableHotswap ? ["-javaagent:" + mixinCfg.singleFile.absolutePath] : []
}))
}
}
}
def runClient17Task = tasks.register("runClient17", RunHotswappableMinecraftTask, Side.CLIENT, "runClient")
def runClient17Task = tasks.register("runClient17", RunHotswappableMinecraftTask, Distribution.CLIENT, "runClient")
runClient17Task.configure {
setup(project)
group = "Modded Minecraft"
description = "Runs the modded client using Java 17, lwjgl3ify and Hodgepodge"
dependsOn(setupHotswapAgentTask, mcpTasks.launcherSources.classesTaskName, minecraftTasks.taskDownloadVanillaAssets, mcpTasks.taskPackagePatchedMc, 'jar')
mainClass = "GradleStart"
username = minecraft.username
userUUID = minecraft.userUUID
}
def runServer17Task = tasks.register("runServer17", RunHotswappableMinecraftTask, Side.SERVER, "runServer")
def runServer17Task = tasks.register("runServer17", RunHotswappableMinecraftTask, Distribution.DEDICATED_SERVER, "runServer")
runServer17Task.configure {
setup(project)
group = "Modded Minecraft"
@@ -814,11 +889,6 @@ tasks.named("jar", Jar).configure {
}
if (usesShadowedDependencies.toBoolean()) {
tasks.register('relocateShadowJar', ConfigureShadowRelocation) {
target = tasks.shadowJar
prefix = modGroup + ".shadow"
enabled = minimizeShadowedDependencies.toBoolean()
}
tasks.named("shadowJar", ShadowJar).configure {
manifest {
attributes(getManifestAttributes())
@@ -833,8 +903,9 @@ if (usesShadowedDependencies.toBoolean()) {
project.configurations.shadeCompile
]
archiveClassifier.set('dev')
if (minimizeShadowedDependencies.toBoolean()) {
dependsOn(relocateShadowJar)
if (relocateShadowedDependencies.toBoolean()) {
relocationPrefix = modGroup + ".shadow"
enableRelocation = true
}
}
configurations.runtimeElements.outgoing.artifacts.clear()
@@ -894,6 +965,19 @@ idea {
}
project {
settings {
if (ideaOverrideBuildType != "") {
delegateActions {
if ("gradle".equalsIgnoreCase(ideaOverrideBuildType)) {
delegateBuildRunToGradle = true
testRunner = org.jetbrains.gradle.ext.ActionDelegationConfig.TestRunner.GRADLE
} else if ("idea".equalsIgnoreCase(ideaOverrideBuildType)) {
delegateBuildRunToGradle = false
testRunner = org.jetbrains.gradle.ext.ActionDelegationConfig.TestRunner.PLATFORM
} else {
throw GradleScriptException('Accepted value for ideaOverrideBuildType is one of gradle or idea.')
}
}
}
runConfigurations {
"1. Run Client"(Gradle) {
taskNames = ["runClient"]
@@ -932,7 +1016,7 @@ idea {
}
"Run Client (IJ Native)"(Application) {
mainClass = "GradleStart"
moduleName = project.name + ".main"
moduleName = project.name + ".ideVirtualMain"
afterEvaluate {
workingDirectory = tasks.runClient.workingDir.absolutePath
programParameters = tasks.runClient.calculateArgs(project).collect { '"' + it + '"' }.join(' ')
@@ -943,7 +1027,7 @@ idea {
}
"Run Server (IJ Native)"(Application) {
mainClass = "GradleStartServer"
moduleName = project.name + ".main"
moduleName = project.name + ".ideVirtualMain"
afterEvaluate {
workingDirectory = tasks.runServer.workingDir.absolutePath
programParameters = tasks.runServer.calculateArgs(project).collect { '"' + it + '"' }.join(' ')
@@ -955,11 +1039,57 @@ idea {
}
compiler.javac {
afterEvaluate {
javacAdditionalOptions = "-encoding utf8"
moduleJavacAdditionalOptions = [
(project.name + ".main"): tasks.compileJava.options.compilerArgs.collect { '"' + it + '"' }.join(' ')
]
}
}
withIDEADir { File ideaDir ->
if (!ideaDir.path.contains(".idea")) {
// If an .ipr file exists, the project root directory is passed here instead of the .idea subdirectory
ideaDir = new File(ideaDir, ".idea")
}
if (ideaDir.isDirectory()) {
def miscFile = new File(ideaDir, "misc.xml")
if (miscFile.isFile()) {
boolean dirty = false
def miscTransformer = new XmlTransformer()
miscTransformer.addAction { root ->
Node rootNode = root.asNode()
def rootManager = rootNode
.component.find { it.@name == 'ProjectRootManager' }
if (!rootManager) {
rootManager = rootNode.appendNode('component', ['name': 'ProjectRootManager', 'version': '2'])
dirty = true
}
def output = rootManager.output
if (!output) {
output = rootManager.appendNode('output')
dirty = true
}
if (!output.@url) {
// Only modify the output url if it doesn't yet have one, or if the existing one is blank somehow.
// This is a sensible default for most setups
output.@url = 'file://$PROJECT_DIR$/build/ideaBuild'
dirty = true
}
}
def result = miscTransformer.transform(miscFile.text)
if (dirty) {
miscFile.write(result)
}
} else {
miscFile.text = """<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2">
<output url="file://\$PROJECT_DIR\$/out" />
</component>
</project>
"""
}
}
}
}
}
}
@@ -1029,7 +1159,7 @@ if (modrinthProjectId.size() != 0 && System.getenv("MODRINTH_TOKEN") != null) {
}
}
if (usesMixins.toBoolean()) {
addModrinthDep("required", "project", "gtnhmixins")
addModrinthDep("required", "project", "unimixins")
}
tasks.modrinth.dependsOn(build)
tasks.publish.dependsOn(tasks.modrinth)
@@ -1073,7 +1203,7 @@ if (curseForgeProjectId.size() != 0 && System.getenv("CURSEFORGE_TOKEN") != null
}
}
if (usesMixins.toBoolean()) {
addCurseForgeRelation("requiredDependency", "gtnhmixins")
addCurseForgeRelation("requiredDependency", "unimixins")
}
tasks.curseforge.dependsOn(build)
tasks.publish.dependsOn(tasks.curseforge)
@@ -1107,10 +1237,21 @@ def addCurseForgeRelation(String type, String name) {
}
// Updating
def buildscriptGradleVersion = "8.1.1"
tasks.named('wrapper', Wrapper).configure {
gradleVersion = buildscriptGradleVersion
}
tasks.register('updateBuildScript') {
group = 'GTNH Buildscript'
description = 'Updates the build script to the latest version'
if (gradle.gradleVersion != buildscriptGradleVersion && !Boolean.getBoolean('DISABLE_BUILDSCRIPT_GRADLE_UPDATE')) {
dependsOn('wrapper')
}
doLast {
if (performBuildScriptUpdate()) return
@@ -1123,6 +1264,26 @@ if (!project.getGradle().startParameter.isOffline() && !Boolean.getBoolean('DISA
performBuildScriptUpdate()
} else {
out.style(Style.SuccessHeader).println("Build script update available! Run 'gradle updateBuildScript'")
if (gradle.gradleVersion != buildscriptGradleVersion) {
out.style(Style.SuccessHeader).println("updateBuildScript can update gradle from ${gradle.gradleVersion} to ${buildscriptGradleVersion}\n")
}
}
}
// If you want to add more cases to this task, implement them as arguments if total amount to print gets too large
tasks.register('faq') {
group = 'GTNH Buildscript'
description = 'Prints frequently asked questions about building a project'
doLast {
print("If your build fails to fetch dependencies, run './gradlew updateDependencies'. " +
"Or you can manually check if the versions are still on the distributing sites - " +
"the links can be found in repositories.gradle and build.gradle:repositories, " +
"but not build.gradle:buildscript.repositories - those ones are for gradle plugin metadata.\n\n" +
"If your build fails to recognize the syntax of new Java versions, enable Jabel in your " +
"gradle.properties. See how it's done in GTNH ExampleMod/gradle.properties. " +
"However, keep in mind that Jabel enables only syntax features, but not APIs that were introduced in " +
"Java 9 or later.")
}
}
@@ -1263,7 +1424,7 @@ static int replaceParams(File file, Map<String, String> params) {
return 0
}
// Dependency Deobfuscation
// Dependency Deobfuscation (Deprecated, use the new RFG API documented in dependencies.gradle)
def deobf(String sourceURL) {
try {
@@ -1305,11 +1466,7 @@ def deobfMaven(String repoURL, String mavenDep) {
}
def deobfCurse(String curseDep) {
try {
return deobfMaven("https://www.cursemaven.com/", "curse.maven:$curseDep")
} catch (Exception ignored) {
out.style(Style.Failure).println("Failed to get $curseDep from cursemaven.")
}
return dependencies.rfg.deobf("curse.maven:$curseDep")
}
// The method above is to be preferred. Use this method if the filename is not at the end of the URL.
@@ -1317,34 +1474,7 @@ def deobf(String sourceURL, String rawFileName) {
String bon2Version = "2.5.1"
String fileName = URLDecoder.decode(rawFileName, "UTF-8")
String cacheDir = "$project.gradle.gradleUserHomeDir/caches"
String bon2Dir = "$cacheDir/forge_gradle/deobf"
String bon2File = "$bon2Dir/BON2-${bon2Version}.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)
}
String mappingsVer
String remoteMappings = project.hasProperty('remoteMappings') ? project.remoteMappings : 'https://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/'
if (remoteMappings) {
String id = "${forgeVersion.split("\\.")[3]}-$minecraftVersion"
String mappingsZIP = "$cacheDir/forge_gradle/maven_downloader/de/oceanlabs/mcp/mcp_snapshot_nodoc/$id/mcp_snapshot_nodoc-${id}.zip"
zipMappings(mappingsZIP, remoteMappings, bon2Dir)
mappingsVer = "snapshot_$id"
} else {
mappingsVer = "${channel}_$mappingsVersion"
}
download.run {
src "http://jenkins.usrv.eu:8081/nexus/content/repositories/releases/com/github/parker8283/BON2/$bon2Version-CUSTOM/BON2-$bon2Version-CUSTOM-all.jar"
dest bon2File
quiet true
overwrite false
}
download.run {
src sourceURL
@@ -1352,50 +1482,8 @@ def deobf(String sourceURL, String rawFileName) {
quiet true
overwrite false
}
exec {
commandLine 'java', '-jar', bon2File, '--inputJar', obfFile, '--outputJar', deobfFile, '--mcVer', minecraftVersion, '--mappingsVer', mappingsVer, '--notch'
workingDir bon2Dir
standardOutput = new FileOutputStream("${deobfFile}.log")
}
return files(deobfFile)
return dependencies.rfg.deobf(files(obfFile))
}
def zipMappings(String zipPath, String url, String bon2Dir) {
File zipFile = new File(zipPath)
if (zipFile.exists()) {
return
}
String fieldsCache = "$bon2Dir/data/fields.csv"
String methodsCache = "$bon2Dir/data/methods.csv"
download.run {
src "${url}fields.csv"
dest fieldsCache
quiet true
}
download.run {
src "${url}methods.csv"
dest methodsCache
quiet true
}
zipFile.getParentFile().mkdirs()
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))
zos.putNextEntry(new ZipEntry("fields.csv"))
Files.copy(Paths.get(fieldsCache), zos)
zos.closeEntry()
zos.putNextEntry(new ZipEntry("methods.csv"))
Files.copy(Paths.get(methodsCache), zos)
zos.closeEntry()
zos.close()
}
// Helper methods
def checkPropertyExists(String propertyName) {
+3 -3
View File
@@ -1,7 +1,7 @@
// Add your dependencies here
dependencies {
api('com.github.GTNewHorizons:CodeChickenLib:1.1.6:dev')
api('com.github.GTNewHorizons:CodeChickenCore:1.1.10:dev')
shadowImplementation('org.apache.commons:commons-csv:1.9.0')
api('com.github.GTNewHorizons:CodeChickenLib:1.1.8:dev')
api('com.github.GTNewHorizons:CodeChickenCore:1.1.11:dev')
shadowImplementation('org.apache.commons:commons-csv:1.10.0')
}
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-11
View File
@@ -1,15 +1,4 @@
// Add any additional repositiroes for your dependencies here
repositories {
mavenCentral()
maven {
name 'GTNH Maven'
url 'http://jenkins.usrv.eu:8081/nexus/content/groups/public/'
}
maven {
url 'https://cursemaven.com'
content {
includeGroup 'curse.maven'
}
}
}
+3
View File
@@ -26,3 +26,6 @@ blowdryerSetup {
github('GTNewHorizons/ExampleMod1.7.10', 'tag', '0.2.0')
//devLocal '.' // Use this when testing config updates locally
}
rootProject.name = "NotEnoughItems"
@@ -24,6 +24,11 @@ import net.minecraft.nbt.NBTTagCompound;
import org.apache.commons.io.IOUtils;
import org.lwjgl.opengl.GL11;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSyntaxException;
import codechicken.core.CommonUtils;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.ItemPanel.ItemPanelSlot;
@@ -33,11 +38,6 @@ import codechicken.nei.recipe.StackInfo;
import codechicken.nei.util.NBTJson;
import codechicken.nei.util.ReadableNumberConverter;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSyntaxException;
public class BookmarkPanel extends PanelWidget {
protected File bookmarkFile;
@@ -84,6 +84,10 @@ public class BookmarkPanel extends PanelWidget {
protected boolean[] todoSpaces;
protected int todoItemsCount = 0;
public BookmarkGrid() {
this.setShowRecipeTooltips(true);
}
public void setViewMode(BookmarkViewMode mode) {
if (viewMode == mode) {
return;
@@ -464,7 +468,7 @@ public class BookmarkPanel extends PanelWidget {
final ItemStack normalizedA = StackInfo.loadFromNBT(nbTagA);
BookmarkRecipeId recipeId = null;
if (handlerName != "" && ingredients != null && !ingredients.isEmpty()) {
if (handlerName != "" && ingredients != null) {
recipeId = new BookmarkRecipeId(handlerName, ingredients);
}
@@ -474,7 +478,7 @@ public class BookmarkPanel extends PanelWidget {
BGrid.removeRecipe(idx, saveIngredients);
} else {
if (saveIngredients && handlerName != "" && ingredients != null && !ingredients.isEmpty()) {
if (saveIngredients && handlerName != "" && ingredients != null) {
final Map<NBTTagCompound, Integer> unique = new HashMap<>();
final ArrayList<NBTTagCompound> sorted = new ArrayList<>();
@@ -9,9 +9,6 @@ import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -37,6 +34,8 @@ import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.apache.commons.io.IOUtils;
import com.google.common.collect.Lists;
import codechicken.core.ClientUtils;
import codechicken.core.GuiModListScroll;
import codechicken.lib.packet.PacketCustom;
@@ -44,25 +43,14 @@ 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;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.TickEvent;
import cpw.mods.fml.common.gameevent.TickEvent.Phase;
public class ClientHandler {
private static String[] defaultSerialHandlers = {
"WayofTime.alchemicalWizardry.client.nei.NEIAlchemyRecipeHandler" };
private static String[] defaultHeightHackHandlerRegex = { "buildcraft.compat.nei.*",
"cofh.thermalexpansion.plugins.nei.handlers.*", "crazypants.enderio.nei.*",
"forestry.factory.recipes.nei.*", "ic2.neiIntegration.core.recipehandler.*", "mariculture.plugins.nei.*",
"redgear.brewcraft.plugins.nei.*", "tconstruct.plugins.nei.*",
"WayofTime.alchemicalWizardry.client.nei.*", };
private static String[] defaultHandlerOrdering = {
"# Each line in this file should either be a comment (starts with '#') or an ordering.",
"# Ordering lines are <handler ID>,<ordering number>.",
@@ -166,16 +154,19 @@ public class ClientHandler {
if (!file.exists()) {
try (FileWriter writer = new FileWriter(file)) {
NEIClientConfig.logger.info("Creating default serial handlers list {}", file);
Collection<String> toSave = Loader.isModLoaded("dreamcraft") ? Collections.singletonList("")
: Arrays.asList(defaultSerialHandlers);
IOUtils.writeLines(toSave, "\n", writer);
URL defaultSerialHandlersResource = ClientHandler.class
.getResource("/assets/nei/cfg/serialhandlers.cfg");
if (defaultSerialHandlersResource != null) {
IOUtils.copy(defaultSerialHandlersResource.openStream(), writer);
}
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to save default serial handlers list to file {}", file, e);
}
}
try (FileReader reader = new FileReader(file)) {
NEIClientConfig.logger.info("Loading serial handlers from file {}", file);
NEIClientConfig.serialHandlers = new HashSet<>(IOUtils.readLines(reader));
NEIClientConfig.serialHandlers = IOUtils.readLines(reader).stream().filter((line) -> !line.startsWith("#"))
.collect(Collectors.toCollection(HashSet::new));
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to load serial handlers from file {}", file, e);
}
@@ -186,8 +177,11 @@ public class ClientHandler {
if (!file.exists()) {
try (FileWriter writer = new FileWriter(file)) {
NEIClientConfig.logger.info("Creating default height hack handlers list {}", file);
Collection<String> toSave = Arrays.asList(defaultHeightHackHandlerRegex);
IOUtils.writeLines(toSave, "\n", writer);
URL defaultHeightHackHandlersResource = ClientHandler.class
.getResource("/assets/nei/cfg/heighthackhandlers.cfg");
if (defaultHeightHackHandlersResource != null) {
IOUtils.copy(defaultHeightHackHandlersResource.openStream(), writer);
}
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to save default height hack handlers list to file {}", file, e);
}
@@ -195,7 +189,8 @@ public class ClientHandler {
try (FileReader reader = new FileReader(file)) {
NEIClientConfig.logger.info("Loading height hack handlers from file {}", file);
NEIClientConfig.heightHackHandlerRegex = IOUtils.readLines(reader).stream().map(Pattern::compile)
NEIClientConfig.heightHackHandlerRegex = IOUtils.readLines(reader).stream()
.filter((line) -> !line.startsWith("#")).map(Pattern::compile)
.collect(Collectors.toCollection(HashSet::new));
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to load height hack handlers from file {}", file, e);
@@ -276,7 +271,11 @@ public class ClientHandler {
if (!NEIClientConfig.isEnabled()) return;
KeyManager.tickKeyStates();
/*
* NEI plugins are loaded in a separate thread. Make sure loading them has finished otherwise a CME might
* occur in KeyManager if a plugin calls API.addKeyBind() during initialization.
*/
if (NEIClientConfig.isLoaded()) KeyManager.tickKeyStates();
NEIController.updateUnlimitedItems(mc.thePlayer.inventory);
if (mc.currentScreen == null) NEIController.processCreativeCycling(mc.thePlayer.inventory);
+3 -3
View File
@@ -13,15 +13,15 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import codechicken.nei.ThreadOperationTimer.TimeoutException;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
import codechicken.nei.api.ItemInfo;
import codechicken.nei.guihook.GuiContainerManager;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
public class ItemList {
/**
@@ -22,8 +22,8 @@ import net.minecraftforge.client.MinecraftForgeClient;
public class ItemMobSpawner extends ItemBlock {
private static Map<Integer, EntityLiving> entityHashMap;
private static Map<Integer, String> IDtoNameMap;
private static final Map<Integer, EntityLiving> entityHashMap = new HashMap<>();
private static final Map<Integer, String> IDtoNameMap = new HashMap<>();
public static int idPig;
private static boolean loaded;
@@ -32,9 +32,6 @@ public class ItemMobSpawner extends ItemBlock {
hasSubtypes = true;
MinecraftForgeClient.registerItemRenderer(this, new SpawnerRenderer());
entityHashMap = new HashMap<>();
IDtoNameMap = new HashMap<>();
}
/**
+20 -9
View File
@@ -166,19 +166,30 @@ public class ItemPanel extends PanelWidget {
}
protected int resizeFooter(GuiContainer gui) {
if (!NEIClientConfig.showItemQuantityWidget()) return 0;
final int BUTTON_SIZE = 16;
if (!NEIClientConfig.showItemQuantityWidget() && NEIClientConfig.isSearchWidgetCentered()) return 0;
final int BUTTON_SIZE = 20;
more.w = less.w = BUTTON_SIZE;
more.h = less.h = quantity.h = BUTTON_SIZE;
quantity.h = BUTTON_SIZE;
less.x = x;
more.x = x + w - BUTTON_SIZE;
more.y = less.y = quantity.y = y + h - BUTTON_SIZE;
if (NEIClientConfig.isSearchWidgetCentered()) {
more.h = less.h = BUTTON_SIZE;
more.x = x + w - BUTTON_SIZE;
more.y = less.y = quantity.y = y + h - BUTTON_SIZE;
less.x = x;
quantity.x = x + BUTTON_SIZE + 2;
quantity.w = more.x - quantity.x - 2;
} else {
quantity.x = (int) (x + (w * 0.7)) + 3;
quantity.y = y + h - BUTTON_SIZE;
quantity.w = (int) ((w * 0.3) - BUTTON_SIZE - 1);
quantity.x = x + BUTTON_SIZE + 2;
quantity.w = more.x - quantity.x - 2;
more.h = less.h = BUTTON_SIZE / 2;
more.y = y + h - (more.h * 2);
less.x = more.x = quantity.x + quantity.w;
less.y = more.y + more.h;
}
return BUTTON_SIZE + 2;
}
@@ -1,19 +1,24 @@
package codechicken.nei;
import static codechicken.lib.gui.GuiDraw.drawRect;
import static codechicken.lib.gui.GuiDraw.getMousePosition;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
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.inventory.Slot;
import net.minecraft.item.ItemStack;
import org.lwjgl.opengl.GL11;
@@ -22,6 +27,9 @@ import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.ItemPanel.ItemPanelSlot;
import codechicken.nei.api.GuiInfo;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.recipe.BookmarkRecipeId;
import codechicken.nei.recipe.GuiCraftingRecipe;
import codechicken.nei.recipe.GuiRecipe;
import codechicken.nei.recipe.StackInfo;
public class ItemsGrid {
@@ -43,6 +51,7 @@ public class ItemsGrid {
protected int rows;
protected int columns;
protected boolean showRecipeTooltips = false;
protected boolean[] invalidSlotMap;
@@ -150,6 +159,10 @@ public class ItemsGrid {
refreshBuffer = true;
}
public void setShowRecipeTooltips(boolean show) {
this.showRecipeTooltips = show;
}
public void refresh(GuiContainer gui) {
updateGuiOverlapSlots(gui);
shiftPage(0);
@@ -244,6 +257,120 @@ public class ItemsGrid {
}
}
private int recipeTooltipSlotIdx = -1;
private int recipeTooltipLines = 2;
private Runnable recipeTooltipUpdater = null;
private GuiRecipe<?> recipeTooltipGui = null;
public void update() {
if (recipeTooltipUpdater != null) {
recipeTooltipUpdater.run();
recipeTooltipUpdater = null;
}
if (recipeTooltipGui != null) {
recipeTooltipGui.updateAsTooltip();
}
}
private static <T> List<T> listOrEmptyList(final List<T> listOrNull) {
return listOrNull == null ? Collections.emptyList() : listOrNull;
}
private void drawRecipeTooltip(int mousex, int mousey, List<String> itemTooltip) {
if (!NEIClientConfig.isLoaded()) {
return;
}
final Minecraft mc = Minecraft.getMinecraft();
ItemPanelSlot focused = getSlotMouseOver(mousex, mousey);
if (focused == null) {
recipeTooltipSlotIdx = -1;
recipeTooltipGui = null;
return;
}
final List<Integer> mask = getMask();
int slotIdx = -1;
for (int i = 0; i < mask.size(); i++) {
if (mask.get(i) == null) {
continue;
}
if (focused.slotIndex != mask.get(i)) {
continue;
}
slotIdx = i;
break;
}
if (slotIdx == -1) {
recipeTooltipSlotIdx = -1;
recipeTooltipGui = null;
return;
}
final Point mouseover = getMousePosition();
final ItemPanelSlot panelSlot = ItemPanels.bookmarkPanel.getSlotMouseOver(mouseover.x, mouseover.y);
final BookmarkRecipeId recipeId;
if (panelSlot != null) {
recipeId = ItemPanels.bookmarkPanel.getBookmarkRecipeId(panelSlot.slotIndex);
} else {
recipeId = ItemPanels.bookmarkPanel.getBookmarkRecipeId(focused.item);
}
if (recipeId == null) {
return;
}
if (slotIdx != recipeTooltipSlotIdx) {
recipeTooltipSlotIdx = slotIdx;
recipeTooltipGui = null;
recipeTooltipUpdater = () -> {
recipeTooltipGui = GuiCraftingRecipe.createRecipeGui("item", false, false, false, focused.item);
if (recipeTooltipGui != null) {
recipeTooltipGui.limitToOneRecipe();
recipeTooltipGui.initGui(true);
recipeTooltipGui.guiTop = 0;
recipeTooltipGui.guiLeft = 0;
}
recipeTooltipLines = Math.max(1, itemTooltip.size());
};
}
if (recipeTooltipGui == null) {
return;
}
GL11.glPushMatrix();
final float tooltipYOffset;
if (mousey - marginTop > height / 2) {
tooltipYOffset = mousey - recipeTooltipGui.getHeightAsWidget() + 8;
} else {
tooltipYOffset = mousey + ((recipeTooltipLines < 2) ? 1 : 3 + ((recipeTooltipLines - 1) * 10));
}
GL11.glTranslatef(mousex, tooltipYOffset, 500);
final GuiContainer gui;
if (mc.currentScreen instanceof GuiRecipe) {
gui = ((GuiRecipe<?>) mc.currentScreen).firstGui;
} else if (mc.currentScreen instanceof GuiContainer) {
gui = (GuiContainer) mc.currentScreen;
} else {
gui = null;
}
recipeTooltipGui.drawGuiContainerBackgroundLayer(0.0f, -100, -100);
if (recipeTooltipGui.slotcontainer != null) {
@SuppressWarnings("unchecked")
List<Slot> slots = (List<Slot>) recipeTooltipGui.slotcontainer.inventorySlots;
for (Slot slot : slots) {
if (slot != null && slot.getStack() != null) {
GuiContainerManager.drawItem(slot.xDisplayPosition, slot.yDisplayPosition, slot.getStack());
}
}
}
recipeTooltipGui.drawGuiContainerForegroundLayer(-100, -100);
for (GuiButton btn : recipeTooltipGui.getOverlayButtons()) {
btn.drawButton(mc, -100, -100);
}
GL11.glPopMatrix();
}
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
@@ -329,6 +456,16 @@ public class ItemsGrid {
}
}
public void postDrawTooltips(int mousex, int mousey, List<String> tooltip) {
if (NEIClientConfig.showRecipeTooltips() && showRecipeTooltips) {
try {
drawRecipeTooltip(mousex, mousey, tooltip);
} catch (Exception e) {
NEIClientConfig.logger.warn("Cannot draw recipe tooltip", e);
}
}
}
public void setVisible() {
if (getItems().isEmpty() && getMessageOnEmpty() != null) {
LayoutManager.addWidget(messageLabel);
@@ -280,6 +280,13 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
}
}
@Override
public void postRenderTooltips(GuiContainer gui, int mousex, int mousey, List<String> tooltip) {
if (!isHidden() && isEnabled()) {
for (Widget widget : drawWidgets) widget.postDrawTooltips(mousex, mousey, tooltip);
}
}
@Override
public List<String> handleTooltip(GuiContainer gui, int mousex, int mousey, List<String> currenttip) {
if (!isHidden() && isEnabled() && GuiContainerManager.shouldShowTooltip(gui)) {
@@ -359,11 +366,18 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
this.icons[2] = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 64, 0, 16, 16).build();
}
private boolean getIsAccessibleControlEventKey() {
if (Minecraft.isRunningOnMac) {
return Keyboard.getEventKey() == Keyboard.KEY_LMETA || Keyboard.getEventKey() == Keyboard.KEY_RMETA;
}
return Keyboard.getEventKey() == Keyboard.KEY_LCONTROL
|| Keyboard.getEventKey() == Keyboard.KEY_RCONTROL;
}
@Override
public boolean onButtonPress(boolean rightclick) {
if (!rightclick) {
if (Keyboard.getEventKeyState() && (Keyboard.getEventKey() == Keyboard.KEY_LCONTROL
|| Keyboard.getEventKey() == Keyboard.KEY_RCONTROL)) {
if (Keyboard.getEventKeyState() && getIsAccessibleControlEventKey()) {
NEIClientConfig.cycleSetting("inventory.cheatmode", 3);
} else {
if (Keyboard.getEventKeyState() && (Keyboard.getEventKey() == Keyboard.KEY_LSHIFT
@@ -524,8 +538,8 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
}
@Override
public String getButtonTip() {
return getTimeTip(NEIActions.timeZones[zone], state);
public void addTooltips(List<String> tooltip) {
addTimeTip(NEIActions.timeZones[zone], state, tooltip);
}
};
}
@@ -558,9 +572,13 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
return translate("inventory." + name + "." + sfx);
}
private static String getTimeTip(String name, int state) {
String sfx = (state & 0x3) == 2 ? "enable" : "set";
return translate("inventory." + name + "." + sfx);
private static void addTimeTip(String name, int state, List<String> tooltip) {
if ((state & 0x3) == 2) {
tooltip.add(translate("inventory." + name + ".enable"));
} else {
tooltip.add(translate("inventory." + name + ".set"));
tooltip.add(EnumChatFormatting.GRAY + translate("inventory." + name + ".disable"));
}
}
private static boolean handleDisabledButtonPress(String ident, boolean rightclick) {
@@ -127,8 +127,13 @@ public class LayoutStyleMinecraft extends LayoutStyle {
presetsPanel.x = (gui.width - gui.xSize) / 2 + gui.xSize - presetsPanel.w;
searchField.h = 20;
searchField.w = 150;
searchField.x = (gui.width - searchField.w) / 2;
if (NEIClientConfig.isSearchWidgetCentered()) {
searchField.w = 150;
searchField.x = (gui.width - searchField.w) / 2;
} else {
searchField.w = (int) (itemPanel.w * (NEIClientConfig.showItemQuantityWidget() ? 0.7 : 1));
searchField.x = itemPanel.x;
}
searchField.y = gui.height - searchField.h - 2;
if (!visiblity.showItemSection) {
@@ -21,6 +21,8 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.input.Keyboard;
import com.google.common.base.Objects;
import codechicken.core.CCUpdateChecker;
import codechicken.core.ClassDiscoverer;
import codechicken.core.ClientUtils;
@@ -53,11 +55,10 @@ import codechicken.nei.recipe.RecipeCatalysts;
import codechicken.nei.recipe.RecipeInfo;
import codechicken.obfuscator.ObfuscationRun;
import com.google.common.base.Objects;
public class NEIClientConfig {
private static boolean configLoaded;
private static boolean mainNEIConfigLoaded;
private static boolean pluginNEIConfigLoaded;
private static boolean enabledOverride;
private static String worldPath;
@@ -241,12 +242,18 @@ public class NEIClientConfig {
tag.getTag("inventory.bookmarksAnimationEnabled").setComment("REI Style Animation in Bookmarks")
.getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.bookmarksAnimationEnabled", true));
tag.getTag("inventory.recipeTooltipsEnabled").setComment("Show recipe tooltips in Bookmarks")
.getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.recipeTooltipsEnabled", true));
tag.getTag("inventory.showRecipeMarker").setComment("Show Recipe Marker").getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.showRecipeMarker", true));
tag.getTag("inventory.showItemQuantityWidget").setComment("Show Item Quantity Widget").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.showItemQuantityWidget", true));
tag.getTag("inventory.centerSearchWidget").setComment("Center Search Widget").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.centerSearchWidget", true));
tag.getTag("inventory.jei_style_tabs").setComment("Enable/disable JEI Style Tabs").getBooleanValue(true);
API.addOption(new OptionToggleButtonBoubs("inventory.jei_style_tabs", true));
tag.getTag("inventory.jei_style_item_presence_overlay")
@@ -417,7 +424,7 @@ public class NEIClientConfig {
}
public static int getKeyBinding(String string) {
return getSetting("keys." + string).getIntValue();
return getSetting("keys." + string).getIntValue(Keyboard.KEY_NONE);
}
public static void setDefaultKeyBinding(String string, int key) {
@@ -460,8 +467,9 @@ public class NEIClientConfig {
}
public static void bootNEI(World world) {
if (configLoaded) return;
if (mainNEIConfigLoaded) return;
// main NEI config loading
ItemInfo.load(world);
GuiInfo.load();
RecipeInfo.load();
@@ -469,12 +477,13 @@ public class NEIClientConfig {
NEIController.load();
RecipeCatalysts.loadCatalystInfo();
configLoaded = true;
mainNEIConfigLoaded = true;
new Thread("NEI Plugin Loader") {
@Override
public void run() {
logger.debug("Started NEI plugin loading");
ClassDiscoverer classDiscoverer = new ClassDiscoverer(
test -> test.startsWith("NEI") && test.endsWith("Config.class"),
IConfigureNEI.class);
@@ -492,6 +501,13 @@ public class NEIClientConfig {
}
}
// Set pluginNEIConfigLoaded here before posting the NEIConfigsLoadedEvent. This used to be the other
// way around, but apparently if your modpack includes 800 mods the event poster might not return in
// time and cause issues when loading a world for a second time as configLoaded is still false. This may
// cause issues in case one of the event handler calls the (non-thread-safe) NEI API. I don't expect any
// handler to do this, but who knows what modders have come up with...
pluginNEIConfigLoaded = true;
logger.debug("NEI plugin loading finished");
MinecraftForge.EVENT_BUS.post(new NEIConfigsLoadedEvent());
}
}.start();
@@ -546,6 +562,10 @@ public class NEIClientConfig {
return getBooleanSetting("inventory.bookmarksAnimationEnabled");
}
public static boolean showRecipeTooltips() {
return getBooleanSetting("inventory.recipeTooltipsEnabled");
}
public static boolean showRecipeMarker() {
return getBooleanSetting("inventory.showRecipeMarker");
}
@@ -554,6 +574,10 @@ public class NEIClientConfig {
return getBooleanSetting("inventory.showItemQuantityWidget");
}
public static boolean isSearchWidgetCentered() {
return getBooleanSetting("inventory.centerSearchWidget");
}
public static boolean areJEIStyleTabsVisible() {
return getBooleanSetting("inventory.jei_style_tabs");
}
@@ -590,6 +614,10 @@ public class NEIClientConfig {
return enabledOverride && getBooleanSetting("inventory.widgetsenabled");
}
public static boolean isLoaded() {
return mainNEIConfigLoaded && pluginNEIConfigLoaded;
}
public static boolean loadHandlersFromJar() {
return !getBooleanSetting("tools.handler_load_from_config");
}
@@ -43,6 +43,8 @@ import net.minecraft.util.ResourceLocation;
import org.lwjgl.input.Keyboard;
import com.google.common.collect.Iterables;
import codechicken.lib.inventory.InventoryRange;
import codechicken.lib.inventory.InventoryUtils;
import codechicken.lib.util.LangProxy;
@@ -50,8 +52,6 @@ import codechicken.nei.api.GuiInfo;
import codechicken.nei.api.IInfiniteItemHandler;
import codechicken.nei.api.ItemInfo;
import com.google.common.collect.Iterables;
public class NEIClientUtils extends NEIServerUtils {
public static LangProxy lang = new LangProxy("nei");
@@ -251,6 +251,9 @@ public class NEIClientUtils extends NEIServerUtils {
}
public static boolean controlKey() {
if (Minecraft.isRunningOnMac) {
return Keyboard.isKeyDown(Keyboard.KEY_LMETA) || Keyboard.isKeyDown(Keyboard.KEY_RMETA);
}
return Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL);
}
@@ -5,16 +5,15 @@ import java.util.*;
import net.minecraft.util.EnumChatFormatting;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import codechicken.core.CommonUtils;
import codechicken.core.launch.CodeChickenCorePlugin;
import codechicken.nei.api.IConfigureNEI;
import codechicken.nei.asm.NEICorePlugin;
import codechicken.nei.config.IMCHandler;
import codechicken.nei.recipe.GuiRecipeTab;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import cpw.mods.fml.client.FMLFileResourcePack;
import cpw.mods.fml.client.FMLFolderResourcePack;
import cpw.mods.fml.common.DummyModContainer;
@@ -22,6 +22,7 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -108,7 +109,11 @@ public class NEIServerConfig {
private static void saveWorld(int dim) {
try {
File file = new File(getSaveDir(DimensionManager.getWorld(dim)), "world.dat");
final File saveDir = getSaveDir(DimensionManager.getWorld(dim));
if (!saveDir.isDirectory()) {
FileUtils.forceMkdir(saveDir);
}
File file = new File(saveDir, "world.dat");
NEIServerUtils.writeNBT(dimTags.get(dim), file);
} catch (Exception e) {
throw new RuntimeException(e);
@@ -1,6 +1,7 @@
package codechicken.nei;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
@@ -171,6 +172,11 @@ public abstract class PanelWidget extends Widget {
}
}
@Override
public void update() {
grid.update();
}
@Override
public void draw(int mousex, int mousey) {
grid.draw(mousex, mousey);
@@ -185,6 +191,11 @@ public abstract class PanelWidget extends Widget {
}
}
@Override
public void postDrawTooltips(int mx, int my, List<String> tooltip) {
grid.postDrawTooltips(mx, my, tooltip);
}
@Override
public void mouseDragged(int mousex, int mousey, int button, long heldTime) {
if (mouseDownSlot >= 0 && draggedStack == null
@@ -21,6 +21,11 @@ import net.minecraft.item.ItemStack;
import org.apache.commons.io.IOUtils;
import org.lwjgl.input.Keyboard;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSyntaxException;
import codechicken.core.CommonUtils;
import codechicken.core.gui.GuiScrollSlot;
import codechicken.lib.gui.GuiDraw;
@@ -30,11 +35,6 @@ import codechicken.nei.api.ItemFilter;
import codechicken.nei.recipe.GuiRecipe;
import codechicken.nei.recipe.StackInfo;
import codechicken.nei.util.NBTJson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSyntaxException;
import cpw.mods.fml.common.registry.GameRegistry;
public class PresetsWidget extends Widget {
@@ -1,6 +1,7 @@
package codechicken.nei;
import com.google.common.base.Objects;
import cpw.mods.fml.common.FMLCommonHandler;
public class ThreadOperationTimer extends Thread {
@@ -14,6 +14,8 @@ public abstract class Widget {
public void postDraw(int mx, int my) {}
public void postDrawTooltips(int mx, int my, List<String> tooltip) {}
public boolean handleClick(int mx, int my, int button) {
return true;
}
@@ -1,6 +1,7 @@
package codechicken.nei;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.passive.EntityPig;
@@ -14,7 +15,6 @@ import net.minecraft.world.chunk.Chunk;
import org.lwjgl.opengl.GL11;
import codechicken.lib.math.MathHelper;
import codechicken.lib.render.RenderUtils;
import codechicken.nei.KeyManager.IKeyStateTracker;
public class WorldOverlayRenderer implements IKeyStateTracker {
@@ -24,10 +24,13 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
public static int mobOverlay = 0;
private static byte[] mobSpawnCache;
private static long mobOverlayUpdateTime;
private static String oregenPatternName;
private static boolean hasOregenPatternBeenSet = false;
public static void reset() {
mobOverlay = 0;
chunkOverlay = 0;
hasOregenPatternBeenSet = false;
}
@Override
@@ -42,10 +45,19 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
public static void render(float frame) {
GL11.glPushMatrix();
Entity entity = Minecraft.getMinecraft().renderViewEntity;
RenderUtils.translateToWorldCoords(entity, frame);
renderChunkBounds(entity);
renderMobSpawnOverlay(entity);
double interpPosX = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * frame;
double interpPosY = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * frame;
double interpPosZ = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * frame;
int intOffsetX = (int) interpPosX;
int intOffsetY = (int) interpPosY;
int intOffsetZ = (int) interpPosZ;
GL11.glTranslated(-interpPosX + intOffsetX, -interpPosY + intOffsetY, -interpPosZ + intOffsetZ);
renderChunkBounds(entity, intOffsetX, intOffsetY, intOffsetZ);
renderMobSpawnOverlay(entity, intOffsetX, intOffsetY, intOffsetZ);
GL11.glPopMatrix();
}
@@ -86,7 +98,7 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
}
}
private static void renderMobSpawnOverlay(Entity entity) {
private static void renderMobSpawnOverlay(Entity entity, int intOffsetX, int intOffsetY, int intOffsetZ) {
if (mobOverlay == 0) {
if (mobSpawnCache != null) {
mobSpawnCache = null;
@@ -105,15 +117,17 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glLineWidth(1.5F);
GL11.glBegin(GL11.GL_LINES);
GL11.glColor4f(1, 0, 0, 1);
int curSpawnMode = 2;
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);
int x1 = (int) entity.posX - intOffsetX;
int z1 = (int) entity.posZ - intOffsetZ;
int y1 = (int) MathHelper.clip(entity.posY, 16, world.getHeight() - 16) - intOffsetY;
final Tessellator tess = Tessellator.instance;
tess.startDrawing(GL11.GL_LINES);
tess.setColorOpaque(255, 0, 0);
for (int i = 0; i <= 32; i++) {
int x = x1 - 16 + i;
@@ -132,22 +146,22 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
if (spawnMode != curSpawnMode) {
if (spawnMode == 1) {
GL11.glColor4f(1, 1, 0, 1);
tess.setColorOpaque(255, 255, 0);
} else {
GL11.glColor4f(1, 0, 0, 1);
tess.setColorOpaque(255, 0, 0);
}
curSpawnMode = spawnMode;
}
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);
tess.addVertex(x, y + 0.02, z);
tess.addVertex(x + 1, y + 0.02, z + 1);
tess.addVertex(x + 1, y + 0.02, z);
tess.addVertex(x, y + 0.02, z + 1);
}
}
}
GL11.glEnd();
tess.draw();
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_BLEND);
@@ -157,8 +171,8 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
private static final AxisAlignedBB aabb = AxisAlignedBB.getBoundingBox(0, 0, 0, 0, 0, 0);
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) {
if (chunk.getSavedLightValue(EnumSkyBlock.Block, x & 15, y, z & 15) >= 8
|| !SpawnerAnimals.canCreatureTypeSpawnAtLocation(EnumCreatureType.monster, chunk.worldObj, x, y, z)) {
return 0;
}
@@ -176,7 +190,7 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
return (byte) (chunk.getSavedLightValue(EnumSkyBlock.Sky, x & 15, y, z & 15) >= 8 ? 1 : 2);
}
private static void renderChunkBounds(Entity entity) {
private static void renderChunkBounds(Entity entity, int intOffsetX, int intOffsetY, int intOffsetZ) {
if (chunkOverlay == 0) return;
GL11.glDisable(GL11.GL_TEXTURE_2D);
@@ -187,8 +201,8 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
GL11.glBegin(GL11.GL_LINES);
for (int cx = -4; cx <= 4; cx++) for (int cz = -4; cz <= 4; cz++) {
double x1 = (entity.chunkCoordX + cx) << 4;
double z1 = (entity.chunkCoordZ + cz) << 4;
double x1 = ((entity.chunkCoordX + cx) << 4) - intOffsetX;
double z1 = ((entity.chunkCoordZ + cz) << 4) - intOffsetZ;
double x2 = x1 + 16;
double z2 = z1 + 16;
@@ -205,6 +219,9 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
y1 = y2 - dy;
}
y1 -= intOffsetY;
y2 -= intOffsetY;
double dist = Math.pow(1.5, -(cx * cx + cz * cz));
GL11.glColor4d(0.9, 0, 0, dist);
@@ -240,6 +257,9 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
y1 = y2 - dy;
}
y1 -= intOffsetY;
y2 -= intOffsetY;
GL11.glColor4d(0, 0.9, 0, 0.4);
for (double y = (int) y1; y <= y2; y++) {
GL11.glVertex3d(x2, y, z1);
@@ -262,13 +282,33 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
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 (!hasOregenPatternBeenSet) {
try {
oregenPatternName = ((Enum<?>) Class.forName("gregtech.common.GT_Worldgenerator")
.getDeclaredField("oregenPattern").get(null)).name();
} catch (Exception ignored) {
oregenPatternName = "AXISSYMMETRICAL";
}
hasOregenPatternBeenSet = true;
}
if (entity.chunkCoordZ < 0) {
gz1 += 16;
int gx1;
int gz1;
if (oregenPatternName.equals("EQUAL_SPACING")) {
// gt oregen uses new regular pattern
gx1 = ((Math.floorDiv(entity.chunkCoordX, 3) * 3) << 4) - intOffsetX;
gz1 = ((Math.floorDiv(entity.chunkCoordZ, 3) * 3) << 4) - intOffsetZ;
} else {
// gt oregen uses old bugged pattern
gx1 = (((entity.chunkCoordX < 0 ? entity.chunkCoordX - 3 : entity.chunkCoordX) / 3 * 3) << 4)
- intOffsetX;
gz1 = (((entity.chunkCoordZ < 0 ? entity.chunkCoordZ - 3 : entity.chunkCoordZ) / 3 * 3) << 4)
- intOffsetZ;
if (entity.chunkCoordX < 0) {
gx1 += 16;
}
if (entity.chunkCoordZ < 0) {
gz1 += 16;
}
}
int gx2 = gx1 + 48;
int gz2 = gz1 + 48;
+2 -2
View File
@@ -12,6 +12,8 @@ import net.minecraft.item.ItemStack;
import org.lwjgl.input.Keyboard;
import com.google.common.collect.Sets;
import codechicken.nei.ItemList;
import codechicken.nei.ItemSorter;
import codechicken.nei.ItemStackSet;
@@ -37,8 +39,6 @@ import codechicken.nei.recipe.RecipeCatalysts;
import codechicken.nei.recipe.RecipeInfo;
import codechicken.nei.recipe.StackInfo;
import com.google.common.collect.Sets;
/**
* This is the main class that handles item property configuration. WARNING: DO NOT access this class until the world
* has been loaded These methods should be called from INEIConfig implementors
@@ -39,6 +39,8 @@ import net.minecraftforge.common.BiomeDictionary;
import net.minecraftforge.common.IShearable;
import net.minecraftforge.oredict.OreDictionary;
import com.google.common.collect.ArrayListMultimap;
import codechicken.core.featurehack.GameDataManipulator;
import codechicken.nei.InfiniteStackSizeHandler;
import codechicken.nei.InfiniteToolHandler;
@@ -55,9 +57,6 @@ import codechicken.nei.config.RegistryDumper;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.recipe.BrewingRecipeHandler;
import codechicken.nei.recipe.RecipeItemInputHandler;
import com.google.common.collect.ArrayListMultimap;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.registry.GameRegistry;
@@ -20,6 +20,10 @@ public abstract class ShortcutInputHandler {
public static boolean handleKeyEvent(ItemStack stackover) {
if (!NEIClientConfig.isLoaded()) {
return false;
}
if (NEIClientConfig.isKeyHashDown("gui.overlay_hide")) {
return hideOverlayRecipe();
}
@@ -67,6 +71,10 @@ public abstract class ShortcutInputHandler {
public static boolean handleMouseClick(ItemStack stackover) {
if (!NEIClientConfig.isLoaded()) {
return false;
}
if (stackover != null) {
final int button = Mouse.getEventButton();
stackover = stackover.copy();
@@ -10,6 +10,8 @@ import net.minecraft.util.ChatComponentTranslation;
import org.apache.commons.io.IOUtils;
import com.google.common.base.Objects;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.recipe.GuiRecipeTab;
import codechicken.nei.recipe.GuiUsageRecipe;
@@ -18,8 +20,6 @@ import codechicken.nei.recipe.IRecipeHandler;
import codechicken.nei.recipe.TemplateRecipeHandler;
import codechicken.nei.util.NBTJson;
import com.google.common.base.Objects;
public class HandlerDumper extends DataDumper {
public HandlerDumper(String name) {
@@ -8,12 +8,12 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.LayoutManager;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.LayoutManager;
public abstract class OptionStringSet extends Option {
public final LinkedList<String> options = new LinkedList<>();
@@ -14,6 +14,8 @@ import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiScreen;
@@ -159,33 +161,21 @@ public class GuiContainerManager {
return namelist;
}
public static String itemCountDetails(ItemStack stack) {
final FluidStack fluid = StackInfo.getFluid(stack);
int maxStackSize = stack.getMaxStackSize();
int stackSize = stack.stackSize;
String FULL_PATTERN = "Count: %s = %s * %s + %s";
String SHORT_PATTERN = "Count: %s = %s * %s";
if (fluid != null) {
maxStackSize = 144;
stackSize = fluid.amount * Math.max(1, stack.stackSize);
FULL_PATTERN = "Amount: %s L = %s * %s L + %s L";
SHORT_PATTERN = "Amount: %s L = %s * %s L";
}
@Nullable
public static String countDetails(int stackSize, int maxStackSize, String fullPattern, String shortPattern) {
if (maxStackSize > 1 && stackSize > maxStackSize) {
final int remainder = stackSize % maxStackSize;
if (remainder > 0) {
return String.format(
FULL_PATTERN,
fullPattern,
NEIClientUtils.formatNumbers(stackSize),
NEIClientUtils.formatNumbers(stackSize / maxStackSize),
NEIClientUtils.formatNumbers(maxStackSize),
NEIClientUtils.formatNumbers(remainder));
} else {
return String.format(
SHORT_PATTERN,
shortPattern,
NEIClientUtils.formatNumbers(stackSize),
NEIClientUtils.formatNumbers(stackSize / maxStackSize),
NEIClientUtils.formatNumbers(maxStackSize));
@@ -195,6 +185,31 @@ public class GuiContainerManager {
return null;
}
@Nullable
public static String itemCountDetails(ItemStack stack) {
FluidStack fluid = StackInfo.getFluid(stack);
if (fluid != null) {
return fluidAmountDetails(fluid.amount * Math.max(1, stack.stackSize));
} else {
return countDetails(
stack.stackSize,
stack.getMaxStackSize(),
"Count: %s = %s * %s + %s",
"Count: %s = %s * %s");
}
}
@SuppressWarnings("unused")
@Nullable
public static String fluidAmountDetails(FluidStack fluid) {
return fluidAmountDetails(fluid.amount);
}
@Nullable
public static String fluidAmountDetails(int amount) {
return countDetails(amount, 144, "Amount: %s L = %s * %s L + %s L", "Amount: %s L = %s * %s L");
}
/**
* The general name of this item.
*
@@ -499,6 +514,10 @@ public class GuiContainerManager {
if (tooltip.size() > 0) tooltip.set(0, tooltip.get(0) + GuiDraw.TOOLTIP_LINESPACE); // add space after 'title'
drawPagedTooltip(font, mousex + 12, mousey - 12, tooltip);
for (IContainerDrawHandler drawHandler : drawHandlers) {
drawHandler.postRenderTooltips(window, mousex, mousey, tooltip);
}
}
private static int tooltipPage;
@@ -1,5 +1,7 @@
package codechicken.nei.guihook;
import java.util.List;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.Slot;
@@ -30,6 +32,17 @@ public interface IContainerDrawHandler {
*/
public void postRenderObjects(GuiContainer gui, int mousex, int mousey);
/**
* Use this to draw things that should be drawn just after vanilla slot tooltips, on top of buttons and other
* usually always-on-top widgets.
*
* @param gui An instance of the currentscreen
* @param mousex The x position of the mouse in pixels from left
* @param mousey The y position of the mouse in pixels from top
* @param tooltip The contents of the tooltip that has previously been drawn
*/
default void postRenderTooltips(GuiContainer gui, int mousex, int mousey, List<String> tooltip) {}
/**
* Render something over a slot before the item in the slot.
*
@@ -6,14 +6,14 @@ import java.util.List;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import codechicken.nei.PositionedStack;
import codechicken.nei.util.NBTJson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import codechicken.nei.PositionedStack;
import codechicken.nei.util.NBTJson;
public class BookmarkRecipeId {
public int position = -1;
@@ -121,6 +121,43 @@ public class BookmarkRecipeId {
return arr;
}
/**
* Ensures the {@link BookmarkRecipeId#recipetype} and {@link BookmarkRecipeId#position} fields point to a valid
* recipe. This is needed, because the recipe IDs are loaded lazily on first use.
*
* @param recipeHandlers The subset of recipe handlers to search for the recipe
*/
public void updateTargetRecipe(List<? extends IRecipeHandler> recipeHandlers) {
if (this.recipetype == -1 || this.position == -1) {
this.recipetype = 0;
this.position = 0;
if (this.handlerName != null) {
for (int j = 0; j < recipeHandlers.size(); j++) {
IRecipeHandler localHandler = recipeHandlers.get(j);
HandlerInfo localHandlerInfo = GuiRecipeTab.getHandlerInfo(localHandler);
if (localHandlerInfo.getHandlerName().equals(this.handlerName)) {
if (!this.ingredients.isEmpty()) {
for (int i = 0; i < localHandler.numRecipes(); i++) {
if (this.equalsIngredients(localHandler.getIngredientStacks(i))) {
this.recipetype = j;
this.position = i;
break;
}
}
}
break;
}
}
}
}
}
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
@@ -8,11 +8,11 @@ import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
import com.google.common.collect.ForwardingList;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIServerUtils;
import com.google.common.collect.ForwardingList;
// Do not directly extend ArrayList, see Effective Java Item 16
public class CatalystInfoList extends ForwardingList<CatalystInfo> {
@@ -146,11 +146,20 @@ public class DefaultOverlayHandler implements IOverlayHandler {
DistributedIngred istack = distrib.distrib;
if (istack.numSlots == 0) return 0;
final int maxStackSize = istack.stack.getMaxStackSize();
int allSlots = istack.invAmount;
if (allSlots / istack.numSlots > istack.stack.getMaxStackSize())
allSlots = istack.numSlots * istack.stack.getMaxStackSize();
if (allSlots / istack.numSlots > maxStackSize) allSlots = istack.numSlots * maxStackSize;
quantity = Math.min(quantity, allSlots / istack.distributed);
final int newQuantity = allSlots / istack.distributed;
if (maxStackSize == 1) {
// If non-stackable, fill up as much as possible of the other ingredients
continue;
}
quantity = Math.min(quantity, newQuantity);
}
if (quantity == Integer.MAX_VALUE) {
// Only possible if all ingredients were non-stackable
quantity = 1;
}
return quantity;
@@ -28,28 +28,27 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
public static boolean openRecipeGui(String outputId, final Boolean overlay, final Boolean shift,
Object... results) {
return createRecipeGui(outputId, overlay, shift, true, results) != null;
}
public static GuiRecipe<?> createRecipeGui(String outputId, final Boolean overlay, final Boolean shift,
final boolean open, Object... results) {
final Minecraft mc = NEIClientUtils.mc();
final BookmarkRecipeId recipeId = "item".equals(outputId)
? getRecipeId(mc.currentScreen, (ItemStack) results[0])
: getCurrentRecipe(mc.currentScreen);
if (overlay && recipeId == null) return false;
if (overlay && recipeId == null) return null;
final RecipeHandlerQuery<ICraftingHandler> recipeQuery = new RecipeHandlerQuery<>(
h -> h.getRecipeHandler(outputId, results),
craftinghandlers,
serialCraftingHandlers,
"Error while looking up crafting recipe",
"outputId: " + outputId,
"results: " + Arrays.toString(results));
final ArrayList<ICraftingHandler> handlers = recipeQuery.runWithProfiling("recipe.concurrent.crafting");
final ArrayList<ICraftingHandler> handlers = getCraftingHandlers(outputId, results);
if (!handlers.isEmpty()) {
GuiCraftingRecipe gui = new GuiCraftingRecipe(handlers, recipeId);
mc.displayGuiScreen(gui);
if (open) {
mc.displayGuiScreen(gui);
}
if (recipeId != null) {
gui.openTargetRecipe(gui.recipeId);
@@ -59,10 +58,22 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
gui.overlayRecipe(gui.recipeId.position, shift);
}
return true;
return gui;
}
return false;
return null;
}
public static ArrayList<ICraftingHandler> getCraftingHandlers(String outputId, Object... results) {
final RecipeHandlerQuery<ICraftingHandler> recipeQuery = new RecipeHandlerQuery<>(
h -> h.getRecipeHandler(outputId, results),
craftinghandlers,
serialCraftingHandlers,
"Error while looking up crafting recipe",
"outputId: " + outputId,
"results: " + Arrays.toString(results));
return recipeQuery.runWithProfiling("recipe.concurrent.crafting");
}
protected static BookmarkRecipeId getRecipeId(GuiScreen gui, ItemStack stackover) {
@@ -1,5 +1,7 @@
package codechicken.nei.recipe;
import static codechicken.lib.gui.GuiDraw.fontRenderer;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
@@ -11,8 +13,10 @@ import java.util.regex.Matcher;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
@@ -59,6 +63,8 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
private static final int buttonWidth = 13;
private static final int buttonHeight = 12;
private boolean limitToOneRecipe = false;
// Background image
final DrawableResource bgTop = new DrawableBuilder("nei:textures/gui/recipebg.png", 0, BG_TOP_Y, 176, BG_TOP_HEIGHT)
.build();
@@ -100,6 +106,12 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
private int yShift = 0;
/**
* This will only be true iff height hacking has been configured for the current recipe handler AND we are currently
* within the scope of an active {@link HeightHack} instance.
*/
private boolean isHeightHackApplied = false;
protected GuiRecipe(GuiScreen prevgui) {
super(new ContainerRecipe());
recipeTabs = new GuiRecipeTabs(this);
@@ -116,9 +128,14 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
}
}
/** Changes the GUI mode to only display one recipe at a time, e.g. for tooltip usage */
public void limitToOneRecipe() {
limitToOneRecipe = true;
}
/**
* Many old mods assumed a fixed NEI window height of {@code 166} pixels. Now that this is no longer the case, their
* fluid mouseover handling is broken. This helper class fixes these old mods by hacking the {@link #height}
* tooltip and click zone handling is broken. This helper class fixes these old mods by hacking the {@link #height}
* property's value so that these old mods' calculations return the correct value for the new height.
*
* <p>
@@ -128,40 +145,77 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
private class HeightHack implements AutoCloseable {
private final int trueHeight;
private final int trueGuiTop;
private final GuiScreen trueGui;
private HeightHack() {
trueHeight = height;
trueGuiTop = guiTop;
trueGui = Minecraft.getMinecraft().currentScreen;
boolean applyHeightHack = NEIClientConfig.heightHackHandlerRegex.stream()
isHeightHackApplied = NEIClientConfig.heightHackHandlerRegex.stream()
.map(pattern -> pattern.matcher(handler.getHandlerId())).anyMatch(Matcher::matches);
if (applyHeightHack) {
// The old mods use the calculation ((height - 166) / 2) to compute the y-value of
// the top edge of the NEI window.
// guiTop is exactly that: the y-value of the top edge of the NEI window.
// So we set height to be equal to the inverse of this calculation, applied to
// guiTop, so that old mods get the right result back when they use this calculation.
if (isHeightHackApplied) {
// guiTop is the top edge of the recipe screen on the y-axis. Old recipe handlers expect a single paging
// widget at the top and at the bottom of the recipe screen with a height of 16px each, but GTNH NEI
// moved the bottom paging widget to the top following JEI's design, increasing the "forbidden" zone at
// the top to 32px. To fix these old recipe handlers we move guiTop down 16px so that they can keep
// working with the old 16px gap.
guiTop += 16;
// The old NEI recipe screen had a fixed width and height and was always centered on the screen. Legacy
// recipe handlers use the calculation ((height - 166) / 2) to compute the y-value of the top edge of
// the NEI window. GTNH NEI changes the layout so that the recipe screen length now has a flexible
// length and is no longer centered vertically. In order for the top-of-screen calculation to return the
// correct result, we have to hack the height field with an inverse of the calculation using the actual
// top of the recipe screen stored in guiTop.
height = (2 * guiTop) + 166;
// For reference, in case we ever need to modify width as well:
// the legacy calculation used for width is ((width - 176) / 2), which should
// evaluate to be equal to guiWidth (the x-value of the left edge of the NEI window).
// So if we wanted to override width as well, we'd do this:
// the legacy calculation used for width is ((width - 176) / 2), which should evaluate to be equal to
// guiWidth (the x-value of the left edge of the NEI recipe screen). So if we wanted to override width
// as well, we'd do this:
// width = (2 * guiWidth) + 176;
// Recipe handlers may assume the current screen is the GuiRecipe object, which is not the case in
// recipe tooltips drawn on the bookmarks panel with the main inventory open.
if (limitToOneRecipe) {
Minecraft.getMinecraft().currentScreen = GuiRecipe.this;
}
}
}
@Override
public void close() {
guiTop = trueGuiTop;
height = trueHeight;
Minecraft.getMinecraft().currentScreen = trueGui;
isHeightHackApplied = false;
}
}
@Override
@SuppressWarnings("unchecked")
public void initGui() {
initGui(false);
}
@SuppressWarnings("unchecked")
public void initGui(boolean asWidget) {
xSize = 176;
ySize = Math.min(Math.max(height - 68, 166), 370);
super.initGui();
if (!asWidget) {
super.initGui();
} else {
this.guiLeft = (this.width - this.xSize) / 2;
this.mc = Minecraft.getMinecraft();
this.fontRendererObj = mc.fontRenderer;
ScaledResolution scaledresolution = new ScaledResolution(
this.mc,
this.mc.displayWidth,
this.mc.displayHeight);
this.width = scaledresolution.getScaledWidth();
this.height = scaledresolution.getScaledHeight();
}
guiTop = (height - ySize) / 2 + 10;
currenthandlers = getCurrentRecipeHandlers(); // Probably don't comment me out
@@ -198,14 +252,23 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
final int recipesPerPage = getRecipesPerPage();
overlayButtons = new GuiButton[recipesPerPage];
final int xOffset = limitToOneRecipe ? ((xSize / 2) - 2) : (width / 2);
final String overlayKeyName = NEIClientConfig
.getKeyName(NEIClientConfig.getKeyBinding("gui.overlay_use"), true);
for (int i = 0; i < recipesPerPage; i++) {
overlayButtons[i] = new GuiNEIButton(
OVERLAY_BUTTON_ID_START + i,
(width / 2) + 65,
guiTop + 16 + (handlerInfo.getHeight() * (i + 1)) - 2,
xOffset + 65,
16 + (handlerInfo.getHeight() * (i + 1)) - 2,
buttonWidth,
buttonHeight,
"?");
if (overlayKeyName != null && limitToOneRecipe) {
overlayButtons[i].visible = true;
overlayButtons[i].displayString = overlayKeyName;
overlayButtons[i].width = fontRenderer.getStringWidth(overlayKeyName) + 6;
overlayButtons[i].xPosition = xOffset + 85 - overlayButtons[i].width;
}
}
Collections.addAll(buttonList, overlayButtons);
itemPresenceCacheRecipe = -1;
@@ -232,41 +295,17 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
initOverlayButtons();
}
public List<GuiButton> getOverlayButtons() {
return Collections.unmodifiableList(Arrays.asList(overlayButtons));
}
public void openTargetRecipe(BookmarkRecipeId recipeId) {
if (recipeId == null) {
return;
}
if (recipeId.recipetype == -1 || recipeId.position == -1) {
recipeId.recipetype = 0;
recipeId.position = 0;
if (recipeId.handlerName != null) {
for (int j = 0; j < currenthandlers.size(); j++) {
H localHandler = currenthandlers.get(j);
HandlerInfo localHandlerInfo = GuiRecipeTab.getHandlerInfo(localHandler);
if (localHandlerInfo.getHandlerName().equals(recipeId.handlerName)) {
if (!recipeId.ingredients.isEmpty()) {
for (int i = 0; i < localHandler.numRecipes(); i++) {
if (recipeId.equalsIngredients(localHandler.getIngredientStacks(i))) {
recipeId.recipetype = j;
recipeId.position = i;
break;
}
}
}
break;
}
}
}
}
recipeId.updateTargetRecipe(currenthandlers);
setRecipePage(recipeId.recipetype, recipeId.position);
}
@@ -388,8 +427,22 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
// the value of the height field will be different from in other mouseover methods, which
// could be confusing...
// First, invoke scroll handling over recipe handler tabbar. Makes sure it is not overwritten by recipe
// handler-specific scroll behavior.
if (recipeTabs.mouseScrolled(i)) return;
for (int recipe : getRecipeIndices()) if (handler.mouseScrolled(this, i, recipe)) return;
// If shift is held, try switching to the next recipe handler. Replicates the GuiRecipeTabs.mouseScrolled()
// without the checking for the cursor being inside the tabbar.
if (NEIClientUtils.shiftKey()) {
if (i < 0) nextType();
else prevType();
return;
}
// Finally, if nothing else has handled scrolling, try changing to the next recipe page.
if (new Rectangle(guiLeft, guiTop, xSize, ySize).contains(GuiDraw.getMousePosition())) {
if (i > 0) prevPage();
else nextPage();
@@ -424,6 +477,11 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
@Override
public void updateScreen() {
super.updateScreen();
updateAsTooltip();
}
/** updateScreen() that's safe to call when this isn't the currently open GUI */
public void updateAsTooltip() {
handler.onUpdate();
refreshPage();
}
@@ -440,9 +498,9 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
@Override
public List<String> handleItemTooltip(GuiContainer gui, ItemStack stack, int mousex, int mousey,
List<String> currenttip) {
// Height hacking is probably not needed as it doesn't look like any mods check mouse
// position for this method.
for (int i : getRecipeIndices()) currenttip = handler.handleItemTooltip(this, stack, currenttip, i);
try (HeightHack heightHack = new HeightHack()) {
for (int i : getRecipeIndices()) currenttip = handler.handleItemTooltip(this, stack, currenttip, i);
}
return currenttip;
}
@@ -462,11 +520,11 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
if (page < 0) page = (handler.numRecipes() - 1) / getRecipesPerPage();
}
private void nextType() {
protected void nextType() {
setRecipePage(++recipetype);
}
private void prevType() {
protected void prevType() {
setRecipePage(--recipetype);
}
@@ -481,7 +539,9 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
mc.displayGuiScreen(firstGui);
if (renderer == null || moveItems) {
overlayHandler.overlayRecipe(firstGui, currenthandlers.get(recipetype), recipe, moveItems);
if (overlayHandler != null) {
overlayHandler.overlayRecipe(firstGui, currenthandlers.get(recipetype), recipe, moveItems);
}
} else {
LayoutManager.overlayRenderer = renderer;
}
@@ -526,6 +586,12 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
final int recipesPerPage = getRecipesPerPage();
for (int i = page * recipesPerPage; i < handler.numRecipes() && i < (page + 1) * recipesPerPage; i++) {
Point p = getRecipePosition(i);
// Legacy recipe handlers only expect a single paging widget at the top of the recipe screen, in contrast,
// GTNH NEI moves the recipe paging widget from the bottom to the top, which means said legacy handlers will
// position item slots 16px too high in the screen.
if (isHeightHackApplied) {
p.translate(0, 16);
}
List<PositionedStack> stacks = handler.getIngredientStacks(i);
for (PositionedStack stack : stacks) slotcontainer.addSlot(stack, p.x, p.y);
@@ -536,11 +602,13 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
PositionedStack result = handler.getResultStack(i);
if (result != null) slotcontainer.addSlot(result, p.x, p.y);
List<PositionedStack> catalysts = RecipeCatalysts.getRecipeCatalysts(handler);
for (PositionedStack catalyst : catalysts) {
int xOffset = -GuiRecipeCatalyst.ingredientSize + 1;
int yOffset = BG_TOP_Y + GuiRecipeCatalyst.fullBorder;
slotcontainer.addSlot(catalyst, xOffset, yOffset);
if (!limitToOneRecipe) {
List<PositionedStack> catalysts = RecipeCatalysts.getRecipeCatalysts(handler);
for (PositionedStack catalyst : catalysts) {
int xOffset = -GuiRecipeCatalyst.ingredientSize + 1;
int yOffset = BG_TOP_Y + GuiRecipeCatalyst.fullBorder;
slotcontainer.addSlot(catalyst, xOffset, yOffset);
}
}
}
}
@@ -574,21 +642,24 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
}
@Override
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
public void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
GuiContainerManager.enable2DRender();
final int recipesPerPage = getRecipesPerPage();
String s = handler.getRecipeName().trim();
fontRendererObj.drawStringWithShadow(s, (xSize - fontRendererObj.getStringWidth(s)) / 2, 5, 0xffffff);
s = NEIClientUtils.translate("recipe.page", page + 1, (handler.numRecipes() - 1) / recipesPerPage + 1);
fontRendererObj.drawStringWithShadow(s, (xSize - fontRendererObj.getStringWidth(s)) / 2, 19, 0xffffff);
final int ySkip = limitToOneRecipe ? 25 : 0;
if (!limitToOneRecipe) {
String s = handler.getRecipeName().trim();
fontRendererObj.drawStringWithShadow(s, (xSize - fontRendererObj.getStringWidth(s)) / 2, 5, 0xffffff);
s = NEIClientUtils.translate("recipe.page", page + 1, (handler.numRecipes() - 1) / recipesPerPage + 1);
fontRendererObj.drawStringWithShadow(s, (xSize - fontRendererObj.getStringWidth(s)) / 2, 19, 0xffffff);
}
final boolean drawItemPresence = NEIClientConfig.isJEIStyleItemPresenceOverlayVisible();
GL11.glPushMatrix();
GL11.glTranslatef(5, 32 + yShift, 0);
GL11.glTranslatef(5, 32 - ySkip + yShift, 0);
try (HeightHack heightHack = new HeightHack()) {
for (int i = page * recipesPerPage; i < handler.numRecipes() && i < (page + 1) * recipesPerPage; i++) {
handler.drawForeground(i);
if (drawItemPresence && isMouseOverOverlayButton(i - page * recipesPerPage)
if (drawItemPresence && (isMouseOverOverlayButton(i - page * recipesPerPage) || limitToOneRecipe)
&& firstGui.inventorySlots != null) {
List<PositionedStack> ingredients = handler.getIngredientStacks(i);
if (itemPresenceCacheRecipe != i || itemPresenceCacheSlots == null
@@ -608,28 +679,27 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
}
@Override
protected void drawGuiContainerBackgroundLayer(float f, int mouseX, int mouseY) {
public void drawGuiContainerBackgroundLayer(float f, int mouseX, int mouseY) {
final int recipesPerPage = getRecipesPerPage();
final int ySkip = limitToOneRecipe ? 25 : 0;
GL11.glColor4f(1, 1, 1, 1);
final int j = (width - xSize) / 2;
final int k = guiTop;
drawBackgroundTiled(j, k);
drawBackgroundTiled(guiLeft, guiTop);
drawRect(
guiLeft + borderPadding + buttonWidth - 1,
nexttype.yPosition,
guiLeft + xSize - borderPadding - buttonWidth,
nexttype.yPosition + buttonHeight,
0x30000000);
drawRect(
guiLeft + borderPadding + buttonWidth - 1,
nextpage.yPosition,
guiLeft + xSize - borderPadding - buttonWidth,
nextpage.yPosition + buttonHeight,
0x30000000);
if (NEIClientConfig.areJEIStyleTabsVisible() && !limitToOneRecipe) {
drawRect(
guiLeft + borderPadding + buttonWidth - 1,
nexttype.yPosition,
guiLeft + xSize - borderPadding - buttonWidth,
nexttype.yPosition + buttonHeight,
0x30000000);
drawRect(
guiLeft + borderPadding + buttonWidth - 1,
nextpage.yPosition,
guiLeft + xSize - borderPadding - buttonWidth,
nextpage.yPosition + buttonHeight,
0x30000000);
if (NEIClientConfig.areJEIStyleTabsVisible()) {
RenderHelper.enableGUIStandardItemLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
recipeTabs.draw(mouseX, mouseY);
@@ -640,7 +710,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
}
GL11.glPushMatrix();
GL11.glTranslatef(j + 5, k + 32 + yShift, 0);
GL11.glTranslatef(guiLeft + 5, guiTop - ySkip + 32 + yShift, 0);
try (HeightHack heightHack = new HeightHack()) {
for (int i = page * recipesPerPage; i < handler.numRecipes() && i < (page + 1) * recipesPerPage; i++) {
handler.drawBackground(i);
@@ -652,10 +722,12 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
private void drawBackgroundTiled(int j, int k) {
// Draw the top
final int ySkip = limitToOneRecipe ? 25 : 0;
final int handlerHeight = limitToOneRecipe ? getHeightAsWidget() : ySize;
bgTop.draw(j, k + BG_TOP_Y);
// Maybe Tile the middle
final int tiledHeight = ySize - BG_TOP_HEIGHT - BG_BOTTOM_HEIGHT;
final int tiledHeight = handlerHeight - ySkip - BG_TOP_HEIGHT - BG_BOTTOM_HEIGHT;
if (tiledHeight > 0) {
final int yTileCount = tiledHeight / BG_MIDDLE_HEIGHT;
@@ -672,7 +744,11 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
}
// Draw the bottom
bgBottom.draw(j, k + ySize - BG_BOTTOM_HEIGHT);
bgBottom.draw(j, k + handlerHeight - ySkip - BG_BOTTOM_HEIGHT);
}
public int getHeightAsWidget() {
return (handlerInfo == null) ? ySize : (handlerInfo.getHeight() + 56);
}
@Override
@@ -708,7 +784,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
}
private int getRecipesPerPage() {
return getRecipesPerPage(handlerInfo);
return limitToOneRecipe ? 1 : getRecipesPerPage(handlerInfo);
}
private int getRecipesPerPage(HandlerInfo handlerInfo) {
@@ -719,7 +795,14 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
}
public Point getRecipePosition(int recipe) {
return new Point(5, 32 + yShift + ((recipe % getRecipesPerPage()) * handlerInfo.getHeight()));
// Legacy recipe handlers using the height hack might use getRecipePosition in combination with guiTop/height to
// position certain elements like tooltips. Since guiTop is moved down by 16px during height hacking, we need to
// reduce the vertical shift here to 16px instead of 32px.
return new Point(
5,
(isHeightHackApplied ? 16 : 32) - (limitToOneRecipe ? 25 : 0)
+ yShift
+ ((recipe % getRecipesPerPage()) * handlerInfo.getHeight()));
}
public abstract ArrayList<H> getCurrentRecipeHandlers();
@@ -282,6 +282,20 @@ public abstract class GuiRecipeTab extends Widget {
handlerMap.keySet().removeAll(handlerRemoverFromIMC);
handlerMap.putAll(handlerAdderFromIMC);
if (!handlerAdderFromIMC.isEmpty()) {
// If we're getting an IMC message, it probably means it should match
Set<String> handlerIds = new HashSet<>(handlerMap.keySet());
handlerAdderFromIMC.keySet().forEach(handlerName -> {
if (!handlerIds.contains(handlerName)) {
NEIClientConfig.logger.warn("Could not find a registered handlerID that matches " + handlerName);
handlerIds.forEach(handler -> {
if (handler.equalsIgnoreCase(handlerName)) {
NEIClientConfig.logger.warn(" -- Did you mean: " + handler);
}
});
}
});
}
NEIClientConfig.logger.info("Sending {}", NEIRegisterHandlerInfosEvent.class.getSimpleName());
MinecraftForge.EVENT_BUS.post(new NEIRegisterHandlerInfosEvent());
}
@@ -1,5 +1,7 @@
package codechicken.nei.recipe;
import static codechicken.lib.gui.GuiDraw.getMousePosition;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
@@ -192,4 +194,18 @@ public class GuiRecipeTabs {
}
return false;
}
protected boolean mouseScrolled(int i) {
Point mousePosition = getMousePosition();
// Switch between recipe handlers if the cursor is over the tabbar.
if (NEIClientConfig.areJEIStyleTabsVisible() && area.contains(mousePosition)) {
if (i < 0) guiRecipe.nextType();
else guiRecipe.prevType();
return true;
}
return false;
}
}
@@ -13,8 +13,10 @@ import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.minecraft.item.ItemStack;
@@ -22,11 +24,11 @@ import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import com.google.common.base.Objects;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIServerUtils;
import codechicken.nei.PositionedStack;
import com.google.common.base.Objects;
import cpw.mods.fml.common.Loader;
public class RecipeCatalysts {
@@ -227,6 +229,20 @@ public class RecipeCatalysts {
}
}
if (!catalystsAdderFromIMC.isEmpty()) {
// If we're getting an IMC message, it probably means it should match
Set<String> handlerIds = new HashSet<>(GuiRecipeTab.handlerMap.keySet());
catalystsAdderFromIMC.keySet().forEach(handlerName -> {
if (!handlerIds.contains(handlerName)) {
NEIClientConfig.logger.warn("Could not find a registered handlerID that matches " + handlerName);
handlerIds.forEach(handler -> {
if (handler.equalsIgnoreCase(handlerName)) {
NEIClientConfig.logger.warn(" -- Did you mean: " + handler);
}
});
}
});
}
for (Map.Entry<String, List<ItemStack>> entry : catalystsRemoverFromAPI.entrySet()) {
String handlerID = entry.getKey();
if (recipeCatalystMap.containsKey(handlerID)) {
@@ -8,13 +8,13 @@ import net.minecraft.client.gui.inventory.GuiCrafting;
import net.minecraft.client.gui.inventory.GuiFurnace;
import net.minecraft.client.gui.inventory.GuiInventory;
import com.google.common.base.Objects;
import codechicken.nei.OffsetPositioner;
import codechicken.nei.api.API;
import codechicken.nei.api.IOverlayHandler;
import codechicken.nei.api.IStackPositioner;
import com.google.common.base.Objects;
public class RecipeInfo {
private static class OverlayKey {
@@ -21,6 +21,7 @@ import java.util.stream.Collectors;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.inventory.Container;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@@ -29,6 +30,8 @@ import net.minecraft.tileentity.TileEntityFurnace;
import org.lwjgl.opengl.GL11;
import com.google.common.base.Stopwatch;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.ItemList;
import codechicken.nei.NEIClientConfig;
@@ -43,8 +46,6 @@ import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.guihook.IContainerInputHandler;
import codechicken.nei.guihook.IContainerTooltipHandler;
import com.google.common.base.Stopwatch;
/**
* A Template Recipe Handler! How about that. Because it was sooo hard, and more seriously required lots of copied code
* to make a handler in the past. you can now extend this class to make your custom recipe handlers much easier to
@@ -210,7 +211,7 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
for (int i = 0; i < stack.items.length; i++) {
if (NEIServerUtils.areStacksSameTypeCrafting(ingredient, stack.items[i])) {
stack.item = stack.items[i];
stack.item.setItemDamage(ingredient.getItemDamage());
Items.feather.setDamage(stack.item, Items.feather.getDamage(ingredient));
if (ingredient.hasTagCompound()) {
stack.item.setTagCompound((NBTTagCompound) ingredient.getTagCompound().copy());
}
@@ -0,0 +1,15 @@
# Each line in this file should either be a comment (line starts with '#'), or a fully-qualified class name (that
# includes the package name) for a recipe handler. Wildcard patterns ('*') can be used to catch multiple classes with a
# single entry.
# If you delete this file, it will be regenerated with the default height hacked handlers list.
buildcraft.compat.nei.*
cofh.thermalexpansion.plugins.nei.handlers.*
crazypants.enderio.nei.*
forestry.factory.recipes.nei.*
ic2.neiIntegration.core.recipehandler.*
mariculture.plugins.nei.*
redgear.brewcraft.plugins.nei.*
tconstruct.plugins.nei.*
WayofTime.alchemicalWizardry.client.nei.*
exnihilo.compatibility.nei.*
blusunrize.immersiveengineering.client.nei.*
@@ -0,0 +1,6 @@
# This version of NEI loads recipes in parallel. Some recipe handlers have not been designed with that in mind and might
# crash. List these handlers in this file to force them to be loaded single threaded. Each line in this file should
# either be a comment (line starts with '#'), or a fully-qualified class name (that includes the package name) for a
# recipe handler.
# If you delete this file, it will be regenerated with the default serial handlers list.
WayofTime.alchemicalWizardry.client.nei.NEIAlchemyRecipeHandler
@@ -547,8 +547,9 @@ nc.crafting.nei.FissionRecipeHandler,NuclearCraft:fissionReactorGraphiteIdle,,Nu
nc.crafting.nei.FissionSteamRecipeHandler,NuclearCraft:fissionReactorSteamIdle,,NuclearCraft,TRUE,,,,,,
nc.crafting.nei.FusionRecipeHandler,NuclearCraft:fusionReactor,,NuclearCraft,TRUE,,,,,,
nc.crafting.nei.FusionSteamRecipeHandler,NuclearCraft:fusionReactorSteam,,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
nc.crafting.nei.ElectrolyserRecipeHandler,NuclearCraft:electrolyserIdle,,NuclearCraft,TRUE,,,,,,
nc.crafting.nei.CrusherRecipeHandler,NuclearCraft:crusherIdle,,NuclearCraft,TRUE,,,,,,
nc.crafting.nei.ElectricCrusherRecipeHandler,NuclearCraft:electricCrusherIdle,,NuclearCraft,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,,,,,,
@@ -1343,6 +1344,12 @@ tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerSewer,MineFactoryRel
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerGrinder,MineFactoryReloaded:machine.0:13,,MineFactoryReloaded,TRUE,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerBioReactor,MineFactoryReloaded:machine.1:10,,MineFactoryReloaded,TRUE,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerSlaughterhouse,MineFactoryReloaded:machine.1:13,,MineFactoryReloaded,TRUE,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerLaserDrill,MineFactoryReloaded:machine.2:0,,MineFactoryReloaded,TRUE,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerLaserDrill,MineFactoryReloaded:machine.2:1,,MineFactoryReloaded,TRUE,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerSludgeBoiler,MineFactoryReloaded:machine.0:9,,MineFactoryReloaded,TRUE,,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerMeatPacker,MineFactoryReloaded:machine.1:14,,MineFactoryReloaded,TRUE,,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerComposter,MineFactoryReloaded:machine.0:11,,MineFactoryReloaded,TRUE,,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerLavaFabricator,MineFactoryReloaded:machine.1:5,,MineFactoryReloaded,TRUE,,,,,,
de.ellpeck.actuallyadditions.mod.nei.NEIBookletRecipe,ActuallyAdditions:itemBooklet,,ActuallyAdditions,TRUE,,,,,,
de.ellpeck.actuallyadditions.mod.nei.NEIHairyBallRecipe,ActuallyAdditions:itemHairyBall,,ActuallyAdditions,TRUE,,,,,,
de.ellpeck.actuallyadditions.mod.nei.NEICrusherRecipe$Double,ActuallyAdditions:blockGrinderDouble,,ActuallyAdditions,TRUE,,,,,,
@@ -1371,3 +1378,45 @@ de.ellpeck.actuallyadditions.mod.nei.NEICoffeeMachineRecipe,ActuallyAdditions:bl
de.ellpeck.actuallyadditions.mod.nei.NEICompostRecipe,ActuallyAdditions:blockCompost,,ActuallyAdditions,TRUE,,,,,,,,,,,
de.ellpeck.actuallyadditions.mod.nei.NEIReconstructorRecipe,ActuallyAdditions:blockAtomicReconstructor,,ActuallyAdditions,TRUE,,,,,,,,,,,
de.ellpeck.actuallyadditions.mod.nei.NEITreasureChestRecipe,ActuallyAdditions:blockTreasureChest,,ActuallyAdditions,TRUE,,,,,,,,,,,
factorization.nei.RecipeSlagFurnace,factorization:FzBlock:11,,factorization,TRUE,,,,,,
factorization.nei.RecipeCrystallizer,factorization:FzBlock:19,,factorization,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.WorktableRecipeHandler,RotaryCraft:rotarycraft_item_machine:75,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.ToolChargingHandler,RotaryCraft:rotarycraft_item_machine:75,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.ToolCraftingHandler,RotaryCraft:rotarycraft_item_machine:75,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.BlastFurnaceHandler,RotaryCraft:rotarycraft_item_machine:45,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.GrinderHandler,RotaryCraft:rotarycraft_item_machine:11,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.ExtractorHandler,RotaryCraft:rotarycraft_item_machine:20,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.FermenterHandler,RotaryCraft:rotarycraft_item_machine:7,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.CompactorHandler,RotaryCraft:rotarycraft_item_machine:22,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.PulseJetHandler,RotaryCraft:rotarycraft_item_machine:21,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.FractionHandler,RotaryCraft:rotarycraft_item_machine:25,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.CrystallizerHandler,RotaryCraft:rotarycraft_item_machine:110,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.FridgeHandler,RotaryCraft:rotarycraft_item_machine:118,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.FillingStationHandler,RotaryCraft:rotarycraft_item_machine:101,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.FrictionHandler,RotaryCraft:rotarycraft_item_machine:67,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.FrictionHandler,minecraft:furnace,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.ComposterHandler,RotaryCraft:rotarycraft_item_machine:121,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.LavaMakerHandler,RotaryCraft:rotarycraft_item_machine:91,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.CentrifugeHandler,RotaryCraft:rotarycraft_item_machine:125,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.DryingBedHandler,RotaryCraft:rotarycraft_item_machine:127,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.WetterHandler,RotaryCraft:rotarycraft_item_machine:128,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.FuelEnhancerHandler,RotaryCraft:rotarycraft_item_machine:86,,RotaryCraft,TRUE,,,,,,
Reika.RotaryCraft.ModInterface.NEI.DropProcessorHandler,RotaryCraft:rotarycraft_item_machine:129,,RotaryCraft,TRUE,,,,,,
Reika.ReactorCraft.NEI.SynthesizerHandler,ReactorCraft:reactorcraft_item_placer:14,,ReactorCraft,TRUE,,,,,,
Reika.ReactorCraft.NEI.UProcessorHandler,ReactorCraft:reactorcraft_item_placer:9,,ReactorCraft,TRUE,,,,,,
Reika.ReactorCraft.NEI.CentrifugeHandler,ReactorCraft:reactorcraft_item_placer:8,,ReactorCraft,TRUE,,,,,,
Reika.ReactorCraft.NEI.ElectrolyzerHandler,ReactorCraft:reactorcraft_item_placer:16,,ReactorCraft,TRUE,,,,,,
Reika.ReactorCraft.NEI.ElectrolyzerHandler,RotaryCraft:rotarycraft_item_machine:103,,RotaryCraft,TRUE,,,,,,
Reika.ChromatiCraft.ModInterface.NEI.CrystalBrewerHandler,ChromatiCraft:chromaticraft_item_placer:7,,ChromatiCraft,TRUE,,,,,,
Reika.ChromatiCraft.ModInterface.NEI.CrystalFurnaceHandler,ChromatiCraft:chromaticraft_item_placer:15,,ChromatiCraft,TRUE,,,,,,
Reika.ChromatiCraft.ModInterface.NEI.GlowFireHandler,ChromatiCraft:chromaticraft_item_placer:60,,ChromatiCraft,TRUE,,,,,,
Reika.ChromatiCraft.ModInterface.NEI.EnchantDecompHandler,ChromatiCraft:chromaticraft_item_placer:69,,ChromatiCraft,TRUE,,,,,,
Reika.ChromatiCraft.ModInterface.NEI.FabricatorHandler,ChromatiCraft:chromaticraft_item_placer:23,,ChromatiCraft,TRUE,,,,,,
tonius.neiintegration.mods.bigreactors.RecipeHandlerCyaniteReprocessor,BigReactors:BRDevice:0,,BigReactors,TRUE,,,,,,
ru.nanolive.draconicplus.common.fusioncrafting.nei.FusionCraftingNEI,draconicplus:fusionCraftingCore,,draconicplus,TRUE,,,,,,
techguns.nei.TechgunsFabricatorNEIRecipeHandler,Techguns:machineMultiBlock:4,,Techguns,TRUE,,,,,,
techguns.nei.TechgunsReactionChamberNEIRecipeHandler,Techguns:machineMultiBlock:1,,Techguns,TRUE,,,,,,
techguns.nei.TechgunsChemLabNEIRecipeHandler,Techguns:basicMachine:4,,Techguns,TRUE,,,,,,
techguns.nei.TechgunsAmmoPressNEIRecipeHandler,Techguns:basicMachine:0,,Techguns,TRUE,,,,,,
techguns.nei.TechgunsMetalPressNEIRecipeHandler,Techguns:basicMachine:1,,Techguns,TRUE,,,,,,
techguns.nei.TechgunsChargingStationNEIRecipeHandler,Techguns:basicMachine:9,,Techguns,TRUE,,,,,,
1 handler itemName nbtInfo modId modRequired excludedModId priority minVersion maxVersion forceClassName itemNotes
547 nc.crafting.nei.FissionSteamRecipeHandler NuclearCraft:fissionReactorSteamIdle NuclearCraft TRUE
548 nc.crafting.nei.FusionRecipeHandler NuclearCraft:fusionReactor NuclearCraft TRUE
549 nc.crafting.nei.FusionSteamRecipeHandler NuclearCraft:fusionReactorSteam NuclearCraft TRUE
550 ganymedes01.etfuturum.NEI_EtFuturum_Config$NEI_Recipes_Smoker nc.crafting.nei.ElectrolyserRecipeHandler etfuturum:smoker NuclearCraft:electrolyserIdle etfuturum NuclearCraft TRUE not working well
551 ganymedes01.etfuturum.NEI_EtFuturum_Config$NEI_Recipes_BlastFurnace nc.crafting.nei.CrusherRecipeHandler etfuturum:blast_furnace NuclearCraft:crusherIdle etfuturum NuclearCraft TRUE not working well
552 nc.crafting.nei.ElectricCrusherRecipeHandler NuclearCraft:electricCrusherIdle NuclearCraft TRUE
553 connor135246.campfirebackport.client.compat.nei.NEICampfireRecipeHandler campfirebackport:campfire campfirebackport TRUE
554 connor135246.campfirebackport.client.compat.nei.NEICampfireRecipeHandler campfirebackport:soul_campfire campfirebackport TRUE
555 connor135246.campfirebackport.client.compat.nei.NEICampfireStateChangerHandler campfirebackport:campfire campfirebackport TRUE
1344 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerGrinder MineFactoryReloaded:machine.0:13 MineFactoryReloaded TRUE
1345 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerBioReactor MineFactoryReloaded:machine.1:10 MineFactoryReloaded TRUE
1346 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerSlaughterhouse MineFactoryReloaded:machine.1:13 MineFactoryReloaded TRUE
1347 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerLaserDrill MineFactoryReloaded:machine.2:0 MineFactoryReloaded TRUE
1348 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerLaserDrill MineFactoryReloaded:machine.2:1 MineFactoryReloaded TRUE
1349 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerSludgeBoiler MineFactoryReloaded:machine.0:9 MineFactoryReloaded TRUE
1350 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerMeatPacker MineFactoryReloaded:machine.1:14 MineFactoryReloaded TRUE
1351 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerComposter MineFactoryReloaded:machine.0:11 MineFactoryReloaded TRUE
1352 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerLavaFabricator MineFactoryReloaded:machine.1:5 MineFactoryReloaded TRUE
1353 de.ellpeck.actuallyadditions.mod.nei.NEIBookletRecipe ActuallyAdditions:itemBooklet ActuallyAdditions TRUE
1354 de.ellpeck.actuallyadditions.mod.nei.NEIHairyBallRecipe ActuallyAdditions:itemHairyBall ActuallyAdditions TRUE
1355 de.ellpeck.actuallyadditions.mod.nei.NEICrusherRecipe$Double ActuallyAdditions:blockGrinderDouble ActuallyAdditions TRUE
1378 de.ellpeck.actuallyadditions.mod.nei.NEICompostRecipe ActuallyAdditions:blockCompost ActuallyAdditions TRUE
1379 de.ellpeck.actuallyadditions.mod.nei.NEIReconstructorRecipe ActuallyAdditions:blockAtomicReconstructor ActuallyAdditions TRUE
1380 de.ellpeck.actuallyadditions.mod.nei.NEITreasureChestRecipe ActuallyAdditions:blockTreasureChest ActuallyAdditions TRUE
1381 factorization.nei.RecipeSlagFurnace factorization:FzBlock:11 factorization TRUE
1382 factorization.nei.RecipeCrystallizer factorization:FzBlock:19 factorization TRUE
1383 Reika.RotaryCraft.ModInterface.NEI.WorktableRecipeHandler RotaryCraft:rotarycraft_item_machine:75 RotaryCraft TRUE
1384 Reika.RotaryCraft.ModInterface.NEI.ToolChargingHandler RotaryCraft:rotarycraft_item_machine:75 RotaryCraft TRUE
1385 Reika.RotaryCraft.ModInterface.NEI.ToolCraftingHandler RotaryCraft:rotarycraft_item_machine:75 RotaryCraft TRUE
1386 Reika.RotaryCraft.ModInterface.NEI.BlastFurnaceHandler RotaryCraft:rotarycraft_item_machine:45 RotaryCraft TRUE
1387 Reika.RotaryCraft.ModInterface.NEI.GrinderHandler RotaryCraft:rotarycraft_item_machine:11 RotaryCraft TRUE
1388 Reika.RotaryCraft.ModInterface.NEI.ExtractorHandler RotaryCraft:rotarycraft_item_machine:20 RotaryCraft TRUE
1389 Reika.RotaryCraft.ModInterface.NEI.FermenterHandler RotaryCraft:rotarycraft_item_machine:7 RotaryCraft TRUE
1390 Reika.RotaryCraft.ModInterface.NEI.CompactorHandler RotaryCraft:rotarycraft_item_machine:22 RotaryCraft TRUE
1391 Reika.RotaryCraft.ModInterface.NEI.PulseJetHandler RotaryCraft:rotarycraft_item_machine:21 RotaryCraft TRUE
1392 Reika.RotaryCraft.ModInterface.NEI.FractionHandler RotaryCraft:rotarycraft_item_machine:25 RotaryCraft TRUE
1393 Reika.RotaryCraft.ModInterface.NEI.CrystallizerHandler RotaryCraft:rotarycraft_item_machine:110 RotaryCraft TRUE
1394 Reika.RotaryCraft.ModInterface.NEI.FridgeHandler RotaryCraft:rotarycraft_item_machine:118 RotaryCraft TRUE
1395 Reika.RotaryCraft.ModInterface.NEI.FillingStationHandler RotaryCraft:rotarycraft_item_machine:101 RotaryCraft TRUE
1396 Reika.RotaryCraft.ModInterface.NEI.FrictionHandler RotaryCraft:rotarycraft_item_machine:67 RotaryCraft TRUE
1397 Reika.RotaryCraft.ModInterface.NEI.FrictionHandler minecraft:furnace RotaryCraft TRUE
1398 Reika.RotaryCraft.ModInterface.NEI.ComposterHandler RotaryCraft:rotarycraft_item_machine:121 RotaryCraft TRUE
1399 Reika.RotaryCraft.ModInterface.NEI.LavaMakerHandler RotaryCraft:rotarycraft_item_machine:91 RotaryCraft TRUE
1400 Reika.RotaryCraft.ModInterface.NEI.CentrifugeHandler RotaryCraft:rotarycraft_item_machine:125 RotaryCraft TRUE
1401 Reika.RotaryCraft.ModInterface.NEI.DryingBedHandler RotaryCraft:rotarycraft_item_machine:127 RotaryCraft TRUE
1402 Reika.RotaryCraft.ModInterface.NEI.WetterHandler RotaryCraft:rotarycraft_item_machine:128 RotaryCraft TRUE
1403 Reika.RotaryCraft.ModInterface.NEI.FuelEnhancerHandler RotaryCraft:rotarycraft_item_machine:86 RotaryCraft TRUE
1404 Reika.RotaryCraft.ModInterface.NEI.DropProcessorHandler RotaryCraft:rotarycraft_item_machine:129 RotaryCraft TRUE
1405 Reika.ReactorCraft.NEI.SynthesizerHandler ReactorCraft:reactorcraft_item_placer:14 ReactorCraft TRUE
1406 Reika.ReactorCraft.NEI.UProcessorHandler ReactorCraft:reactorcraft_item_placer:9 ReactorCraft TRUE
1407 Reika.ReactorCraft.NEI.CentrifugeHandler ReactorCraft:reactorcraft_item_placer:8 ReactorCraft TRUE
1408 Reika.ReactorCraft.NEI.ElectrolyzerHandler ReactorCraft:reactorcraft_item_placer:16 ReactorCraft TRUE
1409 Reika.ReactorCraft.NEI.ElectrolyzerHandler RotaryCraft:rotarycraft_item_machine:103 RotaryCraft TRUE
1410 Reika.ChromatiCraft.ModInterface.NEI.CrystalBrewerHandler ChromatiCraft:chromaticraft_item_placer:7 ChromatiCraft TRUE
1411 Reika.ChromatiCraft.ModInterface.NEI.CrystalFurnaceHandler ChromatiCraft:chromaticraft_item_placer:15 ChromatiCraft TRUE
1412 Reika.ChromatiCraft.ModInterface.NEI.GlowFireHandler ChromatiCraft:chromaticraft_item_placer:60 ChromatiCraft TRUE
1413 Reika.ChromatiCraft.ModInterface.NEI.EnchantDecompHandler ChromatiCraft:chromaticraft_item_placer:69 ChromatiCraft TRUE
1414 Reika.ChromatiCraft.ModInterface.NEI.FabricatorHandler ChromatiCraft:chromaticraft_item_placer:23 ChromatiCraft TRUE
1415 tonius.neiintegration.mods.bigreactors.RecipeHandlerCyaniteReprocessor BigReactors:BRDevice:0 BigReactors TRUE
1416 ru.nanolive.draconicplus.common.fusioncrafting.nei.FusionCraftingNEI draconicplus:fusionCraftingCore draconicplus TRUE
1417 techguns.nei.TechgunsFabricatorNEIRecipeHandler Techguns:machineMultiBlock:4 Techguns TRUE
1418 techguns.nei.TechgunsReactionChamberNEIRecipeHandler Techguns:machineMultiBlock:1 Techguns TRUE
1419 techguns.nei.TechgunsChemLabNEIRecipeHandler Techguns:basicMachine:4 Techguns TRUE
1420 techguns.nei.TechgunsAmmoPressNEIRecipeHandler Techguns:basicMachine:0 Techguns TRUE
1421 techguns.nei.TechgunsMetalPressNEIRecipeHandler Techguns:basicMachine:1 Techguns TRUE
1422 techguns.nei.TechgunsChargingStationNEIRecipeHandler Techguns:basicMachine:9 Techguns TRUE
+65 -17
View File
@@ -170,12 +170,12 @@ ic2.neiIntegration.core.recipehandler.BlockCutterRecipeHandler,IndustrialCraft 2
ic2.neiIntegration.core.recipehandler.CentrifugeRecipeHandler,IndustrialCraft 2,IC2:blockMachine2:3,,IC2,TRUE,,,65,,5,,,,,,
ic2.neiIntegration.core.recipehandler.CompressorRecipeHandler,IndustrialCraft 2,IC2:blockMachine:5,,IC2,TRUE,,,65,,5,,,,,,
ic2.neiIntegration.core.recipehandler.ExtractorRecipeHandler,IndustrialCraft 2,IC2:blockMachine:4,,IC2,TRUE,,,65,,5,,,,,,
ic2.neiIntegration.core.recipehandler.FluidCannerRecipeHandler,IndustrialCraft 2,IC2:blockMachine:6,,IC2,TRUE,,,75,,4,,,,,,
ic2.neiIntegration.core.recipehandler.FluidCannerRecipeHandler,IndustrialCraft 2,IC2:blockMachine:6,,IC2,TRUE,,,85,,4,,,,,,
ic2.neiIntegration.core.recipehandler.LatheRecipeHandler,IndustrialCraft 2,IC2:blockMachine3:8,,IC2,TRUE,,,65,,5,,,,,,
ic2.neiIntegration.core.recipehandler.MaceratorRecipeHandler,IndustrialCraft 2,IC2:blockMachine:3,,IC2,TRUE,,,65,,5,,,,,,
ic2.neiIntegration.core.recipehandler.MetalFormerRecipeHandlerCutting,IndustrialCraft 2,IC2:blockMachine2:4,,IC2,TRUE,,,55,,6,,,,,,
ic2.neiIntegration.core.recipehandler.MetalFormerRecipeHandlerExtruding,IndustrialCraft 2,IC2:blockMachine2:4,,IC2,TRUE,,,55,,6,,,,,,
ic2.neiIntegration.core.recipehandler.MetalFormerRecipeHandlerRolling,IndustrialCraft 2,IC2:blockMachine2:4,,IC2,TRUE,,,55,,6,,,,,,
ic2.neiIntegration.core.recipehandler.MetalFormerRecipeHandlerCutting,IndustrialCraft 2,IC2:blockMachine2:4,,IC2,TRUE,,,65,,6,,,,,,
ic2.neiIntegration.core.recipehandler.MetalFormerRecipeHandlerExtruding,IndustrialCraft 2,IC2:blockMachine2:4,,IC2,TRUE,,,65,,6,,,,,,
ic2.neiIntegration.core.recipehandler.MetalFormerRecipeHandlerRolling,IndustrialCraft 2,IC2:blockMachine2:4,,IC2,TRUE,,,65,,6,,,,,,
ic2.neiIntegration.core.recipehandler.OreWashingRecipeHandler,IndustrialCraft 2,IC2:blockMachine2:5,,IC2,TRUE,,,,,,,,,,,
ic2.neiIntegration.core.recipehandler.ScrapboxRecipeHandler,IndustrialCraft 2,IC2:itemScrapbox,,IC2,TRUE,,,50,,6,,,,,,
ic2.neiIntegration.core.recipehandler.SolidCannerRecipeHandler,IndustrialCraft 2,IC2:blockMachine2:9,,IC2,TRUE,,,,,,,,,,,
@@ -373,11 +373,11 @@ NEIArcFurnaceHandlerCarrot Ingot,Immersive Engineering,minecraft:carrot,,Immersi
NEIArcFurnaceHandlerExtraction,Immersive Engineering,minecraft:glowstone_dust,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEIShaderBagHandler,Immersive Engineering,ImmersiveEngineering:shaderBag,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEIBlueprintHandler,Immersive Engineering,ImmersiveEngineering:woodenDevice:5,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEICokeOvenHandler,Immersive Engineering,ImmersiveEngineering:stoneDecoration:1,,ImmersiveEngineering,TRUE,,,71,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEIBlastFurnaceHandler,Immersive Engineering,ImmersiveEngineering:stoneDecoration:2,,ImmersiveEngineering,TRUE,,,71,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEISqueezerHandler,Immersive Engineering,ImmersiveEngineering:metalMultiblock:2,,ImmersiveEngineering,TRUE,,,71,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEIFermenterHandler,Immersive Engineering,ImmersiveEngineering:metalMultiblock:3,,ImmersiveEngineering,TRUE,,,71,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEIRefineryHandler,Immersive Engineering,ImmersiveEngineering:metalMultiblock:4,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEICokeOvenHandler,Immersive Engineering,ImmersiveEngineering:stoneDecoration:1,,ImmersiveEngineering,TRUE,,,71,166,2,,,,,,
blusunrize.immersiveengineering.client.nei.NEIBlastFurnaceHandler,Immersive Engineering,ImmersiveEngineering:stoneDecoration:2,,ImmersiveEngineering,TRUE,,,71,166,2,,,,,,
blusunrize.immersiveengineering.client.nei.NEISqueezerHandler,Immersive Engineering,ImmersiveEngineering:metalMultiblock:2,,ImmersiveEngineering,TRUE,,1,64,166,2,,,,,,
blusunrize.immersiveengineering.client.nei.NEIFermenterHandler,Immersive Engineering,ImmersiveEngineering:metalMultiblock:3,,ImmersiveEngineering,TRUE,,1,64,166,2,,,,,,
blusunrize.immersiveengineering.client.nei.NEIRefineryHandler,Immersive Engineering,ImmersiveEngineering:metalMultiblock:4,,ImmersiveEngineering,TRUE,,,65,166,2,,,,,,
blusunrize.immersiveengineering.client.nei.NEIBottlingMachineHandler,Immersive Engineering,minecraft:glass_bottle,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEIMetalPressHandler,Immersive Engineering,ImmersiveEngineering:metalMultiblock:13,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
blusunrize.immersiveengineering.client.nei.NEICrusherHandler,Immersive Engineering,ImmersiveEngineering:metalMultiblock:5,,ImmersiveEngineering,TRUE,,,71,166,5,,,,,,
@@ -410,13 +410,13 @@ cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCharger,Thermal Expansio
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCraftingMachine,Thermal Expansion,ThermalExpansion:Frame,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCraftingSecure,Thermal Expansion,ThermalExpansion:material:16,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCraftingUpgrade,Thermal Expansion,ThermalExpansion:Frame:3,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCrucible,Thermal Expansion,ThermalExpansion:Machine:4,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCrucible,Thermal Expansion,ThermalExpansion:Machine:4,,ThermalExpansion,TRUE,,,65,166,2,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerFurnace,Thermal Expansion,ThermalExpansion:Machine:0,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerInsolator,Thermal Expansion,ThermalExpansion:Machine:11,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerInsolator,Thermal Expansion,ThermalExpansion:Machine:11,,ThermalExpansion,TRUE,,,65,166,2,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerPulverizer,Thermal Expansion,ThermalExpansion:Machine:1,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerSawmill,Thermal Expansion,ThermalExpansion:Machine:2,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerSmelter,Thermal Expansion,ThermalExpansion:Machine:3,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerTransposer,Thermal Expansion,ThermalExpansion:Machine:5,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerTransposer,Thermal Expansion,ThermalExpansion:Machine:5,,ThermalExpansion,TRUE,,,65,166,2,,,,,,
mekanism.client.nei.ChemicalCrystallizerRecipeHandler,Mekanism,Mekanism:MachineBlock2:8,,Mekanism,TRUE,,,79,,4,,,,,,
mekanism.client.nei.ChemicalDissolutionChamberRecipeHandler,Mekanism,Mekanism:MachineBlock2:6,,Mekanism,TRUE,,,79,,4,,,,,,
mekanism.client.nei.ChemicalInfuserRecipeHandler,Mekanism,Mekanism:MachineBlock2:2,,Mekanism,TRUE,,,80,,4,,,,,,
@@ -437,7 +437,7 @@ mekanism.client.nei.ShapelessMekanismRecipeHandler,Mekanism,minecraft:crafting_t
mekanism.client.nei.SolarNeutronRecipeHandler,Mekanism,Mekanism:MachineBlock3:1,,Mekanism,TRUE,,,70,,5,,,,,,
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,,,,,,
exnihilo.compatibility.nei.RecipeHandlerSieve,Ex Nihilo,exnihilo:sifting_table,,exnihilo,TRUE,,,130,,1,,,,,,
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,,,,,,
@@ -496,8 +496,9 @@ nc.crafting.nei.FissionRecipeHandler,NuclearCraft,NuclearCraft:fissionReactorGra
nc.crafting.nei.FissionSteamRecipeHandler,NuclearCraft,NuclearCraft:fissionReactorSteamIdle,,NuclearCraft,TRUE,,,,,,,,,,,
nc.crafting.nei.FusionRecipeHandler,NuclearCraft,NuclearCraft:fusionReactor,,NuclearCraft,TRUE,,,,,,,,,,,
nc.crafting.nei.FusionSteamRecipeHandler,NuclearCraft,NuclearCraft:fusionReactorSteam,,NuclearCraft,TRUE,,,,,,,,,,,
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,,,,,,
nc.crafting.nei.ElectrolyserRecipeHandler,NuclearCraft,NuclearCraft:electrolyserIdle,,NuclearCraft,TRUE,,,65,,4,,,,,,
nc.crafting.nei.CrusherRecipeHandler,NuclearCraft,NuclearCraft:crusherIdle,,NuclearCraft,TRUE,,,65,,4,,,,,,
nc.crafting.nei.ElectricCrusherRecipeHandler,NuclearCraft,NuclearCraft:electricCrusherIdle,,NuclearCraft,TRUE,,,65,,4,,,,,,
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,,,,,,
net.blay09.mods.excompressum.compat.nei.RecipeHandlerHeavySieve,Ex Compressum,excompressum:heavySieve,,excompressum,TRUE,,,130,166,5,,,,,,
@@ -507,10 +508,15 @@ net.blay09.mods.excompressum.compat.nei.RecipeHandlerCompressedHammer,Ex Compres
com.InfinityRaider.AgriCraft.compatibility.NEI.NEICropMutationHandler,AgriCraft,AgriCraft:cropsItem,,AgriCraft,TRUE,,,85,166,5,,,,,,
com.InfinityRaider.AgriCraft.compatibility.NEI.NEICropProductHandler,AgriCraft,minecraft:farmland,,AgriCraft,TRUE,,,85,166,5,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerHarvester,MineFactory Reloaded,MineFactoryReloaded:machine.0:2,,MineFactoryReloaded,TRUE,,,,,,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerSewer,MineFactory Reloaded,MineFactoryReloaded:machine.0:10,,MineFactoryReloaded,TRUE,,,,,,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerSewer,MineFactory Reloaded,MineFactoryReloaded:machine.0:10,,MineFactoryReloaded,TRUE,,,,,5,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerGrinder,MineFactory Reloaded,MineFactoryReloaded:machine.0:13,,MineFactoryReloaded,TRUE,,,,,,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerBioReactor,MineFactory Reloaded,MineFactoryReloaded:machine.1:10,,MineFactoryReloaded,TRUE,,,,,,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerBioReactor,MineFactory Reloaded,MineFactoryReloaded:machine.1:10,,MineFactoryReloaded,TRUE,,,,,5,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerSlaughterhouse,MineFactory Reloaded,MineFactoryReloaded:machine.1:13,,MineFactoryReloaded,TRUE,,,,,,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerLaserDrill,MineFactory Reloaded,MineFactoryReloaded:machine.2:0,,MineFactoryReloaded,TRUE,,,,,5,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerSludgeBoiler,MineFactory Reloaded,MineFactoryReloaded:machine.0:9,,MineFactoryReloaded,TRUE,,,,,5,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerMeatPacker,MineFactory Reloaded,MineFactoryReloaded:machine.1:14,,MineFactoryReloaded,TRUE,,,,,5,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerComposter,MineFactory Reloaded,MineFactoryReloaded:machine.0:11,,MineFactoryReloaded,TRUE,,,,,,,,,,,
tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerLavaFabricator,MineFactory Reloaded,MineFactoryReloaded:machine.1:5,,MineFactoryReloaded,TRUE,,,,,,,,,,,
de.ellpeck.actuallyadditions.mod.nei.NEIBookletRecipe,Actually Additions,ActuallyAdditions:itemBooklet,,ActuallyAdditions,TRUE,,,,,,,,,,,
de.ellpeck.actuallyadditions.mod.nei.NEIHairyBallRecipe,Actually Additions,ActuallyAdditions:itemHairyBall,,ActuallyAdditions,TRUE,,,,,,,,,,,
de.ellpeck.actuallyadditions.mod.nei.NEICrusherRecipe$Double,Actually Additions,ActuallyAdditions:blockGrinderDouble,,ActuallyAdditions,TRUE,,,,,,,,,,,
@@ -531,3 +537,45 @@ vazkii.botania.client.integration.nei.RecipeHandlerLexicaBotania,Botania,Botania
neiplugins.forge.OreDictionaryList,NEIPlugins,minecraft:book,,NEIPlugins,TRUE,,,,,,,,,,,
neiplugins.forge.FluidRegistryList,NEIPlugins,minecraft:bucket,,NEIPlugins,TRUE,,,,,,,,,,,
de.ellpeck.actuallyadditions.mod.nei.NEITreasureChestRecipe,Actually Additions,ActuallyAdditions:blockTreasureChest,,ActuallyAdditions,TRUE,,,,,,,,,,,
factorization.nei.RecipeGrinder,Factorization,factorization:diamond_cutting_head,,factorization,TRUE,,,,,3,,,,,,
factorization.nei.RecipeSlagFurnace,Factorization,factorization:FzBlock:11,,factorization,TRUE,,,,,3,,,,,,
factorization.nei.RecipeCrystallizer,Factorization,factorization:FzBlock:19,,factorization,TRUE,,,100,,2,,,,,,
Reika.RotaryCraft.ModInterface.NEI.WorktableRecipeHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:75,,RotaryCraft,TRUE,,,,,5,,,,,,
Reika.RotaryCraft.ModInterface.NEI.ToolChargingHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:75,,RotaryCraft,TRUE,,,,,5,,,,,,
Reika.RotaryCraft.ModInterface.NEI.ToolCraftingHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:75,,RotaryCraft,TRUE,,,,,5,,,,,,
Reika.RotaryCraft.ModInterface.NEI.BlastFurnaceHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:45,,RotaryCraft,TRUE,,,115,,3,,,,,,
Reika.RotaryCraft.ModInterface.NEI.GrinderHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:11,,RotaryCraft,TRUE,,,70,,5,,,,,,
Reika.RotaryCraft.ModInterface.NEI.ExtractorHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:20,,RotaryCraft,TRUE,,,115,,3,,,,,,
Reika.RotaryCraft.ModInterface.NEI.FermenterHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:7,,RotaryCraft,TRUE,,,,,5,,,,,,
Reika.RotaryCraft.ModInterface.NEI.CompactorHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:22,,RotaryCraft,TRUE,,,115,,3,,,,,,
Reika.RotaryCraft.ModInterface.NEI.PulseJetHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:21,,RotaryCraft,TRUE,,,75,,5,,,,,,
Reika.RotaryCraft.ModInterface.NEI.FractionHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:25,,RotaryCraft,TRUE,,,,,,,,,,,Single Recipe
Reika.RotaryCraft.ModInterface.NEI.CrystallizerHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:110,,RotaryCraft,TRUE,,,75,,5,,,,,,
Reika.RotaryCraft.ModInterface.NEI.FridgeHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:118,,RotaryCraft,TRUE,,,,,,,,,,,Single Recipe
Reika.RotaryCraft.ModInterface.NEI.FillingStationHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:101,,RotaryCraft,TRUE,,,75,,5,,,,,,
Reika.RotaryCraft.ModInterface.NEI.FrictionHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:67,,RotaryCraft,TRUE,,,110,,3,,,,,,
Reika.RotaryCraft.ModInterface.NEI.ComposterHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:121,,RotaryCraft,TRUE,,,,,5,,,,,,
Reika.RotaryCraft.ModInterface.NEI.LavaMakerHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:91,,RotaryCraft,TRUE,,,75,,5,,,,,,
Reika.RotaryCraft.ModInterface.NEI.CentrifugeHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:125,,RotaryCraft,TRUE,,,80,,5,,,,,,
Reika.RotaryCraft.ModInterface.NEI.DryingBedHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:127,,RotaryCraft,TRUE,,,75,,5,,,,,,
Reika.RotaryCraft.ModInterface.NEI.WetterHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:128,,RotaryCraft,TRUE,,,,,5,,,,,,
Reika.RotaryCraft.ModInterface.NEI.FuelEnhancerHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:86,,RotaryCraft,TRUE,,,,,,,,,,,
Reika.RotaryCraft.ModInterface.NEI.DropProcessorHandler,RotaryCraft,RotaryCraft:rotarycraft_item_machine:129,,RotaryCraft,TRUE,,,,,,,,,,,Searching for the Usage of a Drop Processor results in a glitchy and useless first page
Reika.ReactorCraft.NEI.SynthesizerHandler,ReactorCraft,ReactorCraft:reactorcraft_item_placer:14,,ReactorCraft,TRUE,,,75,,2,,,,,,
Reika.ReactorCraft.NEI.UProcessorHandler,ReactorCraft,ReactorCraft:reactorcraft_item_placer:9,,ReactorCraft,TRUE,,,,,,,,,,,Single Recipe
Reika.ReactorCraft.NEI.CentrifugeHandler,ReactorCraft,ReactorCraft:reactorcraft_item_placer:8,,ReactorCraft,TRUE,,,,,,,,,,,Single Recipe
Reika.ReactorCraft.NEI.ElectrolyzerHandler,ReactorCraft,ReactorCraft:reactorcraft_item_placer:16,,ReactorCraft,TRUE,,,,,5,,,,,,
Reika.ChromatiCraft.ModInterface.NEI.CrystalBrewerHandler,ChromatiCraft,ChromatiCraft:chromaticraft_item_placer:7,,ChromatiCraft,TRUE,,,,,5,,,,,,
Reika.ChromatiCraft.ModInterface.NEI.CrystalFurnaceHandler,ChromatiCraft,ChromatiCraft:chromaticraft_item_placer:15,,ChromatiCraft,TRUE,,,,,5,,,,,,
Reika.ChromatiCraft.ModInterface.NEI.GlowFireHandler,ChromatiCraft,ChromatiCraft:chromaticraft_item_placer:60,,ChromatiCraft,TRUE,,,,,,,,,,,
Reika.ChromatiCraft.ModInterface.NEI.EnchantDecompHandler,ChromatiCraft,ChromatiCraft:chromaticraft_item_placer:69,,ChromatiCraft,TRUE,,,,,5,,,,,,
Reika.ChromatiCraft.ModInterface.NEI.FabricatorHandler,ChromatiCraft,ChromatiCraft:chromaticraft_item_placer:23,,ChromatiCraft,TRUE,,,,,,,,,,,
Reika.ChromatiCraft.ModInterface.NEI.PlantDustHandler,ChromatiCraft,ChromatiCraft:chromaticraft_block_decoflower:0,,ChromatiCraft,TRUE,,,,,3,,,,,,Anything other than 3 high tiling looks wrong
tonius.neiintegration.mods.bigreactors.RecipeHandlerCyaniteReprocessor,Big Reactors,BigReactors:BRDevice:0,,BigReactors,TRUE,,,,,,,,,,,
ru.nanolive.draconicplus.common.fusioncrafting.nei.FusionCraftingNEI,Draconic Plus,draconicplus:fusionCraftingCore,,draconicplus,TRUE,,,115,,2,,,,,,
techguns.nei.TechgunsFabricatorNEIRecipeHandler,Techguns,Techguns:machineMultiBlock:4,,Techguns,TRUE,,,70,,3,,,,,,
techguns.nei.TechgunsReactionChamberNEIRecipeHandler,Techguns,Techguns:machineMultiBlock:1,,Techguns,TRUE,,,70,,3,,,,,,
techguns.nei.TechgunsChemLabNEIRecipeHandler,Techguns,Techguns:basicMachine:4,,Techguns,TRUE,,,70,,3,,,,,,
techguns.nei.TechgunsAmmoPressNEIRecipeHandler,Techguns,Techguns:basicMachine:0,,Techguns,TRUE,,,75,,3,,,,,,
techguns.nei.TechgunsMetalPressNEIRecipeHandler,Techguns,Techguns:basicMachine:1,,Techguns,TRUE,,,75,,3,,,,,,
techguns.nei.TechgunsChargingStationNEIRecipeHandler,Techguns,Techguns:basicMachine:9,,Techguns,TRUE,,,65,,3,,,,,,
1 handler modName itemName nbtInfo modId modRequired excludedModId yShift handlerHeight handlerWidth maxRecipesPerPage imageResource imageX imageY imageWidth imageHeight itemNotes
170 ic2.neiIntegration.core.recipehandler.CentrifugeRecipeHandler IndustrialCraft 2 IC2:blockMachine2:3 IC2 TRUE 65 5
171 ic2.neiIntegration.core.recipehandler.CompressorRecipeHandler IndustrialCraft 2 IC2:blockMachine:5 IC2 TRUE 65 5
172 ic2.neiIntegration.core.recipehandler.ExtractorRecipeHandler IndustrialCraft 2 IC2:blockMachine:4 IC2 TRUE 65 5
173 ic2.neiIntegration.core.recipehandler.FluidCannerRecipeHandler IndustrialCraft 2 IC2:blockMachine:6 IC2 TRUE 75 85 4
174 ic2.neiIntegration.core.recipehandler.LatheRecipeHandler IndustrialCraft 2 IC2:blockMachine3:8 IC2 TRUE 65 5
175 ic2.neiIntegration.core.recipehandler.MaceratorRecipeHandler IndustrialCraft 2 IC2:blockMachine:3 IC2 TRUE 65 5
176 ic2.neiIntegration.core.recipehandler.MetalFormerRecipeHandlerCutting IndustrialCraft 2 IC2:blockMachine2:4 IC2 TRUE 55 65 6
177 ic2.neiIntegration.core.recipehandler.MetalFormerRecipeHandlerExtruding IndustrialCraft 2 IC2:blockMachine2:4 IC2 TRUE 55 65 6
178 ic2.neiIntegration.core.recipehandler.MetalFormerRecipeHandlerRolling IndustrialCraft 2 IC2:blockMachine2:4 IC2 TRUE 55 65 6
179 ic2.neiIntegration.core.recipehandler.OreWashingRecipeHandler IndustrialCraft 2 IC2:blockMachine2:5 IC2 TRUE
180 ic2.neiIntegration.core.recipehandler.ScrapboxRecipeHandler IndustrialCraft 2 IC2:itemScrapbox IC2 TRUE 50 6
181 ic2.neiIntegration.core.recipehandler.SolidCannerRecipeHandler IndustrialCraft 2 IC2:blockMachine2:9 IC2 TRUE
373 NEIArcFurnaceHandlerExtraction Immersive Engineering minecraft:glowstone_dust ImmersiveEngineering TRUE 65 166 5
374 blusunrize.immersiveengineering.client.nei.NEIShaderBagHandler Immersive Engineering ImmersiveEngineering:shaderBag ImmersiveEngineering TRUE 65 166 5
375 blusunrize.immersiveengineering.client.nei.NEIBlueprintHandler Immersive Engineering ImmersiveEngineering:woodenDevice:5 ImmersiveEngineering TRUE 65 166 5
376 blusunrize.immersiveengineering.client.nei.NEICokeOvenHandler Immersive Engineering ImmersiveEngineering:stoneDecoration:1 ImmersiveEngineering TRUE 71 166 5 2
377 blusunrize.immersiveengineering.client.nei.NEIBlastFurnaceHandler Immersive Engineering ImmersiveEngineering:stoneDecoration:2 ImmersiveEngineering TRUE 71 166 5 2
378 blusunrize.immersiveengineering.client.nei.NEISqueezerHandler Immersive Engineering ImmersiveEngineering:metalMultiblock:2 ImmersiveEngineering TRUE 1 71 64 166 5 2
379 blusunrize.immersiveengineering.client.nei.NEIFermenterHandler Immersive Engineering ImmersiveEngineering:metalMultiblock:3 ImmersiveEngineering TRUE 1 71 64 166 5 2
380 blusunrize.immersiveengineering.client.nei.NEIRefineryHandler Immersive Engineering ImmersiveEngineering:metalMultiblock:4 ImmersiveEngineering TRUE 65 166 5 2
381 blusunrize.immersiveengineering.client.nei.NEIBottlingMachineHandler Immersive Engineering minecraft:glass_bottle ImmersiveEngineering TRUE 65 166 5
382 blusunrize.immersiveengineering.client.nei.NEIMetalPressHandler Immersive Engineering ImmersiveEngineering:metalMultiblock:13 ImmersiveEngineering TRUE 65 166 5
383 blusunrize.immersiveengineering.client.nei.NEICrusherHandler Immersive Engineering ImmersiveEngineering:metalMultiblock:5 ImmersiveEngineering TRUE 71 166 5
410 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCraftingMachine Thermal Expansion ThermalExpansion:Frame ThermalExpansion TRUE 65 166 5
411 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCraftingSecure Thermal Expansion ThermalExpansion:material:16 ThermalExpansion TRUE 65 166 5
412 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCraftingUpgrade Thermal Expansion ThermalExpansion:Frame:3 ThermalExpansion TRUE 65 166 5
413 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCrucible Thermal Expansion ThermalExpansion:Machine:4 ThermalExpansion TRUE 65 166 5 2
414 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerFurnace Thermal Expansion ThermalExpansion:Machine:0 ThermalExpansion TRUE 65 166 5
415 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerInsolator Thermal Expansion ThermalExpansion:Machine:11 ThermalExpansion TRUE 65 166 5 2
416 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerPulverizer Thermal Expansion ThermalExpansion:Machine:1 ThermalExpansion TRUE 65 166 5
417 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerSawmill Thermal Expansion ThermalExpansion:Machine:2 ThermalExpansion TRUE 65 166 5
418 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerSmelter Thermal Expansion ThermalExpansion:Machine:3 ThermalExpansion TRUE 65 166 5
419 cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerTransposer Thermal Expansion ThermalExpansion:Machine:5 ThermalExpansion TRUE 65 166 5 2
420 mekanism.client.nei.ChemicalCrystallizerRecipeHandler Mekanism Mekanism:MachineBlock2:8 Mekanism TRUE 79 4
421 mekanism.client.nei.ChemicalDissolutionChamberRecipeHandler Mekanism Mekanism:MachineBlock2:6 Mekanism TRUE 79 4
422 mekanism.client.nei.ChemicalInfuserRecipeHandler Mekanism Mekanism:MachineBlock2:2 Mekanism TRUE 80 4
437 mekanism.client.nei.SolarNeutronRecipeHandler Mekanism Mekanism:MachineBlock3:1 Mekanism TRUE 70 5
438 mekanism.client.nei.ThermalEvaporationRecipeHandler Mekanism Mekanism:BasicBlock:14 Mekanism TRUE 62 5
439 exnihilo.compatibility.nei.RecipeHandlerHammer Ex Nihilo exnihilo:hammer_iron exnihilo TRUE 58 5
440 exnihilo.compatibility.nei.RecipeHandlerSieve Ex Nihilo exnihilo:sifting_table exnihilo TRUE 130 2 1
441 gregtech.Alloy GregTech-Addon gregtech_addon:machine:56 gregtech_addon TRUE 15 145 166 2
442 gregtech.Assembler GregTech-Addon gregtech_addon:machine:60 gregtech_addon TRUE 15 145 166 2
443 gregtech.Bender GregTech-Addon gregtech_addon:machine:59 gregtech_addon TRUE 15 145 166 2
496 nc.crafting.nei.FissionSteamRecipeHandler NuclearCraft NuclearCraft:fissionReactorSteamIdle NuclearCraft TRUE
497 nc.crafting.nei.FusionRecipeHandler NuclearCraft NuclearCraft:fusionReactor NuclearCraft TRUE
498 nc.crafting.nei.FusionSteamRecipeHandler NuclearCraft NuclearCraft:fusionReactorSteam NuclearCraft TRUE
499 ganymedes01.etfuturum.NEI_EtFuturum_Config$NEI_Recipes_Smoker nc.crafting.nei.ElectrolyserRecipeHandler EtFuturum Requiem NuclearCraft etfuturum:lit_smoker NuclearCraft:electrolyserIdle etfuturum NuclearCraft TRUE 65 166 5 4
500 ganymedes01.etfuturum.NEI_EtFuturum_Config$NEI_Recipes_BlastFurnace nc.crafting.nei.CrusherRecipeHandler EtFuturum Requiem NuclearCraft etfuturum:lit_blast_furnace NuclearCraft:crusherIdle etfuturum NuclearCraft TRUE 65 166 5 4
501 nc.crafting.nei.ElectricCrusherRecipeHandler NuclearCraft NuclearCraft:electricCrusherIdle NuclearCraft TRUE 65 4
502 connor135246.campfirebackport.client.compat.nei.NEICampfireRecipeHandler Campfire Backport campfirebackport:campfire campfirebackport TRUE 65 166 5
503 connor135246.campfirebackport.client.compat.nei.NEICampfireStateChangerHandler Campfire Backport campfirebackport:campfire_base campfirebackport TRUE 65 166 5
504 net.blay09.mods.excompressum.compat.nei.RecipeHandlerHeavySieve Ex Compressum excompressum:heavySieve excompressum TRUE 130 166 5
508 com.InfinityRaider.AgriCraft.compatibility.NEI.NEICropMutationHandler AgriCraft AgriCraft:cropsItem AgriCraft TRUE 85 166 5
509 com.InfinityRaider.AgriCraft.compatibility.NEI.NEICropProductHandler AgriCraft minecraft:farmland AgriCraft TRUE 85 166 5
510 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerHarvester MineFactory Reloaded MineFactoryReloaded:machine.0:2 MineFactoryReloaded TRUE
511 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerSewer MineFactory Reloaded MineFactoryReloaded:machine.0:10 MineFactoryReloaded TRUE 5
512 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerGrinder MineFactory Reloaded MineFactoryReloaded:machine.0:13 MineFactoryReloaded TRUE
513 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerBioReactor MineFactory Reloaded MineFactoryReloaded:machine.1:10 MineFactoryReloaded TRUE 5
514 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerSlaughterhouse MineFactory Reloaded MineFactoryReloaded:machine.1:13 MineFactoryReloaded TRUE
515 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerLaserDrill MineFactory Reloaded MineFactoryReloaded:machine.2:0 MineFactoryReloaded TRUE 5
516 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerSludgeBoiler MineFactory Reloaded MineFactoryReloaded:machine.0:9 MineFactoryReloaded TRUE 5
517 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerMeatPacker MineFactory Reloaded MineFactoryReloaded:machine.1:14 MineFactoryReloaded TRUE 5
518 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerComposter MineFactory Reloaded MineFactoryReloaded:machine.0:11 MineFactoryReloaded TRUE
519 tonius.neiintegration.mods.minefactoryreloaded.RecipeHandlerLavaFabricator MineFactory Reloaded MineFactoryReloaded:machine.1:5 MineFactoryReloaded TRUE
520 de.ellpeck.actuallyadditions.mod.nei.NEIBookletRecipe Actually Additions ActuallyAdditions:itemBooklet ActuallyAdditions TRUE
521 de.ellpeck.actuallyadditions.mod.nei.NEIHairyBallRecipe Actually Additions ActuallyAdditions:itemHairyBall ActuallyAdditions TRUE
522 de.ellpeck.actuallyadditions.mod.nei.NEICrusherRecipe$Double Actually Additions ActuallyAdditions:blockGrinderDouble ActuallyAdditions TRUE
537 neiplugins.forge.OreDictionaryList NEIPlugins minecraft:book NEIPlugins TRUE
538 neiplugins.forge.FluidRegistryList NEIPlugins minecraft:bucket NEIPlugins TRUE
539 de.ellpeck.actuallyadditions.mod.nei.NEITreasureChestRecipe Actually Additions ActuallyAdditions:blockTreasureChest ActuallyAdditions TRUE
540 factorization.nei.RecipeGrinder Factorization factorization:diamond_cutting_head factorization TRUE 3
541 factorization.nei.RecipeSlagFurnace Factorization factorization:FzBlock:11 factorization TRUE 3
542 factorization.nei.RecipeCrystallizer Factorization factorization:FzBlock:19 factorization TRUE 100 2
543 Reika.RotaryCraft.ModInterface.NEI.WorktableRecipeHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:75 RotaryCraft TRUE 5
544 Reika.RotaryCraft.ModInterface.NEI.ToolChargingHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:75 RotaryCraft TRUE 5
545 Reika.RotaryCraft.ModInterface.NEI.ToolCraftingHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:75 RotaryCraft TRUE 5
546 Reika.RotaryCraft.ModInterface.NEI.BlastFurnaceHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:45 RotaryCraft TRUE 115 3
547 Reika.RotaryCraft.ModInterface.NEI.GrinderHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:11 RotaryCraft TRUE 70 5
548 Reika.RotaryCraft.ModInterface.NEI.ExtractorHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:20 RotaryCraft TRUE 115 3
549 Reika.RotaryCraft.ModInterface.NEI.FermenterHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:7 RotaryCraft TRUE 5
550 Reika.RotaryCraft.ModInterface.NEI.CompactorHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:22 RotaryCraft TRUE 115 3
551 Reika.RotaryCraft.ModInterface.NEI.PulseJetHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:21 RotaryCraft TRUE 75 5
552 Reika.RotaryCraft.ModInterface.NEI.FractionHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:25 RotaryCraft TRUE Single Recipe
553 Reika.RotaryCraft.ModInterface.NEI.CrystallizerHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:110 RotaryCraft TRUE 75 5
554 Reika.RotaryCraft.ModInterface.NEI.FridgeHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:118 RotaryCraft TRUE Single Recipe
555 Reika.RotaryCraft.ModInterface.NEI.FillingStationHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:101 RotaryCraft TRUE 75 5
556 Reika.RotaryCraft.ModInterface.NEI.FrictionHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:67 RotaryCraft TRUE 110 3
557 Reika.RotaryCraft.ModInterface.NEI.ComposterHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:121 RotaryCraft TRUE 5
558 Reika.RotaryCraft.ModInterface.NEI.LavaMakerHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:91 RotaryCraft TRUE 75 5
559 Reika.RotaryCraft.ModInterface.NEI.CentrifugeHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:125 RotaryCraft TRUE 80 5
560 Reika.RotaryCraft.ModInterface.NEI.DryingBedHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:127 RotaryCraft TRUE 75 5
561 Reika.RotaryCraft.ModInterface.NEI.WetterHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:128 RotaryCraft TRUE 5
562 Reika.RotaryCraft.ModInterface.NEI.FuelEnhancerHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:86 RotaryCraft TRUE
563 Reika.RotaryCraft.ModInterface.NEI.DropProcessorHandler RotaryCraft RotaryCraft:rotarycraft_item_machine:129 RotaryCraft TRUE Searching for the Usage of a Drop Processor results in a glitchy and useless first page
564 Reika.ReactorCraft.NEI.SynthesizerHandler ReactorCraft ReactorCraft:reactorcraft_item_placer:14 ReactorCraft TRUE 75 2
565 Reika.ReactorCraft.NEI.UProcessorHandler ReactorCraft ReactorCraft:reactorcraft_item_placer:9 ReactorCraft TRUE Single Recipe
566 Reika.ReactorCraft.NEI.CentrifugeHandler ReactorCraft ReactorCraft:reactorcraft_item_placer:8 ReactorCraft TRUE Single Recipe
567 Reika.ReactorCraft.NEI.ElectrolyzerHandler ReactorCraft ReactorCraft:reactorcraft_item_placer:16 ReactorCraft TRUE 5
568 Reika.ChromatiCraft.ModInterface.NEI.CrystalBrewerHandler ChromatiCraft ChromatiCraft:chromaticraft_item_placer:7 ChromatiCraft TRUE 5
569 Reika.ChromatiCraft.ModInterface.NEI.CrystalFurnaceHandler ChromatiCraft ChromatiCraft:chromaticraft_item_placer:15 ChromatiCraft TRUE 5
570 Reika.ChromatiCraft.ModInterface.NEI.GlowFireHandler ChromatiCraft ChromatiCraft:chromaticraft_item_placer:60 ChromatiCraft TRUE
571 Reika.ChromatiCraft.ModInterface.NEI.EnchantDecompHandler ChromatiCraft ChromatiCraft:chromaticraft_item_placer:69 ChromatiCraft TRUE 5
572 Reika.ChromatiCraft.ModInterface.NEI.FabricatorHandler ChromatiCraft ChromatiCraft:chromaticraft_item_placer:23 ChromatiCraft TRUE
573 Reika.ChromatiCraft.ModInterface.NEI.PlantDustHandler ChromatiCraft ChromatiCraft:chromaticraft_block_decoflower:0 ChromatiCraft TRUE 3 Anything other than 3 high tiling looks wrong
574 tonius.neiintegration.mods.bigreactors.RecipeHandlerCyaniteReprocessor Big Reactors BigReactors:BRDevice:0 BigReactors TRUE
575 ru.nanolive.draconicplus.common.fusioncrafting.nei.FusionCraftingNEI Draconic Plus draconicplus:fusionCraftingCore draconicplus TRUE 115 2
576 techguns.nei.TechgunsFabricatorNEIRecipeHandler Techguns Techguns:machineMultiBlock:4 Techguns TRUE 70 3
577 techguns.nei.TechgunsReactionChamberNEIRecipeHandler Techguns Techguns:machineMultiBlock:1 Techguns TRUE 70 3
578 techguns.nei.TechgunsChemLabNEIRecipeHandler Techguns Techguns:basicMachine:4 Techguns TRUE 70 3
579 techguns.nei.TechgunsAmmoPressNEIRecipeHandler Techguns Techguns:basicMachine:0 Techguns TRUE 75 3
580 techguns.nei.TechgunsMetalPressNEIRecipeHandler Techguns Techguns:basicMachine:1 Techguns TRUE 75 3
581 techguns.nei.TechgunsChargingStationNEIRecipeHandler Techguns Techguns:basicMachine:9 Techguns TRUE 65 3
+11 -1
View File
@@ -44,12 +44,16 @@ nei.inventory.magnet.enable=Enable magnet mode
nei.inventory.magnet.1=Turn magnet mode on
nei.inventory.magnet.0=Turn magnet mode off
nei.inventory.dawn.enable=Enable dawn-noon
nei.inventory.dawn.disable=Right-click: Disable dawn-noon phase
nei.inventory.dawn.set=Set time to dawn
nei.inventory.noon.enable=Enable noon-dusk
nei.inventory.noon.disable=Right-click: Disable noon-dusk phase
nei.inventory.noon.set=Set time to noon
nei.inventory.dusk.enable=Enable dusk-midnight
nei.inventory.dusk.disable=Right-click: Disable dusk-midnight phase
nei.inventory.dusk.set=Set time to dusk
nei.inventory.midnight.enable=Enable midnight-dawn
nei.inventory.midnight.disable=Right-click: Disable midnight-dawn phase
nei.inventory.midnight.set=Set time to midnight
nei.inventory.heal=Heal the player
nei.inventory.current.gamemode.0=Current gamemode: survival
@@ -148,6 +152,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.recipeTooltipsEnabled=Show recipe tooltips in Bookmarks
nei.options.inventory.recipeTooltipsEnabled.true=Yes
nei.options.inventory.recipeTooltipsEnabled.false=No
nei.options.inventory.bookmarksAnimationEnabled=REI Style Animation in Bookmarks
nei.options.inventory.bookmarksAnimationEnabled.true=Yes
nei.options.inventory.bookmarksAnimationEnabled.false=No
@@ -157,6 +164,9 @@ nei.options.inventory.showRecipeMarker.false=No
nei.options.inventory.showItemQuantityWidget=Show Item Quantity Widget
nei.options.inventory.showItemQuantityWidget.true=Yes
nei.options.inventory.showItemQuantityWidget.false=No
nei.options.inventory.centerSearchWidget=Center Search Widget
nei.options.inventory.centerSearchWidget.true=Yes
nei.options.inventory.centerSearchWidget.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
@@ -335,4 +345,4 @@ 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
nei.presets.label.selected=%s Presets