diff --git a/.github/workflows/publish_project.yml b/.github/workflows/publish_project.yml index 2172ac6806e..a6bb305d5bb 100644 --- a/.github/workflows/publish_project.yml +++ b/.github/workflows/publish_project.yml @@ -41,6 +41,12 @@ jobs: generate_release_notes: true fail_on_unmatched_files: true + - name: Publish to Maven + env: + MAVEN_USER: "${{ secrets.MAVEN_USER }}" + MAVEN_PASSWORD: "${{ secrets.MAVEN_PASSWORD }}" + run: ./gradlew publish + - name: Publish to Curseforge env: CURSEFORGE_API_KEY: "${{ secrets.CURSEFORGE_API_KEY }}" diff --git a/README.md b/README.md index 5876b6d1b60..8a4fcfa7209 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Anything else? Sure come to [Discord](https://discord.gg/bWSWuYvURP). ## Credited Works Heating Coil Textures, Wooden Forms, World Accelerators, and the Extreme Combustion Engine are from the **[GregTech: New Horizons Modpack](https://www.curseforge.com/minecraft/modpacks/gt-new-horizons)**. -Primitive Water Pump and Super Tank GUI Textures are from the **[IMPACT: GREGTECH EDITION Modpack](https://gtimpact.space/)**. +Primitive Water Pump and Super Tank GUI Textures are from the **[IMPACT: GREGTECH EDITION Modpack](https://gt-impact.github.io/)**. Ender Fluid Link Cover, Auto-Maintenance Hatch, Optical Fiber, and Data Bank Textures are from **[TecTech](https://github.com/Technus/TecTech)**. diff --git a/build.gradle b/build.gradle index 913152a71c5..8ea7b057a37 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -//version: 1702805890 +//version: 1707682661 /* * DO NOT CHANGE THIS FILE! * Also, you may replace this file at any time if there is an update available. @@ -24,9 +24,9 @@ plugins { id 'eclipse' id 'maven-publish' id 'org.jetbrains.gradle.plugin.idea-ext' version '1.1.7' - id 'com.gtnewhorizons.retrofuturagradle' version '1.3.25' - id 'net.darkhax.curseforgegradle' version '1.1.17' apply false - id 'com.modrinth.minotaur' version '2.8.6' apply false + id 'com.gtnewhorizons.retrofuturagradle' version '1.3.33' + id 'net.darkhax.curseforgegradle' version '1.1.18' apply false + id 'com.modrinth.minotaur' version '2.8.7' apply false id 'com.diffplug.spotless' version '6.13.0' apply false id 'com.palantir.git-version' version '3.0.0' apply false id 'com.github.johnrengelman.shadow' version '8.1.1' apply false @@ -62,6 +62,7 @@ propertyDefaultIfUnset("generateGradleTokenClass", "") propertyDefaultIfUnset("gradleTokenModId", "") propertyDefaultIfUnset("gradleTokenModName", "") propertyDefaultIfUnset("gradleTokenVersion", "") +propertyDefaultIfUnset("useSrcApiPath", false) propertyDefaultIfUnset("includeWellKnownRepositories", true) propertyDefaultIfUnset("includeCommonDevEnvMods", true) propertyDefaultIfUnset("noPublishedSources", false) @@ -105,9 +106,16 @@ if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists( } if (apiPackage) { - targetPackageJava = javaSourceDir + modGroupPath + '/' + apiPackagePath - targetPackageScala = scalaSourceDir + modGroupPath + '/' + apiPackagePath - targetPackageKotlin = kotlinSourceDir + modGroupPath + '/' + apiPackagePath + final String endApiPath = modGroupPath + '/' + apiPackagePath + if (useSrcApiPath) { + targetPackageJava = 'src/api/java/' + endApiPath + targetPackageScala = 'src/api/scala/' + endApiPath + targetPackageKotlin = 'src/api/kotlin/' + endApiPath + } else { + targetPackageJava = javaSourceDir + endApiPath + targetPackageScala = scalaSourceDir + endApiPath + targetPackageKotlin = kotlinSourceDir + endApiPath + } if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists() && !getFile(targetPackageKotlin).exists()) { throw new GradleException("Could not resolve \"apiPackage\"! Could not find ${targetPackageJava} or ${targetPackageScala} or ${targetPackageKotlin}") } @@ -436,8 +444,11 @@ repositories { } maven { name 'GTNH Maven' - url 'http://jenkins.usrv.eu:8081/nexus/content/groups/public' - allowInsecureProtocol = true + url 'https://nexus.gtnewhorizons.com/repository/public/' + } + maven { + name 'GTCEu Maven' + url 'https://maven.gtceu.com' } } if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) { @@ -466,9 +477,25 @@ configurations { config.extendsFrom(shadowCompile) } } + + create("runtimeOnlyNonPublishable") { + description = "Runtime only dependencies that are not published alongside the jar" + 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) + runtimeClasspath.extendsFrom(runtimeOnlyNonPublishable) + testRuntimeClasspath.extendsFrom(runtimeOnlyNonPublishable) } -String mixinProviderSpec = 'zone.rong:mixinbooter:8.9' +String mixinProviderSpec = 'zone.rong:mixinbooter:9.1' dependencies { if (usesMixins.toBoolean()) { annotationProcessor 'org.ow2.asm:asm-debug-all:5.2' @@ -486,7 +513,7 @@ dependencies { transitive = false } } else if (forceEnableMixins.toBoolean()) { - runtimeOnly(mixinProviderSpec) + runtimeOnlyNonPublishable(mixinProviderSpec) } if (enableJUnit.toBoolean()) { @@ -496,8 +523,8 @@ dependencies { } if (enableModernJavaSyntax.toBoolean()) { - annotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.0' - compileOnly('com.github.bsideup.jabel:jabel-javac-plugin:1.0.0') { + annotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.1' + compileOnly('com.github.bsideup.jabel:jabel-javac-plugin:1.0.1') { transitive = false } // workaround for https://github.com/bsideup/jabel/issues/174 @@ -506,8 +533,8 @@ dependencies { patchedMinecraft 'me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0' // allow Jabel to work in tests - testAnnotationProcessor "com.github.bsideup.jabel:jabel-javac-plugin:1.0.0" - testCompileOnly("com.github.bsideup.jabel:jabel-javac-plugin:1.0.0") { + testAnnotationProcessor "com.github.bsideup.jabel:jabel-javac-plugin:1.0.1" + testCompileOnly("com.github.bsideup.jabel:jabel-javac-plugin:1.0.1") { transitive = false // We only care about the 1 annotation class } testCompileOnly "me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0" @@ -520,9 +547,13 @@ dependencies { } if (includeCommonDevEnvMods.toBoolean()) { - implementation 'mezz.jei:jei_1.12.2:4.16.1.302' - //noinspection DependencyNotationArgument - implementation rfg.deobf('curse.maven:top-245211:2667280') // TOP 1.4.28 + if (!(modId.equals('jei'))) { + implementation 'mezz.jei:jei_1.12.2:4.16.1.302' + } + if (!(modId.equals('theoneprobe'))) { + //noinspection DependencyNotationArgument + implementation rfg.deobf('curse.maven:top-245211:2667280') // TOP 1.4.28 + } } } @@ -534,6 +565,12 @@ pluginManager.withPlugin('org.jetbrains.kotlin.kapt') { } } +configurations.configureEach { + resolutionStrategy.dependencySubstitution { + substitute module('org.scala-lang:scala-library:2.11.1') using module('org.scala-lang:scala-library:2.11.5') because('To allow mixing with Java 8 targets') + } +} + if (getFile('dependencies.gradle').exists()) { apply from: 'dependencies.gradle' } else if (getFile('dependencies.gradle.kts').exists()) { @@ -675,6 +712,19 @@ jar { it.isDirectory() ? it : zipTree(it) } } + + if (useSrcApiPath && apiPackage) { + from sourceSets.api.output + dependsOn apiClasses + + include "${modGroupPath}/**" + include "assets/**" + include "mcmod.info" + include "pack.mcmeta" + if (accessTransformersFile) { + include "META-INF/${accessTransformersFile}" + } + } } // Configure default run tasks @@ -691,12 +741,21 @@ if (separateRunDirectories.toBoolean()) { // Create API library jar tasks.register('apiJar', Jar) { archiveClassifier.set 'api' - from(sourceSets.main.java) { - include "${modGroupPath}/${apiPackagePath}/**" - } + if (useSrcApiPath) { + from(sourceSets.api.java) { + include "${modGroupPath}/${apiPackagePath}/**" + } + from(sourceSets.api.output) { + include "${modGroupPath}/${apiPackagePath}/**" + } + } else { + from(sourceSets.main.java) { + include "${modGroupPath}/${apiPackagePath}/**" + } - from(sourceSets.main.output) { - include "${modGroupPath}/${apiPackagePath}/**" + from(sourceSets.main.output) { + include "${modGroupPath}/${apiPackagePath}/**" + } } } @@ -906,6 +965,12 @@ if (cfApiKey.isPresent() || deploymentDebug.toBoolean()) { } String[] parts = dep.split(':') String type = parts[0], slug = parts[1] + def types = [ + 'req' : 'requiredDependency', 'required': 'requiredDependency', + 'opt' : 'optionalDependency', 'optional': 'optionalDependency', + 'embed' : 'embeddedLibrary', 'embedded': 'embeddedLibrary', + 'incomp': 'incompatible', 'fail' : 'incompatible'] + if (types.containsKey(type)) type = types[type] if (!(type in ['requiredDependency', 'embeddedLibrary', 'optionalDependency', 'tool', 'incompatible'])) { throw new Exception('Invalid Curseforge dependency type: ' + type) } @@ -948,7 +1013,7 @@ if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) { } String[] parts = dep.split(':') String[] qual = parts[0].split('-') - addModrinthDep(qual[0], qual[1], parts[1]) + addModrinthDep(qual[0], qual.length > 1 ? qual[1] : 'project', parts[1]) } } tasks.modrinth.dependsOn(build) @@ -957,9 +1022,17 @@ if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) { def addModrinthDep(String scope, String type, String name) { com.modrinth.minotaur.dependencies.Dependency dep + def types = [ + 'req' : 'required', + 'opt' : 'optional', + 'embed' : 'embedded', + 'incomp': 'incompatible', 'fail': 'incompatible'] + if (types.containsKey(scope)) scope = types[scope] if (!(scope in ['required', 'optional', 'incompatible', 'embedded'])) { throw new Exception('Invalid modrinth dependency scope: ' + scope) } + types = ['proj': 'project', '': 'project', 'p': 'project', 'ver': 'version', 'v': 'version'] + if (types.containsKey(type)) type = types[type] switch (type) { case 'project': dep = new ModDependency(name, scope) diff --git a/dependencies.gradle b/dependencies.gradle index 82ef07ce6a8..4ab81db91bd 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,58 +1,71 @@ //file:noinspection DependencyNotationArgument // TODO remove when fixed in RFG ^ /* - * Add your dependencies here. Common configurations: - * - implementation("group:name:version:classifier"): if you need this for internal implementation details of the mod. - * Available at compiletime and runtime for your environment. - * - * - compileOnlyApi("g:n:v:c"): if you need this for internal implementation details of the mod. - * Available at compiletime but not runtime for your environment. - * + * Add your dependencies here. Supported configurations: + * - api("group:name:version:classifier"): if you use the types from this dependency in the public API of this mod + * Available at runtime and compiletime for mods depending on this mod + * - implementation("g:n:v:c"): if you need this for internal implementation details of the mod, but none of it is visible via the public API + * Available at runtime but not compiletime for mods depending on this mod + * - compileOnly("g:n:v:c"): if the mod you're building doesn't need this dependency during runtime at all, e.g. for optional mods + * Not available at all for mods depending on this mod, only visible at compiletime for this mod + * - compileOnlyApi("g:n:v:c"): like compileOnly, but also visible at compiletime for mods depending on this mod + * Available at compiletime but not runtime for mods depending on this mod + * - runtimeOnlyNonPublishable("g:n:v:c"): if you want to include a mod in this mod's runClient/runServer runs, but not publish it as a dependency + * Not available at all for mods depending on this mod, only visible at runtime for this mod + * - devOnlyNonPublishable("g:n:v:c"): a combination of runtimeOnlyNonPublishable and compileOnly for dependencies present at both compiletime and runtime, + * but not published as Maven dependencies - useful for RFG-deobfuscated dependencies or local testing + * - runtimeOnly("g:n:v:c"): if you don't need this at compile time, but want it to be present at runtime + * Available at runtime for mods depending on this mod * - annotationProcessor("g:n:v:c"): mostly for java compiler plugins, if you know you need this, use it, otherwise don't worry + * - testCONFIG("g:n:v:c") - replace CONFIG by one of the above (except api), same as above but for the test sources instead of main * - * - testCONFIG("g:n:v:c"): replace CONFIG by one of the above, same as above but for the test sources instead of main + * - shadowImplementation("g:n:v:c"): effectively the same as API, but the dependency is included in your jar under a renamed package name + * Requires you to enable usesShadowedDependencies in gradle.properties + * For more info, see https://github.com/GregTechCEu/Buildscripts/blob/master/docs/shadow.md * - * You can exclude transitive dependencies (dependencies of the chosen dependency) by appending { transitive = false } if needed. + * You can exclude transitive dependencies (dependencies of the chosen dependency) by appending { transitive = false } if needed, + * but use this sparingly as it can break using your mod as another mod's dependency if you're not careful. + * + * To depend on obfuscated jars you can use `devOnlyNonPublishable(rfg.deobf("dep:spec:1.2.3"))` to fetch an obfuscated jar from maven, + * or `devOnlyNonPublishable(rfg.deobf(project.files("libs/my-mod-jar.jar")))` to use a file. * * To add a mod with CurseMaven, replace '("g:n:v:c")' in the above with 'rfg.deobf("curse.maven:project_slug-project_id:file_id")' - * Example: implementation rfg.deobf("curse.maven:gregtech-ce-unofficial-557242:4527757") + * Example: devOnlyNonPublishable(rfg.deobf("curse.maven:top-245211:2667280")) + * + * Gradle names for some of the configuration can be misleading, compileOnlyApi and runtimeOnly both get published as dependencies in Maven, but compileOnly does not. + * The buildscript adds runtimeOnlyNonPublishable to also have a runtime dependency that's not published. * - * For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph + * For more details, see https://docs.gradle.org/8.4/userguide/java_library_plugin.html#sec:java_library_configurations_graph */ dependencies { - // Hard Dependencies - - // the CCL deobf jar uses very old MCP mappings, making it error at runtime in runClient/runServer - // therefore we manually deobf the regular jar - implementation rfg.deobf("curse.maven:codechicken-lib-1-8-242818:2779848") // CCL 3.2.3.358 - implementation("com.cleanroommc:modularui:2.4.1") { transitive = false } - - // Soft Dependencies - // Can change any of these from compileOnlyApi -> implementation to test them in-game. - - implementation "CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.684" - implementation rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31 - implementation("com.cleanroommc:groovyscript:0.7.1") { transitive = false } - implementation rfg.deobf("curse.maven:ae2-extended-life-570458:4402048") // AE2UEL 0.55.6 + // Published dependencies + api("codechicken:codechickenlib:3.2.3.358") + api("com.cleanroommc:modularui:2.4.3") { transitive = false } + api("com.cleanroommc:groovyscript:1.0.1") { transitive = false } + api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.684") + api rfg.deobf("curse.maven:ae2-extended-life-570458:4402048") // AE2UEL 0.55.6 + api rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31 - compileOnlyApi rfg.deobf("curse.maven:opencomputers-223008:4526246") // OpenComputers 1.8.0+9833087 - compileOnlyApi "curse.maven:journeymap-32274:2916002" // Journeymap 5.7.1 - compileOnlyApi "curse.maven:voxelmap-225179:3029445" // VoxelMap 1.9.28 - compileOnlyApi "curse.maven:xaeros-263420:4516832" // Xaero's Minimap 23.4.1 - compileOnlyApi rfg.deobf("curse.maven:hwyla-253449:2568751") // HWYLA 1.8.26-B41 - compileOnlyApi rfg.deobf("curse.maven:baubles-227083:2518667") // Baubles 1.5.2 - compileOnlyApi rfg.deobf("curse.maven:forestry-59751:2684780") // Forestry 5.8.2.387 - compileOnlyApi rfg.deobf("curse.maven:chisel-235279:2915375") // Chisel 1.0.2.45 + // Non-published dependencies + // Change any to devOnlyNonPublishable to test them in-game. + compileOnly("curse.maven:journeymap-32274:2916002") // Journeymap 5.7.1 + compileOnly("curse.maven:voxelmap-225179:3029445") // VoxelMap 1.9.28 + compileOnly("curse.maven:xaeros-263420:4516832") // Xaero's Minimap 23.4.1 + compileOnly rfg.deobf("curse.maven:opencomputers-223008:4526246") // OpenComputers 1.8.0+9833087 + compileOnly rfg.deobf("curse.maven:hwyla-253449:2568751") // HWYLA 1.8.26-B41 + compileOnly rfg.deobf("curse.maven:baubles-227083:2518667") // Baubles 1.5.2 + compileOnly rfg.deobf("curse.maven:forestry-59751:2684780") // Forestry 5.8.2.387 + compileOnly rfg.deobf("curse.maven:chisel-235279:2915375") // Chisel 1.0.2.45 // Mods with Soft compat but which have no need to be in code, such as isModLoaded() checks and getModItem() recipes. // Uncomment any of these to test them in-game. - // runtimeOnly rfg.deobf("curse.maven:beebetteratbees-244516:2627215") // BeeBetterAtBees 2.0.3 (recommended to enable when testing Forestry compat) - // runtimeOnly rfg.deobf("curse.maven:jei-bees-248370:2490058") // JEIBees 0.9.0.5 (recommended to enable when testing Forestry compat) - // runtimeOnly rfg.deobf("curse.maven:binnies-mods-223525:2916129") // Binnie 2.5.1.203 - // runtimeOnly rfg.deobf("curse.maven:magic-bees-65764:2855061") // Magic Bees 3.2.25 - // runtimeOnly rfg.deobf("curse.maven:gendustry-70492:2516215") // Gendustry 1.6.5.8 - // runtimeOnly rfg.deobf("curse.maven:bdlib-70496:2518031") // BdLib 1.14.3.12 + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:beebetteratbees-244516:2627215") // BeeBetterAtBees 2.0.3 (recommended to enable when testing Forestry compat) + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:jei-bees-248370:2490058") // JEIBees 0.9.0.5 (recommended to enable when testing Forestry compat) + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:binnies-mods-223525:2916129") // Binnie 2.5.1.203 + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:magic-bees-65764:2855061") // Magic Bees 3.2.25 + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:gendustry-70492:2516215") // Gendustry 1.6.5.8 + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:bdlib-70496:2518031") // BdLib 1.14.3.12 } minecraft { @@ -60,7 +73,7 @@ minecraft { } configurations { - implementation { + compileOnly { // exclude GNU trove, FastUtil is superior and still updated exclude group: "net.sf.trove4j", module: "trove4j" // exclude javax.annotation from findbugs, jetbrains annotations are superior diff --git a/gradle.properties b/gradle.properties index 2408eee2147..9de88c6bf58 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ modGroup = gregtech # Version of your mod. # This field can be left empty if you want your mod's version to be determined by the latest git tag instead. -modVersion = 2.8.5-beta +modVersion = 2.8.7-beta # Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version) includeMCVersionJar = true @@ -42,6 +42,8 @@ gradleTokenVersion = VERSION # leave this property empty. # Example value: apiPackage = api + modGroup = com.myname.mymodid -> com.myname.mymodid.api apiPackage = +# If you want to keep your API code in src/api instead of src/main +useSrcApiPath=false # Specify the configuration file for Forge's access transformers here. It must be placed into /src/main/resources/ # There can be multiple files in a comma-separated list. @@ -90,6 +92,7 @@ relocateShadowedDependencies = true # Separate run directories into "run/client" for runClient task, and "run/server" for runServer task. # Useful for debugging a server and client simultaneously. If not enabled, it will be in the standard location "run/" separateRunDirectories = false + # The display name format of versions published to Curse and Modrinth. $MOD_NAME and $VERSION are available variables. # Default: $MOD_NAME \u2212 $VERSION. \u2212 is the minus character which looks much better than the hyphen minus on Curse. versionDisplayFormat=$MOD_NAME: $VERSION @@ -142,7 +145,7 @@ noPublishedSources = false # For maven credentials: # Username is set with the 'MAVEN_USER' environment variable, default to "NONE" # Password is set with the 'MAVEN_PASSWORD' environment variable, default to "NONE" -customMavenPublishUrl= +customMavenPublishUrl= https://maven.gtceu.com # The group for maven artifacts. Defaults to the 'project.modGroup' until the last '.' (if any). # So 'mymod' becomes 'mymod' and 'com.myname.mymodid' 'becomes com.myname' mavenArtifactGroup= diff --git a/settings.gradle b/settings.gradle index b6371aad5ab..771def37e1f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,9 +3,7 @@ pluginManagement { maven { // RetroFuturaGradle name 'GTNH Maven' - //noinspection HttpUrlsUsage - url 'http://jenkins.usrv.eu:8081/nexus/content/groups/public/' - allowInsecureProtocol = true + url 'https://nexus.gtnewhorizons.com/repository/public/' //noinspection GroovyAssignabilityCheck mavenContent { includeGroup 'com.gtnewhorizons' diff --git a/src/main/java/gregtech/GregTechMod.java b/src/main/java/gregtech/GregTechMod.java index f76989a97d5..883b581292c 100644 --- a/src/main/java/gregtech/GregTechMod.java +++ b/src/main/java/gregtech/GregTechMod.java @@ -3,6 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.modules.ModuleContainerRegistryEvent; +import gregtech.api.persistence.PersistentData; import gregtech.client.utils.BloomEffectUtil; import gregtech.modules.GregTechModules; import gregtech.modules.ModuleManager; @@ -32,7 +33,7 @@ dependencies = "required:forge@[14.23.5.2847,);" + "required-after:codechickenlib@[3.2.3,);" + "required-after:modularui@[2.3,);" + "required-after:mixinbooter@[8.0,);" + "after:appliedenergistics2;" + "after:forestry;" + "after:extrabees;" + "after:extratrees;" + "after:genetics;" + "after:magicbees;" + - "after:jei@[4.15.0,);" + "after:crafttweaker@[4.1.20,);" + "after:groovyscript@[0.7.0,);" + + "after:jei@[4.15.0,);" + "after:crafttweaker@[4.1.20,);" + "after:groovyscript@[1.0.1,);" + "after:theoneprobe;" + "after:hwyla;") public class GregTechMod { @@ -50,6 +51,7 @@ public GregTechMod() { @EventHandler public void onConstruction(FMLConstructionEvent event) { + PersistentData.instance().init(); moduleManager = ModuleManager.getInstance(); GregTechAPI.moduleManager = moduleManager; moduleManager.registerContainer(new GregTechModules()); diff --git a/src/main/java/gregtech/api/GTValues.java b/src/main/java/gregtech/api/GTValues.java index 7a1b5d34f4f..05053d6fbb8 100644 --- a/src/main/java/gregtech/api/GTValues.java +++ b/src/main/java/gregtech/api/GTValues.java @@ -7,6 +7,8 @@ import net.minecraftforge.fml.relauncher.FMLLaunchHandler; import net.minecraftforge.oredict.OreDictionary; +import org.jetbrains.annotations.ApiStatus; + import java.time.LocalDate; import java.util.Random; import java.util.function.Supplier; @@ -120,10 +122,14 @@ public class GTValues { "Overpowered Voltage", "Maximum Voltage" }; /** - * ModID strings, since they are quite common parameters + * GregTech Mod ID */ - public static final String MODID = "gregtech", - MODID_FR = "forestry", + public static final String MODID = "gregtech"; + + /** @deprecated Use {@link gregtech.api.util.Mods} instead */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") + public static final String MODID_FR = "forestry", MODID_CT = "crafttweaker", MODID_TOP = "theoneprobe", MODID_CTM = "ctm", @@ -158,7 +164,8 @@ public class GTValues { MODID_TCON = "tconstruct", MODID_PROJRED_CORE = "projectred-core", MODID_RC = "railcraft", - MODID_CHISEL = "chisel"; + MODID_CHISEL = "chisel", + MODID_RS = "refinedstorage"; private static Boolean isClient; diff --git a/src/main/java/gregtech/api/GregTechAPI.java b/src/main/java/gregtech/api/GregTechAPI.java index f3279eb5b3b..c4506dfbfc0 100644 --- a/src/main/java/gregtech/api/GregTechAPI.java +++ b/src/main/java/gregtech/api/GregTechAPI.java @@ -12,23 +12,14 @@ import gregtech.api.modules.IModuleManager; import gregtech.api.network.INetworkHandler; import gregtech.api.sound.ISoundManager; -import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Material; -import gregtech.api.unification.material.Materials; import gregtech.api.unification.material.registry.IMaterialRegistryManager; import gregtech.api.unification.material.registry.MarkerMaterialRegistry; -import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.ore.StoneType; -import gregtech.api.util.BaseCreativeTab; import gregtech.api.util.GTControlledRegistry; import gregtech.api.util.GTLog; import gregtech.api.util.IBlockOre; import gregtech.common.ConfigHolder; -import gregtech.common.blocks.BlockWarningSign; -import gregtech.common.blocks.MetaBlocks; -import gregtech.common.items.MetaItems; -import gregtech.common.items.ToolItems; -import gregtech.common.metatileentities.MetaTileEntities; import net.minecraft.block.state.IBlockState; import net.minecraft.util.ResourceLocation; @@ -78,23 +69,6 @@ public class GregTechAPI { public static final Object2ObjectMap HEATING_COILS = new Object2ObjectOpenHashMap<>(); public static final Object2ObjectMap PSS_BATTERIES = new Object2ObjectOpenHashMap<>(); - public static final BaseCreativeTab TAB_GREGTECH = new BaseCreativeTab(GTValues.MODID + ".main", - () -> MetaItems.LOGO.getStackForm(), true); - public static final BaseCreativeTab TAB_GREGTECH_MACHINES = new BaseCreativeTab(GTValues.MODID + ".machines", - () -> MetaTileEntities.ELECTRIC_BLAST_FURNACE.getStackForm(), true); - public static final BaseCreativeTab TAB_GREGTECH_CABLES = new BaseCreativeTab(GTValues.MODID + ".cables", - () -> OreDictUnifier.get(OrePrefix.cableGtDouble, Materials.Aluminium), true); - public static final BaseCreativeTab TAB_GREGTECH_PIPES = new BaseCreativeTab(GTValues.MODID + ".pipes", - () -> OreDictUnifier.get(OrePrefix.pipeNormalFluid, Materials.Aluminium), true); - public static final BaseCreativeTab TAB_GREGTECH_TOOLS = new BaseCreativeTab(GTValues.MODID + ".tools", - () -> ToolItems.HARD_HAMMER.get(Materials.Aluminium), true); - public static final BaseCreativeTab TAB_GREGTECH_MATERIALS = new BaseCreativeTab(GTValues.MODID + ".materials", - () -> OreDictUnifier.get(OrePrefix.ingot, Materials.Aluminium), true); - public static final BaseCreativeTab TAB_GREGTECH_ORES = new BaseCreativeTab(GTValues.MODID + ".ores", - () -> OreDictUnifier.get(OrePrefix.ore, Materials.Aluminium), true); - public static final BaseCreativeTab TAB_GREGTECH_DECORATIONS = new BaseCreativeTab(GTValues.MODID + ".decorations", - () -> MetaBlocks.WARNING_SIGN.getItemVariant(BlockWarningSign.SignType.YELLOW_STRIPES), true); - /** Will be available at the Pre-Initialization stage */ public static boolean isHighTier() { return highTier; diff --git a/src/main/java/gregtech/api/block/VariantActiveBlock.java b/src/main/java/gregtech/api/block/VariantActiveBlock.java index 4818c4a933a..ba4ac712a03 100644 --- a/src/main/java/gregtech/api/block/VariantActiveBlock.java +++ b/src/main/java/gregtech/api/block/VariantActiveBlock.java @@ -1,6 +1,6 @@ package gregtech.api.block; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.client.model.ActiveVariantBlockBakedModel; import gregtech.client.utils.BloomEffectUtil; import gregtech.common.ConfigHolder; @@ -22,7 +22,6 @@ import net.minecraftforge.common.property.ExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -135,7 +134,7 @@ public IExtendedBlockState getExtendedState(@NotNull IBlockState state, @NotNull .withProperty(ACTIVE, Minecraft.getMinecraft().world != null && isBlockActive(Minecraft.getMinecraft().world.provider.getDimension(), pos)); - if (Loader.isModLoaded(GTValues.MODID_CTM)) { + if (Mods.CTM.isModLoaded()) { // if the Connected Textures Mod is loaded we wrap our IExtendedBlockState with their wrapper, // so that the CTM renderer can render the block properly. return new CTMExtendedState(ext, world, pos); diff --git a/src/main/java/gregtech/api/block/VariantBlock.java b/src/main/java/gregtech/api/block/VariantBlock.java index 5b0310263ef..7e31dd48c3b 100644 --- a/src/main/java/gregtech/api/block/VariantBlock.java +++ b/src/main/java/gregtech/api/block/VariantBlock.java @@ -1,7 +1,7 @@ package gregtech.api.block; -import gregtech.api.GregTechAPI; import gregtech.api.util.LocalizationUtils; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.Block; import net.minecraft.block.material.Material; @@ -43,7 +43,7 @@ public VariantBlock(Material materialIn) { state); } } - setCreativeTab(GregTechAPI.TAB_GREGTECH); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH); setDefaultState(this.blockState.getBaseState().withProperty(VARIANT, VALUES[0])); } diff --git a/src/main/java/gregtech/api/block/machines/BlockMachine.java b/src/main/java/gregtech/api/block/machines/BlockMachine.java index f9a77ccbe07..181c670d540 100644 --- a/src/main/java/gregtech/api/block/machines/BlockMachine.java +++ b/src/main/java/gregtech/api/block/machines/BlockMachine.java @@ -1,6 +1,5 @@ package gregtech.api.block.machines; -import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.block.BlockCustomParticle; import gregtech.api.block.UnlistedIntegerProperty; @@ -15,7 +14,9 @@ import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.pipenet.IBlockAppearance; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.client.renderer.handler.MetaTileEntityRenderer; +import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.items.MetaItems; import gregtech.integration.ctm.IFacadeWrapper; @@ -40,7 +41,11 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.*; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumBlockRenderType; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; @@ -51,7 +56,6 @@ import net.minecraftforge.common.property.ExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -63,7 +67,12 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.Set; import static gregtech.api.util.GTUtility.getMetaTileEntity; @@ -83,7 +92,7 @@ public class BlockMachine extends BlockCustomParticle implements ITileEntityProv public BlockMachine() { super(Material.IRON); - setCreativeTab(GregTechAPI.TAB_GREGTECH_MACHINES); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_MACHINES); setSoundType(SoundType.METAL); setHardness(6.0f); setResistance(6.0f); @@ -272,7 +281,7 @@ public void onBlockPlacedBy(World worldIn, @NotNull BlockPos pos, @NotNull IBloc } } } - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { if (metaTileEntity.getProxy() != null) { metaTileEntity.getProxy().setOwner((EntityPlayer) placer); } @@ -423,7 +432,7 @@ public void harvestBlock(@NotNull World worldIn, @NotNull EntityPlayer player, @ @NotNull IBlockState state, @Nullable TileEntity te, @NotNull ItemStack stack) { tileEntities.set(te == null ? tileEntities.get() : ((IGregTechTileEntity) te).getMetaTileEntity()); super.harvestBlock(worldIn, player, pos, state, te, stack); - tileEntities.set(null); + tileEntities.remove(); } @Nullable @@ -473,7 +482,7 @@ public int getLightValue(@NotNull IBlockState state, @NotNull IBlockAccess world public int getLightOpacity(@NotNull IBlockState state, @NotNull IBlockAccess world, @NotNull BlockPos pos) { // since it is called on neighbor blocks MetaTileEntity metaTileEntity = getMetaTileEntity(world, pos); - return metaTileEntity == null ? 0 : metaTileEntity.getLightOpacity(); + return metaTileEntity == null ? 255 : metaTileEntity.getLightOpacity(); } @Override diff --git a/src/main/java/gregtech/api/block/machines/MachineItemBlock.java b/src/main/java/gregtech/api/block/machines/MachineItemBlock.java index 1186eaefa7c..d8fb09dcc19 100644 --- a/src/main/java/gregtech/api/block/machines/MachineItemBlock.java +++ b/src/main/java/gregtech/api/block/machines/MachineItemBlock.java @@ -10,6 +10,7 @@ import gregtech.api.util.LocalizationUtils; import gregtech.client.utils.TooltipHelper; import gregtech.common.ConfigHolder; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; @@ -61,8 +62,8 @@ public class MachineItemBlock extends ItemBlock { */ public static void addCreativeTab(CreativeTabs creativeTab) { Preconditions.checkNotNull(creativeTab, "creativeTab"); - if (creativeTab == GregTechAPI.TAB_GREGTECH_MACHINES) { - throw new IllegalArgumentException("Adding " + GregTechAPI.TAB_GREGTECH_MACHINES.tabLabel + + if (creativeTab == GTCreativeTabs.TAB_GREGTECH_MACHINES) { + throw new IllegalArgumentException("Adding " + GTCreativeTabs.TAB_GREGTECH_MACHINES.tabLabel + " as additional creative tab is redundant."); } else if (creativeTab == CreativeTabs.SEARCH) { throw new IllegalArgumentException( @@ -91,7 +92,7 @@ public boolean placeBlockAt(@NotNull ItemStack stack, @NotNull EntityPlayer play // prevent rendering glitch before meta tile entity sync to client, but after block placement // set opaque property on the placing on block, instead during set of meta tile entity boolean superVal = super.placeBlockAt(stack, player, world, pos, side, hitX, hitY, hitZ, - newState.withProperty(BlockMachine.OPAQUE, metaTileEntity != null && metaTileEntity.isOpaqueCube())); + newState.withProperty(BlockMachine.OPAQUE, metaTileEntity == null || metaTileEntity.isOpaqueCube())); if (superVal && !world.isRemote) { BlockPos possiblePipe = pos.offset(side.getOpposite()); Block block = world.getBlockState(possiblePipe).getBlock(); diff --git a/src/main/java/gregtech/api/capability/GregtechDataCodes.java b/src/main/java/gregtech/api/capability/GregtechDataCodes.java index 81c224bfa40..5743fad9c26 100644 --- a/src/main/java/gregtech/api/capability/GregtechDataCodes.java +++ b/src/main/java/gregtech/api/capability/GregtechDataCodes.java @@ -23,6 +23,9 @@ public static int assignId() { public static final int UPDATE_AUTO_OUTPUT_FLUIDS = assignId(); public static final int UPDATE_IS_VOIDING = assignId(); + // Robotic Arm + public static final int UPDATE_TRANSFER_MODE = assignId(); + // Drum public static final int UPDATE_AUTO_OUTPUT = assignId(); @@ -169,4 +172,12 @@ public static int assignId() { // Alarm public static final int UPDATE_SOUND = assignId(); public static final int UPDATE_RADIUS = assignId(); + + // Fission Reactor + public static int SYNC_REACTOR_STATS = assignId(); + public static int SYNC_LOCKING_STATE = assignId(); + + // ME Parts + public static final int UPDATE_AUTO_PULL = assignId(); + public static final int UPDATE_ONLINE_STATUS = assignId(); } diff --git a/src/main/java/gregtech/api/capability/IDataStickIntractable.java b/src/main/java/gregtech/api/capability/IDataStickIntractable.java new file mode 100644 index 00000000000..4b9d36ee6ff --- /dev/null +++ b/src/main/java/gregtech/api/capability/IDataStickIntractable.java @@ -0,0 +1,11 @@ +package gregtech.api.capability; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +public interface IDataStickIntractable { + + void onDataStickLeftClick(EntityPlayer player, ItemStack dataStick); + + boolean onDataStickRightClick(EntityPlayer player, ItemStack dataStick); +} diff --git a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java index cc2ce878aee..6d8877ff1dc 100644 --- a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java @@ -1,7 +1,11 @@ package gregtech.api.capability.impl; import gregtech.api.GTValues; -import gregtech.api.capability.*; +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IMultiblockController; +import gregtech.api.capability.IMultipleTankHandler; +import gregtech.api.capability.IWorkable; import gregtech.api.metatileentity.MTETrait; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.multiblock.CleanroomType; @@ -12,6 +16,7 @@ import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.logic.IParallelableRecipeLogic; import gregtech.api.recipes.recipeproperties.CleanroomProperty; +import gregtech.api.recipes.recipeproperties.DimensionProperty; import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; @@ -403,7 +408,7 @@ protected boolean checkPreviousRecipe() { * @return true if the recipe is allowed to be used, else false */ public boolean checkRecipe(@NotNull Recipe recipe) { - return checkCleanroomRequirement(recipe); + return checkCleanroomRequirement(recipe) && checkDimensionRequirement(recipe); } /** @@ -427,39 +432,64 @@ protected boolean checkCleanroomRequirement(@NotNull Recipe recipe) { return false; } + protected boolean checkDimensionRequirement(@NotNull Recipe recipe) { + if (!recipe.hasProperty(DimensionProperty.getInstance())) return true; + return recipe.getProperty(DimensionProperty.getInstance(), DimensionProperty.DimensionPropertyList.EMPTY_LIST) + .checkDimension(this.getMetaTileEntity().getWorld().provider.getDimension()); + } + /** * Prepares the recipe to be run. *
    *
  1. The recipe is run in parallel if possible.
  2. *
  3. The potentially parallel recipe is then checked to exist.
  4. - *
  5. If it exists, it checks if the recipe is runnable with the current inputs.
  6. + *
  7. If it exists, it checks if the recipe is runnable with the inputs provided.
  8. *
* If the above conditions are met, the recipe is engaged to be run * - * @param recipe the recipe to prepare + * @param recipe the recipe to prepare + * @param inputInventory the inventory to draw items from + * @param inputFluidInventory the fluid tanks to draw fluid from * @return true if the recipe was successfully prepared, else false */ - protected boolean prepareRecipe(Recipe recipe) { + public boolean prepareRecipe(Recipe recipe, IItemHandlerModifiable inputInventory, + IMultipleTankHandler inputFluidInventory) { recipe = Recipe.trimRecipeOutputs(recipe, getRecipeMap(), metaTileEntity.getItemOutputLimit(), metaTileEntity.getFluidOutputLimit()); // Pass in the trimmed recipe to the parallel logic recipe = findParallelRecipe( recipe, - getInputInventory(), - getInputTank(), + inputInventory, + inputFluidInventory, getOutputInventory(), getOutputTank(), getMaxParallelVoltage(), getParallelLimit()); - if (recipe != null && setupAndConsumeRecipeInputs(recipe, getInputInventory())) { + if (recipe != null && setupAndConsumeRecipeInputs(recipe, inputInventory, inputFluidInventory)) { setupRecipe(recipe); return true; } return false; } + /** + * Prepares the recipe to be run. + *
    + *
  1. The recipe is run in parallel if possible.
  2. + *
  3. The potentially parallel recipe is then checked to exist.
  4. + *
  5. If it exists, it checks if the recipe is runnable with the current inputs.
  6. + *
+ * If the above conditions are met, the recipe is engaged to be run + * + * @param recipe the recipe to prepare + * @return true if the recipe was successfully prepared from the default inventory, else false + */ + public boolean prepareRecipe(Recipe recipe) { + return prepareRecipe(recipe, getInputInventory(), getInputTank()); + } + /** * DO NOT use the parallelLimit field directly, EVER * @@ -549,11 +579,14 @@ protected static boolean areItemStacksEqual(@NotNull ItemStack stackA, @NotNull * @param recipe - The Recipe that will be consumed from the inputs and ran in the machine * @param importInventory - The inventory that the recipe should be consumed from. * Used mainly for Distinct bus implementation for multiblocks to specify - * a specific bus + * a specific bus, or for addons to use external inventories. + * @param importFluids - The tanks that the recipe should be consumed from + * Used currently in addons to use external tanks. * @return - true if the recipe is successful, false if the recipe is not successful */ protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, - @NotNull IItemHandlerModifiable importInventory) { + @NotNull IItemHandlerModifiable importInventory, + @NotNull IMultipleTankHandler importFluids) { this.overclockResults = calculateOverclock(recipe); modifyOverclockPost(overclockResults, recipe.getRecipePropertyStorage()); @@ -563,7 +596,6 @@ protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, } IItemHandlerModifiable exportInventory = getOutputInventory(); - IMultipleTankHandler importFluids = getInputTank(); IMultipleTankHandler exportFluids = getOutputTank(); // We have already trimmed outputs and chanced outputs at this time @@ -589,37 +621,42 @@ protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, return false; } + /** + * Determines if the provided recipe is possible to run from the provided inventory, or if there is anything + * preventing + * the Recipe from being completed. + *

+ * Will consume the inputs of the Recipe if it is possible to run. + * + * @param recipe - The Recipe that will be consumed from the inputs and ran in the machine + * @param importInventory - The inventory that the recipe should be consumed from. + * Used mainly for Distinct bus implementation for multiblocks to specify + * a specific bus + * @return - true if the recipe is successful, false if the recipe is not successful + */ + protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, + @NotNull IItemHandlerModifiable importInventory) { + return setupAndConsumeRecipeInputs(recipe, importInventory, this.getInputTank()); + } + /** * @param resultOverclock the overclock data to use. Format: {@code [EUt, duration]}. * @return true if there is enough energy to continue recipe progress */ - protected boolean hasEnoughPower(@NotNull int[] resultOverclock) { + protected boolean hasEnoughPower(int @NotNull [] resultOverclock) { // Format of resultOverclock: EU/t, duration - int totalEUt = resultOverclock[0] * resultOverclock[1]; + int recipeEUt = resultOverclock[0]; // RIP Ternary // Power Consumption case - if (totalEUt >= 0) { - int capacity; - // If the total consumed power is greater than half the internal capacity - if (totalEUt > getEnergyCapacity() / 2) { - // Only draw 1A of power from the internal buffer to allow for recharging of the internal buffer from - // external sources - capacity = resultOverclock[0]; - } else { - // If the total consumed power is less than half the capacity, just drain the whole thing - capacity = totalEUt; - } - - // Return true if we have enough energy stored to progress the recipe, either 1A or the whole amount - return getEnergyStored() >= capacity; + if (recipeEUt >= 0) { + // ensure it can run for at least 8 ticks. Arbitrary value, but should prevent instant failures + return getEnergyStored() >= ((long) recipeEUt << 3); } // Power Generation case else { - // This is the EU/t generated by the generator - int power = resultOverclock[0]; // Return true if we can fit at least 1A of energy into the energy output - return getEnergyStored() - (long) power <= getEnergyCapacity(); + return getEnergyStored() - (long) recipeEUt <= getEnergyCapacity(); } } diff --git a/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java index 9f93440025c..168ed40c67c 100644 --- a/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java @@ -78,6 +78,11 @@ public int getParallelLimit() { return Integer.MAX_VALUE; } + @Override + protected long getMaxParallelVoltage() { + return getMaxVoltage(); + } + /** * Boost the energy production. * Should not change the state of the workable logic. Only read current values. diff --git a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java index 1ebb3e73c82..b27685c6987 100644 --- a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java @@ -434,6 +434,11 @@ public long getMaxVoltage() { } } + @Override + protected long getMaxParallelVoltage() { + return getMaximumOverclockVoltage(); + } + @Nullable @Override public RecipeMap getRecipeMap() { diff --git a/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java index 182b900ae3b..e3367929b06 100644 --- a/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java @@ -38,15 +38,19 @@ protected boolean drawEnergy(int recipeEUt, boolean simulate) { return true; // spoof energy being drawn } + @Override + protected boolean hasEnoughPower(int @NotNull [] resultOverclock) { + return true; + } + @Override public long getMaxVoltage() { return GTValues.LV; } - @NotNull @Override - protected int[] runOverclockingLogic(@NotNull IRecipePropertyStorage propertyStorage, int recipeEUt, - long maxVoltage, int recipeDuration, int amountOC) { + protected int @NotNull [] runOverclockingLogic(@NotNull IRecipePropertyStorage propertyStorage, int recipeEUt, + long maxVoltage, int recipeDuration, int amountOC) { return standardOverclockingLogic( 1, getMaxVoltage(), diff --git a/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java b/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java index c5d7dcbb960..c1e4fc665a9 100644 --- a/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java +++ b/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java @@ -227,6 +227,23 @@ public long getMaxVoltage() { return GTValues.V[GTValues.LV]; } + @Override + protected boolean hasEnoughPower(int @NotNull [] resultOverclock) { + int totalSteam = (int) (resultOverclock[0] * resultOverclock[1] / conversionRate); + if (totalSteam > 0) { + long steamStored = getEnergyStored(); + long steamCapacity = getEnergyCapacity(); + // if the required steam is larger than the full buffer, just require the full buffer + if (steamCapacity < totalSteam) { + return steamCapacity == steamStored; + } + // otherwise require the full amount of steam for the recipe + return steamStored >= totalSteam; + } + // generation case unchanged + return super.hasEnoughPower(resultOverclock); + } + @NotNull @Override public NBTTagCompound serializeNBT() { diff --git a/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java index b227f3942c2..d649a7d6fa7 100644 --- a/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java @@ -167,4 +167,21 @@ private void performVentingAnimation(BlockPos machinePos, EnumFacing ventingSide 1.0f); } } + + @Override + protected boolean hasEnoughPower(int @NotNull [] resultOverclock) { + int totalSteam = (int) (resultOverclock[0] * resultOverclock[1] / conversionRate); + if (totalSteam > 0) { + long steamStored = getEnergyStored(); + long steamCapacity = getEnergyCapacity(); + // if the required steam is larger than the full buffer, just require the full buffer + if (steamCapacity < totalSteam) { + return steamCapacity == steamStored; + } + // otherwise require the full amount of steam for the recipe + return steamStored >= totalSteam; + } + // generation case unchanged + return super.hasEnoughPower(resultOverclock); + } } diff --git a/src/main/java/gregtech/api/cover/CoverWithUI.java b/src/main/java/gregtech/api/cover/CoverWithUI.java index f40f2df37bc..d8780c611d9 100644 --- a/src/main/java/gregtech/api/cover/CoverWithUI.java +++ b/src/main/java/gregtech/api/cover/CoverWithUI.java @@ -2,6 +2,7 @@ import gregtech.api.gui.IUIHolder; import gregtech.api.gui.ModularUI; +import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuiTheme; import gregtech.api.mui.GregTechGuiScreen; import gregtech.api.mui.factory.CoverGuiFactory; @@ -9,20 +10,25 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; +import net.minecraft.util.IStringSerializable; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import com.cleanroommc.modularui.api.IGuiHolder; +import com.cleanroommc.modularui.api.drawable.IDrawable; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.screen.ModularScreen; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.value.BoolValue; import com.cleanroommc.modularui.value.sync.EnumSyncValue; import com.cleanroommc.modularui.value.sync.GuiSyncManager; import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.ToggleButton; import com.cleanroommc.modularui.widgets.layout.Row; import org.jetbrains.annotations.ApiStatus; @@ -92,13 +98,12 @@ default void markAsDirty() { /** * Create the Title bar widget for a Cover. */ - default Row createTitleRow() { - ItemStack item = getDefinition().getDropItemStack(); + static Row createTitleRow(ItemStack stack) { return new Row() .pos(4, 4) .height(16).coverChildrenWidth() - .child(new ItemDrawable(getDefinition().getDropItemStack()).asWidget().size(16).marginRight(4)) - .child(IKey.str(item.getDisplayName()).color(UI_TITLE_COLOR).asWidget().heightRel(1.0f)); + .child(new ItemDrawable(stack).asWidget().size(16).marginRight(4)) + .child(IKey.str(stack.getDisplayName()).color(UI_TITLE_COLOR).asWidget().heightRel(1.0f)); } /** @@ -108,6 +113,31 @@ default ParentWidget createSettingsRow() { return new ParentWidget<>().height(16).widthRel(1.0f).marginBottom(2); } + default int getIncrementValue(MouseData data) { + int adjust = 1; + if (data.shift) adjust *= 4; + if (data.ctrl) adjust *= 16; + if (data.alt) adjust *= 64; + return adjust; + } + + default IKey createAdjustOverlay(boolean increment) { + final StringBuilder builder = new StringBuilder(); + builder.append(increment ? '+' : '-'); + builder.append(getIncrementValue(MouseData.create(-1))); + + float scale = 1f; + if (builder.length() == 3) { + scale = 0.8f; + } else if (builder.length() == 4) { + scale = 0.6f; + } else if (builder.length() > 4) { + scale = 0.5f; + } + return IKey.str(builder.toString()) + .scale(scale); + } + /** * Get a BoolValue for use with toggle buttons which are "linked together," * meaning only one of them can be pressed at a time. @@ -123,4 +153,88 @@ default > BoolValue.Dynamic boolValueOf(EnumSyncValue syncV default BoolValue.Dynamic boolValueOf(IntSyncValue syncValue, int value) { return new BoolValue.Dynamic(() -> syncValue.getValue() == value, $ -> syncValue.setValue(value)); } + + class EnumRowBuilder> { + + private EnumSyncValue syncValue; + private final Class enumValue; + private String lang; + private IDrawable[] background; + private IDrawable selectedBackground; + private IDrawable[] overlay; + + public EnumRowBuilder(Class enumValue) { + this.enumValue = enumValue; + } + + public EnumRowBuilder value(EnumSyncValue syncValue) { + this.syncValue = syncValue; + return this; + } + + public EnumRowBuilder lang(String lang) { + this.lang = lang; + return this; + } + + public EnumRowBuilder background(IDrawable... background) { + this.background = background; + return this; + } + + public EnumRowBuilder selectedBackground(IDrawable selectedBackground) { + this.selectedBackground = selectedBackground; + return this; + } + + public EnumRowBuilder overlay(IDrawable... overlay) { + this.overlay = overlay; + return this; + } + + public EnumRowBuilder overlay(int size, IDrawable... overlay) { + this.overlay = new IDrawable[overlay.length]; + for (int i = 0; i < overlay.length; i++) { + this.overlay[i] = overlay[i].asIcon().size(size); + } + return this; + } + + private BoolValue.Dynamic boolValueOf(EnumSyncValue syncValue, T value) { + return new BoolValue.Dynamic(() -> syncValue.getValue() == value, $ -> syncValue.setValue(value)); + } + + public Row build() { + var row = new Row().marginBottom(2).coverChildrenHeight().widthRel(1f); + if (this.enumValue != null && this.syncValue != null) { + for (var enumVal : enumValue.getEnumConstants()) { + var button = new ToggleButton().size(18).marginRight(2) + .value(boolValueOf(this.syncValue, enumVal)); + + if (this.background != null && this.background.length > 0) + button.background(this.background); + else + button.background(GTGuiTextures.MC_BUTTON); + + if (this.selectedBackground != null) + button.selectedBackground(this.selectedBackground); + else + button.selectedBackground(GTGuiTextures.MC_BUTTON_DISABLED); + + if (this.overlay != null) + button.overlay(this.overlay[enumVal.ordinal()]); + + if (enumVal instanceof IStringSerializable serializable) { + button.addTooltipLine(IKey.lang(serializable.getName())); + } + row.child(button); + } + } + + if (this.lang != null && !this.lang.isEmpty()) + row.child(IKey.lang(this.lang).asWidget().align(Alignment.CenterRight).height(18)); + + return row; + } + } } diff --git a/src/main/java/gregtech/api/util/BaseCreativeTab.java b/src/main/java/gregtech/api/creativetab/BaseCreativeTab.java similarity index 78% rename from src/main/java/gregtech/api/util/BaseCreativeTab.java rename to src/main/java/gregtech/api/creativetab/BaseCreativeTab.java index 0b9fd926651..4607cf05d08 100644 --- a/src/main/java/gregtech/api/util/BaseCreativeTab.java +++ b/src/main/java/gregtech/api/creativetab/BaseCreativeTab.java @@ -1,4 +1,6 @@ -package gregtech.api.util; +package gregtech.api.creativetab; + +import gregtech.api.util.GTLog; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.init.Blocks; @@ -13,31 +15,32 @@ public class BaseCreativeTab extends CreativeTabs { private final boolean hasSearchBar; private final Supplier iconSupplier; - public BaseCreativeTab(String TabName, Supplier iconSupplier, boolean hasSearchBar) { - super(TabName); + public BaseCreativeTab(String tabName, Supplier iconSupplier, boolean hasSearchBar) { + super(tabName); this.iconSupplier = iconSupplier; this.hasSearchBar = hasSearchBar; - if (hasSearchBar) + if (hasSearchBar) { setBackgroundImageName("item_search.png"); + } } @NotNull @Override public ItemStack createIcon() { if (iconSupplier == null) { - GTLog.logger.error("Icon supplier was null for CreativeTab " + getTabLabel()); + GTLog.logger.error("Icon supplier was null for CreativeTab {}", getTabLabel()); return new ItemStack(Blocks.STONE); } ItemStack stack = iconSupplier.get(); if (stack == null) { - GTLog.logger.error("Icon supplier return null for CreativeTab " + getTabLabel()); + GTLog.logger.error("Icon supplier return null for CreativeTab {}", getTabLabel()); return new ItemStack(Blocks.STONE); } - if (stack == ItemStack.EMPTY) { - GTLog.logger.error("Icon built from iconSupplied is EMPTY for CreativeTab " + getTabLabel()); + if (stack.isEmpty()) { + GTLog.logger.error("Icon built from iconSupplied is EMPTY for CreativeTab {}", getTabLabel()); return new ItemStack(Blocks.STONE); } diff --git a/src/main/java/gregtech/api/fluids/FluidBuilder.java b/src/main/java/gregtech/api/fluids/FluidBuilder.java index f7a75111cc4..a7c9d6528ef 100644 --- a/src/main/java/gregtech/api/fluids/FluidBuilder.java +++ b/src/main/java/gregtech/api/fluids/FluidBuilder.java @@ -1,6 +1,5 @@ package gregtech.api.fluids; -import gregtech.api.GTValues; import gregtech.api.fluids.attribute.AttributedFluid; import gregtech.api.fluids.attribute.FluidAttribute; import gregtech.api.fluids.store.FluidStorageKey; @@ -12,13 +11,13 @@ import gregtech.api.util.FluidTooltipUtil; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import net.minecraft.block.material.MaterialLiquid; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fluids.BlockFluidBase; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; -import net.minecraftforge.fml.common.Loader; import com.google.common.base.Preconditions; import io.github.drmanganese.topaddons.reference.Colors; @@ -380,7 +379,7 @@ private static int convertViscosity(double viscosity) { } // register cross mod compat for colors - if (Loader.isModLoaded(GTValues.MODID_TOP_ADDONS)) { + if (Mods.TOPAddons.isModLoaded()) { int displayColor = isColorEnabled || material == null ? color : material.getMaterialRGB(); Colors.FLUID_NAME_COLOR_MAP.put(name, displayColor); } diff --git a/src/main/java/gregtech/api/gui/GuiTextures.java b/src/main/java/gregtech/api/gui/GuiTextures.java index e85bffcfe97..e2b7afa929a 100644 --- a/src/main/java/gregtech/api/gui/GuiTextures.java +++ b/src/main/java/gregtech/api/gui/GuiTextures.java @@ -48,6 +48,9 @@ public class GuiTextures { public static final TextureArea FLUID_TANK_OVERLAY = TextureArea .fullImage("textures/gui/base/fluid_tank_overlay.png"); public static final TextureArea SLOT = AdoptableTextureArea.fullImage("textures/gui/base/slot.png", 18, 18, 1, 1); + public static final TextureArea SLOT_DARK = AdoptableTextureArea.fullImage("textures/gui/base/slot_dark.png", 18, + 18, 1, 1); + @Deprecated // idek what this texture is public static final TextureArea SLOT_DARKENED = TextureArea.fullImage("textures/gui/base/darkened_slot.png"); public static final SteamTexture SLOT_STEAM = SteamTexture.fullImage("textures/gui/base/slot_%s.png"); public static final TextureArea TOGGLE_BUTTON_BACK = TextureArea @@ -504,6 +507,9 @@ public class GuiTextures { public static final TextureArea CONFIG_ARROW_DARK = TextureArea .fullImage("textures/gui/widget/config_arrow_dark.png"); public static final TextureArea SELECT_BOX = TextureArea.fullImage("textures/gui/widget/select_box.png"); + public static final TextureArea BUTTON_AUTO_PULL = TextureArea + .fullImage("textures/gui/widget/button_me_auto_pull.png"); + public static final TextureArea ARROW_DOUBLE = TextureArea.fullImage("textures/gui/widget/arrow_double.png"); // Fusion Reactor custom images public static final TextureArea FUSION_REACTOR_MK1_TITLE = TextureArea diff --git a/src/main/java/gregtech/api/gui/resources/TextTexture.java b/src/main/java/gregtech/api/gui/resources/TextTexture.java index 19928d07c8b..2750890d749 100644 --- a/src/main/java/gregtech/api/gui/resources/TextTexture.java +++ b/src/main/java/gregtech/api/gui/resources/TextTexture.java @@ -20,16 +20,26 @@ public class TextTexture implements IGuiTexture { public TextType type; @SideOnly(Side.CLIENT) private List texts; + private final boolean isClient = FMLCommonHandler.instance().getSide().isClient(); public TextTexture(String text, int color) { this.color = color; this.type = TextType.NORMAL; - if (FMLCommonHandler.instance().getSide().isClient()) { + if (isClient) { this.text = I18n.format(text); texts = Collections.singletonList(this.text); } } + public TextTexture() { + this.color = 0xFFFFFF; + this.type = TextType.NORMAL; + this.text = ""; + + if (isClient) + this.texts = Collections.singletonList(this.text); + } + public TextTexture setColor(int color) { this.color = color; return this; @@ -42,11 +52,18 @@ public TextTexture setDropShadow(boolean dropShadow) { public TextTexture setWidth(int width) { this.width = width; - if (FMLCommonHandler.instance().getSide().isClient()) { - if (this.width > 0) { - texts = Minecraft.getMinecraft().fontRenderer.listFormattedStringToWidth(text, width); - } else { - texts = Collections.singletonList(text); + return this; + } + + public TextTexture setText(String text) { + if (!this.text.equals(text)) { + this.text = text; + if (isClient) { + if (this.width > 0) { + texts = Minecraft.getMinecraft().fontRenderer.listFormattedStringToWidth(text, width); + } else { + texts = Collections.singletonList(text); + } } } return this; diff --git a/src/main/java/gregtech/api/gui/widgets/PhantomFluidWidget.java b/src/main/java/gregtech/api/gui/widgets/PhantomFluidWidget.java index f6d3f4857f7..7fed3591548 100644 --- a/src/main/java/gregtech/api/gui/widgets/PhantomFluidWidget.java +++ b/src/main/java/gregtech/api/gui/widgets/PhantomFluidWidget.java @@ -6,7 +6,11 @@ import gregtech.api.gui.ingredient.IGhostIngredientTarget; import gregtech.api.gui.ingredient.IIngredientSlot; import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.util.*; +import gregtech.api.util.GTLog; +import gregtech.api.util.LocalizationUtils; +import gregtech.api.util.Position; +import gregtech.api.util.Size; +import gregtech.api.util.TextFormattingUtil; import gregtech.client.utils.RenderUtil; import gregtech.client.utils.TooltipHelper; diff --git a/src/main/java/gregtech/api/gui/widgets/SliderWidget.java b/src/main/java/gregtech/api/gui/widgets/SliderWidget.java index 9e0315e530e..f71d246d58d 100644 --- a/src/main/java/gregtech/api/gui/widgets/SliderWidget.java +++ b/src/main/java/gregtech/api/gui/widgets/SliderWidget.java @@ -25,21 +25,21 @@ public class SliderWidget extends Widget { public static final BiFunction DEFAULT_TEXT_SUPPLIER = (name, value) -> I18n.format(name, value.intValue()); - private int sliderWidth = 8; - private TextureArea backgroundArea = GuiTextures.SLIDER_BACKGROUND; - private TextureArea sliderIcon = GuiTextures.SLIDER_ICON; + protected int sliderWidth = 8; + protected TextureArea backgroundArea = GuiTextures.SLIDER_BACKGROUND; + protected TextureArea sliderIcon = GuiTextures.SLIDER_ICON; private final BiFunction textSupplier = DEFAULT_TEXT_SUPPLIER; - private int textColor = 0xFFFFFF; + protected int textColor = 0xFFFFFF; - private final float min; - private final float max; + protected final float min; + protected final float max; private final String name; private final FloatConsumer responder; private boolean isPositionSent; - private String displayString; - private float sliderPosition; + protected String displayString; + protected float sliderPosition; public boolean isMouseDown; public SliderWidget(String name, int xPosition, int yPosition, int width, int height, float min, float max, diff --git a/src/main/java/gregtech/api/gui/widgets/SortingButtonWidget.java b/src/main/java/gregtech/api/gui/widgets/SortingButtonWidget.java index d053c49e7d1..2c491d18ecc 100644 --- a/src/main/java/gregtech/api/gui/widgets/SortingButtonWidget.java +++ b/src/main/java/gregtech/api/gui/widgets/SortingButtonWidget.java @@ -1,14 +1,13 @@ package gregtech.api.gui.widgets; +import gregtech.api.util.Mods; + import net.minecraft.client.settings.KeyBinding; -import net.minecraftforge.fml.common.Loader; import java.util.function.Consumer; public class SortingButtonWidget extends ClickButtonWidget { - private static boolean inventoryTweaksChecked; - private static boolean inventoryTweaksPresent; private static KeyBinding sortKeyBinding; public SortingButtonWidget(int xPosition, int yPosition, int width, int height, String displayText, @@ -43,13 +42,10 @@ public boolean keyTyped(char charTyped, int keyCode) { } private static int getInvTweaksSortCode() { - if (!inventoryTweaksChecked) { - inventoryTweaksChecked = true; - inventoryTweaksPresent = Loader.isModLoaded("inventorytweaks"); - } - if (!inventoryTweaksPresent) { + if (!Mods.InventoryTweaks.isModLoaded()) { return 0; } + try { if (sortKeyBinding == null) { Class proxyClass = Class.forName("invtweaks.forge.ClientProxy"); diff --git a/src/main/java/gregtech/api/gui/widgets/UpdatedSliderWidget.java b/src/main/java/gregtech/api/gui/widgets/UpdatedSliderWidget.java new file mode 100644 index 00000000000..dab355a2901 --- /dev/null +++ b/src/main/java/gregtech/api/gui/widgets/UpdatedSliderWidget.java @@ -0,0 +1,40 @@ +package gregtech.api.gui.widgets; + +import gregtech.api.gui.IRenderContext; +import gregtech.api.util.Position; +import gregtech.api.util.Size; +import gregtech.api.util.function.FloatConsumer; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; + +import java.util.function.Supplier; + +public class UpdatedSliderWidget extends SliderWidget { + + Supplier detector; + + public UpdatedSliderWidget(String name, int xPosition, int yPosition, int width, int height, float min, float max, + float currentValue, FloatConsumer responder, Supplier detector) { + super(name, xPosition, yPosition, width, height, min, max, currentValue, responder); + this.detector = detector; + } + + @Override + public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { + Position pos = getPosition(); + Size size = getSize(); + if (backgroundArea != null) { + backgroundArea.draw(pos.x, pos.y, size.width, size.height); + } + sliderPosition = (detector.get() - min) / (max - min); + this.displayString = getDisplayString(); + + sliderIcon.draw(pos.x + (int) (this.sliderPosition * (float) (size.width - 8)), pos.y, sliderWidth, + size.height); + FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; + fontRenderer.drawString(displayString, + pos.x + size.width / 2 - fontRenderer.getStringWidth(displayString) / 2, + pos.y + size.height / 2 - fontRenderer.FONT_HEIGHT / 2, textColor); + } +} diff --git a/src/main/java/gregtech/api/items/armor/ArmorMetaItem.java b/src/main/java/gregtech/api/items/armor/ArmorMetaItem.java index e7e663377d0..a972b669c95 100644 --- a/src/main/java/gregtech/api/items/armor/ArmorMetaItem.java +++ b/src/main/java/gregtech/api/items/armor/ArmorMetaItem.java @@ -1,9 +1,9 @@ package gregtech.api.items.armor; -import gregtech.api.GregTechAPI; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.metaitem.stats.IEnchantabilityHelper; import gregtech.api.items.metaitem.stats.IItemComponent; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.model.ModelBiped; @@ -33,7 +33,7 @@ public class ArmorMetaItem.ArmorMetaValueItem> extend public ArmorMetaItem() { super((short) 0); - setCreativeTab(GregTechAPI.TAB_GREGTECH_TOOLS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS); } @SuppressWarnings("unchecked") diff --git a/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java b/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java index cfe1c65aee4..9a0a4b9d539 100644 --- a/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java +++ b/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java @@ -1,7 +1,6 @@ package gregtech.api.items.materialitem; import gregtech.api.GTValues; -import gregtech.api.GregTechAPI; import gregtech.api.damagesources.DamageSources; import gregtech.api.items.armor.ArmorMetaItem; import gregtech.api.items.metaitem.StandardMetaItem; @@ -15,6 +14,7 @@ import gregtech.api.unification.material.registry.MaterialRegistry; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.UnificationEntry; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.BlockCauldron; import net.minecraft.block.state.IBlockState; @@ -58,7 +58,7 @@ public MetaPrefixItem(@NotNull MaterialRegistry registry, @NotNull OrePrefix ore super(); this.registry = registry; this.prefix = orePrefix; - this.setCreativeTab(GregTechAPI.TAB_GREGTECH_MATERIALS); + this.setCreativeTab(GTCreativeTabs.TAB_GREGTECH_MATERIALS); } @Override diff --git a/src/main/java/gregtech/api/items/metaitem/ElectricStats.java b/src/main/java/gregtech/api/items/metaitem/ElectricStats.java index 91bd1b739da..bf336ec4676 100644 --- a/src/main/java/gregtech/api/items/metaitem/ElectricStats.java +++ b/src/main/java/gregtech/api/items/metaitem/ElectricStats.java @@ -6,6 +6,7 @@ import gregtech.api.capability.IElectricItem; import gregtech.api.capability.impl.ElectricItem; import gregtech.api.items.metaitem.stats.*; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import gregtech.integration.baubles.BaublesModule; @@ -25,7 +26,6 @@ import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.energy.CapabilityEnergy; import net.minecraftforge.energy.IEnergyStorage; -import net.minecraftforge.fml.common.Loader; import java.time.Duration; import java.time.Instant; @@ -75,7 +75,7 @@ public void onUpdate(ItemStack itemStack, Entity entity) { IInventory inventoryPlayer = entityPlayer.inventory; long transferLimit = electricItem.getTransferLimit(); - if (Loader.isModLoaded(GTValues.MODID_BAUBLES)) { + if (Mods.Baubles.isModLoaded()) { inventoryPlayer = BaublesModule.getBaublesWrappedInventory(entityPlayer); } diff --git a/src/main/java/gregtech/api/items/metaitem/MetaItem.java b/src/main/java/gregtech/api/items/metaitem/MetaItem.java index ba1f713f010..a17559b05b2 100644 --- a/src/main/java/gregtech/api/items/metaitem/MetaItem.java +++ b/src/main/java/gregtech/api/items/metaitem/MetaItem.java @@ -1,7 +1,6 @@ package gregtech.api.items.metaitem; import gregtech.api.GTValues; -import gregtech.api.GregTechAPI; import gregtech.api.capability.GregtechCapabilities; import gregtech.api.capability.IElectricItem; import gregtech.api.capability.IFilteredFluidContainer; @@ -12,7 +11,18 @@ import gregtech.api.items.OreDictNames; import gregtech.api.items.gui.ItemUIFactory; import gregtech.api.items.gui.PlayerInventoryHolder; -import gregtech.api.items.metaitem.stats.*; +import gregtech.api.items.metaitem.stats.IEnchantabilityHelper; +import gregtech.api.items.metaitem.stats.IFoodBehavior; +import gregtech.api.items.metaitem.stats.IItemBehaviour; +import gregtech.api.items.metaitem.stats.IItemCapabilityProvider; +import gregtech.api.items.metaitem.stats.IItemColorProvider; +import gregtech.api.items.metaitem.stats.IItemComponent; +import gregtech.api.items.metaitem.stats.IItemContainerItemProvider; +import gregtech.api.items.metaitem.stats.IItemDurabilityManager; +import gregtech.api.items.metaitem.stats.IItemMaxStackSizeProvider; +import gregtech.api.items.metaitem.stats.IItemNameProvider; +import gregtech.api.items.metaitem.stats.IItemUseManager; +import gregtech.api.items.metaitem.stats.ISubItemHandler; import gregtech.api.recipes.ingredients.IntCircuitIngredient; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Material; @@ -20,8 +30,11 @@ import gregtech.api.unification.stack.ItemMaterialInfo; import gregtech.api.util.GTUtility; import gregtech.api.util.LocalizationUtils; +import gregtech.api.util.Mods; import gregtech.client.utils.ToolChargeBarRenderer; import gregtech.common.ConfigHolder; +import gregtech.common.covers.filter.IFilter; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.block.model.ModelBakery; @@ -40,7 +53,12 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.*; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.client.model.ModelLoader; @@ -72,23 +90,31 @@ import java.time.Duration; import java.time.Instant; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; /** - * MetaItem is item that can have up to Short.MAX_VALUE items inside one id. - * These items even can be edible, have custom behaviours, be electric or act like fluid containers! - * They can also have different burn time, plus be handheld, oredicted or invisible! - * They also can be reactor components. + * MetaItem is item that can have up to Short.MAX_VALUE items inside one id. These items even can be edible, have custom + * behaviours, be electric or act like fluid containers! They can also have different burn time, plus be handheld, + * oredicted or invisible! They also can be reactor components. *

* You can also extend this class and occupy some of it's MetaData, and just pass an meta offset in constructor, and * everything will work properly. *

* Items are added in MetaItem via {@link #addItem(int, String)}. You will get {@link MetaValueItem} instance, which you * can configure in builder-alike pattern: - * {@code addItem(0, "test_item").addStats(new ElectricStats(10000, 1, false)) } - * This will add single-use (not rechargeable) LV battery with initial capacity 10000 EU + * {@code addItem(0, "test_item").addStats(new ElectricStats(10000, 1, false)) } This will add single-use (not + * rechargeable) LV battery with initial capacity 10000 EU */ -@Optional.Interface(modid = GTValues.MODID_ECORE, iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") +@Optional.Interface( + modid = Mods.Names.ENDER_CORE, + iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") public abstract class MetaItem.MetaValueItem> extends Item implements ItemUIFactory, IOverlayRenderAware { @@ -107,11 +133,12 @@ public static List> getMetaItems() { protected final short metaItemOffset; - private CreativeTabs[] defaultCreativeTabs = new CreativeTabs[] { GregTechAPI.TAB_GREGTECH }; + private CreativeTabs[] defaultCreativeTabs = new CreativeTabs[] { GTCreativeTabs.TAB_GREGTECH }; private final Set additionalCreativeTabs = new ObjectArraySet<>(); + private String translationKey = "metaitem"; + public MetaItem(short metaItemOffset) { - setTranslationKey("meta_item"); setHasSubtypes(true); this.metaItemOffset = metaItemOffset; META_ITEMS.add(this); @@ -354,6 +381,7 @@ public void onPlayerStoppedUsing(@NotNull ItemStack stack, @NotNull World world, } } + @NotNull @Override public ItemStack onItemUseFinish(@NotNull ItemStack stack, @NotNull World world, @NotNull EntityLivingBase player) { if (player instanceof EntityPlayer) { @@ -527,10 +555,28 @@ public boolean shouldCauseReequipAnimation(@NotNull ItemStack oldStack, @NotNull return !ItemStack.areItemStacksEqual(oldStack, newStack); } + @NotNull + @Override + public MetaItem setTranslationKey(@NotNull String key) { + this.translationKey = Objects.requireNonNull(key, "key == null"); + return this; + } + + @NotNull @Override - public String getTranslationKey(ItemStack stack) { - T metaItem = getItem(stack); - return metaItem == null ? getTranslationKey() : getTranslationKey() + "." + metaItem.unlocalizedName; + public String getTranslationKey() { + return getTranslationKey((T) null); + } + + @NotNull + @Override + public String getTranslationKey(@NotNull ItemStack stack) { + return getTranslationKey(getItem(stack)); + } + + @NotNull + protected String getTranslationKey(@Nullable T metaValueItem) { + return metaValueItem == null ? this.translationKey : this.translationKey + "." + metaValueItem.unlocalizedName; } @NotNull @@ -541,7 +587,7 @@ public String getItemStackDisplayName(ItemStack stack) { if (item == null) { return "invalid item"; } - String unlocalizedName = String.format("metaitem.%s.name", item.unlocalizedName); + String unlocalizedName = getTranslationKey(item) + ".name"; if (item.getNameProvider() != null) { return item.getNameProvider().getItemStackDisplayName(stack, unlocalizedName); } @@ -564,7 +610,7 @@ public void addInformation(@NotNull ItemStack itemStack, @Nullable World worldIn @NotNull ITooltipFlag tooltipFlag) { T item = getItem(itemStack); if (item == null) return; - String unlocalizedTooltip = "metaitem." + item.unlocalizedName + ".tooltip"; + String unlocalizedTooltip = getTranslationKey(item) + ".tooltip"; if (I18n.hasKey(unlocalizedTooltip)) { Collections.addAll(lines, LocalizationUtils.formatLines(unlocalizedTooltip)); } @@ -660,25 +706,27 @@ public ItemStack getContainerItem(@NotNull ItemStack itemStack) { @NotNull @Override - public CreativeTabs[] getCreativeTabs() { + public CreativeTabs @NotNull [] getCreativeTabs() { if (additionalCreativeTabs.isEmpty()) return defaultCreativeTabs; // short circuit Set tabs = new ObjectArraySet<>(additionalCreativeTabs); tabs.addAll(Arrays.asList(defaultCreativeTabs)); return tabs.toArray(new CreativeTabs[0]); } + @NotNull @Override - public MetaItem setCreativeTab(CreativeTabs tab) { + public MetaItem setCreativeTab(@NotNull CreativeTabs tab) { this.defaultCreativeTabs = new CreativeTabs[] { tab }; return this; } - public MetaItem setCreativeTabs(CreativeTabs... tabs) { + @NotNull + public MetaItem setCreativeTabs(@NotNull CreativeTabs @NotNull... tabs) { this.defaultCreativeTabs = tabs; return this; } - public void addAdditionalCreativeTabs(CreativeTabs... tabs) { + public void addAdditionalCreativeTabs(@NotNull CreativeTabs @NotNull... tabs) { for (CreativeTabs tab : tabs) { if (!ArrayUtils.contains(defaultCreativeTabs, tab) && tab != CreativeTabs.SEARCH) { additionalCreativeTabs.add(tab); @@ -687,7 +735,7 @@ public void addAdditionalCreativeTabs(CreativeTabs... tabs) { } @Override - protected boolean isInCreativeTab(CreativeTabs tab) { + protected boolean isInCreativeTab(@NotNull CreativeTabs tab) { return tab == CreativeTabs.SEARCH || ArrayUtils.contains(defaultCreativeTabs, tab) || additionalCreativeTabs.contains(tab); @@ -734,6 +782,7 @@ public MetaItem getMetaItem() { private final List behaviours = new ArrayList<>(); private IItemUseManager useManager; private ItemUIFactory uiManager; + private IFilter.Factory filterBehavior; private IItemColorProvider colorProvider; private IItemDurabilityManager durabilityManager; private IEnchantabilityHelper enchantabilityHelper; @@ -861,9 +910,12 @@ protected void addItemComponentsInternal(IItemComponent... stats) { if (itemComponent instanceof IFoodBehavior) { this.useManager = new FoodUseManager((IFoodBehavior) itemComponent); } - if (itemComponent instanceof ItemUIFactory) + if (itemComponent instanceof ItemUIFactory) { this.uiManager = (ItemUIFactory) itemComponent; - + } + if (itemComponent instanceof IFilter.Factory) { + this.filterBehavior = (IFilter.Factory) itemComponent; + } if (itemComponent instanceof IItemColorProvider) { this.colorProvider = (IItemColorProvider) itemComponent; } @@ -909,6 +961,11 @@ public ItemUIFactory getUIManager() { return uiManager; } + @Nullable + public IFilter.Factory getFilterFactory() { + return filterBehavior; + } + @Nullable public IItemColorProvider getColorProvider() { return colorProvider; diff --git a/src/main/java/gregtech/api/items/toolitem/IGTTool.java b/src/main/java/gregtech/api/items/toolitem/IGTTool.java index 4c3ba369341..94ae45effb9 100644 --- a/src/main/java/gregtech/api/items/toolitem/IGTTool.java +++ b/src/main/java/gregtech/api/items/toolitem/IGTTool.java @@ -24,6 +24,7 @@ import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.api.util.TextFormattingUtil; import gregtech.client.utils.ToolChargeBarRenderer; import gregtech.client.utils.TooltipHelper; @@ -89,14 +90,21 @@ * Backing of every variation of a GT Tool */ @Optional.InterfaceList({ - @Optional.Interface(modid = GTValues.MODID_APPENG, iface = "appeng.api.implementations.items.IAEWrench"), - @Optional.Interface(modid = GTValues.MODID_BC, iface = "buildcraft.api.tools.IToolWrench"), - @Optional.Interface(modid = GTValues.MODID_COFH, iface = "cofh.api.item.IToolHammer"), - @Optional.Interface(modid = GTValues.MODID_EIO, iface = "crazypants.enderio.api.tool.ITool"), - @Optional.Interface(modid = GTValues.MODID_FR, iface = "forestry.api.arboriculture.IToolGrafter"), - @Optional.Interface(modid = GTValues.MODID_PROJRED_CORE, iface = "mrtjp.projectred.api.IScrewdriver"), - @Optional.Interface(modid = GTValues.MODID_RC, iface = "mods.railcraft.api.items.IToolCrowbar"), - @Optional.Interface(modid = GTValues.MODID_ECORE, + @Optional.Interface(modid = Mods.Names.APPLIED_ENERGISTICS2, + iface = "appeng.api.implementations.items.IAEWrench"), + @Optional.Interface(modid = Mods.Names.BUILD_CRAFT_CORE, + iface = "buildcraft.api.tools.IToolWrench"), + @Optional.Interface(modid = Mods.Names.COFH_CORE, + iface = "cofh.api.item.IToolHammer"), + @Optional.Interface(modid = Mods.Names.ENDER_IO, + iface = "crazypants.enderio.api.tool.ITool"), + @Optional.Interface(modid = Mods.Names.FORESTRY, + iface = "forestry.api.arboriculture.IToolGrafter"), + @Optional.Interface(modid = Mods.Names.PROJECT_RED_CORE, + iface = "mrtjp.projectred.api.IScrewdriver"), + @Optional.Interface(modid = Mods.Names.RAILCRAFT, + iface = "mods.railcraft.api.items.IToolCrowbar"), + @Optional.Interface(modid = Mods.Names.ENDER_CORE, iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") }) public interface IGTTool extends ItemUIFactory, IAEWrench, IToolWrench, IToolHammer, ITool, IToolGrafter, IOverlayRenderAware, IScrewdriver, IToolCrowbar { diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTAxe.java b/src/main/java/gregtech/api/items/toolitem/ItemGTAxe.java index 5acd7f41780..2537884399a 100644 --- a/src/main/java/gregtech/api/items/toolitem/ItemGTAxe.java +++ b/src/main/java/gregtech/api/items/toolitem/ItemGTAxe.java @@ -1,7 +1,7 @@ package gregtech.api.items.toolitem; -import gregtech.api.GregTechAPI; import gregtech.api.util.LocalizationUtils; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.state.IBlockState; import net.minecraft.client.util.ITooltipFlag; @@ -14,7 +14,12 @@ import net.minecraft.item.ItemAxe; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.*; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; @@ -59,7 +64,7 @@ protected ItemGTAxe(String domain, String id, int tier, IGTToolDefinition toolSt this.secondaryOreDicts = secondaryOreDicts; this.markerItem = markerItem; setMaxStackSize(1); - setCreativeTab(GregTechAPI.TAB_GREGTECH_TOOLS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS); setTranslationKey("gt.tool." + id + ".name"); setRegistryName(domain, id); } diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTHoe.java b/src/main/java/gregtech/api/items/toolitem/ItemGTHoe.java index 7f52587be7c..13e14e8e574 100644 --- a/src/main/java/gregtech/api/items/toolitem/ItemGTHoe.java +++ b/src/main/java/gregtech/api/items/toolitem/ItemGTHoe.java @@ -1,7 +1,7 @@ package gregtech.api.items.toolitem; -import gregtech.api.GregTechAPI; import gregtech.api.util.LocalizationUtils; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.state.IBlockState; import net.minecraft.client.util.ITooltipFlag; @@ -14,7 +14,12 @@ import net.minecraft.item.ItemHoe; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.*; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; @@ -59,7 +64,7 @@ protected ItemGTHoe(String domain, String id, int tier, IGTToolDefinition toolSt this.secondaryOreDicts = secondaryOreDicts; this.markerItem = markerItem; setMaxStackSize(1); - setCreativeTab(GregTechAPI.TAB_GREGTECH_TOOLS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS); setTranslationKey("gt.tool." + id + ".name"); setRegistryName(domain, id); } diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTSword.java b/src/main/java/gregtech/api/items/toolitem/ItemGTSword.java index 5b95f6f3718..2786f91d558 100644 --- a/src/main/java/gregtech/api/items/toolitem/ItemGTSword.java +++ b/src/main/java/gregtech/api/items/toolitem/ItemGTSword.java @@ -1,7 +1,7 @@ package gregtech.api.items.toolitem; -import gregtech.api.GregTechAPI; import gregtech.api.util.LocalizationUtils; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.state.IBlockState; import net.minecraft.client.util.ITooltipFlag; @@ -14,7 +14,12 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.*; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; @@ -61,7 +66,7 @@ protected ItemGTSword(String domain, String id, int tier, IGTToolDefinition tool this.secondaryOreDicts = secondaryOreDicts; this.markerItem = markerItem; setMaxStackSize(1); - setCreativeTab(GregTechAPI.TAB_GREGTECH_TOOLS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS); setTranslationKey("gt.tool." + id + ".name"); setRegistryName(domain, id); } diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTTool.java b/src/main/java/gregtech/api/items/toolitem/ItemGTTool.java index edcfa83126d..375aadb845c 100644 --- a/src/main/java/gregtech/api/items/toolitem/ItemGTTool.java +++ b/src/main/java/gregtech/api/items/toolitem/ItemGTTool.java @@ -1,7 +1,7 @@ package gregtech.api.items.toolitem; -import gregtech.api.GregTechAPI; import gregtech.api.util.LocalizationUtils; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.state.IBlockState; import net.minecraft.client.util.ITooltipFlag; @@ -14,7 +14,12 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.ItemTool; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.*; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; @@ -65,7 +70,7 @@ protected ItemGTTool(String domain, String id, int tier, IGTToolDefinition toolS this.secondaryOreDicts = secondaryOreDicts; this.markerItem = markerItem; setMaxStackSize(1); - setCreativeTab(GregTechAPI.TAB_GREGTECH_TOOLS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS); setTranslationKey("gt.tool." + id + ".name"); setRegistryName(domain, id); } diff --git a/src/main/java/gregtech/api/items/toolitem/ToolHelper.java b/src/main/java/gregtech/api/items/toolitem/ToolHelper.java index 2e0a3335df0..23d3145ca9b 100644 --- a/src/main/java/gregtech/api/items/toolitem/ToolHelper.java +++ b/src/main/java/gregtech/api/items/toolitem/ToolHelper.java @@ -270,7 +270,7 @@ public static void damageItem(@NotNull ItemStack stack, @Nullable EntityLivingBa if (electricItem != null) { electricItem.discharge(electricDamage, tool.getElectricTier(), true, false, false); if (electricItem.getCharge() > 0 && - random.nextInt(100) > ConfigHolder.tools.rngDamageElectricTools) { + random.nextInt(100) >= ConfigHolder.tools.rngDamageElectricTools) { return; } } else { diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index 8b922ffc3f6..fd0f404e2dc 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -6,9 +6,18 @@ import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IControllable; +import gregtech.api.capability.IDataStickIntractable; import gregtech.api.capability.IEnergyContainer; -import gregtech.api.capability.impl.*; -import gregtech.api.cover.*; +import gregtech.api.capability.impl.AbstractRecipeLogic; +import gregtech.api.capability.impl.FluidHandlerProxy; +import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.ItemHandlerProxy; +import gregtech.api.capability.impl.NotifiableFluidTank; +import gregtech.api.cover.Cover; +import gregtech.api.cover.CoverHolder; +import gregtech.api.cover.CoverRayTracer; +import gregtech.api.cover.CoverSaveHandler; +import gregtech.api.cover.CoverUtil; import gregtech.api.gui.ModularUI; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.items.toolitem.ToolClasses; @@ -22,9 +31,12 @@ import gregtech.api.util.GTLog; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.BloomEffectUtil; import gregtech.common.ConfigHolder; +import gregtech.common.creativetab.GTCreativeTabs; +import gregtech.common.items.MetaItems; import net.minecraft.block.Block; import net.minecraft.block.state.BlockFaceShape; @@ -40,7 +52,13 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.*; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; @@ -51,6 +69,7 @@ import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.Optional.Method; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -84,7 +103,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -132,6 +155,7 @@ public abstract class MetaTileEntity implements ISyncedTileEntity, CoverHolder, protected boolean muffled = false; private int playSoundCooldown = 0; + private int lastTick = 0; public MetaTileEntity(ResourceLocation metaTileEntityId) { this.metaTileEntityId = metaTileEntityId; @@ -328,7 +352,7 @@ public void getSubItems(CreativeTabs creativeTab, NonNullList subItem * MachineItemBlock#addCreativeTab(CreativeTabs) */ public boolean isInCreativeTab(CreativeTabs creativeTab) { - return creativeTab == CreativeTabs.SEARCH || creativeTab == GregTechAPI.TAB_GREGTECH_MACHINES; + return creativeTab == CreativeTabs.SEARCH || creativeTab == GTCreativeTabs.TAB_GREGTECH_MACHINES; } public String getItemSubTypeId(ItemStack itemStack) { @@ -465,6 +489,12 @@ public final void onCoverLeftClick(EntityPlayer playerIn, CuboidRayTraceResult r public boolean onRightClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, CuboidRayTraceResult hitResult) { ItemStack heldStack = playerIn.getHeldItem(hand); + if (this instanceof IDataStickIntractable dsi) { + if (MetaItems.TOOL_DATA_STICK.isItemEqual(heldStack) && dsi.onDataStickRightClick(playerIn, heldStack)) { + return true; + } + } + if (!playerIn.isSneaking() && openGUIOnRightClick()) { if (getWorld() != null && !getWorld().isRemote) { if (usesMui2()) { @@ -620,7 +650,14 @@ public boolean onHardHammerClick(EntityPlayer playerIn, EnumHand hand, EnumFacin return true; } - public void onLeftClick(EntityPlayer player, EnumFacing facing, CuboidRayTraceResult hitResult) {} + public void onLeftClick(EntityPlayer player, EnumFacing facing, CuboidRayTraceResult hitResult) { + if (this instanceof IDataStickIntractable dsi) { + ItemStack stack = player.getHeldItemMainhand(); + if (MetaItems.TOOL_DATA_STICK.isItemEqual(stack)) { + dsi.onDataStickLeftClick(player, stack); + } + } + } /** * @return true if the player must sneak to rotate this metatileentity, otherwise false @@ -789,11 +826,20 @@ private void updateLightValue() { } public void update() { + if (!getWorld().isRemote && !allowTickAcceleration()) { + int currentTick = FMLCommonHandler.instance().getMinecraftServerInstance().getTickCounter(); + if (currentTick == lastTick) { + return; + } + lastTick = currentTick; + } + for (MTETrait mteTrait : this.mteTraits.values()) { if (shouldUpdate(mteTrait)) { mteTrait.update(); } } + if (!getWorld().isRemote) { updateCovers(); } else { @@ -804,6 +850,15 @@ public void update() { } } + /** + * @return Whether this machine is allowed to be tick accelerated by external means. This does NOT + * apply to World Accelerators from GT, those will never work on machines. This refers to effects + * like Time in a Bottle, or Torcherino, or similar. + */ + public boolean allowTickAcceleration() { + return ConfigHolder.machines.allowTickAcceleration; + } + protected boolean shouldUpdate(MTETrait trait) { return true; } @@ -1528,17 +1583,17 @@ public boolean canVoidRecipeFluidOutputs() { } @NotNull - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AECableType getCableConnectionType(@NotNull AEPartLocation part) { return AECableType.NONE; } @Nullable - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AENetworkProxy getProxy() { return null; } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void gridChanged() {} } diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java index 9d5662a1153..5c6487e6180 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java @@ -1,6 +1,5 @@ package gregtech.api.metatileentity; -import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.block.machines.BlockMachine; import gregtech.api.capability.GregtechDataCodes; @@ -8,6 +7,7 @@ import gregtech.api.gui.IUIHolder; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.api.util.TextFormattingUtil; import gregtech.client.particle.GTNameTagParticle; import gregtech.client.particle.GTParticleManager; @@ -29,7 +29,6 @@ import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.Constants.NBT; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional.Interface; import net.minecraftforge.fml.common.Optional.InterfaceList; import net.minecraftforge.fml.common.Optional.Method; @@ -54,10 +53,11 @@ @InterfaceList(value = { @Interface(iface = "appeng.api.networking.security.IActionHost", - modid = GTValues.MODID_APPENG, + modid = Mods.Names.APPLIED_ENERGISTICS2, striprefs = true), - @Interface(iface = "appeng.me.helpers.IGridProxyable", modid = GTValues.MODID_APPENG, striprefs = true), -}) + @Interface(iface = "appeng.me.helpers.IGridProxyable", + modid = Mods.Names.APPLIED_ENERGISTICS2, + striprefs = true) }) public class MetaTileEntityHolder extends TickableTileEntityBase implements IGregTechTileEntity, IUIHolder, IWorldNameable, IActionHost, IGridProxyable { @@ -138,7 +138,7 @@ public void readFromNBT(@NotNull NBTTagCompound compound) { } else { GTLog.logger.error("Failed to load MetaTileEntity with invalid ID " + metaTileEntityIdRaw); } - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { readFromNBT_AENetwork(compound); } } @@ -154,7 +154,7 @@ public NBTTagCompound writeToNBT(@NotNull NBTTagCompound compound) { NBTTagCompound metaTileEntityData = new NBTTagCompound(); metaTileEntity.writeToNBT(metaTileEntityData); compound.setTag("MetaTileEntity", metaTileEntityData); - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { writeToNBT_AENetwork(compound); } } @@ -167,7 +167,7 @@ public void invalidate() { metaTileEntity.invalidate(); } super.invalidate(); - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { invalidateAE(); } } @@ -375,7 +375,7 @@ public void onChunkUnload() { if (metaTileEntity != null) { metaTileEntity.onUnload(); } - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { onChunkUnloadAE(); } } @@ -505,7 +505,7 @@ public ITextComponent getDisplayName() { @Nullable @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public IGridNode getGridNode(@NotNull AEPartLocation part) { // Forbid it connects the faces it shouldn't connect. if (this.getCableConnectionType(part) == AECableType.NONE) { @@ -517,44 +517,44 @@ public IGridNode getGridNode(@NotNull AEPartLocation part) { @NotNull @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AECableType getCableConnectionType(@NotNull AEPartLocation part) { return metaTileEntity == null ? AECableType.NONE : metaTileEntity.getCableConnectionType(part); } @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void securityBreak() {} @NotNull @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public IGridNode getActionableNode() { AENetworkProxy proxy = getProxy(); return proxy == null ? null : proxy.getNode(); } @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AENetworkProxy getProxy() { return metaTileEntity == null ? null : metaTileEntity.getProxy(); } @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public DimensionalCoord getLocation() { return new DimensionalCoord(this); } @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void gridChanged() { if (metaTileEntity != null) { metaTileEntity.gridChanged(); } } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void readFromNBT_AENetwork(NBTTagCompound data) { AENetworkProxy proxy = getProxy(); if (proxy != null) { @@ -562,7 +562,7 @@ public void readFromNBT_AENetwork(NBTTagCompound data) { } } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void writeToNBT_AENetwork(NBTTagCompound data) { AENetworkProxy proxy = getProxy(); if (proxy != null) { @@ -570,7 +570,7 @@ public void writeToNBT_AENetwork(NBTTagCompound data) { } } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) void onChunkUnloadAE() { AENetworkProxy proxy = getProxy(); if (proxy != null) { @@ -578,7 +578,7 @@ void onChunkUnloadAE() { } } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) void invalidateAE() { AENetworkProxy proxy = getProxy(); if (proxy != null) { diff --git a/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java index 69c42322da8..5e648be0f60 100644 --- a/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java @@ -1,7 +1,12 @@ package gregtech.api.metatileentity; import gregtech.api.GTValues; -import gregtech.api.capability.impl.*; +import gregtech.api.capability.impl.AbstractRecipeLogic; +import gregtech.api.capability.impl.EnergyContainerHandler; +import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.NotifiableFluidTank; +import gregtech.api.capability.impl.NotifiableItemStackHandler; +import gregtech.api.capability.impl.RecipeLogicEnergy; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.multiblock.ICleanroomProvider; import gregtech.api.metatileentity.multiblock.ICleanroomReceiver; @@ -34,7 +39,7 @@ public abstract class WorkableTieredMetaTileEntity extends TieredMetaTileEntity implements IDataInfoProvider, ICleanroomReceiver { - protected final RecipeLogicEnergy workable; + protected final AbstractRecipeLogic workable; protected final RecipeMap recipeMap; protected final ICubeRenderer renderer; @@ -63,7 +68,7 @@ public WorkableTieredMetaTileEntity(ResourceLocation metaTileEntityId, RecipeMap reinitializeEnergyContainer(); } - protected RecipeLogicEnergy createWorkable(RecipeMap recipeMap) { + protected AbstractRecipeLogic createWorkable(RecipeMap recipeMap) { return new RecipeLogicEnergy(this, recipeMap, () -> energyContainer); } diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/IControlRodPort.java b/src/main/java/gregtech/api/metatileentity/multiblock/IControlRodPort.java index a62d906664f..f43a15533f7 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/IControlRodPort.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/IControlRodPort.java @@ -1,6 +1,5 @@ package gregtech.api.metatileentity.multiblock; public interface IControlRodPort { - - byte getInsertionAmount(); + // Allows for a special multiblock ability. } diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockPart.java b/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockPart.java index dc6cb0e5d28..520a36dcebb 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockPart.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockPart.java @@ -11,4 +11,7 @@ public interface IMultiblockPart { default boolean canPartShare() { return true; } + + /** Called when distinct mode is toggled on the controller that this part is attached to */ + default void onDistinctChange(boolean newValue) {} } diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java index 933ec7b1259..54b5bd45b5c 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java @@ -343,9 +343,9 @@ public void checkStructurePattern() { abilityPart.registerAbilities(abilityInstancesList); } } - parts.forEach(part -> part.addToMultiBlock(this)); this.multiblockParts.addAll(parts); this.multiblockAbilities.putAll(abilities); + parts.forEach(part -> part.addToMultiBlock(this)); this.structureFormed = true; writeCustomData(STRUCTURE_FORMED, buf -> buf.writeBoolean(true)); formStructure(context); diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java index 4301adbacce..d90c9b548db 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java @@ -246,6 +246,7 @@ public boolean isDistinct() { public void setDistinct(boolean isDistinct) { this.isDistinct = isDistinct; recipeMapWorkable.onDistinctChanged(); + getMultiblockParts().forEach(part -> part.onDistinctChange(isDistinct)); // mark buses as changed on distinct toggle if (this.isDistinct) { this.notifiedItemInputList.addAll(this.getAbilities(MultiblockAbility.IMPORT_ITEMS)); diff --git a/src/main/java/gregtech/api/mui/GTGuiTextures.java b/src/main/java/gregtech/api/mui/GTGuiTextures.java index 3c99abaee1e..d585285efc2 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTextures.java +++ b/src/main/java/gregtech/api/mui/GTGuiTextures.java @@ -12,6 +12,7 @@ * while MUI port is still ongoing. When MUI port is done, this annotation will be removed. */ // TODO ^ +@SuppressWarnings("unused") @ApiStatus.Experimental public class GTGuiTextures { @@ -153,6 +154,56 @@ public static class IDs { .canApplyTheme() .build(); + public static final UITexture[] BUTTON_BLACKLIST = slice("textures/gui/widget/button_blacklist.png", + 16, 32, 16, 16, true); + public static final UITexture[] BUTTON_IGNORE_DAMAGE = slice("textures/gui/widget/button_filter_damage.png", + 16, 32, 16, 16, true); + public static final UITexture[] BUTTON_IGNORE_NBT = slice("textures/gui/widget/button_filter_nbt.png", + 16, 32, 16, 16, true); + + public static final UITexture[] BUTTON_CASE_SENSITIVE = slice( + "textures/gui/widget/ore_filter/button_case_sensitive.png", + 16, 32, 16, 16, true); + + public static final UITexture[] BUTTON_MATCH_ALL = slice("textures/gui/widget/ore_filter/button_match_all.png", + 16, 32, 16, 16, true); + + public static final UITexture OREDICT_ERROR = fullImage("textures/gui/widget/ore_filter/error.png"); + public static final UITexture OREDICT_INFO = fullImage("textures/gui/widget/ore_filter/info.png"); + public static final UITexture OREDICT_MATCH = fullImage("textures/gui/widget/ore_filter/match.png"); + public static final UITexture OREDICT_NO_MATCH = fullImage("textures/gui/widget/ore_filter/no_match.png"); + public static final UITexture OREDICT_SUCCESS = fullImage("textures/gui/widget/ore_filter/success.png"); + public static final UITexture OREDICT_WAITING = fullImage("textures/gui/widget/ore_filter/waiting.png"); + public static final UITexture OREDICT_WARN = fullImage("textures/gui/widget/ore_filter/warn.png"); + + public static final UITexture[] MANUAL_IO_OVERLAY = slice("textures/gui/overlay/manual_io_overlay.png", + 18, 18 * 3, 18, 18, true); + public static final UITexture[] CONVEYOR_MODE_OVERLAY = slice("textures/gui/overlay/conveyor_mode_overlay.png", + 18, 18 * 2, 18, 18, true); + + public static final UITexture[] TRANSFER_MODE_OVERLAY = slice("textures/gui/overlay/transfer_mode_overlay.png", + 18, 18 * 3, 18, 18, true); + + public static final UITexture[] FLUID_TRANSFER_MODE_OVERLAY = slice( + "textures/gui/overlay/fluid_transfer_mode_overlay.png", + 18, 18 * 3, 18, 18, true); + + public static final UITexture[] DISTRIBUTION_MODE_OVERLAY = slice( + "textures/gui/widget/button_distribution_mode.png", + 16, 48, 16, 16, true); + + public static final UITexture[] VOIDING_MODE_OVERLAY = slice( + "textures/gui/overlay/voiding_mode_overlay.png", + 16, 32, 16, 16, true); + + public static final UITexture[] FILTER_MODE_OVERLAY = slice( + "textures/gui/overlay/filter_mode_overlay.png", + 16, 48, 16, 16, true); + + public static final UITexture[] PRIVATE_MODE_BUTTON = slice( + "textures/gui/widget/button_public_private.png", + 18, 36, 18, 18, true); + // todo bronze/steel/primitive fluid slots? // SLOT OVERLAYS @@ -205,6 +256,9 @@ public static class IDs { public static final UITexture EXTRACTOR_OVERLAY_STEEL = fullImage( "textures/gui/overlay/extractor_overlay_steel.png"); public static final UITexture FILTER_SLOT_OVERLAY = fullImage("textures/gui/overlay/filter_slot_overlay.png", true); + public static final UITexture FILTER_SETTINGS_OVERLAY = fullImage( + "textures/gui/overlay/filter_settings_overlay.png", + true); public static final UITexture FURNACE_OVERLAY_1 = fullImage("textures/gui/overlay/furnace_overlay_1.png", true); public static final UITexture FURNACE_OVERLAY_2 = fullImage("textures/gui/overlay/furnace_overlay_2.png", true); public static final UITexture FURNACE_OVERLAY_BRONZE = fullImage("textures/gui/overlay/furnace_overlay_bronze.png"); @@ -265,7 +319,7 @@ public static class IDs { public static final UITexture BUTTON = new UITexture.Builder() .location(GTValues.MODID, "textures/gui/widget/button.png") .imageSize(18, 18) - .adaptable(1) + .adaptable(2) .name(IDs.STANDARD_BUTTON) .canApplyTheme() .build(); @@ -274,13 +328,13 @@ public static class IDs { .location("modularui", "gui/widgets/mc_button.png") // todo .imageSize(16, 32) .uv(0.0f, 0.0f, 1.0f, 0.5f) - .adaptable(1) + .adaptable(2) .build(); public static final UITexture MC_BUTTON_DISABLED = new UITexture.Builder() .location("modularui", "gui/widgets/mc_button_disabled.png") // todo .imageSize(16, 16) - .adaptable(1) + .adaptable(2) .build(); // BUTTON OVERLAYS @@ -453,6 +507,29 @@ private static UITexture fullImage(String path, boolean canApplyTheme) { return UITexture.fullImage(GTValues.MODID, path, canApplyTheme); } + @SuppressWarnings("SameParameterValue") + private static UITexture[] slice(String path, int imageWidth, int imageHeight, int sliceWidth, int sliceHeight, + boolean canApplyTheme) { + if (imageWidth % sliceWidth != 0 || imageHeight % sliceHeight != 0) + throw new IllegalArgumentException("Slice height and slice width must divide the image evenly!"); + + int countX = imageWidth / sliceWidth; + int countY = imageHeight / sliceHeight; + UITexture[] slices = new UITexture[countX * countY]; + + for (int indexX = 0; indexX < countX; indexX++) { + for (int indexY = 0; indexY < countY; indexY++) { + slices[(indexX * countX) + indexY] = UITexture.builder() + .location(GTValues.MODID, path) + .canApplyTheme(canApplyTheme) + .imageSize(imageWidth, imageHeight) + .uv(indexX * sliceWidth, indexY * sliceHeight, sliceWidth, sliceHeight) + .build(); + } + } + return slices; + } + private static UITexture progressBar(String path) { return progressBar(path, 20, 40, false); } diff --git a/src/main/java/gregtech/api/mui/sync/FixedFluidSlotSH.java b/src/main/java/gregtech/api/mui/sync/FixedFluidSlotSH.java new file mode 100644 index 00000000000..bf3c6c581d7 --- /dev/null +++ b/src/main/java/gregtech/api/mui/sync/FixedFluidSlotSH.java @@ -0,0 +1,150 @@ +package gregtech.api.mui.sync; + +import gregtech.common.covers.filter.readers.SimpleFluidFilterReader; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandlerItem; + +import com.cleanroommc.modularui.utils.MouseData; +import com.cleanroommc.modularui.value.sync.FluidSlotSyncHandler; +import org.jetbrains.annotations.Nullable; + +public class FixedFluidSlotSH extends FluidSlotSyncHandler { + + @Nullable + private FluidStack lastStoredPhantomFluid; + + public FixedFluidSlotSH(IFluidTank fluidTank) { + super(fluidTank); + if (this.updateCacheFromSource(true) && fluidTank.getFluid() != null) { + this.lastStoredPhantomFluid = fluidTank.getFluid().copy(); + } + } + + @Override + public void readOnServer(int id, PacketBuffer buf) { + super.readOnServer(id, buf); + if (id == 0) { + var fluid = getFluidTank().getFluid(); + if (this.lastStoredPhantomFluid == null && fluid != null || + (this.lastStoredPhantomFluid != null && !this.lastStoredPhantomFluid.isFluidEqual(fluid))) { + this.lastStoredPhantomFluid = fluid; + } + } + } + + @Override + public void setValue(@Nullable FluidStack value, boolean setSource, boolean sync) { + super.setValue(value, setSource, sync); + if (setSource) { + this.getFluidTank().drain(Integer.MAX_VALUE, true); + if (!isFluidEmpty(value)) { + this.getFluidTank().fill(value.copy(), true); + } + } + } + + @Override + public void tryClickPhantom(MouseData mouseData) { + EntityPlayer player = getSyncManager().getPlayer(); + ItemStack currentStack = player.inventory.getItemStack(); + FluidStack currentFluid = this.getFluidTank().getFluid(); + IFluidHandlerItem fluidHandlerItem = currentStack + .getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null); + + if (mouseData.mouseButton == 0) { + if (currentStack.isEmpty() || fluidHandlerItem == null) { + if (this.canDrainSlot()) { + this.getFluidTank().drain(mouseData.shift ? Integer.MAX_VALUE : 1000, true); + } + } else { + FluidStack cellFluid = fluidHandlerItem.drain(Integer.MAX_VALUE, false); + if ((this.controlsAmount() || currentFluid == null) && cellFluid != null) { + if (this.canFillSlot()) { + if (!this.controlsAmount()) { + cellFluid.amount = 1; + } + if (this.getFluidTank().fill(cellFluid, true) > 0) { + this.lastStoredPhantomFluid = cellFluid.copy(); + } + } + } else { + if (this.canDrainSlot()) { + this.getFluidTank().drain(mouseData.shift ? Integer.MAX_VALUE : 1000, true); + } + } + } + } else if (mouseData.mouseButton == 1) { + if (this.canFillSlot()) { + if (currentFluid != null) { + if (this.controlsAmount()) { + FluidStack toFill = currentFluid.copy(); + toFill.amount = 1000; + this.getFluidTank().fill(toFill, true); + } + } else if (this.lastStoredPhantomFluid != null) { + FluidStack toFill = this.lastStoredPhantomFluid.copy(); + toFill.amount = this.controlsAmount() ? 1 : toFill.amount; + this.getFluidTank().fill(toFill, true); + } + } + } else if (mouseData.mouseButton == 2 && currentFluid != null && this.canDrainSlot()) { + this.getFluidTank().drain(mouseData.shift ? Integer.MAX_VALUE : 1000, true); + } + this.setValue(this.getFluidTank().getFluid(), false, true); + } + + @Override + public void tryScrollPhantom(MouseData mouseData) { + FluidStack currentFluid = this.getFluidTank().getFluid(); + int amount = mouseData.mouseButton; + if (!this.controlsAmount()) { + var fluid = getFluidTank().getFluid(); + int newAmt = amount == 1 ? 1 : 0; + if (fluid != null && fluid.amount != newAmt) { + fluid.amount = newAmt; + setValue(fluid, true, true); + return; + } + } + if (mouseData.shift) { + amount *= 10; + } + if (mouseData.ctrl) { + amount *= 100; + } + if (mouseData.alt) { + amount *= 1000; + } + if (currentFluid == null) { + if (amount > 0 && this.lastStoredPhantomFluid != null) { + FluidStack toFill = this.lastStoredPhantomFluid.copy(); + toFill.amount = this.controlsAmount() ? amount : 1; + this.getFluidTank().fill(toFill, true); + } + this.setValue(this.getFluidTank().getFluid(), false, true); + return; + } + if (amount > 0) { + FluidStack toFill = currentFluid.copy(); + toFill.amount = amount; + this.getFluidTank().fill(toFill, true); + } else if (amount < 0) { + this.getFluidTank().drain(-amount, true); + } + this.setValue(this.getFluidTank().getFluid(), false, true); + } + + @Override + public boolean controlsAmount() { + if (getFluidTank() instanceof SimpleFluidFilterReader.WritableFluidTank writableFluidTank) { + return writableFluidTank.showAmount(); + } + return super.controlsAmount(); + } +} diff --git a/src/main/java/gregtech/api/nuclear/fission/FissionReactor.java b/src/main/java/gregtech/api/nuclear/fission/FissionReactor.java index 6e0a982000e..7c778ad1207 100644 --- a/src/main/java/gregtech/api/nuclear/fission/FissionReactor.java +++ b/src/main/java/gregtech/api/nuclear/fission/FissionReactor.java @@ -4,15 +4,21 @@ import gregtech.api.nuclear.fission.components.CoolantChannel; import gregtech.api.nuclear.fission.components.FuelRod; import gregtech.api.nuclear.fission.components.ReactorComponent; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.properties.CoolantProperty; import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.common.ConfigHolder; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.FluidStack; import java.util.ArrayList; public class FissionReactor { /** - * The gas constant in J * K^-1 * mol^-1 if you want to use a different - * set of units prepare thy life to become the worst of nightmares + * The gas constant in J * K^-1 * mol^-1 if you want to use a different set of units prepare thy life to become the + * worst of nightmares */ public static final double R = 8.31446261815324; /** @@ -20,19 +26,34 @@ public class FissionReactor { */ public static final double standardPressure = 101325; + /** + * The starting temperature of the reactor in Kelvin + */ + public static final double roomTemperature = 273; + + /** + * Boiling point of air at standard pressure in Kelvin + */ + public static final double airBoilingPoint = 78.8; + private ReactorComponent[][] reactorLayout; private ArrayList fuelRods; private ArrayList controlRods; private ArrayList coolantChannels; private ArrayList effectiveControlRods; private ArrayList effectiveCoolantChannels; + + // TODO: Verify usefulness of the following things private int numberOfComponents; private double totNeutronSources; private double avgGeometricFactorSlowNeutrons; private double avgGeometricFactorFastNeutrons; - private int geometricIntegrationSteps; + // TODO: Make this configurable + private int geometricIntegrationSteps = 100; + + // Wtf is lSlow private double lSlow; private double lFast; private double kSlow; @@ -42,51 +63,90 @@ public class FissionReactor { private double avgCoolantTemperature; private double controlRodFactor; - private double kEff; + // TODO: Determine tolerance range from config + public double kEff; // criticality value, based on k + // Is this still needed? private double avgBoilingPoint; private double avgAbsorption; private double avgPressure; private double avgModeration; /** - * Thresholds important for determining the evolution of the reactor + * Thresholds important for determining the evolution of the reactor ^^^ This is a very epic comment */ - public int criticalRodInsertion; + public int criticalRodInsertion = 15; // determined by k value /** - * Integers used on variables with direct player control for easier adjustments + * Integers used on variables with direct player control for easier adjustments (normalize this to 0,1) */ - public int controlRodInsertion; + public double controlRodInsertion = 1; public int reactorDepth; - public int reactorRadius; + public double reactorRadius; - public boolean moderatorTipped; + public boolean moderatorTipped; // set by the type of control rod in the reactor(prepInitialConditions) /** * Megawatts */ public double power; public double prevPower; - public double temperature; - public double pressure; - public double exteriorPressure; + /** + * Temperature of the reactor + */ + public double temperature = roomTemperature; + public double pressure = standardPressure; + public double exteriorPressure = standardPressure; + /** + * Temperature of boiling point in kelvin at standard pressure Determined by a weighted sum of the individual + * coolant boiling points in {@link FissionReactor#prepareInitialConditions()} + */ public double coolantBoilingPointStandardPressure; + /** + * Latent heat of vaporization in J/mol Determined by a weighted sum of the individual heats of vaporization in + * {@link FissionReactor#prepareInitialConditions()} + */ public double coolantHeatOfVaporization; + /** + * Equilibrium temperature in kelvin Determined by a weighted sum of the individual coolant temperatures in + * {@link FissionReactor#prepareInitialConditions()} + */ public double coolantBaseTemperature; public double fuelDepletion = 1; public double prevFuelDepletion; public double heatRemoved; - public double neutronPoisonAmount; + public double neutronPoisonAmount; // can kill reactor if power is lowered and this value is high public double decayProductsAmount; - public double envTemperature; + public double envTemperature = roomTemperature; // maybe gotten from config per dim public double accumulatedHydrogen; - public double maxTemperature; - public double maxPressure; - public double maxPower; - - public double coolingFactor; + public double maxTemperature = 2000; + // Pascals + public double maxPressure = 15000000; + // In MW apparently + public double maxPower = 3; // determined by the amount of fuel in reactor and neutron matricies + public static double zircaloyHydrogenReactionTemperature = 1500; + + public double surfaceArea; + public static double thermalConductivity = 45; // 45 W/(m K), for steel + public static double wallThickness = 0.1; + public static double coolantWallThickness = 0.06; // Ideal for a 1-m diameter steel pipe with the given maximum + // pressure + public static double specificHeatCapacity = 420; // 420 J/(kg K), for steel + public static double convectiveHeatTransferCoefficient = 10; // 10 W/(m^2 K), for slow-moving air + + public static double powerDefectCoefficient = 0.016; // In units of reactivity + public static double decayProductRate = 0.997; // Based on the half-life of xenon-135, using real-life days as + // Minecraft days, and yes, I am using this for plutonium too + public static double poisonFraction = 0.063; // Xenon-135 yield from fission + public static double crossSectionRatio = 4; // The ratio between the cross section for typical fuels and xenon-135; + // very much changed here for balance purposes + + public double coolantMass; + public double fuelMass; + public double structuralMass; + public boolean needsOutput; + public boolean isOn = false; protected static double responseFunction(double target, double value, double criticalRate, double rate) { if (value <= 0) { @@ -96,23 +156,52 @@ protected static double responseFunction(double target, double value, double cri value = 0.1; } } - return value * criticalRate / rate * Math.sqrt(target / value); + double expDecay = Math.exp(-criticalRate / rate); + return value * expDecay + target * (1 - expDecay); } - protected static double responseFunctionTemperature(double target, double value, double criticalRate, double rate, - double equilibrium) { - value = Math.max(0.1, value); - rate = Math.max(0.1, rate); - return Math.max(value * criticalRate / rate * Math.sqrt(target / value), equilibrium); + protected double responseFunctionTemperature(double envTemperature, double currentTemperature, double heatAdded, + double heatAbsorbed) { + currentTemperature = Math.max(0.1, currentTemperature); + heatAbsorbed = Math.max(0.1, heatAbsorbed); + /* + * Simplifies what is the following: + * heatTransferCoefficient = 1 / (1 / convectiveHeatTransferCoefficient + wallThickness / thermalConductivity); + * (https://en.wikipedia.org/wiki/Newton%27s_law_of_cooling#First-order_transient_response_of_lumped- + * capacitance_objects) + * This assumes that we're extracting heat from the reactor through the wall into slowly moving air, removing + * the second convective heat. + * timeConstant = heatTransferCoefficient * this.surfaceArea / specificHeatCapacity; + */ + double timeConstant = specificHeatCapacity * + (1 / convectiveHeatTransferCoefficient + wallThickness / thermalConductivity) / this.surfaceArea; + + // Solves the following differential equation: + + // dT/dt = h_added_tot / m_tot - k(T - T_env) at t = 1s with T(0) = T_0 + double expDecay = Math.exp(-timeConstant); + + double effectiveEnvTemperature = envTemperature + + (heatAdded - heatAbsorbed) / (timeConstant * (this.coolantMass + this.structuralMass + this.fuelMass)); + return currentTemperature * expDecay + effectiveEnvTemperature * (1 - expDecay); } - public FissionReactor(int size) { + public FissionReactor(int size, int depth, double controlRodInsertion) { reactorLayout = new ReactorComponent[size][size]; + reactorDepth = depth; + reactorRadius = (double) size / 2 + 1.5; // Includes the extra block plus the distance from the center of a + // block to its edge + // Maps (0, 15) -> (0.01, 1) + this.controlRodInsertion = Math.max(0.001, controlRodInsertion); fuelRods = new ArrayList<>(); controlRods = new ArrayList<>(); coolantChannels = new ArrayList<>(); effectiveControlRods = new ArrayList<>(); effectiveCoolantChannels = new ArrayList<>(); + // 2pi * r^2 + 2pi * r * l + surfaceArea = (reactorRadius * reactorRadius) * Math.PI * 2 + reactorDepth * reactorRadius * Math.PI * 2; + structuralMass = reactorDepth * reactorRadius * reactorRadius * Math.PI * + 300; // Assuming 300 kg/m^3 when it's basically empty, does not have to be precise } public boolean canCoolantBoil() { @@ -123,14 +212,6 @@ public boolean explosionPossible() { return false; } - public double voidFactor() { - return this.canCoolantBoil() ? (this.temperature - this.envTemperature) / (double) this.pressure : 0.D; - } - - public double criticalCoolantFlow() { - return this.power / this.coolingFactor; - } - public void prepareThermalProperties() { int idRod = 0, idControl = 0, idChannel = 0; @@ -138,13 +219,13 @@ public void prepareThermalProperties() { for (int j = 0; j < reactorLayout[i].length; j++) { /* * Check for null because the layout - * is in generally not a square + * is in general not a square */ if (reactorLayout[i][j] != null && reactorLayout[i][j].isValid()) { reactorLayout[i][j].setPos(i, j); numberOfComponents++; maxTemperature = Double.min(maxTemperature, reactorLayout[i][j].getMaxTemperature()); - + structuralMass += reactorLayout[i][j].getMass(); if (reactorLayout[i][j] instanceof FuelRod) { reactorLayout[i][j].setID(idRod); fuelRods.add((FuelRod) reactorLayout[i][j]); @@ -191,14 +272,17 @@ public void computeGeometry() { double[] pos = { .5, .5 }; pos[0] += (fuelRods.get(j).getPos()[0] - fuelRods.get(i).getPos()[0]) * ((float) t / geometricIntegrationSteps) + fuelRods.get(i).getPos()[0]; - pos[1] += (fuelRods.get(j).getPos()[0] - fuelRods.get(i).getPos()[1]) * + pos[1] += (fuelRods.get(j).getPos()[1] - fuelRods.get(i).getPos()[1]) * ((float) t / geometricIntegrationSteps) + fuelRods.get(i).getPos()[1]; ReactorComponent component = reactorLayout[(int) Math.floor(pos[0])][(int) Math.floor(pos[1])]; + if (component == null) { + continue; + } mij += component.getModerationFactor(); /* - * For simplicity we pretend that fuel rods are completely opaque to neutrons, paths that hit fuel + * For simplicity, we pretend that fuel rods are completely opaque to neutrons, paths that hit fuel * rods are ignored as obstructed */ if (component instanceof FuelRod && component.samePositionAs(fuelRods.get(i)) && @@ -208,7 +292,7 @@ public void computeGeometry() { } /* - * We keep track of which active elements we hit, so we can determined how important they are + * We keep track of which active elements we hit, so we can determine how important they are * relative to the others later */ if (component instanceof ControlRod) { @@ -301,23 +385,20 @@ public void computeGeometry() { this.computeControlRodWeights(); this.computeCoolantChannelWeights(); - controlRodFactor = ControlRod.controlRodFactor(effectiveControlRods); + double depthDiameterDifference = 0.5 * (reactorDepth - reactorRadius * 2) / reactorRadius; + double sigmoid = 1 / (1 + Math.exp(-depthDiameterDifference)); + double fuelRodFactor = sigmoid * Math.pow(avgFuelRodDistance, -2) + + (1 - sigmoid) * Math.pow(avgFuelRodDistance, -1); + + maxPower = fuelRods.size() * (avgHighEnergyFissionFactor + avgLowEnergyFissionFactor) * fuelRodFactor * + ConfigHolder.machines.nuclearPowerMultiplier; + + controlRodFactor = ControlRod.controlRodFactor(effectiveControlRods, this.controlRodInsertion); avgCoolantTemperature /= coolantChannels.size(); this.prepareInitialConditions(); - for (CoolantChannel channel : effectiveCoolantChannels) { - temperature += channel.getCoolant().getFluid().getTemperature() * channel.getWeight(); - avgBoilingPoint += channel.getCoolant().getProperty(PropertyKey.COOLANT).getBoilingPoint() * - channel.getWeight(); - avgAbsorption += channel.getCoolant().getProperty(PropertyKey.COOLANT).getAbsorption() * - channel.getWeight(); - avgModeration += channel.getCoolant().getProperty(PropertyKey.COOLANT).getModerationFactor() * - channel.getWeight(); - avgPressure += channel.getCoolant().getProperty(PropertyKey.COOLANT).getPressure() * channel.getWeight(); - } - - kEff = 1. * k; + kEff = k; } /** @@ -349,20 +430,103 @@ protected void computeCoolantChannelWeights() { } public void prepareInitialConditions() { + coolantBaseTemperature = 0; + coolantBoilingPointStandardPressure = 0; + avgAbsorption = 0; + avgModeration = 0; + avgPressure = 0; + coolantHeatOfVaporization = 0; for (CoolantChannel channel : effectiveCoolantChannels) { - temperature += channel.getCoolant().getFluid().getTemperature() * channel.getWeight(); - // TODO: Add boiling point values - avgBoilingPoint += channel.getCoolant().getProperty(PropertyKey.COOLANT).getBoilingPoint() * + + CoolantProperty prop = channel.getCoolant().getProperty(PropertyKey.COOLANT); + + coolantBaseTemperature += channel.getCoolant().getFluid().getTemperature() * + channel.getWeight(); + coolantBoilingPointStandardPressure += prop.getBoilingPoint() * channel.getWeight(); - // TODO: Add neutron absorption values - avgAbsorption += channel.getCoolant().getProperty(PropertyKey.COOLANT).getAbsorption() * + avgAbsorption += prop.getAbsorption() * channel.getWeight(); - // TODO: Add neutron moderation values - avgModeration += channel.getCoolant().getProperty(PropertyKey.COOLANT).getModerationFactor() * + avgModeration += prop.getModerationFactor() * channel.getWeight(); - // TODO: Add pressure to coolants - avgPressure += channel.getCoolant().getProperty(PropertyKey.COOLANT).getPressure() * channel.getWeight(); + avgPressure += prop.getPressure() * + channel.getWeight(); + coolantHeatOfVaporization += prop.getHeatOfVaporization() * + channel.getWeight(); + } + + if (coolantBaseTemperature == 0) { + coolantBaseTemperature = envTemperature; + } + if (avgPressure == 0) { + avgPressure = standardPressure; } + if (coolantBoilingPointStandardPressure == 0) { + coolantBoilingPointStandardPressure = airBoilingPoint; + } + isOn = true; + } + + /** + * Consumes the coolant. Calculates the heat removed by the coolant based on an amalgamation of different equations. + * It is not particularly realistic, but allows for some fine-tuning to happen. Heat removed is proportional to the + * surface area of the coolant channel (which is equivalent to the reactor's depth), as well as the flow rate of + * coolant and the difference in temperature between the reactor and the coolant + */ + public void makeCoolantFlow(int flowRate) { + for (CoolantChannel channel : coolantChannels) { + FluidStack tryFluidDrain = channel.getInputHandler().getFluidTank().drain(flowRate, false); + if (tryFluidDrain != null) { + int drained = tryFluidDrain.amount; + + Material coolant = channel.getCoolant(); + + CoolantProperty prop = coolant.getProperty(PropertyKey.COOLANT); + + double heatRemovedPerLiter = prop.getSpecificHeatCapacity() * + (prop.getHotHPCoolant().getFluid().getTemperature() - coolant.getFluid().getTemperature()) / + prop.getSadgeCoefficient(); + // Explained by: + // https://physics.stackexchange.com/questions/153434/heat-transfer-between-the-bulk-of-the-fluid-inside-the-pipe-and-the-pipe-externa + double heatFluxPerAreaAndTemp = 1 / + (1 / prop.getCoolingFactor() + coolantWallThickness / thermalConductivity); + double idealHeatFlux = heatFluxPerAreaAndTemp * 4 * reactorDepth * + (temperature - coolant.getFluid().getTemperature()); + + double idealFluidUsed = idealHeatFlux / heatRemovedPerLiter; + + int remainingSpace = channel.getOutputHandler().getFluidTank().getCapacity() - + channel.getOutputHandler().getFluidTank().getFluidAmount(); + int actualFlowRate = Math.min(Math.min(remainingSpace, drained), + (int) (idealFluidUsed + channel.partialCoolant)); + // Should occasionally decrease when coolant is actually consumed. + channel.partialCoolant += Math.max(0, Math.min(idealFluidUsed, drained)) - actualFlowRate; + + FluidStack HPCoolant = new FluidStack( + prop.getHotHPCoolant().getFluid(), actualFlowRate); + + channel.getInputHandler().getFluidTank().drain(actualFlowRate, true); + + if (this.temperature > this.coolantBoilingPoint()) { + channel.getOutputHandler().getFluidTank().fill(HPCoolant, true); + } + + if (prop.accumulatesHydrogen() && + this.temperature > zircaloyHydrogenReactionTemperature) { + double boilingPoint = coolantBoilingPoint(coolant); + if (this.temperature > boilingPoint) { + this.accumulatedHydrogen += (this.temperature - boilingPoint) / boilingPoint; + } else if (actualFlowRate < Math.min(remainingSpace, idealFluidUsed)) { + this.accumulatedHydrogen += (this.temperature - zircaloyHydrogenReactionTemperature) / + zircaloyHydrogenReactionTemperature; + } + } + + this.coolantMass += actualFlowRate * coolant.getMass(); + this.heatRemoved += actualFlowRate * heatRemovedPerLiter; + } + } + this.coolantMass /= 1000; + this.accumulatedHydrogen *= 0.98; } /** @@ -374,45 +538,73 @@ protected double coolantBoilingPoint() { R * Math.log(this.pressure / standardPressure) / this.coolantHeatOfVaporization); } + protected double coolantBoilingPoint(Material coolant) { + if (coolant.getProperty(PropertyKey.COOLANT).getBoilingPoint() == 0) { + return coolantBoilingPoint(); + } + return 1. / (1. / coolant.getProperty(PropertyKey.COOLANT).getBoilingPoint() - + R * Math.log(this.pressure / standardPressure) / + coolant.getProperty(PropertyKey.COOLANT).getHeatOfVaporization()); + } + public void updateTemperature() { - this.temperature = responseFunctionTemperature(this.maxTemperature, this.temperature, this.power, - this.heatRemoved, this.coolantBaseTemperature); + this.temperature = responseFunctionTemperature(envTemperature, this.temperature, this.power * 1000000, + this.heatRemoved); this.heatRemoved = 0; } public void updatePressure() { this.pressure = responseFunction( - this.temperature <= this.coolantBoilingPoint() ? this.exteriorPressure : 1000. * R * this.temperature, - this.pressure, 1., 1.); + this.temperature <= this.coolantBoilingPoint() || !this.isOn ? this.exteriorPressure : + 1000. * R * this.temperature, + this.pressure, 0.2, 1.); } public void updateNeutronPoisoning() { - this.neutronPoisonAmount += Math.max(0., this.prevPower - this.power); - this.neutronPoisonAmount *= 0.99; + this.neutronPoisonAmount += this.decayProductsAmount * (1 - decayProductRate) * poisonFraction; + this.neutronPoisonAmount *= decayProductRate; } public double getDecayHeat() { return this.neutronPoisonAmount * 0.05 + this.decayProductsAmount * 0.1; } - public double voidContribution() { - return this.voidFactor() * (this.temperature > this.coolantBoilingPoint() ? this.maxPressure : 0.); - } + /* + * public double voidContribution() { + * return this.temperature > this.coolantBoilingPoint() ? this.voidFactor() * this.maxPressure : 0.; + * } + */ public void updatePower() { - this.prevPower = this.power; - this.prevFuelDepletion = this.fuelDepletion; - this.power = responseFunction(this.realMaxPower(), this.power, - this.criticalRodInsertion + this.voidContribution(), this.controlRodInsertion); - this.fuelDepletion = Math.min(this.fuelDepletion + 0.001 * this.power / this.maxPower, 1.); - this.decayProductsAmount += Math.max(this.prevFuelDepletion - this.fuelDepletion, 0.); - this.decayProductsAmount *= 0.99; + if (this.isOn) { + this.kEff = this.k + controlRodFactor; + // Since the power defect is a change in the reactivity rho (1 - 1 / kEff), we have to do this thing. + // (1 - 1 / k) = rho(k) => rho^-1(rho) = 1 / (1 - rho) + // rho^-1(rho(k) - defect) is thus 1 / (1 - (1 - 1/k - defect)) = 1 / (1/k + defect) + this.kEff = 1 / ((1 / this.kEff) + powerDefectCoefficient * (this.power / this.maxPower) + + neutronPoisonAmount * crossSectionRatio); + this.kEff = Math.max(0, this.kEff); + this.prevPower = this.power; + this.prevFuelDepletion = this.fuelDepletion; + // maps (1, 1.1) to (1, 15); this value basically sets how quickly kEff operates + this.criticalRodInsertion = (int) Math.max(1, Math.min(15, (kEff - 1) * 150.)); + + this.power = responseFunction(Math.min(this.realMaxPower(), this.power * kEff + 0.0001), this.power, + this.criticalRodInsertion, 1); + this.fuelDepletion = Math.min(this.fuelDepletion + 0.001 * this.power / this.maxPower, 1.); + + this.decayProductsAmount += Math.max(this.fuelDepletion - this.prevFuelDepletion, 0.); + } else { + this.power = responseFunction(Math.min(this.realMaxPower(), this.power * kEff), this.power, + controlRodInsertion, 1); + } + this.decayProductsAmount *= decayProductRate; } public double realMaxPower() { if (this.moderatorTipped && (this.controlRodInsertion <= 9 && this.controlRodInsertion >= 7)) { return this.maxPower * 1.1; - } else if (this.controlRodInsertion > this.criticalRodInsertion || this.fuelDepletion >= 1.) { + } else if (this.controlRodInsertion > this.criticalRodInsertion || this.fuelDepletion >= 1. || !this.isOn) { return this.getDecayHeat(); } else { return this.maxPower; @@ -427,11 +619,76 @@ public boolean checkForExplosion() { return this.pressure > this.maxPressure; } - public boolean checkForSecondaryExplosion() { - return this.accumulatedHydrogen > 0.; - } - public void addComponent(ReactorComponent component, int x, int y) { reactorLayout[x][y] = component; } + + public NBTTagCompound serializeNBT() { + NBTTagCompound tagCompound = new NBTTagCompound(); + tagCompound.setDouble("Temperature", this.temperature); + tagCompound.setDouble("Pressure", this.pressure); + tagCompound.setDouble("Power", this.power); + tagCompound.setDouble("FuelDepletion", this.fuelDepletion); + tagCompound.setDouble("AccumulatedHydrogen", this.accumulatedHydrogen); + tagCompound.setDouble("HeatRemoved", this.heatRemoved); + tagCompound.setDouble("NeutronPoisonAmount", this.neutronPoisonAmount); + tagCompound.setDouble("DecayProductsAmount", this.decayProductsAmount); + tagCompound.setBoolean("NeedsOutput", this.needsOutput); + tagCompound.setDouble("ControlRodInsertion", this.controlRodInsertion); + tagCompound.setBoolean("IsOn", this.isOn); + + return tagCompound; + } + + public void deserializeNBT(NBTTagCompound tagCompound) { + this.temperature = tagCompound.getDouble("Temperature"); + this.pressure = tagCompound.getDouble("Pressure"); + this.power = tagCompound.getDouble("Power"); + this.fuelDepletion = tagCompound.getDouble("FuelDepletion"); + this.accumulatedHydrogen = tagCompound.getDouble("AccumulatedHydrogen"); + this.heatRemoved = tagCompound.getDouble("HeatRemoved"); + this.neutronPoisonAmount = tagCompound.getDouble("NeutronPoisonAmount"); + this.decayProductsAmount = tagCompound.getDouble("DecayProductsAmount"); + this.needsOutput = tagCompound.getBoolean("NeedsOutput"); + this.controlRodInsertion = tagCompound.getDouble("ControlRodInsertion"); + this.isOn = tagCompound.getBoolean("IsOn"); + } + + public void updateControlRodInsertion(double controlRodInsertion) { + this.controlRodInsertion = Math.max(0.001, controlRodInsertion); + this.controlRodFactor = ControlRod.controlRodFactor(effectiveControlRods, this.controlRodInsertion); + } + + public void regulateControlRods() { + if (!this.isOn) + return; + if (temperature < maxTemperature * 3 / 4 && pressure < maxPressure * 3 / 4) { + if (kEff < 1) { + this.controlRodInsertion -= 1f / 255; + this.controlRodInsertion = Math.max(0, this.controlRodInsertion); + this.controlRodFactor = ControlRod.controlRodFactor(effectiveControlRods, this.controlRodInsertion); + } + } else { + if (kEff > 1) { + this.controlRodInsertion += 1f / 255; + this.controlRodInsertion = Math.min(1, this.controlRodInsertion); + this.controlRodFactor = ControlRod.controlRodFactor(effectiveControlRods, this.controlRodInsertion); + } + } + } + + public void turnOff() { + this.isOn = false; + this.maxPower = 0; + this.k = 0; + this.kEff = 0; + this.coolantMass = 0; + this.fuelMass = 0; + reactorLayout = new ReactorComponent[reactorLayout.length][reactorLayout.length]; + fuelRods.clear(); + controlRods.clear(); + coolantChannels.clear(); + effectiveControlRods.clear(); + effectiveCoolantChannels.clear(); + } } diff --git a/src/main/java/gregtech/api/nuclear/fission/components/ControlRod.java b/src/main/java/gregtech/api/nuclear/fission/components/ControlRod.java index 4c9ee6d0d1c..4bb4ed9ac74 100644 --- a/src/main/java/gregtech/api/nuclear/fission/components/ControlRod.java +++ b/src/main/java/gregtech/api/nuclear/fission/components/ControlRod.java @@ -10,13 +10,11 @@ public class ControlRod extends ReactorComponent { private double weight; private final boolean tipModeration; - private double insertion; private final List> fuelRodPairs = new ObjectArrayList<>(); - public ControlRod(double maxTemperature, boolean tipModeration, double thermalConductivity, double insertion) { - super(0, maxTemperature, thermalConductivity, true); + public ControlRod(double maxTemperature, boolean tipModeration, double thermalConductivity, double mass) { + super(0, maxTemperature, thermalConductivity, mass, true); this.tipModeration = tipModeration; - this.insertion = insertion; this.weight = 0; } @@ -30,17 +28,17 @@ public static void normalizeWeights(ArrayList effectiveControlRods) } } - public static double controlRodFactor(ArrayList effectiveControlRods) { + public static double controlRodFactor(ArrayList effectiveControlRods, double insertion) { double crf = 0; for (ControlRod control_rod : effectiveControlRods) { if (control_rod.hasModeratorTip()) { - if (control_rod.insertion <= 0.3) { - crf += control_rod.insertion / 3 * control_rod.weight; + if (insertion <= 0.3) { + crf += insertion / 3 * control_rod.weight; } else { - crf += (-11F / 7 * (control_rod.insertion - 0.3) + 0.1) * control_rod.weight; + crf += (-11F / 7 * (insertion - 0.3) + 0.1) * control_rod.weight; } } else { - crf += -control_rod.insertion * control_rod.weight; + crf += -insertion * control_rod.weight; } } return crf; @@ -62,14 +60,6 @@ List> getFuelRodPairMap() { return fuelRodPairs; } - public double getInsertion() { - return insertion; - } - - public void setInsertion(double insertion) { - this.insertion = insertion; - } - public void increaseWeight() { weight++; } diff --git a/src/main/java/gregtech/api/nuclear/fission/components/CoolantChannel.java b/src/main/java/gregtech/api/nuclear/fission/components/CoolantChannel.java index 49feefd2b59..538e01b57e9 100644 --- a/src/main/java/gregtech/api/nuclear/fission/components/CoolantChannel.java +++ b/src/main/java/gregtech/api/nuclear/fission/components/CoolantChannel.java @@ -1,5 +1,6 @@ package gregtech.api.nuclear.fission.components; +import gregtech.api.capability.ICoolantHandler; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.properties.PropertyKey; @@ -15,11 +16,18 @@ public class CoolantChannel extends ReactorComponent { private double weight; private final List> fuelRodPairs = new ObjectArrayList<>(); - public CoolantChannel(double maxTemperature, double thermalConductivity, Material coolant) { - super(coolant.getProperty(PropertyKey.COOLANT).getModerationFactor(), maxTemperature, thermalConductivity, + private ICoolantHandler inputHandler; + private ICoolantHandler outputHandler; + public double partialCoolant; + + public CoolantChannel(double maxTemperature, double thermalConductivity, Material coolant, double mass, + ICoolantHandler inputHandler, ICoolantHandler outputHandler) { + super(coolant.getProperty(PropertyKey.COOLANT).getModerationFactor(), maxTemperature, thermalConductivity, mass, true); this.coolant = coolant; this.weight = 0; + this.inputHandler = inputHandler; + this.outputHandler = outputHandler; } public static void normalizeWeights(ArrayList effectiveCoolantChannels) { @@ -55,4 +63,20 @@ public Material getCoolant() { public void computeWeightFromFuelRodMap() { this.weight = fuelRodPairs.size() * 2; } + + public ICoolantHandler getInputHandler() { + return inputHandler; + } + + public void setInputHandler(ICoolantHandler inputHandler) { + this.inputHandler = inputHandler; + } + + public ICoolantHandler getOutputHandler() { + return outputHandler; + } + + public void setOutputHandler(ICoolantHandler outputHandler) { + this.outputHandler = outputHandler; + } } diff --git a/src/main/java/gregtech/api/nuclear/fission/components/FuelRod.java b/src/main/java/gregtech/api/nuclear/fission/components/FuelRod.java index 0ceb6ba7f1c..8409eb6d6ca 100644 --- a/src/main/java/gregtech/api/nuclear/fission/components/FuelRod.java +++ b/src/main/java/gregtech/api/nuclear/fission/components/FuelRod.java @@ -7,9 +7,9 @@ public class FuelRod extends ReactorComponent { private final FissionFuelProperty fuel; private final double neutronSourceIntensity; - public FuelRod(double maxTemperature, double thermalConductivity, FissionFuelProperty fuel, + public FuelRod(double maxTemperature, double thermalConductivity, FissionFuelProperty fuel, double mass, double neutronSourceIntensity) { - super(0, maxTemperature, thermalConductivity, true); + super(0, maxTemperature, thermalConductivity, mass, true); this.fuel = fuel; this.neutronSourceIntensity = neutronSourceIntensity; } diff --git a/src/main/java/gregtech/api/nuclear/fission/components/ReactorComponent.java b/src/main/java/gregtech/api/nuclear/fission/components/ReactorComponent.java index c6ed9bbf21c..5b7d6db1d8c 100644 --- a/src/main/java/gregtech/api/nuclear/fission/components/ReactorComponent.java +++ b/src/main/java/gregtech/api/nuclear/fission/components/ReactorComponent.java @@ -5,6 +5,7 @@ public class ReactorComponent { private final double moderationFactor; private final double maxTemperature; private final double thermalConductivity; + private final double mass; private final int[] pos = new int[2]; @@ -12,11 +13,12 @@ public class ReactorComponent { private int ID = -1; - public ReactorComponent(double moderationFactor, double maxTemperature, double thermalConductivity, + public ReactorComponent(double moderationFactor, double maxTemperature, double thermalConductivity, double mass, boolean isValid) { this.moderationFactor = moderationFactor; this.maxTemperature = maxTemperature; this.thermalConductivity = thermalConductivity; + this.mass = mass; this.isValid = isValid; } @@ -67,10 +69,14 @@ public double getDistance(ReactorComponent component) { public static double getDistanceSquared(ReactorComponent component1, ReactorComponent component2) { return Math.pow(component1.getPos()[0] - component2.getPos()[0], 2) + - Math.pow(component1.getPos()[0] - component2.getPos()[0], 2); + Math.pow(component1.getPos()[1] - component2.getPos()[1], 2); } public static double getDistance(ReactorComponent component1, ReactorComponent component2) { return Math.sqrt(getDistanceSquared(component1, component2)); } + + public double getMass() { + return mass; + } } diff --git a/src/main/java/gregtech/api/pattern/BlockPattern.java b/src/main/java/gregtech/api/pattern/BlockPattern.java index 667202c7404..26867535bdc 100644 --- a/src/main/java/gregtech/api/pattern/BlockPattern.java +++ b/src/main/java/gregtech/api/pattern/BlockPattern.java @@ -165,7 +165,8 @@ private PatternMatchContext checkPatternAt(World world, BlockPos centerPos, Enum for (int b = 0, y = -centerOffset[1]; b < this.thumbLength; b++, y++) { for (int a = 0, x = -centerOffset[0]; a < this.palmLength; a++, x++) { TraceabilityPredicate predicate = this.blockMatches[c][b][a]; - BlockPos pos = setActualRelativeOffset(x, y, z, frontFacing, upwardsFacing, isFlipped) + BlockPos pos = RelativeDirection.setActualRelativeOffset(x, y, z, frontFacing, upwardsFacing, + isFlipped, structureDir) .add(centerPos.getX(), centerPos.getY(), centerPos.getZ()); worldState.update(world, pos, matchContext, globalCount, layerCount, predicate); TileEntity tileEntity = worldState.getTileEntity(); @@ -250,9 +251,10 @@ public void autoBuild(EntityPlayer player, MultiblockControllerBase controllerBa for (int b = 0, y = -centerOffset[1]; b < this.thumbLength; b++, y++) { for (int a = 0, x = -centerOffset[0]; a < this.palmLength; a++, x++) { TraceabilityPredicate predicate = this.blockMatches[c][b][a]; - BlockPos pos = setActualRelativeOffset(x, y, z, facing, controllerBase.getUpwardsFacing(), - controllerBase.isFlipped()) - .add(centerPos.getX(), centerPos.getY(), centerPos.getZ()); + BlockPos pos = RelativeDirection.setActualRelativeOffset(x, y, z, facing, + controllerBase.getUpwardsFacing(), + controllerBase.isFlipped(), structureDir) + .add(centerPos.getX(), centerPos.getY(), centerPos.getZ()); worldState.update(world, pos, matchContext, globalCount, layerCount, predicate); if (!world.getBlockState(pos).getMaterial().isReplaceable()) { blocks.put(pos, world.getBlockState(pos)); @@ -266,13 +268,13 @@ public void autoBuild(EntityPlayer player, MultiblockControllerBase controllerBa if (limit.minLayerCount > 0) { if (!cacheLayer.containsKey(limit)) { cacheLayer.put(limit, 1); - } else - if (cacheLayer.get(limit) < limit.minLayerCount && (limit.maxLayerCount == -1 || - cacheLayer.get(limit) < limit.maxLayerCount)) { - cacheLayer.put(limit, cacheLayer.get(limit) + 1); - } else { - continue; - } + } else if (cacheLayer.get(limit) < limit.minLayerCount && + (limit.maxLayerCount == -1 || + cacheLayer.get(limit) < limit.maxLayerCount)) { + cacheLayer.put(limit, cacheLayer.get(limit) + 1); + } else { + continue; + } } else { continue; } @@ -401,9 +403,10 @@ public void autoBuild(EntityPlayer player, MultiblockControllerBase controllerBa z++; } } - EnumFacing[] facings = ArrayUtils.addAll(new EnumFacing[] { controllerBase.getFrontFacing() }, FACINGS); // follow - // controller - // first + EnumFacing[] facings = ArrayUtils.addAll(new EnumFacing[] { controllerBase.getFrontFacing() }, + FACINGS); // follow + // controller + // first blocks.forEach((pos, block) -> { // adjust facing if (block instanceof MetaTileEntity) { MetaTileEntity metaTileEntity = (MetaTileEntity) block; @@ -449,7 +452,7 @@ public BlockInfo[][][] getPreview(int[] repetition) { boolean find = false; BlockInfo[] infos = null; for (TraceabilityPredicate.SimplePredicate limit : predicate.limited) { // check layer and - // previewCount + // previewCount if (limit.minLayerCount > 0) { if (!cacheLayer.containsKey(limit)) { cacheLayer.put(limit, 1); @@ -571,7 +574,8 @@ public BlockInfo[][][] getPreview(int[] repetition) { } } BlockInfo info = infos == null || infos.length == 0 ? BlockInfo.EMPTY : infos[0]; - BlockPos pos = setActualRelativeOffset(z, y, x, EnumFacing.NORTH, EnumFacing.UP, false); + BlockPos pos = RelativeDirection.setActualRelativeOffset(z, y, x, EnumFacing.NORTH, + EnumFacing.UP, false, structureDir); // TODO if (info.getTileEntity() instanceof MetaTileEntityHolder) { MetaTileEntityHolder holder = new MetaTileEntityHolder(); @@ -624,87 +628,4 @@ public BlockInfo[][][] getPreview(int[] repetition) { }); return result; } - - private BlockPos setActualRelativeOffset(int x, int y, int z, EnumFacing facing, EnumFacing upwardsFacing, - boolean isFlipped) { - int[] c0 = new int[] { x, y, z }, c1 = new int[3]; - if (facing == EnumFacing.UP || facing == EnumFacing.DOWN) { - EnumFacing of = facing == EnumFacing.DOWN ? upwardsFacing : upwardsFacing.getOpposite(); - for (int i = 0; i < 3; i++) { - switch (structureDir[i].getActualFacing(of)) { - case UP -> c1[1] = c0[i]; - case DOWN -> c1[1] = -c0[i]; - case WEST -> c1[0] = -c0[i]; - case EAST -> c1[0] = c0[i]; - case NORTH -> c1[2] = -c0[i]; - case SOUTH -> c1[2] = c0[i]; - } - } - int xOffset = upwardsFacing.getXOffset(); - int zOffset = upwardsFacing.getZOffset(); - int tmp; - if (xOffset == 0) { - tmp = c1[2]; - c1[2] = zOffset > 0 ? c1[1] : -c1[1]; - c1[1] = zOffset > 0 ? -tmp : tmp; - } else { - tmp = c1[0]; - c1[0] = xOffset > 0 ? c1[1] : -c1[1]; - c1[1] = xOffset > 0 ? -tmp : tmp; - } - if (isFlipped) { - if (upwardsFacing == EnumFacing.NORTH || upwardsFacing == EnumFacing.SOUTH) { - c1[0] = -c1[0]; // flip X-axis - } else { - c1[2] = -c1[2]; // flip Z-axis - } - } - } else { - for (int i = 0; i < 3; i++) { - switch (structureDir[i].getActualFacing(facing)) { - case UP -> c1[1] = c0[i]; - case DOWN -> c1[1] = -c0[i]; - case WEST -> c1[0] = -c0[i]; - case EAST -> c1[0] = c0[i]; - case NORTH -> c1[2] = -c0[i]; - case SOUTH -> c1[2] = c0[i]; - } - } - if (upwardsFacing == EnumFacing.WEST || upwardsFacing == EnumFacing.EAST) { - int xOffset = upwardsFacing == EnumFacing.WEST ? facing.rotateY().getXOffset() : - facing.rotateY().getOpposite().getXOffset(); - int zOffset = upwardsFacing == EnumFacing.WEST ? facing.rotateY().getZOffset() : - facing.rotateY().getOpposite().getZOffset(); - int tmp; - if (xOffset == 0) { - tmp = c1[2]; - c1[2] = zOffset > 0 ? -c1[1] : c1[1]; - c1[1] = zOffset > 0 ? tmp : -tmp; - } else { - tmp = c1[0]; - c1[0] = xOffset > 0 ? -c1[1] : c1[1]; - c1[1] = xOffset > 0 ? tmp : -tmp; - } - } else if (upwardsFacing == EnumFacing.SOUTH) { - c1[1] = -c1[1]; - if (facing.getXOffset() == 0) { - c1[0] = -c1[0]; - } else { - c1[2] = -c1[2]; - } - } - if (isFlipped) { - if (upwardsFacing == EnumFacing.NORTH || upwardsFacing == EnumFacing.SOUTH) { - if (facing == EnumFacing.NORTH || facing == EnumFacing.SOUTH) { - c1[0] = -c1[0]; // flip X-axis - } else { - c1[2] = -c1[2]; // flip Z-axis - } - } else { - c1[1] = -c1[1]; // flip Y-axis - } - } - } - return new BlockPos(c1[0], c1[1], c1[2]); - } } diff --git a/src/main/java/gregtech/api/pattern/MultiblockShapeInfo.java b/src/main/java/gregtech/api/pattern/MultiblockShapeInfo.java index a768aae5c68..3c79bc333c9 100644 --- a/src/main/java/gregtech/api/pattern/MultiblockShapeInfo.java +++ b/src/main/java/gregtech/api/pattern/MultiblockShapeInfo.java @@ -3,11 +3,13 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.util.BlockInfo; +import gregtech.api.util.RelativeDirection; import gregtech.common.blocks.MetaBlocks; import net.minecraft.block.state.IBlockState; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; import org.jetbrains.annotations.NotNull; @@ -17,6 +19,8 @@ import java.util.Map; import java.util.function.Supplier; +import static gregtech.api.util.RelativeDirection.*; + public class MultiblockShapeInfo { /** {@code [x][y][z]} */ @@ -34,14 +38,44 @@ public BlockInfo[][][] getBlocks() { } public static Builder builder() { - return new Builder(); + return new Builder(RIGHT, DOWN, BACK); + } + + public static Builder builder(RelativeDirection... structureDir) { + return new Builder(structureDir); } public static class Builder { + private final RelativeDirection[] structureDir = new RelativeDirection[3]; + private List shape = new ArrayList<>(); private Map symbolMap = new HashMap<>(); + public Builder(RelativeDirection... structureDir) { + this.structureDir[0] = structureDir[0]; + this.structureDir[1] = structureDir[1]; + this.structureDir[2] = structureDir[2]; + int flags = 0; + for (int i = 0; i < 3; i++) { + switch (structureDir[i]) { + case UP: + case DOWN: + flags |= 0x1; + break; + case LEFT: + case RIGHT: + flags |= 0x2; + break; + case FRONT: + case BACK: + flags |= 0x4; + break; + } + } + if (flags != 0x7) throw new IllegalArgumentException("Must have 3 different axes!"); + } + public Builder aisle(String... data) { this.shape.add(data); return this; @@ -86,7 +120,13 @@ private BlockInfo[][][] bakeArray() { final int maxZ = shape.size(); final int maxY = shape.get(0).length; final int maxX = shape.get(0)[0].length(); - BlockInfo[][][] blockInfos = new BlockInfo[maxX][maxY][maxZ]; + + BlockPos end = RelativeDirection.setActualRelativeOffset(maxX, maxY, maxZ, EnumFacing.SOUTH, EnumFacing.UP, + true, structureDir); + BlockPos addition = new BlockPos(end.getX() < 0 ? -end.getX() - 1 : 0, end.getY() < 0 ? -end.getY() - 1 : 0, + end.getZ() < 0 ? -end.getZ() - 1 : 0); + BlockPos bound = new BlockPos(Math.abs(end.getX()), Math.abs(end.getY()), Math.abs(end.getZ())); + BlockInfo[][][] blockInfos = new BlockInfo[bound.getX()][bound.getY()][bound.getZ()]; for (int z = 0; z < maxZ; z++) { String[] aisleEntry = shape.get(z); for (int y = 0; y < maxY; y++) { @@ -104,7 +144,9 @@ private BlockInfo[][][] bakeArray() { } else if (tileEntity != null) { info = new BlockInfo(info.getBlockState(), tileEntity); } - blockInfos[x][y][z] = info; + BlockPos pos = RelativeDirection.setActualRelativeOffset(x, y, z, EnumFacing.SOUTH, + EnumFacing.UP, true, structureDir).add(addition); + blockInfos[pos.getX()][pos.getY()][pos.getZ()] = info; } } } @@ -112,7 +154,7 @@ private BlockInfo[][][] bakeArray() { } public Builder shallowCopy() { - Builder builder = new Builder(); + Builder builder = new Builder(this.structureDir); builder.shape = new ArrayList<>(this.shape); builder.symbolMap = new HashMap<>(this.symbolMap); return builder; diff --git a/src/main/java/gregtech/api/persistence/PersistentData.java b/src/main/java/gregtech/api/persistence/PersistentData.java new file mode 100644 index 00000000000..dc88872d9a3 --- /dev/null +++ b/src/main/java/gregtech/api/persistence/PersistentData.java @@ -0,0 +1,108 @@ +package gregtech.api.persistence; + +import gregtech.api.GTValues; +import gregtech.api.util.GTLog; + +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fml.common.Loader; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; + +public final class PersistentData { + + private static final PersistentData INSTANCE = new PersistentData(); + + private @Nullable Path path; + private @Nullable NBTTagCompound tag; + + public static @NotNull PersistentData instance() { + return INSTANCE; + } + + private PersistentData() {} + + @ApiStatus.Internal + public void init() { + this.path = Loader.instance().getConfigDir().toPath() + .resolve(GTValues.MODID) + .resolve("persistent_data.dat"); + } + + /** + * @return the stored persistent data + */ + public synchronized @NotNull NBTTagCompound getTag() { + if (this.tag == null) { + this.tag = read(); + } + return this.tag; + } + + /** + * @return the read NBTTagCompound from disk + */ + private @NotNull NBTTagCompound read() { + GTLog.logger.debug("Reading persistent data from path {}", path); + if (this.path == null) { + throw new IllegalStateException("Persistent data path cannot be null"); + } + + if (!Files.exists(path)) { + return new NBTTagCompound(); + } + + try (InputStream inputStream = Files.newInputStream(this.path)) { + return CompressedStreamTools.readCompressed(inputStream); + } catch (IOException e) { + GTLog.logger.error("Failed to read persistent data", e); + return new NBTTagCompound(); + } + } + + /** + * Save the GT Persistent data to disk + */ + public synchronized void save() { + if (this.tag != null) { + write(this.tag); + } + } + + /** + * @param tagCompound the tag compound to save to disk + */ + private void write(@NotNull NBTTagCompound tagCompound) { + GTLog.logger.debug("Writing persistent data to path {}", path); + if (tagCompound.isEmpty()) { + return; + } + + if (this.path == null) { + throw new IllegalStateException("Persistent data path cannot be null"); + } + + if (!Files.exists(path)) { + try { + Files.createDirectories(path.getParent()); + } catch (IOException e) { + GTLog.logger.error("Could not create persistent data dir", e); + return; + } + } + + try (OutputStream outputStream = Files.newOutputStream(path)) { + CompressedStreamTools.writeCompressed(tagCompound, outputStream); + } catch (IOException e) { + GTLog.logger.error("Failed to write persistent data", e); + } + } +} diff --git a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java index 5468aae38dd..667b67fcf52 100644 --- a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java +++ b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java @@ -34,7 +34,12 @@ import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.*; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.SoundCategory; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; @@ -485,7 +490,7 @@ public void harvestBlock(@NotNull World worldIn, @NotNull EntityPlayer player, @ @NotNull IBlockState state, @Nullable TileEntity te, @NotNull ItemStack stack) { tileEntities.set(te == null ? tileEntities.get() : (IPipeTile) te); super.harvestBlock(worldIn, player, pos, state, te, stack); - tileEntities.set(null); + tileEntities.remove(); } @Override diff --git a/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java b/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java index cb3a9a5abbb..2372a9792c8 100644 --- a/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java +++ b/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java @@ -1,7 +1,7 @@ package gregtech.api.pipenet.longdist; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.Block; import net.minecraft.block.material.Material; @@ -33,8 +33,10 @@ public BlockLongDistancePipe(LongDistancePipeType pipeType) { super(Material.IRON); this.pipeType = pipeType; setTranslationKey("long_distance_" + pipeType.getName() + "_pipeline"); - setCreativeTab(GregTechAPI.TAB_GREGTECH); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH); setHarvestLevel(ToolClasses.WRENCH, 1); + setHardness(2f); + setResistance(10f); } @Override @@ -101,7 +103,7 @@ public void breakBlock(@NotNull World worldIn, @NotNull BlockPos pos, @NotNull I @Override public void getSubBlocks(@NotNull CreativeTabs itemIn, @NotNull NonNullList items) { - if (itemIn == GregTechAPI.TAB_GREGTECH) { + if (itemIn == GTCreativeTabs.TAB_GREGTECH) { items.add(new ItemStack(this)); } } diff --git a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java index 84897a022e8..7d4fc9015ef 100644 --- a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java +++ b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java @@ -335,24 +335,28 @@ public T getCapabilityInternal(Capability capability, @Nullable EnumFacin @Nullable @Override public final T getCapability(@NotNull Capability capability, @Nullable EnumFacing facing) { - boolean isCoverable = capability == GregtechTileCapabilities.CAPABILITY_COVER_HOLDER; - Cover cover = facing == null ? null : coverableImplementation.getCoverAtSide(facing); - T defaultValue; - if (getPipeBlock() == null) - defaultValue = null; - else - defaultValue = getCapabilityInternal(capability, facing); + T pipeCapability = getPipeBlock() == null ? null : getCapabilityInternal(capability, facing); - if (isCoverable) { - return defaultValue; + if (capability == GregtechTileCapabilities.CAPABILITY_COVER_HOLDER) { + return pipeCapability; } - if (cover == null && facing != null) { - return isConnected(facing) ? defaultValue : null; + + Cover cover = facing == null ? null : coverableImplementation.getCoverAtSide(facing); + if (cover == null) { + if (facing == null || isConnected(facing)) { + return pipeCapability; + } + return null; } - if (cover != null) { - return cover.getCapability(capability, defaultValue); + + T coverCapability = cover.getCapability(capability, pipeCapability); + if (coverCapability == pipeCapability) { + if (isConnected(facing)) { + return pipeCapability; + } + return null; } - return defaultValue; + return coverCapability; } @Override diff --git a/src/main/java/gregtech/api/recipes/GTRecipeInputCache.java b/src/main/java/gregtech/api/recipes/GTRecipeInputCache.java index f72fb572f6e..4e9a68fdf03 100644 --- a/src/main/java/gregtech/api/recipes/GTRecipeInputCache.java +++ b/src/main/java/gregtech/api/recipes/GTRecipeInputCache.java @@ -1,11 +1,18 @@ package gregtech.api.recipes; import gregtech.api.GTValues; +import gregtech.api.persistence.PersistentData; import gregtech.api.recipes.ingredients.GTRecipeInput; import gregtech.api.util.GTLog; import gregtech.common.ConfigHolder; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.math.MathHelper; + +import it.unimi.dsi.fastutil.Hash; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Collections; @@ -14,54 +21,77 @@ /** * Cache of GTRecipeInput instances for deduplication. *

- * Each GTRecipeInput is cached by an internal hashtable, and any duplicative - * instances will be replaced by identical object previously created. + * Each GTRecipeInput is cached by an internal hashtable, and any duplicative instances will be replaced by identical + * object previously created. *

- * Caching and duplication is only available during recipe registration; once - * recipe registration is over, the cache will be discarded and no further entries - * will be put into cache. + * Caching and duplication is only available during recipe registration; once recipe registration is over, the cache + * will be discarded and no further entries will be put into cache. */ -public class GTRecipeInputCache { +public final class GTRecipeInputCache { + + private static final int MINIMUM_CACHE_SIZE = 1 << 13; + private static final int MAXIMUM_CACHE_SIZE = 1 << 30; + + private static ObjectOpenHashSet instances; - private static final int EXPECTED_CACHE_SIZE = 16384; - private static ObjectOpenHashSet INSTANCES; + private static final String DATA_NAME = "expectedIngredientInstances"; + + private GTRecipeInputCache() {} public static boolean isCacheEnabled() { - return INSTANCES != null; + return instances != null; } + @ApiStatus.Internal public static void enableCache() { if (!isCacheEnabled()) { - INSTANCES = new ObjectOpenHashSet<>(EXPECTED_CACHE_SIZE, 1); - if (ConfigHolder.misc.debug || GTValues.isDeobfEnvironment()) - GTLog.logger.info("GTRecipeInput cache enabled"); + int size = calculateOptimalExpectedSize(); + instances = new ObjectOpenHashSet<>(size); + + if (ConfigHolder.misc.debug || GTValues.isDeobfEnvironment()) { + GTLog.logger.info("GTRecipeInput cache enabled with expected size {}", size); + } } } + @ApiStatus.Internal public static void disableCache() { if (isCacheEnabled()) { - if (ConfigHolder.misc.debug || GTValues.isDeobfEnvironment()) - GTLog.logger.info("GTRecipeInput cache disabled; releasing {} unique instances", INSTANCES.size()); - INSTANCES = null; + int size = instances.size(); + if (ConfigHolder.misc.debug || GTValues.isDeobfEnvironment()) { + GTLog.logger.info("GTRecipeInput cache disabled; releasing {} unique instances", size); + } + instances = null; + + if (size >= MINIMUM_CACHE_SIZE && size < MAXIMUM_CACHE_SIZE) { + NBTTagCompound tagCompound = PersistentData.instance().getTag(); + if (getExpectedInstanceAmount(tagCompound) != size) { + tagCompound.setInteger(DATA_NAME, size); + PersistentData.instance().save(); + } + } } } + private static int getExpectedInstanceAmount(@NotNull NBTTagCompound tagCompound) { + return MathHelper.clamp(tagCompound.getInteger(DATA_NAME), MINIMUM_CACHE_SIZE, MAXIMUM_CACHE_SIZE); + } + /** - * Tries to deduplicate the instance with previously cached instances. - * If there is no identical GTRecipeInput present in cache, the - * {@code recipeInput} will be put into cache, marked as cached, and returned subsequently. + * Tries to deduplicate the instance with previously cached instances. If there is no identical GTRecipeInput + * present in cache, the {@code recipeInput} will be put into cache, marked as cached, and returned subsequently. *

* This operation returns {@code recipeInput} without doing anything if cache is disabled. * * @param recipeInput ingredient instance to be deduplicated - * @return Either previously cached instance, or {@code recipeInput} marked cached; - * or unmodified {@code recipeInput} instance if the cache is disabled + * @return Either previously cached instance, or {@code recipeInput} marked cached; or unmodified + * {@code recipeInput} instance if the cache is disabled */ public static GTRecipeInput deduplicate(GTRecipeInput recipeInput) { if (!isCacheEnabled() || recipeInput.isCached()) { return recipeInput; } - GTRecipeInput cached = INSTANCES.addOrGet(recipeInput); + GTRecipeInput cached = instances.addOrGet(recipeInput); if (cached == recipeInput) { // If recipeInput is cached just now... cached.setCached(); } @@ -69,9 +99,9 @@ public static GTRecipeInput deduplicate(GTRecipeInput recipeInput) { } /** - * Tries to deduplicate each instance in the list with previously cached instances. - * If there is no identical GTRecipeInput present in cache, the - * {@code recipeInput} will be put into cache, marked as cached, and returned subsequently. + * Tries to deduplicate each instance in the list with previously cached instances. If there is no identical + * GTRecipeInput present in cache, the {@code recipeInput} will be put into cache, marked as cached, and returned + * subsequently. *

* This operation returns {@code inputs} without doing anything if cache is disabled. * @@ -91,4 +121,50 @@ public static List deduplicateInputs(List inputs) } return list; } + + /** + * Calculates the optimal expected size for the input cache: + *

    + *
  1. Pick a Load Factor to test: i.e. {@code 0.75f} (default).
  2. + *
  3. Pick a Size to test: i.e. {@code 8192}.
  4. + *
  5. Internal array's size: next highest power of 2 for {@code size / loadFactor}, + * {@code nextHighestPowerOf2(8192 / 0.75) = 16384}.
  6. + *
  7. The maximum amount of stored values before a rehash is required {@code arraySize * loadFactor}, + * {@code 16384 * 0.75 = 12288}.
  8. + *
  9. Compare with the known amount of values stored: {@code 12288 >= 11774}.
  10. + *
  11. If larger or equal, the initial capacity and load factor will not induce a rehash/resize.
  12. + *
+ * + * @return the optimal expected input cache size + */ + private static int calculateOptimalExpectedSize() { + int min = Math.max(getExpectedInstanceAmount(PersistentData.instance().getTag()), MINIMUM_CACHE_SIZE); + for (int i = 13; i < 31; i++) { + int sizeToTest = 1 << i; + int arraySize = nextHighestPowerOf2((int) (sizeToTest / Hash.DEFAULT_LOAD_FACTOR)); + int maxStoredBeforeRehash = (int) (arraySize * Hash.DEFAULT_LOAD_FACTOR); + + if (maxStoredBeforeRehash >= min) { + return sizeToTest; + } + } + return MINIMUM_CACHE_SIZE; + } + + /** + * Algorithm source. + * + * @param x the number to use + * @return the next highest power of 2 relative to the number + */ + private static int nextHighestPowerOf2(int x) { + x--; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x++; + return x; + } } diff --git a/src/main/java/gregtech/api/recipes/ModHandler.java b/src/main/java/gregtech/api/recipes/ModHandler.java index 010d1c22346..10e55ea68b1 100644 --- a/src/main/java/gregtech/api/recipes/ModHandler.java +++ b/src/main/java/gregtech/api/recipes/ModHandler.java @@ -16,6 +16,7 @@ import gregtech.api.util.DummyContainer; import gregtech.api.util.GTLog; import gregtech.api.util.LocalizationUtils; +import gregtech.api.util.Mods; import gregtech.api.util.world.DummyWorld; import gregtech.common.ConfigHolder; import gregtech.common.crafting.FluidReplaceRecipe; @@ -48,7 +49,12 @@ import org.jetbrains.annotations.Nullable; import java.lang.reflect.Field; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Objects; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -679,8 +685,6 @@ public static Pair getRecipeOutput(@Nullable World world, @N * disable the config and remove the recipes manually */ public static void removeSmeltingEBFMetals() { - boolean isCTLoaded = Loader.isModLoaded(GTValues.MODID_CT); - Field actionAddFurnaceRecipe$output = null; Map furnaceList = FurnaceRecipes.instance().getSmeltingList(); @@ -702,7 +706,7 @@ public static void removeSmeltingEBFMetals() { ItemStack ingot = OreDictUnifier.get(OrePrefix.ingot, material); // Check if the inputs are actually dust -> ingot if (ingot.isItemEqual(output) && dust.isItemEqual(input)) { - if (isCTLoaded) { + if (Mods.CraftTweaker.isModLoaded()) { if (actionAddFurnaceRecipe$output == null) { try { actionAddFurnaceRecipe$output = ActionAddFurnaceRecipe.class @@ -753,6 +757,6 @@ public static boolean setErroredInvalidRecipe(@NotNull String message) throws Il } public static void logInvalidRecipe(@NotNull String message) { - GTLog.logger.warn("Invalid Recipe Found", new IllegalArgumentException(message)); + GTLog.logger.warn("Invalid Recipe Found: {}", message, new Throwable()); } } diff --git a/src/main/java/gregtech/api/recipes/Recipe.java b/src/main/java/gregtech/api/recipes/Recipe.java index b291f994301..d52be1bac09 100644 --- a/src/main/java/gregtech/api/recipes/Recipe.java +++ b/src/main/java/gregtech/api/recipes/Recipe.java @@ -29,7 +29,13 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; /** * Class that represent machine recipe. @@ -185,8 +191,54 @@ public static Recipe trimRecipeOutputs(Recipe currentRecipe, RecipeMap recipe public final boolean matches(boolean consumeIfSuccessful, IItemHandlerModifiable inputs, IMultipleTankHandler fluidInputs) { - return matches(consumeIfSuccessful, GTUtility.itemHandlerToList(inputs), - GTUtility.fluidHandlerToList(fluidInputs)); + Pair fluids = null; + Pair items = null; + + if (fluidInputs.getFluidTanks().size() > 0) { + fluids = matchesFluid(GTUtility.fluidHandlerToList(fluidInputs)); + if (!fluids.getKey()) { + return false; + } + } + + if (inputs.getSlots() > 0) { + items = matchesItems(GTUtility.itemHandlerToList(inputs)); + if (!items.getKey()) { + return false; + } + } + + if (consumeIfSuccessful) { + if (fluids != null) { + int[] fluidAmountInTank = fluids.getValue(); + var backedList = fluidInputs.getFluidTanks(); + + for (int i = 0; i < fluidAmountInTank.length; i++) { + var tank = backedList.get(i); + FluidStack fluidStack = tank.getFluid(); + int fluidAmount = fluidAmountInTank[i]; + + if (fluidStack == null || fluidStack.amount == fluidAmount) { + continue; + } + tank.drain(Math.abs(fluidAmount - fluidStack.amount), true); + } + } + if (items != null) { + int[] itemAmountInSlot = items.getValue(); + for (int i = 0; i < itemAmountInSlot.length; i++) { + ItemStack itemInSlot = inputs.getStackInSlot(i); + int itemAmount = itemAmountInSlot[i]; + + if (itemInSlot.isEmpty() || itemInSlot.getCount() == itemAmount) { + continue; + } + inputs.extractItem(i, Math.abs(itemAmount - itemInSlot.getCount()), false); + } + } + } + + return true; } /** @@ -673,8 +725,9 @@ public boolean hasValidInputsForDisplay() { .anyMatch(s -> !s.isEmpty())) { return true; } + } else if (Arrays.stream(ingredient.getInputStacks()).anyMatch(s -> !s.isEmpty())) { + return true; } - return Arrays.stream(ingredient.getInputStacks()).anyMatch(s -> !s.isEmpty()); } for (GTRecipeInput fluidInput : fluidInputs) { FluidStack fluidIngredient = fluidInput.getInputFluidStack(); diff --git a/src/main/java/gregtech/api/recipes/RecipeBuildAction.java b/src/main/java/gregtech/api/recipes/RecipeBuildAction.java new file mode 100644 index 00000000000..f7310129276 --- /dev/null +++ b/src/main/java/gregtech/api/recipes/RecipeBuildAction.java @@ -0,0 +1,17 @@ +package gregtech.api.recipes; + +import org.jetbrains.annotations.NotNull; + +@FunctionalInterface +public interface RecipeBuildAction> { + + /** + * Process a RecipeBuilder to perform an action with. + *

+ * Do not call {@link RecipeBuilder#buildAndRegister()} on the passed builder. + * It is safe to do so only on other builders, i.e. created through {@link RecipeBuilder#copy()}. + * + * @param builder the builder to utilize + */ + void accept(@NotNull R builder); +} diff --git a/src/main/java/gregtech/api/recipes/RecipeBuilder.java b/src/main/java/gregtech/api/recipes/RecipeBuilder.java index dd5fee598df..2658ecca049 100644 --- a/src/main/java/gregtech/api/recipes/RecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/RecipeBuilder.java @@ -9,10 +9,15 @@ import gregtech.api.recipes.chance.output.ChancedOutputLogic; import gregtech.api.recipes.chance.output.impl.ChancedFluidOutput; import gregtech.api.recipes.chance.output.impl.ChancedItemOutput; -import gregtech.api.recipes.ingredients.*; +import gregtech.api.recipes.ingredients.GTRecipeFluidInput; +import gregtech.api.recipes.ingredients.GTRecipeInput; +import gregtech.api.recipes.ingredients.GTRecipeItemInput; +import gregtech.api.recipes.ingredients.GTRecipeOreInput; +import gregtech.api.recipes.ingredients.IntCircuitIngredient; import gregtech.api.recipes.ingredients.nbtmatch.NBTCondition; import gregtech.api.recipes.ingredients.nbtmatch.NBTMatcher; import gregtech.api.recipes.recipeproperties.CleanroomProperty; +import gregtech.api.recipes.recipeproperties.DimensionProperty; import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage; import gregtech.api.recipes.recipeproperties.RecipeProperty; import gregtech.api.recipes.recipeproperties.RecipePropertyStorage; @@ -22,6 +27,7 @@ import gregtech.api.util.EnumValidationResult; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.api.util.ValidationResult; import gregtech.common.ConfigHolder; import gregtech.integration.groovy.GroovyScriptModule; @@ -38,12 +44,19 @@ import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.helper.ingredient.OreDictIngredient; import crafttweaker.CraftTweakerAPI; +import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.ints.IntLists; import org.apache.commons.lang3.builder.ToStringBuilder; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.MustBeInvokedByOverriders; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; -import java.util.function.Consumer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; /** * @see Recipe @@ -70,9 +83,8 @@ public class RecipeBuilder> { protected GTRecipeCategory category; protected boolean isCTRecipe = false; protected int parallel = 0; - protected Consumer onBuildAction = null; protected EnumValidationResult recipeStatus = EnumValidationResult.VALID; - protected IRecipePropertyStorage recipePropertyStorage = null; + protected @Nullable IRecipePropertyStorage recipePropertyStorage = null; protected boolean recipePropertyStorageErrored = false; protected RecipeBuilder() { @@ -121,8 +133,8 @@ protected RecipeBuilder(RecipeBuilder recipeBuilder) { this.EUt = recipeBuilder.EUt; this.hidden = recipeBuilder.hidden; this.category = recipeBuilder.category; - this.onBuildAction = recipeBuilder.onBuildAction; - this.recipePropertyStorage = recipeBuilder.recipePropertyStorage; + this.recipePropertyStorage = recipeBuilder.recipePropertyStorage == null ? null : + recipeBuilder.recipePropertyStorage.copy(); if (this.recipePropertyStorage != null) { this.recipePropertyStorage = this.recipePropertyStorage.copy(); } @@ -136,8 +148,51 @@ public R cleanroom(@Nullable CleanroomType cleanroom) { return (R) this; } + public R dimension(int dimensionID) { + return dimension(dimensionID, false); + } + + public R dimension(int dimensionID, boolean toBlackList) { + DimensionProperty.DimensionPropertyList dimensionIDs = getCompleteDimensionIDs(); + if (dimensionIDs == DimensionProperty.DimensionPropertyList.EMPTY_LIST) { + dimensionIDs = new DimensionProperty.DimensionPropertyList(); + this.applyProperty(DimensionProperty.getInstance(), dimensionIDs); + } + dimensionIDs.add(dimensionID, toBlackList); + return (R) this; + } + + public DimensionProperty.DimensionPropertyList getCompleteDimensionIDs() { + return this.recipePropertyStorage == null ? DimensionProperty.DimensionPropertyList.EMPTY_LIST : + this.recipePropertyStorage.getRecipePropertyValue(DimensionProperty.getInstance(), + DimensionProperty.DimensionPropertyList.EMPTY_LIST); + } + + public IntList getDimensionIDs() { + return this.recipePropertyStorage == null ? IntLists.EMPTY_LIST : + this.recipePropertyStorage.getRecipePropertyValue(DimensionProperty.getInstance(), + DimensionProperty.DimensionPropertyList.EMPTY_LIST).whiteListDimensions; + } + + public IntList getBlockedDimensionIDs() { + return this.recipePropertyStorage == null ? IntLists.EMPTY_LIST : + this.recipePropertyStorage.getRecipePropertyValue(DimensionProperty.getInstance(), + DimensionProperty.DimensionPropertyList.EMPTY_LIST).whiteListDimensions; + } + public boolean applyProperty(@NotNull String key, @Nullable Object value) { - if (key.equals(CleanroomProperty.KEY)) { + if (key.equals(DimensionProperty.KEY)) { + if (value instanceof DimensionProperty.DimensionPropertyList list) { + DimensionProperty.DimensionPropertyList dimensionIDs = getCompleteDimensionIDs(); + if (dimensionIDs == DimensionProperty.DimensionPropertyList.EMPTY_LIST) { + dimensionIDs = new DimensionProperty.DimensionPropertyList(); + this.applyProperty(DimensionProperty.getInstance(), dimensionIDs); + } + dimensionIDs.merge(list); + return true; + } + return false; + } else if (key.equals(CleanroomProperty.KEY)) { if (value instanceof CleanroomType) { this.cleanroom((CleanroomType) value); } else if (value instanceof String) { @@ -170,8 +225,7 @@ public boolean applyProperty(@NotNull RecipeProperty property, @Nullable Obje public R input(GTRecipeInput input) { if (input.getAmount() < 0) { - GTLog.logger.error("Count cannot be less than 0. Actual: {}.", input.getAmount()); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("Count cannot be less than 0. Actual: {}.", input.getAmount(), new Throwable()); } else { this.inputs.add(input); } @@ -240,18 +294,15 @@ public R input(MetaTileEntity mte, int amount) { public R inputNBT(GTRecipeInput input, NBTMatcher matcher, NBTCondition condition) { if (input.getAmount() < 0) { - GTLog.logger.error("Count cannot be less than 0. Actual: {}.", input.getAmount()); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("Count cannot be less than 0. Actual: {}.", input.getAmount(), new Throwable()); return (R) this; } if (matcher == null) { - GTLog.logger.error("NBTMatcher must not be null"); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("NBTMatcher must not be null", new Throwable()); return (R) this; } if (condition == null) { - GTLog.logger.error("NBTCondition must not be null"); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("NBTCondition must not be null", new Throwable()); return (R) this; } this.inputs.add(input.setNBTMatchingCondition(matcher, condition)); @@ -275,20 +326,20 @@ public R inputNBT(OrePrefix orePrefix, Material material, int count, NBTMatcher } public R inputNBT(Item item, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(item)), matcher, condition); + return inputNBT(new ItemStack(item), matcher, condition); } public R inputNBT(Item item, int count, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(item), count), matcher, condition); + return inputNBT(new ItemStack(item, count), matcher, condition); } public R inputNBT(Item item, int count, int meta, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(item, count, meta)), matcher, condition); + return inputNBT(new ItemStack(item, count, meta), matcher, condition); } public R inputNBT(Item item, int count, @SuppressWarnings("unused") boolean wild, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(item, count, GTValues.W)), matcher, condition); + return inputNBT(new ItemStack(item, count, GTValues.W), matcher, condition); } public R inputNBT(Block block, NBTMatcher matcher, NBTCondition condition) { @@ -296,35 +347,57 @@ public R inputNBT(Block block, NBTMatcher matcher, NBTCondition condition) { } public R inputNBT(Block block, int count, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(block, count)), matcher, condition); + return inputNBT(new ItemStack(block, count), matcher, condition); } public R inputNBT(Block block, int count, @SuppressWarnings("unused") boolean wild, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(block, count, GTValues.W)), matcher, condition); + return inputNBT(new ItemStack(block, count, GTValues.W), matcher, condition); } public R inputNBT(MetaItem.MetaValueItem item, int count, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(item.getStackForm(count)), matcher, condition); + return inputNBT(item.getStackForm(count), matcher, condition); } public R inputNBT(MetaItem.MetaValueItem item, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(item.getStackForm()), matcher, condition); + return inputNBT(item.getStackForm(), matcher, condition); } public R inputNBT(MetaTileEntity mte, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(mte.getStackForm()), matcher, condition); + return inputNBT(mte.getStackForm(), matcher, condition); } public R inputNBT(MetaTileEntity mte, int amount, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(mte.getStackForm(amount)), matcher, condition); + return inputNBT(mte.getStackForm(amount), matcher, condition); + } + + /** + * NBT tags are stripped from the input stack and are not automatically checked. + * + * @param stack the itemstack to input. + * @param matcher the matcher for the stack's nbt + * @param condition the condition for the stack's nbt + * @return this + */ + public R inputNBT(@NotNull ItemStack stack, NBTMatcher matcher, NBTCondition condition) { + return inputNBT(new GTRecipeItemInput(stack), matcher, condition); + } + + public R inputs(ItemStack input) { + if (input == null || input.isEmpty()) { + GTLog.logger.error("Input cannot be null or empty. Input: {}", input, new Throwable()); + recipeStatus = EnumValidationResult.INVALID; + } else { + this.inputs.add(new GTRecipeItemInput(input)); + } + return (R) this; } public R inputs(ItemStack... inputs) { for (ItemStack input : inputs) { if (input == null || input.isEmpty()) { - GTLog.logger.error("Input cannot contain null or empty ItemStacks. Inputs: {}", input); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("Inputs cannot contain null or empty ItemStacks. Inputs: {}", input, + new Throwable()); recipeStatus = EnumValidationResult.INVALID; continue; } @@ -336,8 +409,7 @@ public R inputs(ItemStack... inputs) { public R inputStacks(Collection inputs) { for (ItemStack input : inputs) { if (input == null || input.isEmpty()) { - GTLog.logger.error("Input cannot contain null or empty ItemStacks. Inputs: {}", input); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("Input cannot contain null or empty ItemStacks. Inputs: {}", input, new Throwable()); recipeStatus = EnumValidationResult.INVALID; continue; } @@ -346,11 +418,21 @@ public R inputStacks(Collection inputs) { return (R) this; } + public R inputs(GTRecipeInput input) { + if (input.getAmount() < 0) { + GTLog.logger.error("Input count cannot be less than 0. Actual: {}.", input.getAmount(), new Throwable()); + recipeStatus = EnumValidationResult.INVALID; + } else { + this.inputs.add(input); + } + return (R) this; + } + public R inputs(GTRecipeInput... inputs) { for (GTRecipeInput input : inputs) { if (input.getAmount() < 0) { - GTLog.logger.error("Count cannot be less than 0. Actual: {}.", input.getAmount()); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("Input count cannot be less than 0. Actual: {}.", input.getAmount(), + new Throwable()); recipeStatus = EnumValidationResult.INVALID; continue; } @@ -362,8 +444,7 @@ public R inputs(GTRecipeInput... inputs) { public R inputIngredients(Collection inputs) { for (GTRecipeInput input : inputs) { if (input.getAmount() < 0) { - GTLog.logger.error("Count cannot be less than 0. Actual: {}.", input.getAmount()); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("Count cannot be less than 0. Actual: {}.", input.getAmount(), new Throwable()); recipeStatus = EnumValidationResult.INVALID; continue; } @@ -412,8 +493,7 @@ public R notConsumable(FluidStack fluidStack) { public R circuitMeta(int circuitNumber) { if (IntCircuitIngredient.CIRCUIT_MIN > circuitNumber || circuitNumber > IntCircuitIngredient.CIRCUIT_MAX) { GTLog.logger.error("Integrated Circuit Number cannot be less than {} and more than {}", - IntCircuitIngredient.CIRCUIT_MIN, IntCircuitIngredient.CIRCUIT_MAX); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException("Invalid Integrated Circuit Number")); + IntCircuitIngredient.CIRCUIT_MIN, IntCircuitIngredient.CIRCUIT_MAX, new Throwable()); recipeStatus = EnumValidationResult.INVALID; return (R) this; } @@ -464,6 +544,13 @@ public R output(MetaTileEntity mte, int amount) { return outputs(mte.getStackForm(amount)); } + public R outputs(ItemStack output) { + if (output != null && !output.isEmpty()) { + this.outputs.add(output); + } + return (R) this; + } + public R outputs(ItemStack... outputs) { return outputs(Arrays.asList(outputs)); } @@ -490,14 +577,25 @@ public R fluidInputs(GTRecipeInput fluidIngredient) { return (R) this; } + public R fluidInputs(FluidStack input) { + if (input != null && input.amount > 0) { + this.fluidInputs.add(new GTRecipeFluidInput(input)); + } else if (input != null) { + GTLog.logger.error("Fluid Input count cannot be less than 0. Actual: {}.", input.amount, new Throwable()); + } else { + GTLog.logger.error("FluidStack cannot be null."); + } + return (R) this; + } + public R fluidInputs(FluidStack... fluidStacks) { ArrayList fluidIngredients = new ArrayList<>(); for (FluidStack fluidStack : fluidStacks) { if (fluidStack != null && fluidStack.amount > 0) { fluidIngredients.add(new GTRecipeFluidInput(fluidStack)); } else if (fluidStack != null) { - GTLog.logger.error("Count cannot be less than 0. Actual: {}.", fluidStack.amount); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("Fluid Input count cannot be less than 0. Actual: {}.", fluidStack.amount, + new Throwable()); } else { GTLog.logger.error("FluidStack cannot be null."); } @@ -511,13 +609,20 @@ public R clearFluidInputs() { return (R) this; } + public R fluidOutputs(FluidStack output) { + if (output != null && output.amount > 0) { + this.fluidOutputs.add(output); + } + return (R) this; + } + public R fluidOutputs(FluidStack... outputs) { return fluidOutputs(Arrays.asList(outputs)); } public R fluidOutputs(Collection outputs) { outputs = new ArrayList<>(outputs); - outputs.removeIf(Objects::isNull); + outputs.removeIf(o -> o == null || o.amount <= 0); this.fluidOutputs.addAll(outputs); return (R) this; } @@ -533,8 +638,7 @@ public R chancedOutput(ItemStack stack, int chance, int tierChanceBoost) { } if (0 >= chance || chance > ChancedOutputLogic.getMaxChancedValue()) { GTLog.logger.error("Chance cannot be less or equal to 0 or more than {}. Actual: {}.", - ChancedOutputLogic.getMaxChancedValue(), chance); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + ChancedOutputLogic.getMaxChancedValue(), chance, new Throwable()); recipeStatus = EnumValidationResult.INVALID; return (R) this; } @@ -581,8 +685,7 @@ public R chancedFluidOutput(FluidStack stack, int chance, int tierChanceBoost) { } if (0 >= chance || chance > ChancedOutputLogic.getMaxChancedValue()) { GTLog.logger.error("Chance cannot be less or equal to 0 or more than {}. Actual: {}.", - ChancedOutputLogic.getMaxChancedValue(), chance); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + ChancedOutputLogic.getMaxChancedValue(), chance, new Throwable()); recipeStatus = EnumValidationResult.INVALID; return (R) this; } @@ -607,12 +710,12 @@ public R chancedFluidOutputLogic(@NotNull ChancedOutputLogic logic) { return (R) this; } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public R inputs(IIngredient ingredient) { return input(ofGroovyIngredient(ingredient)); } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public R inputs(IIngredient... ingredients) { for (IIngredient ingredient : ingredients) { inputs(ingredient); @@ -620,7 +723,7 @@ public R inputs(IIngredient... ingredients) { return (R) this; } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public R inputs(Collection ingredients) { for (IIngredient ingredient : ingredients) { inputs(ingredient); @@ -628,12 +731,12 @@ public R inputs(Collection ingredients) { return (R) this; } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public R notConsumable(IIngredient ingredient) { return notConsumable(ofGroovyIngredient(ingredient)); } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) private static GTRecipeInput ofGroovyIngredient(IIngredient ingredient) { if (ingredient instanceof OreDictIngredient) { return new GTRecipeOreInput(((OreDictIngredient) ingredient).getOreDict(), ingredient.getAmount()); @@ -819,31 +922,31 @@ protected EnumValidationResult validate() { return msg.postIfNotEmpty() ? EnumValidationResult.SKIP : EnumValidationResult.VALID; } if (EUt == 0) { - GTLog.logger.error("EU/t cannot be equal to 0", new IllegalArgumentException()); + GTLog.logger.error("EU/t cannot be equal to 0", new Throwable()); if (isCTRecipe) { - CraftTweakerAPI.logError("EU/t cannot be equal to 0", new IllegalArgumentException()); + CraftTweakerAPI.logError("EU/t cannot be equal to 0", new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } if (duration <= 0) { - GTLog.logger.error("Duration cannot be less or equal to 0", new IllegalArgumentException()); + GTLog.logger.error("Duration cannot be less or equal to 0", new Throwable()); if (isCTRecipe) { - CraftTweakerAPI.logError("Duration cannot be less or equal to 0", new IllegalArgumentException()); + CraftTweakerAPI.logError("Duration cannot be less or equal to 0", new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } if (recipeMap != null) { // recipeMap can be null in tests if (category == null) { - GTLog.logger.error("Recipes must have a category", new IllegalArgumentException()); + GTLog.logger.error("Recipes must have a category", new Throwable()); if (isCTRecipe) { - CraftTweakerAPI.logError("Recipes must have a category", new IllegalArgumentException()); + CraftTweakerAPI.logError("Recipes must have a category", new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } else if (category.getRecipeMap() != this.recipeMap) { - GTLog.logger.error("Cannot apply Category with incompatible RecipeMap", new IllegalArgumentException()); + GTLog.logger.error("Cannot apply Category with incompatible RecipeMap", new Throwable()); if (isCTRecipe) { CraftTweakerAPI.logError("Cannot apply Category with incompatible RecipeMap", - new IllegalArgumentException()); + new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } @@ -857,7 +960,7 @@ protected EnumValidationResult validate() { return recipeStatus; } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) protected void validateGroovy(GroovyLog.Msg errorMsg) { errorMsg.add(EUt == 0, () -> "EU/t must not be to 0"); errorMsg.add(duration <= 0, () -> "Duration must not be less or equal to 0"); @@ -886,19 +989,26 @@ protected static String getRequiredString(int max, int actual, @NotNull String t return out; } - protected R onBuild(Consumer consumer) { - this.onBuildAction = consumer; - return (R) this; - } - + /** + * @deprecated Obsolete. Does not need calling. + */ + @ApiStatus.Obsolete + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") + @Deprecated protected R invalidateOnBuildAction() { - this.onBuildAction = null; return (R) this; } + /** + * Build and register the recipe, if valid. + * Do not call outside of the + * {@link net.minecraftforge.event.RegistryEvent.Register} event for recipes. + * + */ + @MustBeInvokedByOverriders public void buildAndRegister() { - if (onBuildAction != null) { - onBuildAction.accept((R) this); + for (RecipeBuildAction action : recipeMap.getBuildActions()) { + action.accept((R) this); } ValidationResult validationResult = build(); recipeMap.addRecipe(validationResult); @@ -975,6 +1085,8 @@ public String toString() { .append("EUt", EUt) .append("hidden", hidden) .append("cleanroom", getCleanroom()) + .append("dimensions", getDimensionIDs().toString()) + .append("dimensions_blocked", getBlockedDimensionIDs().toString()) .append("recipeStatus", recipeStatus) .toString(); } diff --git a/src/main/java/gregtech/api/recipes/RecipeMap.java b/src/main/java/gregtech/api/recipes/RecipeMap.java index 2f9417afe27..9743c549ae5 100644 --- a/src/main/java/gregtech/api/recipes/RecipeMap.java +++ b/src/main/java/gregtech/api/recipes/RecipeMap.java @@ -27,6 +27,7 @@ import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; import gregtech.api.util.LocalizationUtils; +import gregtech.api.util.Mods; import gregtech.api.util.ValidationResult; import gregtech.common.ConfigHolder; import gregtech.integration.crafttweaker.CTRecipeHelper; @@ -38,6 +39,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundEvent; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.common.Optional.Method; @@ -58,6 +60,7 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.UnmodifiableView; import stanhebben.zenscript.annotations.Optional; import stanhebben.zenscript.annotations.ZenClass; import stanhebben.zenscript.annotations.ZenGetter; @@ -74,9 +77,7 @@ import java.util.Map; import java.util.Set; import java.util.WeakHashMap; -import java.util.function.Consumer; import java.util.function.DoubleSupplier; -import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -123,9 +124,9 @@ public class RecipeMap> { private final Map> recipeByCategory = new Object2ObjectOpenHashMap<>(); - private Consumer onRecipeBuildAction; - protected SoundEvent sound; - private RecipeMap smallRecipeMap; + private final Map> recipeBuildActions = new Object2ObjectOpenHashMap<>(); + protected @Nullable SoundEvent sound; + private @Nullable RecipeMap smallRecipeMap; /** * Create and register new instance of RecipeMap with specified properties. All @@ -139,7 +140,7 @@ public class RecipeMap> { * @param defaultRecipeBuilder the default RecipeBuilder for the RecipeMap * @param isHidden if the RecipeMap should have a category in JEI * - * @deprecated {@link #RecipeMap(String, RecipeBuilder, Function, int, int, int, int)} + * @deprecated {@link RecipeMap#RecipeMap(String, R, RecipeMapUIFunction, int, int, int, int)} */ @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @Deprecated @@ -168,7 +169,7 @@ public RecipeMap(@NotNull String unlocalizedName, * @param defaultRecipeBuilder the default RecipeBuilder for the RecipeMap * @param isHidden if the RecipeMap should have a category in JEI * - * @deprecated {@link #RecipeMap(String, RecipeBuilder, Function, int, int, int, int)} + * @deprecated {@link RecipeMap#RecipeMap(String, R, RecipeMapUIFunction, int, int, int, int)} */ @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @Deprecated @@ -310,11 +311,46 @@ public RecipeMap setChanceFunction(@NotNull ChanceBoostFunction function) { return this; } - public RecipeMap onRecipeBuild(Consumer consumer) { - onRecipeBuildAction = consumer; + /** + * Add a recipe build action to be performed upon this RecipeMap's builder's recipe registration. + * + * @param name the unique name of the action + * @param action the action to perform + * @return this + */ + public RecipeMap onRecipeBuild(@NotNull ResourceLocation name, @NotNull RecipeBuildAction action) { + if (recipeBuildActions.containsKey(name)) { + throw new IllegalArgumentException("Cannot register RecipeBuildAction with duplicate name: " + name); + } + recipeBuildActions.put(name, action); return this; } + /** + * @param name the name of the build action to remove + */ + public void removeBuildAction(@NotNull ResourceLocation name) { + recipeBuildActions.remove(name); + } + + /** + * Add a recipe build action to be performed upon this RecipeMap's builder's recipe registration. + * + * @param actions the actions to perform + */ + @ApiStatus.Internal + protected void onRecipeBuild(@NotNull Map> actions) { + recipeBuildActions.putAll(actions); + } + + /** + * @return the build actions for this RecipeMap's default RecipeBuilder + */ + @ApiStatus.Internal + protected @UnmodifiableView @NotNull Collection<@NotNull RecipeBuildAction> getBuildActions() { + return this.recipeBuildActions.values(); + } + public RecipeMap allowEmptyOutput() { this.allowEmptyOutput = true; return this; @@ -426,11 +462,9 @@ protected ValidationResult postValidateRecipe(@NotNull ValidationResult< boolean emptyInputs = recipe.getInputs().isEmpty() && recipe.getFluidInputs().isEmpty(); if (emptyInputs) { - GTLog.logger.error("Invalid amount of recipe inputs. Recipe inputs are empty."); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException("Invalid number of Inputs")); + GTLog.logger.error("Invalid amount of recipe inputs. Recipe inputs are empty.", new Throwable()); if (recipe.getIsCTRecipe()) { - CraftTweakerAPI.logError("Invalid amount of recipe inputs. Recipe inputs are empty."); - CraftTweakerAPI.logError("Stacktrace:", new IllegalArgumentException("Invalid number of Inputs")); + CraftTweakerAPI.logError("Invalid amount of recipe inputs. Recipe inputs are empty.", new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } @@ -438,11 +472,10 @@ protected ValidationResult postValidateRecipe(@NotNull ValidationResult< recipe.getFluidOutputs().isEmpty() && recipe.getChancedOutputs().getChancedEntries().isEmpty() && recipe.getChancedFluidOutputs().getChancedEntries().isEmpty(); if (emptyOutputs) { - GTLog.logger.error("Invalid amount of recipe outputs. Recipe outputs are empty."); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException("Invalid number of Outputs")); + GTLog.logger.error("Invalid amount of recipe outputs. Recipe outputs are empty.", new Throwable()); if (recipe.getIsCTRecipe()) { - CraftTweakerAPI.logError("Invalid amount of outputs inputs. Recipe outputs are empty."); - CraftTweakerAPI.logError("Stacktrace:", new IllegalArgumentException("Invalid number of Outputs")); + CraftTweakerAPI.logError("Invalid amount of outputs inputs. Recipe outputs are empty.", + new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } @@ -450,12 +483,11 @@ protected ValidationResult postValidateRecipe(@NotNull ValidationResult< int amount = recipe.getInputs().size(); if (amount > getMaxInputs()) { GTLog.logger.error("Invalid amount of recipe inputs. Actual: {}. Should be at most {}.", amount, - getMaxInputs()); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException("Invalid number of Inputs")); + getMaxInputs(), new Throwable()); if (recipe.getIsCTRecipe()) { CraftTweakerAPI.logError(String.format( - "Invalid amount of recipe inputs. Actual: %s. Should be at most %s.", amount, getMaxInputs())); - CraftTweakerAPI.logError("Stacktrace:", new IllegalArgumentException("Invalid number of Inputs")); + "Invalid amount of recipe inputs. Actual: %s. Should be at most %s.", amount, getMaxInputs()), + new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } @@ -463,13 +495,11 @@ protected ValidationResult postValidateRecipe(@NotNull ValidationResult< amount = recipe.getOutputs().size() + recipe.getChancedOutputs().getChancedEntries().size(); if (amount > getMaxOutputs()) { GTLog.logger.error("Invalid amount of recipe outputs. Actual: {}. Should be at most {}.", amount, - getMaxOutputs()); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException("Invalid number of Outputs")); + getMaxOutputs(), new Throwable()); if (recipe.getIsCTRecipe()) { CraftTweakerAPI .logError(String.format("Invalid amount of recipe outputs. Actual: %s. Should be at most %s.", - amount, getMaxOutputs())); - CraftTweakerAPI.logError("Stacktrace:", new IllegalArgumentException("Invalid number of Outputs")); + amount, getMaxOutputs()), new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } @@ -477,13 +507,12 @@ protected ValidationResult postValidateRecipe(@NotNull ValidationResult< amount = recipe.getFluidInputs().size(); if (amount > getMaxFluidInputs()) { GTLog.logger.error("Invalid amount of recipe fluid inputs. Actual: {}. Should be at most {}.", amount, - getMaxFluidInputs()); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException("Invalid number of Fluid Inputs")); + getMaxFluidInputs(), new Throwable()); if (recipe.getIsCTRecipe()) { CraftTweakerAPI.logError( String.format("Invalid amount of recipe fluid inputs. Actual: %s. Should be at most %s.", - amount, getMaxFluidInputs())); - CraftTweakerAPI.logError("Stacktrace:", new IllegalArgumentException("Invalid number of Fluid Inputs")); + amount, getMaxFluidInputs()), + new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } @@ -491,14 +520,12 @@ protected ValidationResult postValidateRecipe(@NotNull ValidationResult< amount = recipe.getFluidOutputs().size() + recipe.getChancedFluidOutputs().getChancedEntries().size(); if (amount > getMaxFluidOutputs()) { GTLog.logger.error("Invalid amount of recipe fluid outputs. Actual: {}. Should be at most {}.", amount, - getMaxFluidOutputs()); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException("Invalid number of Fluid Outputs")); + getMaxFluidOutputs(), new Throwable()); if (recipe.getIsCTRecipe()) { CraftTweakerAPI.logError( String.format("Invalid amount of recipe fluid outputs. Actual: %s. Should be at most %s.", - amount, getMaxFluidOutputs())); - CraftTweakerAPI.logError("Stacktrace:", - new IllegalArgumentException("Invalid number of Fluid Outputs")); + amount, getMaxFluidOutputs()), + new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } @@ -942,7 +969,7 @@ private boolean shouldShiftWidgets() { return false; } - @Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Method(modid = Mods.Names.GROOVY_SCRIPT) private VirtualizedRecipeMap getGroovyScriptRecipeMap() { return ((VirtualizedRecipeMap) grsVirtualizedRecipeMap); } @@ -972,7 +999,7 @@ private boolean recurseIngredientTreeAdd(@NotNull Recipe recipe, @NotNull Branch branchMap, int index, int count) { if (count >= ingredients.size()) return true; if (index >= ingredients.size()) { - throw new RuntimeException("Index out of bounds for recurseItemTreeAdd, should not happen"); + throw new IllegalStateException("Index out of bounds for recurseItemTreeAdd, should not happen"); } // Loop through NUMBER_OF_INGREDIENTS times. @@ -1291,7 +1318,7 @@ public Collection getRecipeList() { } @ZenMethod("findRecipe") - @Method(modid = GTValues.MODID_CT) + @Method(modid = Mods.Names.CRAFT_TWEAKER) @Nullable public CTRecipe ctFindRecipe(long maxVoltage, IItemStack[] itemInputs, ILiquidStack[] fluidInputs, @Optional(valueLong = Integer.MAX_VALUE) int outputFluidTankCapacity) { @@ -1304,7 +1331,7 @@ public CTRecipe ctFindRecipe(long maxVoltage, IItemStack[] itemInputs, ILiquidSt } @ZenGetter("recipes") - @Method(modid = GTValues.MODID_CT) + @Method(modid = Mods.Names.CRAFT_TWEAKER) public List ctGetRecipeList() { return getRecipeList().stream().map(recipe -> new CTRecipe(this, recipe)).collect(Collectors.toList()); } @@ -1325,7 +1352,7 @@ public String getUnlocalizedName() { } public R recipeBuilder() { - return recipeBuilderSample.copy().onBuild(onRecipeBuildAction); + return recipeBuilderSample.copy(); } /** @@ -1393,7 +1420,7 @@ public R recipeBuilder() { } @ZenMethod("recipeBuilder") - @Method(modid = GTValues.MODID_CT) + @Method(modid = Mods.Names.CRAFT_TWEAKER) public CTRecipeBuilder ctRecipeBuilder() { return new CTRecipeBuilder(recipeBuilder()); } diff --git a/src/main/java/gregtech/api/recipes/RecipeMapBuilder.java b/src/main/java/gregtech/api/recipes/RecipeMapBuilder.java index 2d6e810cac8..8995cf529aa 100644 --- a/src/main/java/gregtech/api/recipes/RecipeMapBuilder.java +++ b/src/main/java/gregtech/api/recipes/RecipeMapBuilder.java @@ -5,13 +5,17 @@ import gregtech.api.recipes.ui.RecipeMapUI; import gregtech.api.recipes.ui.RecipeMapUIFunction; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundEvent; import it.unimi.dsi.fastutil.bytes.Byte2ObjectArrayMap; import it.unimi.dsi.fastutil.bytes.Byte2ObjectMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Map; + import static gregtech.api.recipes.ui.RecipeMapUI.computeOverlayKey; public class RecipeMapBuilder> { @@ -41,6 +45,8 @@ public class RecipeMapBuilder> { private SoundEvent sound; private boolean allowEmptyOutputs; + private @Nullable Map> buildActions; + /** * @param unlocalizedName the name of the recipemap * @param defaultRecipeBuilder the default recipe builder of the recipemap @@ -247,6 +253,23 @@ public RecipeMapBuilder(@NotNull String unlocalizedName, @NotNull B defaultRecip return this; } + /** + * Add a recipe build action to be performed upon this RecipeMap's builder's recipe registration. + * + * @param name the unique name of the action + * @param action the action to perform + * @return this + */ + public @NotNull RecipeMapBuilder onBuild(@NotNull ResourceLocation name, @NotNull RecipeBuildAction action) { + if (buildActions == null) { + buildActions = new Object2ObjectOpenHashMap<>(); + } else if (buildActions.containsKey(name)) { + throw new IllegalArgumentException("Cannot register RecipeBuildAction with duplicate name: " + name); + } + buildActions.put(name, action); + return this; + } + /** * Do not call this twice. RecipeMapBuilders are not re-usable. * @@ -260,6 +283,9 @@ public RecipeMapBuilder(@NotNull String unlocalizedName, @NotNull B defaultRecip if (allowEmptyOutputs) { recipeMap.allowEmptyOutput(); } + if (buildActions != null) { + recipeMap.onRecipeBuild(buildActions); + } return recipeMap; } } diff --git a/src/main/java/gregtech/api/recipes/RecipeMaps.java b/src/main/java/gregtech/api/recipes/RecipeMaps.java index b9184cc199d..62c608b60cb 100644 --- a/src/main/java/gregtech/api/recipes/RecipeMaps.java +++ b/src/main/java/gregtech/api/recipes/RecipeMaps.java @@ -11,7 +11,6 @@ import gregtech.api.recipes.builders.ComputationRecipeBuilder; import gregtech.api.recipes.builders.FuelRecipeBuilder; import gregtech.api.recipes.builders.FusionRecipeBuilder; -import gregtech.api.recipes.builders.GasCollectorRecipeBuilder; import gregtech.api.recipes.builders.ImplosionRecipeBuilder; import gregtech.api.recipes.builders.NoEnergyRecipeBuilder; import gregtech.api.recipes.builders.PrimitiveRecipeBuilder; @@ -45,6 +44,7 @@ import stanhebben.zenscript.annotations.ZenProperty; import static gregtech.api.GTValues.*; +import static gregtech.api.util.GTUtility.gregtechId; /** * Notes: @@ -124,13 +124,12 @@ public final class RecipeMaps { .fluidOutputs(1) .progressBar(GuiTextures.PROGRESS_BAR_ARC_FURNACE) .sound(GTSoundEvents.ARC) - .build() - .onRecipeBuild(recipeBuilder -> { - recipeBuilder.invalidateOnBuildAction(); + .onBuild(gregtechId("arc_furnace_oxygen"), recipeBuilder -> { if (recipeBuilder.getFluidInputs().isEmpty()) { recipeBuilder.fluidInputs(Materials.Oxygen.getFluid(recipeBuilder.getDuration())); } - }); + }) + .build(); /** * Example: @@ -153,9 +152,7 @@ public final class RecipeMaps { .itemSlotOverlay(GuiTextures.CIRCUIT_OVERLAY, false) .progressBar(GuiTextures.PROGRESS_BAR_CIRCUIT) .sound(GTSoundEvents.ASSEMBLER) - .build() - .onRecipeBuild(recipeBuilder -> { - recipeBuilder.invalidateOnBuildAction(); + .onBuild(gregtechId("assembler_solder"), recipeBuilder -> { var fluidInputs = recipeBuilder.getFluidInputs(); if (fluidInputs.size() == 1 && fluidInputs.get(0).getInputFluidStack().getFluid() == Materials.SolderingAlloy.getFluid()) { @@ -164,7 +161,8 @@ public final class RecipeMaps { recipeBuilder.copy().clearFluidInputs().fluidInputs(Materials.Tin.getFluid(amount * 2)) .buildAndRegister(); } - + }) + .onBuild(gregtechId("assembler_recycling"), recipeBuilder -> { if (recipeBuilder.isWithRecycling()) { // ignore input fluids for recycling ItemStack outputStack = recipeBuilder.getOutputs().get(0); @@ -174,7 +172,8 @@ public final class RecipeMaps { OreDictUnifier.registerOre(outputStack, info); } } - }); + }) + .build(); /** * Example: @@ -193,12 +192,14 @@ public final class RecipeMaps { * .duration(600).EUt(6000).buildAndRegister(); * * - * The Assembly Line Recipe Builder has no special properties/build actions yet, but will in the future + * The Assembly Line Recipe Builder creates additional Research Recipes for its outputs in the Scanner or Research + * Station when specified. */ @ZenProperty public static final RecipeMap ASSEMBLY_LINE_RECIPES = new RecipeMapAssemblyLine<>( "assembly_line", new AssemblyLineRecipeBuilder(), AssemblyLineUI::new) - .onRecipeBuild(AssemblyLineManager::createDefaultResearchRecipe); + .onRecipeBuild(gregtechId("default_research_recipe"), + AssemblyLineManager::createDefaultResearchRecipe); /** * Example: @@ -438,21 +439,18 @@ public final class RecipeMaps { .fluidSlotOverlay(GuiTextures.VIAL_OVERLAY_2, true) .progressBar(GuiTextures.PROGRESS_BAR_ARROW_MULTIPLE) .sound(GTValues.FOOLS.get() ? GTSoundEvents.SCIENCE : GTSoundEvents.CHEMICAL_REACTOR) - .build() - .onRecipeBuild(recipeBuilder -> { - recipeBuilder.invalidateOnBuildAction(); - RecipeMaps.LARGE_CHEMICAL_RECIPES.recipeBuilder() - .inputs(recipeBuilder.getInputs().toArray(new GTRecipeInput[0])) - .fluidInputs(recipeBuilder.getFluidInputs()) - .outputs(recipeBuilder.getOutputs()) - .chancedOutputs(recipeBuilder.getChancedOutputs()) - .fluidOutputs(recipeBuilder.getFluidOutputs()) - .chancedFluidOutputs(recipeBuilder.getChancedFluidOutputs()) - .cleanroom(recipeBuilder.getCleanroom()) - .duration(recipeBuilder.getDuration()) - .EUt(recipeBuilder.getEUt()) - .buildAndRegister(); - }); + .onBuild(gregtechId("lcr_copy"), recipeBuilder -> RecipeMaps.LARGE_CHEMICAL_RECIPES.recipeBuilder() + .inputs(recipeBuilder.getInputs().toArray(new GTRecipeInput[0])) + .fluidInputs(recipeBuilder.getFluidInputs()) + .outputs(recipeBuilder.getOutputs()) + .chancedOutputs(recipeBuilder.getChancedOutputs()) + .fluidOutputs(recipeBuilder.getFluidOutputs()) + .chancedFluidOutputs(recipeBuilder.getChancedFluidOutputs()) + .cleanroom(recipeBuilder.getCleanroom()) + .duration(recipeBuilder.getDuration()) + .EUt(recipeBuilder.getEUt()) + .buildAndRegister()) + .build(); /** * Example: @@ -490,9 +488,7 @@ public final class RecipeMaps { .itemSlotOverlay(GuiTextures.CIRCUIT_OVERLAY, false) .progressBar(GuiTextures.PROGRESS_BAR_CIRCUIT_ASSEMBLER) .sound(GTSoundEvents.ASSEMBLER) - .build() - .onRecipeBuild(recipeBuilder -> { - recipeBuilder.invalidateOnBuildAction(); + .onBuild(gregtechId("circuit_assembler_solder"), recipeBuilder -> { if (recipeBuilder.getFluidInputs().isEmpty()) { recipeBuilder.copy() .fluidInputs(Materials.SolderingAlloy.getFluid(Math.max(1, @@ -505,7 +501,8 @@ public final class RecipeMaps { recipeBuilder.fluidInputs(Materials.Tin.getFluid(Math.max(1, GTValues.L * recipeBuilder.getSolderMultiplier()))); } - }); + }) + .build(); /** * Example: @@ -613,11 +610,8 @@ public final class RecipeMaps { .itemSlotOverlay(GuiTextures.DUST_OVERLAY, true, true) .progressBar(GuiTextures.PROGRESS_BAR_SLICE) .sound(GTSoundEvents.CUT) - .build() - .onRecipeBuild(recipeBuilder -> { - recipeBuilder.invalidateOnBuildAction(); + .onBuild(gregtechId("cutter_fluid"), recipeBuilder -> { if (recipeBuilder.getFluidInputs().isEmpty()) { - int duration = recipeBuilder.getDuration(); int eut = recipeBuilder.getEUt(); recipeBuilder @@ -643,7 +637,8 @@ public final class RecipeMaps { .duration(Math.max(1, duration)); } - }); + }) + .build(); /** * Examples: @@ -983,8 +978,8 @@ public final class RecipeMaps { .build(); @ZenProperty - public static final RecipeMap GAS_COLLECTOR_RECIPES = new RecipeMapBuilder<>( - "gas_collector", new GasCollectorRecipeBuilder()) + public static final RecipeMap GAS_COLLECTOR_RECIPES = new RecipeMapBuilder<>( + "gas_collector", new SimpleRecipeBuilder()) .itemInputs(1) .fluidOutputs(1) .itemSlotOverlay(GuiTextures.INT_CIRCUIT_OVERLAY, false, true) diff --git a/src/main/java/gregtech/api/recipes/builders/AssemblyLineRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/AssemblyLineRecipeBuilder.java index 9ddc9d6851b..40a23a261ff 100644 --- a/src/main/java/gregtech/api/recipes/builders/AssemblyLineRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/AssemblyLineRecipeBuilder.java @@ -58,14 +58,14 @@ public boolean applyProperty(@NotNull String key, @Nullable Object value) { private boolean applyResearchProperty(ResearchPropertyData.ResearchEntry researchEntry) { if (!ConfigHolder.machines.enableResearch) return false; if (researchEntry == null) { - GTLog.logger.error("Assembly Line Research Entry cannot be empty.", new IllegalArgumentException()); + GTLog.logger.error("Assembly Line Research Entry cannot be empty.", new Throwable()); recipeStatus = EnumValidationResult.INVALID; return false; } if (!generatingRecipes) { GTLog.logger.error("Cannot generate recipes when using researchWithoutRecipe()", - new IllegalArgumentException()); + new Throwable()); recipeStatus = EnumValidationResult.INVALID; return false; } diff --git a/src/main/java/gregtech/api/recipes/builders/BlastRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/BlastRecipeBuilder.java index 3e309d76d4b..8aa2bd236cc 100644 --- a/src/main/java/gregtech/api/recipes/builders/BlastRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/BlastRecipeBuilder.java @@ -39,7 +39,7 @@ public boolean applyProperty(@NotNull String key, Object value) { public BlastRecipeBuilder blastFurnaceTemp(int blastFurnaceTemp) { if (blastFurnaceTemp <= 0) { GTLog.logger.error("Blast Furnace Temperature cannot be less than or equal to 0", - new IllegalArgumentException()); + new Throwable()); recipeStatus = EnumValidationResult.INVALID; } this.applyProperty(TemperatureProperty.getInstance(), blastFurnaceTemp); diff --git a/src/main/java/gregtech/api/recipes/builders/CircuitAssemblerRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/CircuitAssemblerRecipeBuilder.java index a6a4cda94d0..20d4652ddb9 100644 --- a/src/main/java/gregtech/api/recipes/builders/CircuitAssemblerRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/CircuitAssemblerRecipeBuilder.java @@ -31,8 +31,8 @@ public CircuitAssemblerRecipeBuilder copy() { public CircuitAssemblerRecipeBuilder solderMultiplier(int multiplier) { if (1 > GTValues.L * multiplier || GTValues.L * multiplier > 64000) { - GTLog.logger.error("Fluid multiplier cannot exceed 64000mb total. Multiplier: {}", multiplier); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("Fluid multiplier cannot exceed 64000mb total. Multiplier: {}", multiplier, + new Throwable()); recipeStatus = EnumValidationResult.INVALID; } this.solderMultiplier = multiplier; diff --git a/src/main/java/gregtech/api/recipes/builders/ComputationRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/ComputationRecipeBuilder.java index d6cadabc988..2da0309972a 100644 --- a/src/main/java/gregtech/api/recipes/builders/ComputationRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/ComputationRecipeBuilder.java @@ -42,7 +42,7 @@ public boolean applyProperty(@NotNull String key, Object value) { public ComputationRecipeBuilder CWUt(int cwut) { if (cwut < 0) { - GTLog.logger.error("CWU/t cannot be less than 0", new IllegalArgumentException()); + GTLog.logger.error("CWU/t cannot be less than 0", new Throwable()); recipeStatus = EnumValidationResult.INVALID; } this.applyProperty(ComputationProperty.getInstance(), cwut); @@ -54,7 +54,7 @@ public ComputationRecipeBuilder CWUt(int cwut) { */ public ComputationRecipeBuilder totalCWU(int totalCWU) { if (totalCWU < 0) { - GTLog.logger.error("Total CWU cannot be less than 0", new IllegalArgumentException()); + GTLog.logger.error("Total CWU cannot be less than 0", new Throwable()); recipeStatus = EnumValidationResult.INVALID; } this.applyProperty(TotalComputationProperty.getInstance(), totalCWU); diff --git a/src/main/java/gregtech/api/recipes/builders/FusionRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/FusionRecipeBuilder.java index e3da67a3114..a6f56e1420a 100644 --- a/src/main/java/gregtech/api/recipes/builders/FusionRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/FusionRecipeBuilder.java @@ -38,7 +38,7 @@ public boolean applyProperty(@NotNull String key, Object value) { public FusionRecipeBuilder EUToStart(long EUToStart) { if (EUToStart <= 0) { - GTLog.logger.error("EU to start cannot be less than or equal to 0", new IllegalArgumentException()); + GTLog.logger.error("EU to start cannot be less than or equal to 0", new Throwable()); recipeStatus = EnumValidationResult.INVALID; } this.applyProperty(FusionEUToStartProperty.getInstance(), EUToStart); diff --git a/src/main/java/gregtech/api/recipes/builders/GasCollectorRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/GasCollectorRecipeBuilder.java deleted file mode 100644 index fe3bb345305..00000000000 --- a/src/main/java/gregtech/api/recipes/builders/GasCollectorRecipeBuilder.java +++ /dev/null @@ -1,82 +0,0 @@ -package gregtech.api.recipes.builders; - -import gregtech.api.recipes.Recipe; -import gregtech.api.recipes.RecipeBuilder; -import gregtech.api.recipes.RecipeMap; -import gregtech.api.recipes.recipeproperties.GasCollectorDimensionProperty; - -import crafttweaker.CraftTweakerAPI; -import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntList; -import it.unimi.dsi.fastutil.ints.IntLists; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -public class GasCollectorRecipeBuilder extends RecipeBuilder { - - public GasCollectorRecipeBuilder() {} - - public GasCollectorRecipeBuilder(Recipe recipe, RecipeMap recipeMap) { - super(recipe, recipeMap); - } - - public GasCollectorRecipeBuilder(RecipeBuilder recipeBuilder) { - super(recipeBuilder); - } - - @Override - public GasCollectorRecipeBuilder copy() { - return new GasCollectorRecipeBuilder(this); - } - - @Override - public boolean applyProperty(@NotNull String key, Object value) { - if (key.equals(GasCollectorDimensionProperty.KEY)) { - if (value instanceof Integer) { - this.dimension((Integer) value); - } else if (value instanceof List && !((List) value).isEmpty() && - ((List) value).get(0) instanceof Integer) { - IntList dimensionIDs = getDimensionIDs(); - if (dimensionIDs == IntLists.EMPTY_LIST) { - dimensionIDs = new IntArrayList(); - this.applyProperty(GasCollectorDimensionProperty.getInstance(), dimensionIDs); - } - dimensionIDs.addAll((List) value); - } else { - if (isCTRecipe) { - CraftTweakerAPI.logError("Dimension for Gas Collector needs to be a Integer"); - return false; - } - throw new IllegalArgumentException("Invalid Dimension Property Type!"); - } - return true; - } - return super.applyProperty(key, value); - } - - public GasCollectorRecipeBuilder dimension(int dimensionID) { - IntList dimensionIDs = getDimensionIDs(); - if (dimensionIDs == IntLists.EMPTY_LIST) { - dimensionIDs = new IntArrayList(); - this.applyProperty(GasCollectorDimensionProperty.getInstance(), dimensionIDs); - } - dimensionIDs.add(dimensionID); - return this; - } - - public IntList getDimensionIDs() { - return this.recipePropertyStorage == null ? IntLists.EMPTY_LIST : - this.recipePropertyStorage.getRecipePropertyValue(GasCollectorDimensionProperty.getInstance(), - IntLists.EMPTY_LIST); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .appendSuper(super.toString()) - .append(GasCollectorDimensionProperty.getInstance().getKey(), getDimensionIDs().toString()) - .toString(); - } -} diff --git a/src/main/java/gregtech/api/recipes/builders/ImplosionRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/ImplosionRecipeBuilder.java index b44771e8a31..3ada0e83415 100644 --- a/src/main/java/gregtech/api/recipes/builders/ImplosionRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/ImplosionRecipeBuilder.java @@ -49,7 +49,7 @@ public boolean applyProperty(@NotNull String key, Object value) { @ZenMethod public ImplosionRecipeBuilder explosivesAmount(int explosivesAmount) { if (1 > explosivesAmount || explosivesAmount > 64) { - GTLog.logger.error("Amount of explosives should be from 1 to 64 inclusive", new IllegalArgumentException()); + GTLog.logger.error("Amount of explosives should be from 1 to 64 inclusive", new Throwable()); recipeStatus = EnumValidationResult.INVALID; } this.applyProperty(ImplosionExplosiveProperty.getInstance(), new ItemStack(Blocks.TNT, explosivesAmount)); @@ -59,7 +59,7 @@ public ImplosionRecipeBuilder explosivesAmount(int explosivesAmount) { @ZenMethod public ImplosionRecipeBuilder explosivesType(ItemStack explosivesType) { if (1 > explosivesType.getCount() || explosivesType.getCount() > 64) { - GTLog.logger.error("Amount of explosives should be from 1 to 64 inclusive", new IllegalArgumentException()); + GTLog.logger.error("Amount of explosives should be from 1 to 64 inclusive", new Throwable()); recipeStatus = EnumValidationResult.INVALID; } this.applyProperty(ImplosionExplosiveProperty.getInstance(), explosivesType); diff --git a/src/main/java/gregtech/api/recipes/ingredients/nbtmatch/ListNBTCondition.java b/src/main/java/gregtech/api/recipes/ingredients/nbtmatch/ListNBTCondition.java index ee8b61833a8..e7d3d744ffa 100644 --- a/src/main/java/gregtech/api/recipes/ingredients/nbtmatch/ListNBTCondition.java +++ b/src/main/java/gregtech/api/recipes/ingredients/nbtmatch/ListNBTCondition.java @@ -19,8 +19,7 @@ protected ListNBTCondition(NBTTagType listTagType, String nbtKey, Object value) super(NBTTagType.LIST, nbtKey, value); this.listTagType = listTagType; if (listTagType == null) { - GTLog.logger.error("ListNBTCondition must not have null parameters."); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("ListNBTCondition must not have null parameters.", new Throwable()); } } diff --git a/src/main/java/gregtech/api/recipes/ingredients/nbtmatch/NBTCondition.java b/src/main/java/gregtech/api/recipes/ingredients/nbtmatch/NBTCondition.java index 06298ae22ad..ebf380d753b 100644 --- a/src/main/java/gregtech/api/recipes/ingredients/nbtmatch/NBTCondition.java +++ b/src/main/java/gregtech/api/recipes/ingredients/nbtmatch/NBTCondition.java @@ -37,8 +37,7 @@ protected NBTCondition(NBTTagType tagType, String nbtKey, Object value) { this.nbtKey = nbtKey; this.value = value; if (tagType == null || nbtKey == null || value == null) { - GTLog.logger.error("NBTCondition must not have null parameters."); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("NBTCondition must not have null parameters.", new Throwable()); } } diff --git a/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java b/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java index 28cd542d11d..7edeb9a7f62 100644 --- a/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java +++ b/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java @@ -63,6 +63,10 @@ public boolean removeRecipe(@NotNull Recipe recipe) { @Override public void addDataStickEntry(@NotNull String researchId, @NotNull Recipe recipe) { + if (researchId.contains("xmetaitem.")) { + // save compatibility with an issue in 2.8.6, causing research IDs to change + addDataStickEntry(researchId.replace("xmetaitem.", "xitem.meta_item."), recipe); + } Collection collection = researchEntries.computeIfAbsent(researchId, (k) -> new ObjectOpenHashSet<>()); collection.add(recipe); } diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/CleanroomProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/CleanroomProperty.java index ccbe97bdc17..2152e3a3e43 100644 --- a/src/main/java/gregtech/api/recipes/recipeproperties/CleanroomProperty.java +++ b/src/main/java/gregtech/api/recipes/recipeproperties/CleanroomProperty.java @@ -32,6 +32,13 @@ public void drawInfo(@NotNull Minecraft minecraft, int x, int y, int color, Obje minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.cleanroom", getName(type)), x, y, color); } + @Override + public int getInfoHeight(Object value) { + CleanroomType type = castValue(value); + if (type == null) return 0; + return super.getInfoHeight(value); + } + @NotNull private static String getName(@NotNull CleanroomType value) { String name = I18n.format(value.getTranslationKey()); diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/DimensionProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/DimensionProperty.java new file mode 100644 index 00000000000..f233e7cd7f3 --- /dev/null +++ b/src/main/java/gregtech/api/recipes/recipeproperties/DimensionProperty.java @@ -0,0 +1,87 @@ +package gregtech.api.recipes.recipeproperties; + +import gregtech.api.worldgen.config.WorldGenRegistry; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.I18n; + +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; + +public class DimensionProperty extends RecipeProperty { + + public static final String KEY = "dimension"; + + private static DimensionProperty INSTANCE; + + private DimensionProperty() { + super(KEY, DimensionPropertyList.class); + } + + public static DimensionProperty getInstance() { + if (INSTANCE == null) + INSTANCE = new DimensionProperty(); + return INSTANCE; + } + + @Override + public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { + DimensionPropertyList list = castValue(value); + + if (list.whiteListDimensions.size() > 0) + minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.dimensions", + getDimensionsForRecipe(castValue(value).whiteListDimensions)), x, y, color); + if (list.blackListDimensions.size() > 0) + minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.dimensions_blocked", + getDimensionsForRecipe(castValue(value).blackListDimensions)), x, y, color); + } + + private static String getDimensionsForRecipe(IntList value) { + Int2ObjectMap dimNames = WorldGenRegistry.getNamedDimensions(); + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < value.size(); i++) { + builder.append(dimNames.getOrDefault(value.getInt(i), String.valueOf(value.getInt(i)))); + if (i != value.size() - 1) + builder.append(", "); + } + String str = builder.toString(); + + if (str.length() >= 13) { + str = str.substring(0, 10) + ".."; + } + return str; + } + + // It would've been better to have one list and swap between blacklist and whitelist, but that would've been + // a bit awkward to apply to the property in practice. + public static class DimensionPropertyList { + + public static DimensionPropertyList EMPTY_LIST = new DimensionPropertyList(); + + public IntList whiteListDimensions = new IntArrayList(); + public IntList blackListDimensions = new IntArrayList(); + + public void add(int key, boolean toBlacklist) { + if (toBlacklist) { + blackListDimensions.add(key); + whiteListDimensions.rem(key); + } else { + whiteListDimensions.add(key); + blackListDimensions.rem(key); + } + } + + public void merge(DimensionPropertyList list) { + this.whiteListDimensions.addAll(list.whiteListDimensions); + this.blackListDimensions.addAll(list.blackListDimensions); + } + + public boolean checkDimension(int dim) { + boolean valid = true; + if (this.blackListDimensions.size() > 0) valid = !this.blackListDimensions.contains(dim); + if (this.whiteListDimensions.size() > 0) valid = this.whiteListDimensions.contains(dim); + return valid; + } + } +} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/GasCollectorDimensionProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/GasCollectorDimensionProperty.java deleted file mode 100644 index 94bb810e3b1..00000000000 --- a/src/main/java/gregtech/api/recipes/recipeproperties/GasCollectorDimensionProperty.java +++ /dev/null @@ -1,48 +0,0 @@ -package gregtech.api.recipes.recipeproperties; - -import gregtech.api.worldgen.config.WorldGenRegistry; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.I18n; - -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.IntList; - -public class GasCollectorDimensionProperty extends RecipeProperty { - - public static final String KEY = "dimension"; - - private static GasCollectorDimensionProperty INSTANCE; - - private GasCollectorDimensionProperty() { - super(KEY, IntList.class); - } - - public static GasCollectorDimensionProperty getInstance() { - if (INSTANCE == null) - INSTANCE = new GasCollectorDimensionProperty(); - return INSTANCE; - } - - @Override - public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { - minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.dimensions", - getDimensionsForRecipe(castValue(value))), x, y, color); - } - - private static String getDimensionsForRecipe(IntList value) { - Int2ObjectMap dimNames = WorldGenRegistry.getNamedDimensions(); - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < value.size(); i++) { - builder.append(dimNames.getOrDefault(value.getInt(i), String.valueOf(value.getInt(i)))); - if (i != value.size() - 1) - builder.append(", "); - } - String str = builder.toString(); - - if (str.length() >= 13) { - str = str.substring(0, 10) + ".."; - } - return str; - } -} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/IRecipePropertyStorage.java b/src/main/java/gregtech/api/recipes/recipeproperties/IRecipePropertyStorage.java index 234434bf003..9781e2484ce 100644 --- a/src/main/java/gregtech/api/recipes/recipeproperties/IRecipePropertyStorage.java +++ b/src/main/java/gregtech/api/recipes/recipeproperties/IRecipePropertyStorage.java @@ -5,8 +5,6 @@ public interface IRecipePropertyStorage { - String STACKTRACE = "Stacktrace:"; - /** * Stores new {@link RecipeProperty} with value * diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/PrimitiveProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/PrimitiveProperty.java index 524fd7180fe..6419cd2aab0 100644 --- a/src/main/java/gregtech/api/recipes/recipeproperties/PrimitiveProperty.java +++ b/src/main/java/gregtech/api/recipes/recipeproperties/PrimitiveProperty.java @@ -24,6 +24,11 @@ public static PrimitiveProperty getInstance() { @Override public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) {} + @Override + public int getInfoHeight(Object value) { + return 0; + } + @Override public boolean hideTotalEU() { return true; diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/RecipePropertyStorage.java b/src/main/java/gregtech/api/recipes/recipeproperties/RecipePropertyStorage.java index a74ba78da6d..cf38c40ef3e 100644 --- a/src/main/java/gregtech/api/recipes/recipeproperties/RecipePropertyStorage.java +++ b/src/main/java/gregtech/api/recipes/recipeproperties/RecipePropertyStorage.java @@ -45,16 +45,15 @@ public boolean store(RecipeProperty recipeProperty, Object value) { try { recipeProperty.castValue(value); - } catch (ClassCastException ex) { - GTLog.logger.warn("Provided incorrect value for RecipeProperty with key {}", key); - GTLog.logger.warn("Full exception:", ex); + } catch (ClassCastException e) { + GTLog.logger.warn("Provided incorrect value for RecipeProperty with key {}", key, e); success = false; } if (success) { recipeProperties.put(recipeProperty, value); } else { - GTLog.logger.warn(STACKTRACE, new IllegalArgumentException()); + GTLog.logger.warn("RecipePropertyStorage error found", new Throwable()); } return success; diff --git a/src/main/java/gregtech/api/terminal/TerminalRegistry.java b/src/main/java/gregtech/api/terminal/TerminalRegistry.java index 6da73912e23..e842eb0c7a9 100644 --- a/src/main/java/gregtech/api/terminal/TerminalRegistry.java +++ b/src/main/java/gregtech/api/terminal/TerminalRegistry.java @@ -5,6 +5,7 @@ import gregtech.api.terminal.hardware.Hardware; import gregtech.api.util.FileUtility; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import gregtech.common.items.MetaItems; import gregtech.common.terminal.app.VirtualTankApp; @@ -131,7 +132,7 @@ public static void init() { .upgrade(1, MetaItems.EMITTER_HV.getStackForm(4), MetaItems.WORKSTATION_EV.getStackForm(2)) .defaultApp() .build(); - if (Loader.isModLoaded(GTValues.MODID_JEI)) { + if (Mods.JustEnoughItems.isModLoaded()) { AppRegistryBuilder.create(new RecipeChartApp()) .battery(GTValues.LV, 160) .upgrade(0, new ItemStack(Items.PAPER, 32)) diff --git a/src/main/java/gregtech/api/unification/material/Material.java b/src/main/java/gregtech/api/unification/material/Material.java index 4151dab0ba5..540adc9df5d 100644 --- a/src/main/java/gregtech/api/unification/material/Material.java +++ b/src/main/java/gregtech/api/unification/material/Material.java @@ -1078,10 +1078,11 @@ public Builder fissionFuelProperties(int maxTemperature, int duration, double sl } public Builder coolantProperty(Material hotCoolant, Material hotHPCoolant, double moderatorFactor, - double coolingFactor, double boilingPoint, double absorption, double pressure) { + double coolingFactor, double boilingPoint, double absorption, double pressure, + double heatOfVaporization, double specificHeatCapacity) { properties.ensureSet(PropertyKey.FLUID); properties.setProperty(PropertyKey.COOLANT, new CoolantProperty(hotCoolant, hotHPCoolant, moderatorFactor, - coolingFactor, boilingPoint, absorption, pressure)); + coolingFactor, boilingPoint, absorption, pressure, heatOfVaporization, specificHeatCapacity)); return this; } diff --git a/src/main/java/gregtech/api/unification/material/Materials.java b/src/main/java/gregtech/api/unification/material/Materials.java index 4d08dca3561..f373d0f8341 100644 --- a/src/main/java/gregtech/api/unification/material/Materials.java +++ b/src/main/java/gregtech/api/unification/material/Materials.java @@ -438,8 +438,10 @@ public static void register() { public static Material NitricOxide; public static Material Iron3Chloride; public static Material UraniumHexafluoride; - public static Material EnrichedUraniumHexafluoride; + public static Material HighEnrichedUraniumHexafluoride; + public static Material LowEnrichedUraniumHexafluoride; public static Material DepletedUraniumHexafluoride; + public static Material LowEnrichedUraniumDioxide; public static Material NitrousOxide; public static Material EnderPearl; public static Material PotassiumFeldspar; @@ -477,10 +479,19 @@ public static void register() { public static Material NaquadriaSulfate; public static Material Pyrochlore; public static Material RTMAlloy; - public static Material EnrichedUraniumDioxide; + public static Material HighEnrichedUraniumDioxide; public static Material DepletedUraniumDioxide; public static Material HighPressureSteam; - public static Material Plutonium239Dioxide; + public static Material FissilePlutoniumDioxide; + public static Material Zircaloy; + public static Material Zircon; + public static Material ZirconiumDioxide; + public static Material ZirconiumTetrachloride; + public static Material HafniumDioxide; + public static Material HafniumTetrachloride; + public static Material Inconel; + public static Material BoronTrioxide; + public static Material BoronCarbide; /** * Organic chemistry @@ -697,6 +708,7 @@ public static void register() { public static Material UUMatter; public static Material PCBCoolant; public static Material Corium; + public static Material SpentUraniumFuelSolution; /** * Second Degree Compounds diff --git a/src/main/java/gregtech/api/unification/material/info/MaterialIconType.java b/src/main/java/gregtech/api/unification/material/info/MaterialIconType.java index c5b3f2e54eb..45f8de79a33 100644 --- a/src/main/java/gregtech/api/unification/material/info/MaterialIconType.java +++ b/src/main/java/gregtech/api/unification/material/info/MaterialIconType.java @@ -88,6 +88,12 @@ public class MaterialIconType { public static final MaterialIconType fuelRod = new MaterialIconType("fuelRod"); public static final MaterialIconType fuelRodDepleted = new MaterialIconType("fuelRodDepleted"); public static final MaterialIconType fuelRodHotDepleted = new MaterialIconType("fuelRodHotDepleted"); + public static final MaterialIconType fuelPellet = new MaterialIconType("fuelPellet"); + public static final MaterialIconType fuelPelletDepleted = new MaterialIconType("fuelPelletDepleted"); + + public static final MaterialIconType dustSpentFuel = new MaterialIconType("dustSpentFuel"); + public static final MaterialIconType dustBredFuel = new MaterialIconType("dustBredFuel"); + public static final MaterialIconType dustFissionByproduct = new MaterialIconType("dustFissionByproduct"); // BLOCK TEXTURES public static final MaterialIconType liquid = new MaterialIconType("liquid"); diff --git a/src/main/java/gregtech/api/unification/material/materials/ElementMaterials.java b/src/main/java/gregtech/api/unification/material/materials/ElementMaterials.java index 89510235302..094610eaf32 100644 --- a/src/main/java/gregtech/api/unification/material/materials/ElementMaterials.java +++ b/src/main/java/gregtech/api/unification/material/materials/ElementMaterials.java @@ -306,7 +306,10 @@ public static void register() { .build(); Hafnium = new Material.Builder(42, gregtechId("hafnium")) + .ingot() .color(0x99999A).iconSet(SHINY) + .flags(GENERATE_LONG_ROD) + .blast(2227) .element(Elements.Hf) .build(); @@ -871,7 +874,7 @@ public static void register() { .color(0x32F032).iconSet(METALLIC) .flags(EXT_METAL) .element(Elements.U) - .fissionFuelProperties(400, 40, 0.1, 0.1, 0.1, 0.1) + // .fissionFuelProperties(1600, 40, 1.2, 0.1, 0.1, 0.5) .build(); Uranium235 = new Material.Builder(117, gregtechId("uranium_235")) @@ -916,6 +919,7 @@ public static void register() { .build(); Zirconium = new Material.Builder(123, gregtechId("zirconium")) + .dust() .color(0xC8FFFF).iconSet(METALLIC) .element(Elements.Zr) .build(); diff --git a/src/main/java/gregtech/api/unification/material/materials/FirstDegreeMaterials.java b/src/main/java/gregtech/api/unification/material/materials/FirstDegreeMaterials.java index 9d2442e1cce..82b8a56485c 100644 --- a/src/main/java/gregtech/api/unification/material/materials/FirstDegreeMaterials.java +++ b/src/main/java/gregtech/api/unification/material/materials/FirstDegreeMaterials.java @@ -514,7 +514,7 @@ public static void register() { .build(); Salt = new Material.Builder(312, gregtechId("salt")) - .gem(1).ore(2, 1) + .gem(1).ore(2, 1).fluid() .color(0xFAFAFA).iconSet(FINE) .flags(NO_SMASHING) .components(Sodium, 1, Chlorine, 1) @@ -1218,7 +1218,7 @@ public static void register() { .build() .setFormula("UF6", true); - EnrichedUraniumHexafluoride = new Material.Builder(413, gregtechId("enriched_uranium_hexafluoride")) + LowEnrichedUraniumHexafluoride = new Material.Builder(413, gregtechId("enriched_uranium_hexafluoride")) .gas() .color(0x4BF52A) .flags(DISABLE_DECOMPOSITION) @@ -1554,9 +1554,9 @@ public static void register() { .vacuumStats(VA[HV], 250)) .build(); - EnrichedUraniumDioxide = new Material.Builder(452, gregtechId("enriched_uranium_dioxide")) + HighEnrichedUraniumDioxide = new Material.Builder(452, gregtechId("high_enriched_uranium_dioxide")) .dust(3) - .color(0x232323).iconSet(DULL) + .color(0x53E353).iconSet(DULL) .flags(DISABLE_DECOMPOSITION) .components(Uranium235, 1, Oxygen, 2) .build() @@ -1564,7 +1564,7 @@ public static void register() { DepletedUraniumDioxide = new Material.Builder(453, gregtechId("depleted_uranium_dioxide")) .dust(3) - .color(0x232323).iconSet(DULL) + .color(0x335323).iconSet(DULL) .flags(DISABLE_DECOMPOSITION) .components(Uranium, 1, Oxygen, 2) .build() @@ -1573,18 +1573,101 @@ public static void register() { HighPressureSteam = new Material.Builder(454, gregtechId("high_pressure_steam")) .gas(new FluidBuilder() .temperature(500) - .customStill()) + /* .customStill() */) .color(0xC4C4C4) .flags(DISABLE_DECOMPOSITION) .components(Hydrogen, 2, Oxygen, 1) .build(); - Plutonium239Dioxide = new Material.Builder(455, gregtechId("plutonium_239_dioxide")) + FissilePlutoniumDioxide = new Material.Builder(455, gregtechId("fissile_plutonium_dioxide")) .dust(3) .color(0xF03232).iconSet(DULL) .flags(DISABLE_DECOMPOSITION) - .components(Uranium235, 1, Oxygen, 2) + .components(Plutonium239, 1, Oxygen, 2) .build() .setFormula("PuO2", true); + + Zircaloy = new Material.Builder(456, gregtechId("zircaloy")) + .ingot() + .color(0x566570).iconSet(METALLIC) + .flags(GENERATE_RING) + .components(Zirconium, 9, Tin, 1) + .blast(1700, GasTier.LOW) + .build(); + + LowEnrichedUraniumDioxide = new Material.Builder(457, gregtechId("low_enriched_uranium_dioxide")) + .dust() + .color(0x43A333) + .flags(DISABLE_DECOMPOSITION) + .components(Uranium235, 1, Oxygen, 2) + .build() + .setFormula("UO2", true); + + Zircon = new Material.Builder(458, gregtechId("zircon")) + .ore() + .color(0x386F6F) + .flags(DISABLE_DECOMPOSITION) + .components(Zirconium, 1, Silicon, 1, Oxygen, 4) + .build(); + + ZirconiumDioxide = new Material.Builder(459, gregtechId("zirconium_dioxide")) + .dust() + .color(0x689F9F) + .flags(DISABLE_DECOMPOSITION) + .components(Zirconium, 1, Oxygen, 2) + .build(); + + ZirconiumTetrachloride = new Material.Builder(460, gregtechId("zirconium_tetrachloride")) + .dust() + .color(0x689FBF) + .flags(DISABLE_DECOMPOSITION) + .components(Zirconium, 1, Chlorine, 4) + .build(); + + HafniumDioxide = new Material.Builder(461, gregtechId("hafnium_dioxide")) + .dust() + .color(0x39393A) + .flags(DISABLE_DECOMPOSITION) + .components(Hafnium, 1, Oxygen, 2) + .build(); + + HafniumTetrachloride = new Material.Builder(462, gregtechId("hafnium_tetrachloride")) + .dust() + .color(0x69699A) + .flags(DISABLE_DECOMPOSITION) + .components(Hafnium, 1, Chlorine, 4) + .build(); + + Inconel = new Material.Builder(463, gregtechId("inconel")) + .ingot().fluid() + .color(0x7F8F75).iconSet(SHINY) + .flags(GENERATE_DOUBLE_PLATE, GENERATE_SPRING, DISABLE_DECOMPOSITION) + .components(Nickel, 5, Chrome, 2, Iron, 2, Niobium, 1, Molybdenum, 1) + .blastTemp(1610, GasTier.MID, GTValues.VA[EV], 200) + .fluidPipeProperties(2010, 175, true, true, true, false) + .build() + .setFormula("Ni50Cr20Fe20Ni5Mo3", true); + + HighEnrichedUraniumHexafluoride = new Material.Builder(464, gregtechId("high_enriched_uranium_hexafluoride")) + .gas() + .color(0x5BF93A) + .flags(DISABLE_DECOMPOSITION) + .components(Uranium235, 1, Fluorine, 6) + .build() + .setFormula("UF6", true); + + BoronTrioxide = new Material.Builder(465, gregtechId("boron_trioxide")) + .dust() + .color(0xC1E9E1) + .components(Boron, 2, Oxygen, 3) + .build(); + + BoronCarbide = new Material.Builder(466, gregtechId("boron_carbide")) + .ingot() + .flags(GENERATE_ROD, DISABLE_DECOMPOSITION) + .blast(2620) + .color(0xC1E9C1) + .components(Boron, 4, Carbon, 1) + .build(); } } diff --git a/src/main/java/gregtech/api/unification/material/materials/MaterialFlagAddition.java b/src/main/java/gregtech/api/unification/material/materials/MaterialFlagAddition.java index 85ffd8ae12c..77f7ffcbb7a 100644 --- a/src/main/java/gregtech/api/unification/material/materials/MaterialFlagAddition.java +++ b/src/main/java/gregtech/api/unification/material/materials/MaterialFlagAddition.java @@ -407,12 +407,13 @@ public static void register() { oreProp = Pyrochlore.getProperty(PropertyKey.ORE); oreProp.setOreByProducts(Apatite, Calcium, Niobium); - /* + /** * Coolant property addition * This sometimes cross-references materials */ DistilledWater.setProperty(PropertyKey.COOLANT, - new CoolantProperty(Steam, HighPressureSteam, 1., 1., - 373, 10., FissionReactor.standardPressure)); + new CoolantProperty(Steam, HighPressureSteam, 1., 1000, + 373, 10., FissionReactor.standardPressure, 2260000, 4168).setSadgeCoefficient(1000) + .setAccumulatesHydrogen(true)); } } diff --git a/src/main/java/gregtech/api/unification/material/materials/SecondDegreeMaterials.java b/src/main/java/gregtech/api/unification/material/materials/SecondDegreeMaterials.java index ac5d6d622c3..aa5ed943384 100644 --- a/src/main/java/gregtech/api/unification/material/materials/SecondDegreeMaterials.java +++ b/src/main/java/gregtech/api/unification/material/materials/SecondDegreeMaterials.java @@ -508,8 +508,8 @@ public static void register() { .dust(3) .color(0x232323).iconSet(METALLIC) .flags(DISABLE_DECOMPOSITION) - .components(EnrichedUraniumDioxide, 1, DepletedUraniumDioxide, 20) - .fissionFuelProperties(2000, 1000, 100., 0., 1000., 0.) + .components(HighEnrichedUraniumDioxide, 1, DepletedUraniumDioxide, 20) + .fissionFuelProperties(2000, 1000, 55., 1., 1000., 0.) .build() .setFormula("UO2", true); @@ -517,8 +517,8 @@ public static void register() { .dust(3) .color(0x242826).iconSet(METALLIC) .flags(DISABLE_DECOMPOSITION) - .components(EnrichedUraniumDioxide, 1, DepletedUraniumDioxide, 5) - .fissionFuelProperties(2000, 1000, 10., 0., 2000., 0.) + .components(HighEnrichedUraniumDioxide, 1, DepletedUraniumDioxide, 5) + .fissionFuelProperties(2000, 1000, 40., 1., 1250., 0.) .build() .setFormula("UO2", true); @@ -526,7 +526,7 @@ public static void register() { .dust(3) .color(0x62C032).iconSet(METALLIC) .flags(DISABLE_DECOMPOSITION) - .components(Plutonium239Dioxide, 1, Uraninite, 20) + .components(FissilePlutoniumDioxide, 1, Uraninite, 20) .fissionFuelProperties(2000, 1500, 50., 10., 1500., 10.) .build() .setFormula("(U,Pu)O2", true); @@ -535,8 +535,8 @@ public static void register() { .dust(3) .color(0x7EA432).iconSet(METALLIC) .flags(DISABLE_DECOMPOSITION) - .components(Plutonium239Dioxide, 1, Uraninite, 5) - .fissionFuelProperties(2000, 1500, 10., 10., 2000., 10.) + .components(FissilePlutoniumDioxide, 1, Uraninite, 5) + .fissionFuelProperties(2000, 1500, 35., 25., 2000., 25.) .build() .setFormula("(U,Pu)O2", true); } diff --git a/src/main/java/gregtech/api/unification/material/materials/UnknownCompositionMaterials.java b/src/main/java/gregtech/api/unification/material/materials/UnknownCompositionMaterials.java index cf55a739501..da49b964c64 100644 --- a/src/main/java/gregtech/api/unification/material/materials/UnknownCompositionMaterials.java +++ b/src/main/java/gregtech/api/unification/material/materials/UnknownCompositionMaterials.java @@ -646,5 +646,9 @@ public static void register() { PCBCoolant = new Material.Builder(1650, gregtechId("pcb_coolant")) .fluid().color(0xD5D69C).build(); + + SpentUraniumFuelSolution = new Material.Builder(1651, gregtechId("spent_uranium_fuel_solution")) + .liquid(new FluidBuilder()) + .color(0x5B5B5B).build(); // TODO color } } diff --git a/src/main/java/gregtech/api/unification/material/properties/BlastProperty.java b/src/main/java/gregtech/api/unification/material/properties/BlastProperty.java index 172e0981ac7..61670ea18f9 100644 --- a/src/main/java/gregtech/api/unification/material/properties/BlastProperty.java +++ b/src/main/java/gregtech/api/unification/material/properties/BlastProperty.java @@ -1,17 +1,18 @@ package gregtech.api.unification.material.properties; +import gregtech.integration.groovy.GroovyScriptModule; + import crafttweaker.CraftTweakerAPI; import org.jetbrains.annotations.NotNull; public class BlastProperty implements IMaterialProperty { /** - * Blast Furnace Temperature of this Material. - * If below 1000K, Primitive Blast Furnace recipes will be also added. + * Blast Furnace Temperature of this Material. If below 1000K, Primitive Blast Furnace recipes will be also added. * If above 1750K, a Hot Ingot and its Vacuum Freezer recipe will be also added. *

- * If a Material with this Property has a Fluid, its temperature - * will be set to this if it is the default Fluid temperature. + * If a Material with this Property has a Fluid, its temperature will be set to this if it is the default Fluid + * temperature. */ private int blastTemperature; @@ -132,7 +133,10 @@ public void verifyProperty(MaterialProperties properties) { public static GasTier validateGasTier(String gasTierName) { if (gasTierName == null) return null; - else if ("LOW".equalsIgnoreCase(gasTierName)) return GasTier.LOW; + if (GroovyScriptModule.isCurrentlyRunning()) { + return GroovyScriptModule.parseAndValidateEnumValue(GasTier.class, gasTierName, "gas tier"); + } + if ("LOW".equalsIgnoreCase(gasTierName)) return GasTier.LOW; else if ("MID".equalsIgnoreCase(gasTierName)) return GasTier.MID; else if ("HIGH".equalsIgnoreCase(gasTierName)) return GasTier.HIGH; else if ("HIGHER".equalsIgnoreCase(gasTierName)) return GasTier.HIGHER; diff --git a/src/main/java/gregtech/api/unification/material/properties/CoolantProperty.java b/src/main/java/gregtech/api/unification/material/properties/CoolantProperty.java index d1e7d14c3d4..08f8be5173f 100644 --- a/src/main/java/gregtech/api/unification/material/properties/CoolantProperty.java +++ b/src/main/java/gregtech/api/unification/material/properties/CoolantProperty.java @@ -7,13 +7,27 @@ public class CoolantProperty implements IMaterialProperty { private Material hotCoolant; private Material hotHPCoolant; private double moderatorFactor; + /** + * Roughly the heat transfer coefficient + * Do not put too much thought into this + */ private double coolingFactor; + // in kelvin at standard conditions private double boilingPoint; + // neutron absorption rate private double absorption; + // in pascal private double pressure; + // in J/L + private double heatOfVaporization; + // in J/(kg*K) + private double specificHeatCapacity; + private double sadgeCoefficient = 1; + private boolean accumulatesHydrogen = false; public CoolantProperty(Material hotCoolant, Material hotHPCoolant, double moderatorFactor, double coolingFactor, - double boilingPoint, double absorption, double pressure) { + double boilingPoint, double absorption, double pressure, double heatOfVaporization, + double specificHeatCapacity) { this.hotCoolant = hotCoolant; this.hotHPCoolant = hotHPCoolant; this.moderatorFactor = moderatorFactor; @@ -21,6 +35,8 @@ public CoolantProperty(Material hotCoolant, Material hotHPCoolant, double modera this.boilingPoint = boilingPoint; this.absorption = absorption; this.pressure = pressure; + this.heatOfVaporization = heatOfVaporization; + this.specificHeatCapacity = specificHeatCapacity; } @Override @@ -83,4 +99,46 @@ public void setPressure(double pressure) { public double getPressure() { return pressure; } + + public double getHeatOfVaporization() { + return heatOfVaporization; + } + + public void setHeatOfVaporization(double heatOfVaporization) { + this.heatOfVaporization = heatOfVaporization; + } + + public double getSpecificHeatCapacity() { + return specificHeatCapacity; + } + + public void setSpecificHeatCapacity(double specificHeatCapacity) { + this.specificHeatCapacity = specificHeatCapacity; + } + + public double getSadgeCoefficient() { + return sadgeCoefficient; + } + + /** + * Used to adjust the amount of heat needed to heat the coolant from the ideal thermodynamic conditions; this is + * really only for distilled water. + * + * @param sadgeCoefficient A divisor to the amount of heat needed to heat the coolant from the ideal thermodynamic + * conditions. + * @return The property itself. + */ + public CoolantProperty setSadgeCoefficient(double sadgeCoefficient) { + this.sadgeCoefficient = sadgeCoefficient; + return this; + } + + public boolean accumulatesHydrogen() { + return accumulatesHydrogen; + } + + public CoolantProperty setAccumulatesHydrogen(boolean accumulatesHydrogen) { + this.accumulatesHydrogen = accumulatesHydrogen; + return this; + } } diff --git a/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java b/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java index 48f92084252..80c971fb4f1 100644 --- a/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java +++ b/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java @@ -2,6 +2,10 @@ import gregtech.api.fluids.store.FluidStorage; import gregtech.api.fluids.store.FluidStorageKey; +import gregtech.api.fluids.store.FluidStorageKeys; + +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -10,6 +14,7 @@ public class FluidProperty implements IMaterialProperty { private final FluidStorage storage = new FluidStorage(); private @Nullable FluidStorageKey primaryKey = null; + private @Nullable Fluid solidifyingFluid = null; public FluidProperty() {} @@ -33,4 +38,33 @@ public void setPrimaryKey(@Nullable FluidStorageKey primaryKey) { @Override public void verifyProperty(MaterialProperties properties) {} + + /** + * @return the Fluid which solidifies into the material. + */ + + public Fluid solidifiesFrom() { + if (this.solidifyingFluid == null) { + return getStorage().get(FluidStorageKeys.LIQUID); + } + return solidifyingFluid; + } + + /** + * @param amount the size of the returned FluidStack. + * @return a FluidStack of the Fluid which solidifies into the material. + */ + public FluidStack solidifiesFrom(int amount) { + return new FluidStack(solidifiesFrom(), amount); + } + + /** + * Sets the fluid that solidifies into the material. + * + * @param solidifyingFluid The Fluid which solidifies into the material. If left null, it will be left as the + * default value: the material's liquid. + */ + public void setSolidifyingFluid(@Nullable Fluid solidifyingFluid) { + this.solidifyingFluid = solidifyingFluid; + } } diff --git a/src/main/java/gregtech/api/unification/ore/OrePrefix.java b/src/main/java/gregtech/api/unification/ore/OrePrefix.java index 47387ff05ab..b0fb1586d58 100644 --- a/src/main/java/gregtech/api/unification/ore/OrePrefix.java +++ b/src/main/java/gregtech/api/unification/ore/OrePrefix.java @@ -23,7 +23,15 @@ import stanhebben.zenscript.annotations.ZenClass; import stanhebben.zenscript.annotations.ZenMethod; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +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 java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import java.util.function.Predicate; @@ -317,13 +325,24 @@ public class OrePrefix { public static final OrePrefix circuit = new OrePrefix("circuit", -1, null, null, ENABLE_UNIFICATION, null); public static final OrePrefix component = new OrePrefix("component", -1, null, null, ENABLE_UNIFICATION, null); - // Nuclear stuff + // Nuclear stuff, introduced by Zalgo and Bruberu public static final OrePrefix fuelRod = new OrePrefix("fuelRod", -1, null, MaterialIconType.fuelRod, 0, material -> material.hasProperty(PropertyKey.FISSION_FUEL)); public static final OrePrefix fuelRodDepleted = new OrePrefix("fuelRodDepleted", -1, null, MaterialIconType.fuelRodDepleted, 0, material -> material.hasProperty(PropertyKey.FISSION_FUEL)); public static final OrePrefix fuelRodHotDepleted = new OrePrefix("fuelRodHotDepleted", -1, null, MaterialIconType.fuelRodHotDepleted, 0, material -> material.hasProperty(PropertyKey.FISSION_FUEL)); + public static final OrePrefix fuelPellet = new OrePrefix("fuelPellet", -1, null, + MaterialIconType.fuelPellet, 0, material -> material.hasProperty(PropertyKey.FISSION_FUEL)); + public static final OrePrefix fuelPelletDepleted = new OrePrefix("fuelPelletDepleted", -1, null, + MaterialIconType.fuelPelletDepleted, 0, material -> material.hasProperty(PropertyKey.FISSION_FUEL)); + + public static final OrePrefix dustSpentFuel = new OrePrefix("dustSpentFuel", -1, null, + MaterialIconType.dustSpentFuel, 0, material -> material.hasProperty(PropertyKey.FISSION_FUEL)); + public static final OrePrefix dustBredFuel = new OrePrefix("dustBredFuel", -1, null, + MaterialIconType.dustBredFuel, 0, material -> material.hasProperty(PropertyKey.FISSION_FUEL)); + public static final OrePrefix dustFissionByproduct = new OrePrefix("dustFissionByproduct", -1, null, + MaterialIconType.dustFissionByproduct, 0, material -> material.hasProperty(PropertyKey.FISSION_FUEL)); public static class Flags { @@ -644,11 +663,11 @@ private void runGeneratedMaterialHandlers() { for (IOreRegistrationHandler registrationHandler : oreProcessingHandlers) { registrationHandler.processMaterial(this, registeredMaterial); } - currentMaterial.set(null); + currentMaterial.remove(); } // clear generated materials for next pass generatedMaterials.clear(); - currentProcessingPrefix.set(null); + currentProcessingPrefix.remove(); } public void setAlternativeOreName(String name) { diff --git a/src/main/java/gregtech/api/unification/ore/StoneType.java b/src/main/java/gregtech/api/unification/ore/StoneType.java index f92bb9c68bf..9e87a43a0b8 100644 --- a/src/main/java/gregtech/api/unification/ore/StoneType.java +++ b/src/main/java/gregtech/api/unification/ore/StoneType.java @@ -1,9 +1,9 @@ package gregtech.api.unification.ore; -import gregtech.api.GTValues; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.properties.PropertyKey; import gregtech.api.util.GTControlledRegistry; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import gregtech.integration.jei.basic.OreByProduct; @@ -11,7 +11,6 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; -import net.minecraftforge.fml.common.Loader; import com.google.common.base.Preconditions; import org.jetbrains.annotations.NotNull; @@ -50,7 +49,7 @@ public StoneType(int id, String name, SoundType soundType, OrePrefix processingP this.predicate = predicate::test; this.shouldBeDroppedAsItem = shouldBeDroppedAsItem || ConfigHolder.worldgen.allUniqueStoneTypes; STONE_TYPE_REGISTRY.register(id, name, this); - if (Loader.isModLoaded(GTValues.MODID_JEI) && this.shouldBeDroppedAsItem) { + if (Mods.JustEnoughItems.isModLoaded() && this.shouldBeDroppedAsItem) { OreByProduct.addOreByProductPrefix(this.processingPrefix); } } diff --git a/src/main/java/gregtech/api/util/CapesRegistry.java b/src/main/java/gregtech/api/util/CapesRegistry.java index 50972a56236..7d0acaa0ba6 100644 --- a/src/main/java/gregtech/api/util/CapesRegistry.java +++ b/src/main/java/gregtech/api/util/CapesRegistry.java @@ -1,6 +1,5 @@ package gregtech.api.util; -import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.client.renderer.texture.Textures; import gregtech.core.network.packets.PacketNotifyCapeChange; @@ -214,13 +213,13 @@ public static void addFreeCape(ResourceLocation cape) { private static final List> ctRegisterCapes = new ArrayList<>(); private static final List ctFreeCapes = new ArrayList<>(); - @Optional.Method(modid = GTValues.MODID_CT) + @Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) @ZenMethod public static void registerCape(String advancement, String cape) { ctRegisterCapes.add(new Tuple<>(new ResourceLocation(advancement), new ResourceLocation(cape))); } - @Optional.Method(modid = GTValues.MODID_CT) + @Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) @ZenMethod public static void registerFreeCape(String cape) { ctFreeCapes.add(new ResourceLocation(cape)); diff --git a/src/main/java/gregtech/api/util/GTStringUtils.java b/src/main/java/gregtech/api/util/GTStringUtils.java index fdfbe1a999e..0e29f2643c3 100644 --- a/src/main/java/gregtech/api/util/GTStringUtils.java +++ b/src/main/java/gregtech/api/util/GTStringUtils.java @@ -97,8 +97,7 @@ public static String ticksToElapsedTime(int ticks) { } /** - * Draws a String centered within a given width. - * If the String exceeds the given width, it is cutoff + * Draws a String centered within a given width. If the String exceeds the given width, it is cutoff * * @param stringToDraw The String to draw * @param fontRenderer An instance of the MC FontRenderer @@ -115,4 +114,23 @@ public static void drawCenteredStringWithCutoff(String stringToDraw, FontRendere fontRenderer.drawString(stringToDraw, startPosition, 1, 0x111111); } + + /** + * Returns a new String with the character at the given index replaced with the given character + * + * @param str The original string whose character is to be replaced + * @param index The index of the character to be replaced + * @param replace The character to replace the character at the given index + * @return The new string with the character at the given index replaced with the given character + */ + public static String replace(String str, int index, char replace) { + if (str == null) { + return str; + } else if (index < 0 || index >= str.length()) { + return str; + } + char[] chars = str.toCharArray(); + chars[index] = replace; + return String.valueOf(chars); + } } diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index 2b95a31fe0f..553279c72f4 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -707,15 +707,19 @@ public static MetaTileEntity getMetaTileEntity(ItemStack stack) { return GregTechAPI.MTE_REGISTRY.getObjectById(stack.getItemDamage()); } - public static boolean canSeeSunClearly(World world, BlockPos blockPos) { - if (!world.canSeeSky(blockPos.up())) { + /** + * @param world the world containing the block + * @param blockPos the position of the block to check + * @return if the block can see the sun clearly + */ + public static boolean canSeeSunClearly(@NotNull World world, @NotNull BlockPos blockPos) { + BlockPos up = blockPos.up(); + if (!world.canSeeSky(up)) { return false; } - Biome biome = world.getBiome(blockPos.up()); - if (world.isRaining()) { - if (biome.canRain() || biome.getEnableSnow()) { - return false; - } + Biome biome = world.getBiome(up); + if (world.isRaining() && (biome.canRain() || biome.getEnableSnow())) { + return false; } Set biomeTypes = BiomeDictionary.getTypes(biome); if (biomeTypes.contains(BiomeDictionary.Type.END)) { diff --git a/src/main/java/gregtech/api/util/ModCompatibility.java b/src/main/java/gregtech/api/util/ModCompatibility.java index 9881948147d..d6b627d3b6a 100644 --- a/src/main/java/gregtech/api/util/ModCompatibility.java +++ b/src/main/java/gregtech/api/util/ModCompatibility.java @@ -1,66 +1,22 @@ package gregtech.api.util; -import gregtech.api.util.world.DummyWorld; +import gregtech.client.utils.ItemRenderCompat; import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import java.lang.reflect.Method; -import java.util.List; -import java.util.Objects; +import org.jetbrains.annotations.ApiStatus; @SideOnly(Side.CLIENT) public class ModCompatibility { - private static RefinedStorage refinedStorage; - - public static void initCompat() { - try { - Class itemClass = Class.forName("com.raoulvdberge.refinedstorage.item.ItemPattern"); - refinedStorage = new RefinedStorage(itemClass); - GTLog.logger.info("RefinedStorage found; enabling integration."); - } catch (ClassNotFoundException ignored) { - GTLog.logger.info("RefinedStorage not found; skipping integration."); - } catch (Throwable exception) { - GTLog.logger.error("Failed to enable RefinedStorage integration", exception); - } - } - + /** + * @deprecated Use {@link ItemRenderCompat#getRepresentedStack(ItemStack)} + */ + @ApiStatus.ScheduledForRemoval(inVersion = "2.10") + @Deprecated public static ItemStack getRealItemStack(ItemStack itemStack) { - if (refinedStorage != null && RefinedStorage.canHandleItemStack(itemStack)) { - return refinedStorage.getRealItemStack(itemStack); - } - return itemStack; - } - - private static class RefinedStorage { - - private final Method getPatternFromCacheMethod; - private final Method getOutputsMethod; - - public RefinedStorage(Class itemPatternClass) throws ReflectiveOperationException { - this.getPatternFromCacheMethod = itemPatternClass.getMethod("getPatternFromCache", World.class, - ItemStack.class); - this.getOutputsMethod = getPatternFromCacheMethod.getReturnType().getMethod("getOutputs"); - } - - public static boolean canHandleItemStack(ItemStack itemStack) { - ResourceLocation registryName = Objects.requireNonNull(itemStack.getItem().getRegistryName()); - return registryName.getNamespace().equals("refinedstorage") && - registryName.getPath().equals("pattern"); - } - - public ItemStack getRealItemStack(ItemStack itemStack) { - try { - Object craftingPattern = getPatternFromCacheMethod.invoke(null, DummyWorld.INSTANCE, itemStack); - List outputs = (List) getOutputsMethod.invoke(craftingPattern); - return outputs.isEmpty() ? itemStack : outputs.get(0); - } catch (ReflectiveOperationException ex) { - throw new RuntimeException("Failed to obtain item from ItemPattern", ex); - } - } + return ItemRenderCompat.getRepresentedStack(itemStack); } } diff --git a/src/main/java/gregtech/api/util/ModIncompatibilityException.java b/src/main/java/gregtech/api/util/ModIncompatibilityException.java new file mode 100644 index 00000000000..c21439cc5fe --- /dev/null +++ b/src/main/java/gregtech/api/util/ModIncompatibilityException.java @@ -0,0 +1,35 @@ +package gregtech.api.util; + +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiErrorScreen; +import net.minecraftforge.fml.client.CustomModLoadingErrorDisplayException; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import java.util.List; + +@SideOnly(Side.CLIENT) +public class ModIncompatibilityException extends CustomModLoadingErrorDisplayException { + + @SuppressWarnings("all") + private static final long serialVersionUID = 1L; + + private final List messages; + + public ModIncompatibilityException(List messages) { + this.messages = messages; + } + + @Override + public void initGui(GuiErrorScreen guiErrorScreen, FontRenderer fontRenderer) {} + + @Override + public void drawScreen(GuiErrorScreen errorScreen, FontRenderer fontRenderer, int mouseX, int mouseY, float time) { + int x = errorScreen.width / 2; + int y = 75; + for (String message : messages) { + errorScreen.drawCenteredString(fontRenderer, message, x, y, 0xFFFFFF); + y += 15; + } + } +} diff --git a/src/main/java/gregtech/api/util/Mods.java b/src/main/java/gregtech/api/util/Mods.java new file mode 100644 index 00000000000..c022672f095 --- /dev/null +++ b/src/main/java/gregtech/api/util/Mods.java @@ -0,0 +1,252 @@ +package gregtech.api.util; + +import gregtech.api.GTValues; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.ModContainer; +import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.relauncher.FMLLaunchHandler; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; + +public enum Mods { + + AdvancedRocketry(Names.ADVANCED_ROCKETRY), + AppliedEnergistics2(Names.APPLIED_ENERGISTICS2), + Baubles(Names.BAUBLES), + BinnieCore(Names.BINNIE_CORE), + BiomesOPlenty(Names.BIOMES_O_PLENTY), + BuildCraftCore(Names.BUILD_CRAFT_CORE), + Chisel(Names.CHISEL), + CoFHCore(Names.COFH_CORE), + CTM(Names.CONNECTED_TEXTURES_MOD), + CubicChunks(Names.CUBIC_CHUNKS), + CraftTweaker(Names.CRAFT_TWEAKER), + EnderCore(Names.ENDER_CORE), + EnderIO(Names.ENDER_IO), + ExtraBees(Names.EXTRA_BEES), + ExtraTrees(Names.EXTRA_TREES), + ExtraUtilities2(Names.EXTRA_UTILITIES2), + Forestry(Names.FORESTRY), + ForestryApiculture(Names.FORESTRY, forestryModule(Names.FORESTRY_APICULTURE)), + ForestryArboriculture(Names.FORESTRY, forestryModule(Names.FORESTRY_ARBORICULTURE)), + ForestryLepidopterology(Names.FORESTRY, forestryModule(Names.FORESTRY_LEPIDOPTEROLOGY)), + GalacticraftCore(Names.GALACTICRAFT_CORE), + Genetics(Names.GENETICS), + GregTech(Names.GREGTECH), + GregTechFoodOption(Names.GREGTECH_FOOD_OPTION), + GroovyScript(Names.GROOVY_SCRIPT), + GTCE2OC(Names.GTCE_2_OC), + HWYLA(Names.HWYLA), + ImmersiveEngineering(Names.IMMERSIVE_ENGINEERING), + IndustrialCraft2(Names.INDUSTRIAL_CRAFT2), + InventoryTweaks(Names.INVENTORY_TWEAKS), + JourneyMap(Names.JOURNEY_MAP), + JustEnoughItems(Names.JUST_ENOUGH_ITEMS), + MagicBees(Names.MAGIC_BEES), + Nothirium(Names.NOTHIRIUM), + NuclearCraft(Names.NUCLEAR_CRAFT, versionExcludes("2o")), + NuclearCraftOverhauled(Names.NUCLEAR_CRAFT, versionContains("2o")), + OpenComputers(Names.OPEN_COMPUTERS), + ProjectRedCore(Names.PROJECT_RED_CORE), + Railcraft(Names.RAILCRAFT), + RefinedStorage(Names.REFINED_STORAGE), + TechReborn(Names.TECH_REBORN), + TheOneProbe(Names.THE_ONE_PROBE), + TinkersConstruct(Names.TINKERS_CONSTRUCT), + TOPAddons(Names.TOP_ADDONS), + VoxelMap(Names.VOXEL_MAP), + XaerosMinimap(Names.XAEROS_MINIMAP), + + // Special Optifine handler, but consolidated here for simplicity + Optifine(null) { + + @Override + public boolean isModLoaded() { + if (this.modLoaded == null) { + try { + Class c = Class.forName("net.optifine.shaders.Shaders"); + Field f = c.getDeclaredField("shaderPackLoaded"); + f.setAccessible(true); + this.modLoaded = f.getBoolean(null); + } catch (Exception ignored) { + this.modLoaded = false; + } + } + return this.modLoaded; + } + }; + + public static class Names { + + public static final String ADVANCED_ROCKETRY = "advancedrocketry"; + public static final String APPLIED_ENERGISTICS2 = "appliedenergistics2"; + public static final String BAUBLES = "baubles"; + public static final String BINNIE_CORE = "binniecore"; + public static final String BIOMES_O_PLENTY = "biomesoplenty"; + public static final String BUILD_CRAFT_CORE = "buildcraftcore"; + public static final String CHISEL = "chisel"; + public static final String COFH_CORE = "cofhcore"; + public static final String CONNECTED_TEXTURES_MOD = "ctm"; + public static final String CUBIC_CHUNKS = "cubicchunks"; + public static final String CRAFT_TWEAKER = "crafttweaker"; + public static final String ENDER_CORE = "endercore"; + public static final String ENDER_IO = "enderio"; + public static final String EXTRA_BEES = "extrabees"; + public static final String EXTRA_TREES = "extratrees"; + public static final String EXTRA_UTILITIES2 = "extrautils2"; + public static final String FORESTRY = "forestry"; + public static final String FORESTRY_APICULTURE = "apiculture"; + public static final String FORESTRY_ARBORICULTURE = "arboriculture"; + public static final String FORESTRY_LEPIDOPTEROLOGY = "lepidopterology"; + public static final String GALACTICRAFT_CORE = "galacticraftcore"; + public static final String GENETICS = "genetics"; + public static final String GREGTECH = GTValues.MODID; + public static final String GREGTECH_FOOD_OPTION = "gregtechfoodoption"; + public static final String GROOVY_SCRIPT = "groovyscript"; + public static final String GTCE_2_OC = "gtce2oc"; + public static final String HWYLA = "hwyla"; + public static final String IMMERSIVE_ENGINEERING = "immersiveengineering"; + public static final String INDUSTRIAL_CRAFT2 = "ic2"; + public static final String INVENTORY_TWEAKS = "inventorytweaks"; + public static final String JOURNEY_MAP = "journeymap"; + public static final String JUST_ENOUGH_ITEMS = "jei"; + public static final String MAGIC_BEES = "magicbees"; + public static final String NOTHIRIUM = "nothirium"; + public static final String NUCLEAR_CRAFT = "nuclearcraft"; + public static final String OPEN_COMPUTERS = "opencomputers"; + public static final String PROJECT_RED_CORE = "projred-core"; + public static final String RAILCRAFT = "railcraft"; + public static final String REFINED_STORAGE = "refinedstorage"; + public static final String TECH_REBORN = "techreborn"; + public static final String THE_ONE_PROBE = "theoneprobe"; + public static final String TINKERS_CONSTRUCT = "tconstruct"; + public static final String TOP_ADDONS = "topaddons"; + public static final String VOXEL_MAP = "voxelmap"; + public static final String XAEROS_MINIMAP = "xaerominimap"; + } + + private final String ID; + private final Function extraCheck; + protected Boolean modLoaded; + + Mods(String ID) { + this.ID = ID; + this.extraCheck = null; + } + + /** + * @param extraCheck A supplier that can be used to test additional factors, such as + * checking if a mod is at a specific version, or a sub-mod is loaded. + * Used in cases like NC vs NCO, where the mod id is the same + * so the version has to be parsed to test which is loaded. + * Another case is checking for specific Forestry modules, checking + * if Forestry is loaded and if a specific module is enabled. + */ + Mods(String ID, Function extraCheck) { + this.ID = ID; + this.extraCheck = extraCheck; + } + + public boolean isModLoaded() { + if (this.modLoaded == null) { + this.modLoaded = Loader.isModLoaded(this.ID); + if (this.modLoaded) { + if (this.extraCheck != null && !this.extraCheck.apply(this)) { + this.modLoaded = false; + } + } + } + return this.modLoaded; + } + + /** + * Throw an exception if this mod is found to be loaded. + * This must be called in or after + * {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent}! + */ + public void throwIncompatibilityIfLoaded(String... customMessages) { + if (isModLoaded()) { + String modName = TextFormatting.BOLD + ID + TextFormatting.RESET; + List messages = new ArrayList<>(); + messages.add(modName + " mod detected, this mod is incompatible with GregTech CE Unofficial."); + messages.addAll(Arrays.asList(customMessages)); + if (FMLLaunchHandler.side() == Side.SERVER) { + throw new RuntimeException(String.join(",", messages)); + } else { + throwClientIncompatibility(messages); + } + } + } + + @SideOnly(Side.CLIENT) + private static void throwClientIncompatibility(List messages) { + throw new ModIncompatibilityException(messages); + } + + public ItemStack getItem(@NotNull String name) { + return getItem(name, 0, 1, null); + } + + @NotNull + public ItemStack getItem(@NotNull String name, int meta) { + return getItem(name, meta, 1, null); + } + + @NotNull + public ItemStack getItem(@NotNull String name, int meta, int amount) { + return getItem(name, meta, amount, null); + } + + @NotNull + public ItemStack getItem(@NotNull String name, int meta, int amount, @Nullable String nbt) { + if (!isModLoaded()) { + return ItemStack.EMPTY; + } + return GameRegistry.makeItemStack(ID + ":" + name, meta, amount, nbt); + } + + // Helpers for the extra checker + + /** Test if the mod version string contains the passed value. */ + private static Function versionContains(String versionPart) { + return mod -> { + if (mod.ID == null) return false; + if (!mod.isModLoaded()) return false; + ModContainer container = Loader.instance().getIndexedModList().get(mod.ID); + if (container == null) return false; + return container.getVersion().contains(versionPart); + }; + } + + /** Test if the mod version string does not contain the passed value. */ + private static Function versionExcludes(String versionPart) { + return mod -> { + if (mod.ID == null) return false; + if (!mod.isModLoaded()) return false; + ModContainer container = Loader.instance().getIndexedModList().get(mod.ID); + if (container == null) return false; + return !container.getVersion().contains(versionPart); + }; + } + + /** Test if a specific Forestry module is enabled. */ + private static Function forestryModule(String moduleID) { + if (Forestry.isModLoaded()) { + return mod -> forestry.modules.ModuleHelper.isEnabled(moduleID); + } else { + return $ -> false; + } + } +} diff --git a/src/main/java/gregtech/api/util/RelativeDirection.java b/src/main/java/gregtech/api/util/RelativeDirection.java index 1e4b2102761..02e4fb86c89 100644 --- a/src/main/java/gregtech/api/util/RelativeDirection.java +++ b/src/main/java/gregtech/api/util/RelativeDirection.java @@ -163,4 +163,116 @@ public static EnumFacing simulateAxisRotation(EnumFacing newFrontFacing, EnumFac return upwardsFacing.getOpposite(); } } + + /** + * Offset a BlockPos relatively in any direction by any amount. Pass negative values to offset down, right or + * backwards. + */ + public static BlockPos offsetPos(BlockPos pos, EnumFacing frontFacing, EnumFacing upwardsFacing, boolean isFlipped, + int upOffset, int leftOffset, int forwardOffset) { + if (upOffset == 0 && leftOffset == 0 && forwardOffset == 0) { + return pos; + } + + int oX = 0, oY = 0, oZ = 0; + final EnumFacing relUp = UP.getRelativeFacing(frontFacing, upwardsFacing, isFlipped); + oX += relUp.getXOffset() * upOffset; + oY += relUp.getYOffset() * upOffset; + oZ += relUp.getZOffset() * upOffset; + + final EnumFacing relLeft = LEFT.getRelativeFacing(frontFacing, upwardsFacing, isFlipped); + oX += relLeft.getXOffset() * leftOffset; + oY += relLeft.getYOffset() * leftOffset; + oZ += relLeft.getZOffset() * leftOffset; + + final EnumFacing relForward = FRONT.getRelativeFacing(frontFacing, upwardsFacing, isFlipped); + oX += relForward.getXOffset() * forwardOffset; + oY += relForward.getYOffset() * forwardOffset; + oZ += relForward.getZOffset() * forwardOffset; + + return pos.add(oX, oY, oZ); + } + + public static BlockPos setActualRelativeOffset(int x, int y, int z, EnumFacing facing, EnumFacing upwardsFacing, + boolean isFlipped, RelativeDirection[] structureDir) { + int[] c0 = new int[] { x, y, z }, c1 = new int[3]; + if (facing == EnumFacing.UP || facing == EnumFacing.DOWN) { + EnumFacing of = facing == EnumFacing.DOWN ? upwardsFacing : upwardsFacing.getOpposite(); + for (int i = 0; i < 3; i++) { + switch (structureDir[i].getActualFacing(of)) { + case UP -> c1[1] = c0[i]; + case DOWN -> c1[1] = -c0[i]; + case WEST -> c1[0] = -c0[i]; + case EAST -> c1[0] = c0[i]; + case NORTH -> c1[2] = -c0[i]; + case SOUTH -> c1[2] = c0[i]; + } + } + int xOffset = upwardsFacing.getXOffset(); + int zOffset = upwardsFacing.getZOffset(); + int tmp; + if (xOffset == 0) { + tmp = c1[2]; + c1[2] = zOffset > 0 ? c1[1] : -c1[1]; + c1[1] = zOffset > 0 ? -tmp : tmp; + } else { + tmp = c1[0]; + c1[0] = xOffset > 0 ? c1[1] : -c1[1]; + c1[1] = xOffset > 0 ? -tmp : tmp; + } + if (isFlipped) { + if (upwardsFacing == EnumFacing.NORTH || upwardsFacing == EnumFacing.SOUTH) { + c1[0] = -c1[0]; // flip X-axis + } else { + c1[2] = -c1[2]; // flip Z-axis + } + } + } else { + for (int i = 0; i < 3; i++) { + switch (structureDir[i].getActualFacing(facing)) { + case UP -> c1[1] = c0[i]; + case DOWN -> c1[1] = -c0[i]; + case WEST -> c1[0] = -c0[i]; + case EAST -> c1[0] = c0[i]; + case NORTH -> c1[2] = -c0[i]; + case SOUTH -> c1[2] = c0[i]; + } + } + if (upwardsFacing == EnumFacing.WEST || upwardsFacing == EnumFacing.EAST) { + int xOffset = upwardsFacing == EnumFacing.WEST ? facing.rotateY().getXOffset() : + facing.rotateY().getOpposite().getXOffset(); + int zOffset = upwardsFacing == EnumFacing.WEST ? facing.rotateY().getZOffset() : + facing.rotateY().getOpposite().getZOffset(); + int tmp; + if (xOffset == 0) { + tmp = c1[2]; + c1[2] = zOffset > 0 ? -c1[1] : c1[1]; + c1[1] = zOffset > 0 ? tmp : -tmp; + } else { + tmp = c1[0]; + c1[0] = xOffset > 0 ? -c1[1] : c1[1]; + c1[1] = xOffset > 0 ? tmp : -tmp; + } + } else if (upwardsFacing == EnumFacing.SOUTH) { + c1[1] = -c1[1]; + if (facing.getXOffset() == 0) { + c1[0] = -c1[0]; + } else { + c1[2] = -c1[2]; + } + } + if (isFlipped) { + if (upwardsFacing == EnumFacing.NORTH || upwardsFacing == EnumFacing.SOUTH) { + if (facing == EnumFacing.NORTH || facing == EnumFacing.SOUTH) { + c1[0] = -c1[0]; // flip X-axis + } else { + c1[2] = -c1[2]; // flip Z-axis + } + } else { + c1[1] = -c1[1]; // flip Y-axis + } + } + } + return new BlockPos(c1[0], c1[1], c1[2]); + } } diff --git a/src/main/java/gregtech/api/worldgen/config/WorldGenRegistry.java b/src/main/java/gregtech/api/worldgen/config/WorldGenRegistry.java index 2a30f9e1eeb..858f28bc328 100644 --- a/src/main/java/gregtech/api/worldgen/config/WorldGenRegistry.java +++ b/src/main/java/gregtech/api/worldgen/config/WorldGenRegistry.java @@ -3,6 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.util.FileUtility; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.api.worldgen.filler.BlacklistedBlockFiller; import gregtech.api.worldgen.filler.BlockFiller; import gregtech.api.worldgen.filler.LayeredBlockFiller; @@ -123,7 +124,7 @@ public void initializeRegistry() { } catch (IOException | RuntimeException exception) { GTLog.logger.fatal("Failed to initialize worldgen registry.", exception); } - if (Loader.isModLoaded("galacticraftcore")) { + if (Mods.GalacticraftCore.isModLoaded()) { try { Class transformerHooksClass = Class.forName("micdoodle8.mods.galacticraft.core.TransformerHooks"); Field otherModGeneratorsWhitelistField = transformerHooksClass diff --git a/src/main/java/gregtech/asm/GregTechTransformer.java b/src/main/java/gregtech/asm/GregTechTransformer.java index 4d98621cfa8..005ec295075 100644 --- a/src/main/java/gregtech/asm/GregTechTransformer.java +++ b/src/main/java/gregtech/asm/GregTechTransformer.java @@ -1,6 +1,6 @@ package gregtech.asm; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.asm.util.ObfMapping; import gregtech.asm.util.TargetClassVisitor; import gregtech.asm.visitors.*; @@ -8,8 +8,6 @@ import net.minecraft.launchwrapper.IClassTransformer; import net.minecraft.launchwrapper.Launch; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.common.ModContainer; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; @@ -136,13 +134,12 @@ public byte[] transform(String name, String transformedName, byte[] basicClass) ClassReader classReader = new ClassReader(basicClass); ClassWriter classWriter = new ClassWriter(0); - // fix NC recipe compat different depending on overhaul vs underhaul - ModContainer container = Loader.instance().getIndexedModList().get(GTValues.MODID_NC); - if (container.getVersion().contains("2o")) { // overhauled + // fix NC recipe compat different depending on overhaul vs normal + if (Mods.NuclearCraftOverhauled.isModLoaded()) { classReader.accept(new TargetClassVisitor(classWriter, NuclearCraftRecipeHelperVisitor.TARGET_METHOD_NCO, NuclearCraftRecipeHelperVisitor::new), 0); - } else { + } else if (Mods.NuclearCraft.isModLoaded()) { classReader.accept(new TargetClassVisitor(classWriter, NuclearCraftRecipeHelperVisitor.TARGET_METHOD_NC, NuclearCraftRecipeHelperVisitor::new), 0); } diff --git a/src/main/java/gregtech/asm/hooks/CTMHooks.java b/src/main/java/gregtech/asm/hooks/CTMHooks.java index 33ddc0d7754..bf254934d5c 100644 --- a/src/main/java/gregtech/asm/hooks/CTMHooks.java +++ b/src/main/java/gregtech/asm/hooks/CTMHooks.java @@ -1,6 +1,6 @@ package gregtech.asm.hooks; -import gregtech.client.shader.Shaders; +import gregtech.api.util.Mods; import gregtech.client.utils.BloomEffectUtil; import net.minecraft.block.state.IBlockState; @@ -20,7 +20,7 @@ public class CTMHooks { public static ThreadLocal ENABLE = new ThreadLocal<>(); public static boolean checkLayerWithOptiFine(boolean canRenderInLayer, byte layers, BlockRenderLayer layer) { - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { if (canRenderInLayer) { if (layer == BloomEffectUtil.getBloomLayer()) return false; } else if ((layers >> BloomEffectUtil.getBloomLayer().ordinal() & 1) == 1 && @@ -34,7 +34,7 @@ public static boolean checkLayerWithOptiFine(boolean canRenderInLayer, byte laye public static List getQuadsWithOptiFine(List ret, BlockRenderLayer layer, IBakedModel bakedModel, IBlockState state, EnumFacing side, long rand) { - if (Shaders.isOptiFineShaderPackLoaded() && CTMHooks.ENABLE.get() == null) { + if (Mods.Optifine.isModLoaded() && CTMHooks.ENABLE.get() == null) { if (layer == BloomEffectUtil.getBloomLayer()) { return Collections.emptyList(); } else if (layer == BloomEffectUtil.getEffectiveBloomLayer()) { @@ -43,7 +43,7 @@ public static List getQuadsWithOptiFine(List ret, BlockRen ForgeHooksClient.setRenderLayer(BloomEffectUtil.getBloomLayer()); result.addAll(bakedModel.getQuads(state, side, rand)); ForgeHooksClient.setRenderLayer(layer); - CTMHooks.ENABLE.set(null); + CTMHooks.ENABLE.remove(); return result; } } diff --git a/src/main/java/gregtech/asm/visitors/RenderItemVisitor.java b/src/main/java/gregtech/asm/visitors/RenderItemVisitor.java index f1b87a1fc12..750de53af3b 100644 --- a/src/main/java/gregtech/asm/visitors/RenderItemVisitor.java +++ b/src/main/java/gregtech/asm/visitors/RenderItemVisitor.java @@ -1,6 +1,6 @@ package gregtech.asm.visitors; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.asm.util.ObfMapping; import net.minecraftforge.fml.common.Loader; @@ -28,7 +28,7 @@ public static void transform(Iterator methods) { callRenderLampOverlay.add(new MethodInsnNode(INVOKESTATIC, "gregtech/asm/hooks/RenderItemHooks", "renderLampOverlay", "(Lnet/minecraft/item/ItemStack;II)V", false)); - boolean enderCoreLoaded = Loader.instance().getIndexedModList().containsKey(GTValues.MODID_ECORE); + boolean enderCoreLoaded = Loader.instance().getIndexedModList().containsKey(Mods.Names.ENDER_CORE); // do not conflict with EnderCore's changes, which already do what we need InsnList callRenderElectricBar; diff --git a/src/main/java/gregtech/client/ClientProxy.java b/src/main/java/gregtech/client/ClientProxy.java index 0210563b18c..7fb4773d478 100644 --- a/src/main/java/gregtech/client/ClientProxy.java +++ b/src/main/java/gregtech/client/ClientProxy.java @@ -10,12 +10,18 @@ import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.FluidTooltipUtil; import gregtech.api.util.IBlockOre; -import gregtech.api.util.ModCompatibility; +import gregtech.api.util.Mods; import gregtech.client.model.customtexture.CustomTextureModelHandler; import gregtech.client.model.customtexture.MetadataSectionCTM; import gregtech.client.renderer.handler.FacadeRenderer; import gregtech.client.renderer.handler.MetaTileEntityRenderer; -import gregtech.client.renderer.pipe.*; +import gregtech.client.renderer.pipe.CableRenderer; +import gregtech.client.renderer.pipe.FluidPipeRenderer; +import gregtech.client.renderer.pipe.ItemPipeRenderer; +import gregtech.client.renderer.pipe.LaserPipeRenderer; +import gregtech.client.renderer.pipe.OpticalPipeRenderer; +import gregtech.client.renderer.pipe.PipeRenderer; +import gregtech.client.utils.ItemRenderCompat; import gregtech.client.utils.TooltipHelper; import gregtech.common.CommonProxy; import gregtech.common.ConfigHolder; @@ -47,7 +53,6 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.IFluidBlock; import net.minecraftforge.fluids.capability.templates.FluidHandlerItemStack; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -72,7 +77,7 @@ public void onPreLoad() { SoundSystemConfig.setNumberNormalChannels(ConfigHolder.client.maxNumSounds); - if (!Loader.isModLoaded(GTValues.MODID_CTM)) { + if (!Mods.CTM.isModLoaded()) { Minecraft.getMinecraft().metadataSerializer.registerMetadataSectionType(new MetadataSectionCTM.Serializer(), MetadataSectionCTM.class); MinecraftForge.EVENT_BUS.register(CustomTextureModelHandler.INSTANCE); @@ -101,7 +106,7 @@ public void onLoad() { public void onPostLoad() { super.onPostLoad(); TerminalRegistry.initTerminalFiles(); - ModCompatibility.initCompat(); + ItemRenderCompat.init(); FacadeRenderer.init(); } diff --git a/src/main/java/gregtech/client/model/pipeline/VertexLighterFlatSpecial.java b/src/main/java/gregtech/client/model/pipeline/VertexLighterFlatSpecial.java index 75f05440797..9f8580344ec 100644 --- a/src/main/java/gregtech/client/model/pipeline/VertexLighterFlatSpecial.java +++ b/src/main/java/gregtech/client/model/pipeline/VertexLighterFlatSpecial.java @@ -1,6 +1,6 @@ package gregtech.client.model.pipeline; -import gregtech.client.shader.Shaders; +import gregtech.api.util.Mods; import net.minecraft.client.renderer.color.BlockColors; import net.minecraft.client.renderer.vertex.VertexFormat; @@ -134,7 +134,7 @@ protected void processQuad() { updateColor(normal[v], color[v], x, y, z, tint, multiplier); // When enabled this causes the rendering to be black with Optifine - if (!Shaders.isOptiFineShaderPackLoaded() && diffuse) { + if (!Mods.Optifine.isModLoaded() && diffuse) { float d = LightUtil.diffuseLight(normal[v][0], normal[v][1], normal[v][2]); for (int i = 0; i < 3; i++) { color[v][i] *= d; diff --git a/src/main/java/gregtech/client/model/pipeline/VertexLighterSmoothAoSpecial.java b/src/main/java/gregtech/client/model/pipeline/VertexLighterSmoothAoSpecial.java index 79b83e9998e..f1d6f852e3c 100644 --- a/src/main/java/gregtech/client/model/pipeline/VertexLighterSmoothAoSpecial.java +++ b/src/main/java/gregtech/client/model/pipeline/VertexLighterSmoothAoSpecial.java @@ -1,6 +1,6 @@ package gregtech.client.model.pipeline; -import gregtech.client.shader.Shaders; +import gregtech.api.util.Mods; import net.minecraft.client.renderer.color.BlockColors; import net.minecraft.util.math.MathHelper; @@ -15,7 +15,7 @@ public VertexLighterSmoothAoSpecial(BlockColors colors) { @Override protected void updateLightmap(float[] normal, float[] lightmap, float x, float y, float z) { - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { super.updateLightmap(normal, lightmap, x, y, z); return; } @@ -28,7 +28,7 @@ protected void updateLightmap(float[] normal, float[] lightmap, float x, float y protected void updateColor(float[] normal, float[] color, float x, float y, float z, float tint, int multiplier) { super.updateColor(normal, color, x, y, z, tint, multiplier); - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { return; } @@ -146,7 +146,7 @@ protected float getAo(float x, float y, float z) { @Override public void updateBlockInfo() { - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { super.updateBlockInfo(); return; } diff --git a/src/main/java/gregtech/client/renderer/handler/CCLBlockRenderer.java b/src/main/java/gregtech/client/renderer/handler/CCLBlockRenderer.java index 5dabff41d6a..e2046685f86 100644 --- a/src/main/java/gregtech/client/renderer/handler/CCLBlockRenderer.java +++ b/src/main/java/gregtech/client/renderer/handler/CCLBlockRenderer.java @@ -2,9 +2,9 @@ import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; -import gregtech.api.util.ModCompatibility; import gregtech.client.renderer.ICCLBlockRenderer; import gregtech.client.renderer.texture.Textures; +import gregtech.client.utils.ItemRenderCompat; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; @@ -60,10 +60,10 @@ public void onModelsBake(ModelBakeEvent event) { @Override public void renderItem(ItemStack rawStack, ItemCameraTransforms.TransformType transformType) { - ItemStack stack = ModCompatibility.getRealItemStack(rawStack); - if (stack.getItem() instanceof ItemBlock && - ((ItemBlock) stack.getItem()).getBlock() instanceof ICCLBlockRenderer) { - ((ICCLBlockRenderer) ((ItemBlock) stack.getItem()).getBlock()).renderItem(stack, transformType); + ItemStack stack = ItemRenderCompat.getRepresentedStack(rawStack); + if (stack.getItem() instanceof ItemBlock itemBlock && + itemBlock.getBlock() instanceof ICCLBlockRenderer renderer) { + renderer.renderItem(stack, transformType); } } diff --git a/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java b/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java index fcd0c3ba523..6db1848659a 100644 --- a/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java +++ b/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java @@ -2,11 +2,11 @@ import gregtech.api.cover.CoverUtil; import gregtech.api.items.metaitem.MetaItem; -import gregtech.api.util.ModCompatibility; import gregtech.client.model.pipeline.VertexLighterFlatSpecial; import gregtech.client.model.pipeline.VertexLighterSmoothAoSpecial; import gregtech.client.utils.AdvCCRSConsumer; import gregtech.client.utils.FacadeBlockAccess; +import gregtech.client.utils.ItemRenderCompat; import gregtech.common.covers.facade.FacadeHelper; import gregtech.common.items.behaviors.FacadeItem; @@ -82,7 +82,7 @@ public static void init() { @Override public void renderItem(ItemStack rawStack, ItemCameraTransforms.TransformType transformType) { - ItemStack itemStack = ModCompatibility.getRealItemStack(rawStack); + ItemStack itemStack = ItemRenderCompat.getRepresentedStack(rawStack); if (!(itemStack.getItem() instanceof MetaItem)) { return; } diff --git a/src/main/java/gregtech/client/renderer/handler/GTExplosiveRenderer.java b/src/main/java/gregtech/client/renderer/handler/GTExplosiveRenderer.java new file mode 100644 index 00000000000..4b0efe1ae63 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/handler/GTExplosiveRenderer.java @@ -0,0 +1,81 @@ +package gregtech.client.renderer.handler; + +import gregtech.common.entities.EntityGTExplosive; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BlockRendererDispatcher; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; + +@SideOnly(Side.CLIENT) +public class GTExplosiveRenderer extends Render { + + public GTExplosiveRenderer(RenderManager renderManager) { + super(renderManager); + this.shadowSize = 0.5F; + } + + @Override + public void doRender(@NotNull T entity, double x, double y, double z, float entityYaw, float partialTicks) { + BlockRendererDispatcher brd = Minecraft.getMinecraft().getBlockRendererDispatcher(); + GlStateManager.pushMatrix(); + GlStateManager.translate((float) x, (float) y + 0.5F, (float) z); + float f2; + if ((float) entity.getFuse() - partialTicks + 1.0F < 10.0F) { + f2 = 1.0F - ((float) entity.getFuse() - partialTicks + 1.0F) / 10.0F; + f2 = MathHelper.clamp(f2, 0.0F, 1.0F); + f2 *= f2; + f2 *= f2; + float f1 = 1.0F + f2 * 0.3F; + GlStateManager.scale(f1, f1, f1); + } + + f2 = (1.0F - ((float) entity.getFuse() - partialTicks + 1.0F) / 100.0F) * 0.8F; + this.bindEntityTexture(entity); + GlStateManager.rotate(-90.0F, 0.0F, 1.0F, 0.0F); + GlStateManager.translate(-0.5F, -0.5F, 0.5F); + + IBlockState state = entity.getExplosiveState(); + brd.renderBlockBrightness(state, entity.getBrightness()); + GlStateManager.translate(0.0F, 0.0F, 1.0F); + if (this.renderOutlines) { + GlStateManager.enableColorMaterial(); + GlStateManager.enableOutlineMode(this.getTeamColor(entity)); + brd.renderBlockBrightness(state, 1.0F); + GlStateManager.disableOutlineMode(); + GlStateManager.disableColorMaterial(); + } else if (entity.getFuse() / 5 % 2 == 0) { + GlStateManager.disableTexture2D(); + GlStateManager.disableLighting(); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.DST_ALPHA); + GlStateManager.color(1.0F, 1.0F, 1.0F, f2); + GlStateManager.doPolygonOffset(-3.0F, -3.0F); + GlStateManager.enablePolygonOffset(); + brd.renderBlockBrightness(state, 1.0F); + GlStateManager.doPolygonOffset(0.0F, 0.0F); + GlStateManager.disablePolygonOffset(); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.disableBlend(); + GlStateManager.enableLighting(); + GlStateManager.enableTexture2D(); + } + + GlStateManager.popMatrix(); + super.doRender(entity, x, y, z, entityYaw, partialTicks); + } + + @Override + protected ResourceLocation getEntityTexture(@NotNull T entity) { + return TextureMap.LOCATION_BLOCKS_TEXTURE; + } +} diff --git a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java index 5aa513fea8c..8e0fe1f6962 100644 --- a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java +++ b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java @@ -4,9 +4,9 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; -import gregtech.api.util.ModCompatibility; import gregtech.client.renderer.CubeRendererState; import gregtech.client.renderer.texture.Textures; +import gregtech.client.utils.ItemRenderCompat; import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.BufferBuilder; @@ -72,7 +72,7 @@ public void onModelsBake(ModelBakeEvent event) { @Override public void renderItem(ItemStack rawStack, TransformType transformType) { - ItemStack stack = ModCompatibility.getRealItemStack(rawStack); + ItemStack stack = ItemRenderCompat.getRepresentedStack(rawStack); MetaTileEntity metaTileEntity = GTUtility.getMetaTileEntity(stack); if (metaTileEntity == null) { return; @@ -94,7 +94,7 @@ public void renderItem(ItemStack rawStack, TransformType transformType) { @Override public boolean renderBlock(IBlockAccess world, BlockPos pos, IBlockState state, BufferBuilder buffer) { MetaTileEntity metaTileEntity = GTUtility.getMetaTileEntity(world, pos); - if (metaTileEntity == null) { + if (metaTileEntity == null || !metaTileEntity.isValid()) { return false; } CCRenderState renderState = CCRenderState.instance(); @@ -115,7 +115,7 @@ public boolean renderBlock(IBlockAccess world, BlockPos pos, IBlockState state, metaTileEntity.renderCovers(renderState, translation.copy(), renderLayer); - Textures.RENDER_STATE.set(null); + Textures.RENDER_STATE.remove(); return true; } diff --git a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityTESR.java b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityTESR.java index c22b454748a..04f29382669 100644 --- a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityTESR.java +++ b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityTESR.java @@ -46,12 +46,12 @@ public void render(@NotNull MetaTileEntityHolder te, double x, double y, double buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); MetaTileEntity metaTileEntity = te.getMetaTileEntity(); - if (metaTileEntity instanceof IFastRenderMetaTileEntity) { + if (metaTileEntity instanceof IFastRenderMetaTileEntity fastRender) { CCRenderState renderState = CCRenderState.instance(); renderState.reset(); renderState.bind(buffer); renderState.setBrightness(te.getWorld(), te.getPos()); - ((IFastRenderMetaTileEntity) metaTileEntity).renderMetaTileEntityFast(renderState, + fastRender.renderMetaTileEntityFast(renderState, new Matrix4().translate(x, y, z), partialTicks); } if (metaTileEntity != null) { diff --git a/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java b/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java index 632bdad8f2b..e3195dba22c 100644 --- a/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java +++ b/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java @@ -11,9 +11,9 @@ import gregtech.api.unification.material.Material; import gregtech.api.unification.material.info.MaterialIconType; import gregtech.api.util.GTUtility; -import gregtech.api.util.ModCompatibility; import gregtech.client.renderer.CubeRendererState; import gregtech.client.renderer.texture.Textures; +import gregtech.client.utils.ItemRenderCompat; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; @@ -150,7 +150,7 @@ public abstract void buildRenderer(PipeRenderContext renderContext, BlockPipe boxFacingMap = new EnumMap<>(EnumFacing.class); + private static final TextTexture textRenderer = new TextTexture().setWidth(32); + @SideOnly(Side.CLIENT) private TextureAtlasSprite glassTexture; @@ -62,30 +68,48 @@ public void registerIcons(TextureMap textureMap) { .registerSprite(new ResourceLocation("gregtech:blocks/overlay/machine/overlay_screen_glass")); } - public void renderMachine(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline, - EnumFacing frontFacing, int tier) { + public void renderMachine(CCRenderState renderState, + Matrix4 translation, + IVertexOperation[] pipeline, + T mte) { + EnumFacing frontFacing = mte.getFrontFacing(); + int tier = mte.getTier(); Textures.renderFace(renderState, translation, pipeline, frontFacing, glassBox, glassTexture, BlockRenderLayer.CUTOUT_MIPPED); TextureAtlasSprite hullTexture = Textures.VOLTAGE_CASINGS[tier] .getSpriteOnSide(RenderSide.bySide(EnumFacing.NORTH)); - boxFacingMap.keySet().forEach(facing -> { - for (EnumFacing box : EnumFacing.VALUES) { - if ((facing != frontFacing || box != frontFacing) && - (facing != EnumFacing.DOWN || box.getAxis().isVertical())) { // Don't render the front facing - // box from the front, nor allow - // Z-fighting to occur on the - // bottom - Textures.renderFace(renderState, translation, pipeline, facing, boxFacingMap.get(box), hullTexture, - BlockRenderLayer.CUTOUT_MIPPED); - } - } - }); + + for (var facing : boxFacingMap.keySet()) { + // do not render the box at the front face when "facing" is "frontFacing" + if (facing == frontFacing) continue; + + // render when the box face matches facing + Textures.renderFace(renderState, translation, pipeline, facing, boxFacingMap.get(facing), + hullTexture, BlockRenderLayer.CUTOUT_MIPPED); + + // render when the box face is opposite of facing + Textures.renderFace(renderState, translation, pipeline, facing.getOpposite(), boxFacingMap.get(facing), + hullTexture, BlockRenderLayer.CUTOUT_MIPPED); + } + + // render the sides of the box that face the front face + if (frontFacing.getAxis() == EnumFacing.Axis.Y) return; + Textures.renderFace(renderState, translation, pipeline, frontFacing, boxFacingMap.get(EnumFacing.DOWN), + hullTexture, BlockRenderLayer.CUTOUT_MIPPED); + Textures.renderFace(renderState, translation, pipeline, frontFacing, boxFacingMap.get(EnumFacing.UP), + hullTexture, BlockRenderLayer.CUTOUT_MIPPED); + + EnumFacing facing = frontFacing.rotateYCCW(); + Textures.renderFace(renderState, translation, pipeline, frontFacing, boxFacingMap.get(facing), + hullTexture, BlockRenderLayer.CUTOUT_MIPPED); + Textures.renderFace(renderState, translation, pipeline, frontFacing, boxFacingMap.get(facing.getOpposite()), + hullTexture, BlockRenderLayer.CUTOUT_MIPPED); } public static void renderChestStack(double x, double y, double z, MetaTileEntityQuantumChest machine, ItemStack stack, long count, float partialTicks) { - if (stack.isEmpty() || count == 0) + if (!ConfigHolder.client.enableFancyChestRender || stack.isEmpty() || count == 0) return; float lastBrightnessX = OpenGlHelper.lastBrightnessX; @@ -93,15 +117,19 @@ public static void renderChestStack(double x, double y, double z, MetaTileEntity World world = machine.getWorld(); setLightingCorrectly(world, machine.getPos()); EnumFacing frontFacing = machine.getFrontFacing(); - RenderItem itemRenderer = Minecraft.getMinecraft().getRenderItem(); - float tick = world.getWorldTime() + partialTicks; - GlStateManager.pushMatrix(); - GlStateManager.translate(x, y, z); - GlStateManager.translate(0.5D, 0.5D, 0.5D); - GlStateManager.rotate(tick * (float) Math.PI * 2 / 40, 0, 1, 0); - GlStateManager.scale(0.6f, 0.6f, 0.6f); - itemRenderer.renderItem(stack, ItemCameraTransforms.TransformType.FIXED); - GlStateManager.popMatrix(); + + if (canRender(x, y, z, 8 * + MathHelper.clamp((double) Minecraft.getMinecraft().gameSettings.renderDistanceChunks / 8, 1.0, 2.5))) { + RenderItem itemRenderer = Minecraft.getMinecraft().getRenderItem(); + float tick = world.getWorldTime() + partialTicks; + GlStateManager.pushMatrix(); + GlStateManager.translate(x, y, z); + GlStateManager.translate(0.5D, 0.5D, 0.5D); + GlStateManager.rotate(tick * (float) Math.PI * 2 / 40, 0, 1, 0); + GlStateManager.scale(0.6f, 0.6f, 0.6f); + itemRenderer.renderItem(stack, ItemCameraTransforms.TransformType.FIXED); + GlStateManager.popMatrix(); + } OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); renderAmountText(x, y, z, count, frontFacing); @@ -110,20 +138,20 @@ public static void renderChestStack(double x, double y, double z, MetaTileEntity public static void renderTankFluid(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline, FluidTank tank, IBlockAccess world, BlockPos pos, EnumFacing frontFacing) { - float lastBrightnessX = OpenGlHelper.lastBrightnessX; - float lastBrightnessY = OpenGlHelper.lastBrightnessY; + FluidStack stack = tank.getFluid(); + if (stack == null || stack.amount == 0 || !ConfigHolder.client.enableFancyChestRender) + return; + if (world != null) { renderState.setBrightness(world, pos); } - FluidStack stack = tank.getFluid(); - if (stack == null || stack.amount == 0) - return; Cuboid6 partialFluidBox = new Cuboid6(1.0625 / 16.0, 2.0625 / 16.0, 1.0625 / 16.0, 14.9375 / 16.0, 14.9375 / 16.0, 14.9375 / 16.0); double fillFraction = (double) stack.amount / tank.getCapacity(); - if (tank.getFluid().getFluid().isGaseous()) { + boolean gas = stack.getFluid().isGaseous(); + if (gas) { partialFluidBox.min.y = Math.max(13.9375 - (11.875 * fillFraction), 2.0) / 16.0; } else { partialFluidBox.max.y = Math.min((11.875 * fillFraction) + 2.0625, 14.0) / 16.0; @@ -133,15 +161,34 @@ public static void renderTankFluid(CCRenderState renderState, Matrix4 translatio ResourceLocation fluidStill = stack.getFluid().getStill(stack); TextureAtlasSprite fluidStillSprite = Minecraft.getMinecraft().getTextureMapBlocks() .getAtlasSprite(fluidStill.toString()); - for (EnumFacing facing : EnumFacing.VALUES) { - Textures.renderFace(renderState, translation, pipeline, facing, partialFluidBox, fluidStillSprite, - BlockRenderLayer.CUTOUT_MIPPED); - } + + Textures.renderFace(renderState, translation, pipeline, frontFacing, partialFluidBox, fluidStillSprite, + BlockRenderLayer.CUTOUT_MIPPED); + + Textures.renderFace(renderState, translation, pipeline, gas ? EnumFacing.DOWN : EnumFacing.UP, partialFluidBox, + fluidStillSprite, + BlockRenderLayer.CUTOUT_MIPPED); + GlStateManager.resetColor(); renderState.reset(); } + /** + * Takes in the difference in x, y, and z from the camera to the rendering TE and + * calculates the squared distance and checks if it's within the range squared + * + * @param x the difference in x from entity to this rendering TE + * @param y the difference in y from entity to this rendering TE + * @param z the difference in z from entity to this rendering TE + * @param range distance needed to be rendered + * @return true if the camera is within the given range, otherwise false + */ + public static boolean canRender(double x, double y, double z, double range) { + double distance = (x * x) + (y * y) + (z * z); + return distance < range * range; + } + public static void renderTankAmount(double x, double y, double z, EnumFacing frontFacing, long amount) { float lastBrightnessX = OpenGlHelper.lastBrightnessX; float lastBrightnessY = OpenGlHelper.lastBrightnessY; @@ -153,6 +200,9 @@ public static void renderTankAmount(double x, double y, double z, EnumFacing fro } public static void renderAmountText(double x, double y, double z, long amount, EnumFacing frontFacing) { + if (!ConfigHolder.client.enableFancyChestRender || !canRender(x, y, z, 64)) + return; + GlStateManager.pushMatrix(); GlStateManager.translate(x, y, z); GlStateManager.translate(frontFacing.getXOffset() * -1 / 16f, frontFacing.getYOffset() * -1 / 16f, @@ -167,7 +217,8 @@ public static void renderAmountText(double x, double y, double z, long amount, E GlStateManager.scale(1f / 64, 1f / 64, 0); GlStateManager.translate(-32, -32, 0); GlStateManager.disableLighting(); - new TextTexture(amountText, 0xFFFFFF).draw(0, 24, 64, 28); + textRenderer.setText(amountText); + textRenderer.draw(0, 24, 64, 28); GlStateManager.enableLighting(); GlStateManager.popMatrix(); } diff --git a/src/main/java/gregtech/client/shader/Shaders.java b/src/main/java/gregtech/client/shader/Shaders.java index e1eb6ef0474..1d20438bbbb 100644 --- a/src/main/java/gregtech/client/shader/Shaders.java +++ b/src/main/java/gregtech/client/shader/Shaders.java @@ -2,6 +2,7 @@ import gregtech.api.GTValues; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import net.minecraft.client.Minecraft; @@ -15,11 +16,10 @@ import codechicken.lib.render.shader.ShaderObject; import codechicken.lib.render.shader.ShaderProgram; +import org.jetbrains.annotations.ApiStatus; -import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; -import java.util.function.BooleanSupplier; import java.util.function.Consumer; import static codechicken.lib.render.shader.ShaderHelper.getStream; @@ -57,35 +57,12 @@ public class Shaders { public static ShaderObject S_BLUR; public static ShaderObject COMPOSITE; - // OptiFine - private static BooleanSupplier isShaderPackLoaded; - static { mc = Minecraft.getMinecraft(); FULL_IMAGE_PROGRAMS = new HashMap<>(); if (allowedShader()) { initShaders(); } - try { // hook optFine. thanks to Scannable. - final Class clazz = Class.forName("net.optifine.shaders.Shaders"); - final Field shaderPackLoaded = clazz.getDeclaredField("shaderPackLoaded"); - shaderPackLoaded.setAccessible(true); - isShaderPackLoaded = () -> { - try { - return shaderPackLoaded.getBoolean(null); - } catch (final IllegalAccessException e) { - GTLog.logger.warn( - "Failed reading field indicating whether shaders are enabled. Shader mod integration disabled."); - isShaderPackLoaded = null; - return false; - } - }; - GTLog.logger.info("Find optiFine mod loaded."); - } catch (ClassNotFoundException e) { - GTLog.logger.info("No optiFine mod found."); - } catch (NoSuchFieldException | NoClassDefFoundError e) { - GTLog.logger.warn("Failed integrating with shader mod. Ignoring."); - } } public static void initShaders() { @@ -128,8 +105,11 @@ public static boolean allowedShader() { return OpenGlHelper.shadersSupported && ConfigHolder.client.shader.useShader; } + /** @deprecated Use {@link Mods#Optifine} to check this instead. */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public static boolean isOptiFineShaderPackLoaded() { - return isShaderPackLoaded != null && isShaderPackLoaded.getAsBoolean(); + return Mods.Optifine.isModLoaded(); } public static Framebuffer renderFullImageInFBO(Framebuffer fbo, ShaderObject frag, diff --git a/src/main/java/gregtech/client/utils/BloomEffectUtil.java b/src/main/java/gregtech/client/utils/BloomEffectUtil.java index d1ac6f07cc0..2dcc7d0be14 100644 --- a/src/main/java/gregtech/client/utils/BloomEffectUtil.java +++ b/src/main/java/gregtech/client/utils/BloomEffectUtil.java @@ -1,6 +1,7 @@ package gregtech.client.utils; import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.util.Mods; import gregtech.client.particle.GTParticle; import gregtech.client.renderer.IRenderSetup; import gregtech.client.shader.Shaders; @@ -20,7 +21,6 @@ import net.minecraft.launchwrapper.Launch; import net.minecraft.util.BlockRenderLayer; import net.minecraftforge.common.util.EnumHelper; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -101,7 +101,7 @@ public static BlockRenderLayer getEffectiveBloomLayer() { */ @Contract("null -> _; !null -> !null") public static BlockRenderLayer getEffectiveBloomLayer(BlockRenderLayer fallback) { - return Shaders.isOptiFineShaderPackLoaded() ? fallback : bloom; + return Mods.Optifine.isModLoaded() ? fallback : bloom; } /** @@ -133,7 +133,7 @@ public static BlockRenderLayer getEffectiveBloomLayer(boolean isBloomActive) { */ @Contract("_, null -> _; _, !null -> !null") public static BlockRenderLayer getEffectiveBloomLayer(boolean isBloomActive, BlockRenderLayer fallback) { - return Shaders.isOptiFineShaderPackLoaded() || !isBloomActive ? fallback : bloom; + return Mods.Optifine.isModLoaded() || !isBloomActive ? fallback : bloom; } /** @@ -221,7 +221,7 @@ public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup @NotNull BloomType bloomType, @NotNull IBloomEffect render, @Nullable Predicate validityChecker) { - if (Shaders.isOptiFineShaderPackLoaded()) return null; + if (Mods.Optifine.isModLoaded()) return null; BloomRenderTicket ticket = new BloomRenderTicket(setup, bloomType, render, validityChecker); SCHEDULED_BLOOM_RENDERS.add(ticket); return ticket; @@ -253,7 +253,7 @@ public boolean test(BloomRenderTicket bloomRenderTicket) { public static void init() { bloom = EnumHelper.addEnum(BlockRenderLayer.class, "BLOOM", new Class[] { String.class }, "Bloom"); BLOOM = bloom; - if (Loader.isModLoaded("nothirium")) { + if (Mods.Nothirium.isModLoaded()) { try { // Nothirium hard copies the BlockRenderLayer enum into a ChunkRenderPass enum. Add our BLOOM layer to // that too. @@ -285,7 +285,7 @@ public static int renderBloomBlockLayer(RenderGlobal renderGlobal, Minecraft mc = Minecraft.getMinecraft(); mc.profiler.endStartSection("BTLayer"); - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { return renderGlobal.renderBlockLayer(blockRenderLayer, partialTicks, pass, entity); } diff --git a/src/main/java/gregtech/client/utils/DepthTextureUtil.java b/src/main/java/gregtech/client/utils/DepthTextureUtil.java index 3aa59bf75b4..d3bd1c4f06d 100644 --- a/src/main/java/gregtech/client/utils/DepthTextureUtil.java +++ b/src/main/java/gregtech/client/utils/DepthTextureUtil.java @@ -1,6 +1,6 @@ package gregtech.client.utils; -import gregtech.client.shader.Shaders; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import net.minecraft.client.Minecraft; @@ -40,7 +40,7 @@ public class DepthTextureUtil { private static int lastWidth, lastHeight; private static boolean shouldRenderDepthTexture() { - return lastBind && !Shaders.isOptiFineShaderPackLoaded() && ConfigHolder.client.hookDepthTexture && + return lastBind && !Mods.Optifine.isModLoaded() && ConfigHolder.client.hookDepthTexture && OpenGlHelper.isFramebufferEnabled(); } diff --git a/src/main/java/gregtech/client/utils/ItemRenderCompat.java b/src/main/java/gregtech/client/utils/ItemRenderCompat.java new file mode 100644 index 00000000000..4ea385c8910 --- /dev/null +++ b/src/main/java/gregtech/client/utils/ItemRenderCompat.java @@ -0,0 +1,169 @@ +package gregtech.client.utils; + +import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; +import gregtech.api.util.world.DummyWorld; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import appeng.items.misc.ItemEncodedPattern; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Method; +import java.util.List; + +public final class ItemRenderCompat { + + private static @Nullable ItemRenderCompat.RepresentativeStackExtractor rsHandler; + private static @Nullable ItemRenderCompat.RepresentativeStackExtractor ae2Handler; + + private ItemRenderCompat() {} + + @ApiStatus.Internal + public static void init() { + ae2Handler = AE2StackExtractor.create(); + rsHandler = RSStackExtractor.create(); + } + + /** + * Attempts to retrieve the actual ItemStack another stack represents. + *

+ * Primarily used to retrieve the output stack from AE2 or RS Patterns. + * + * @param stack the stack to retrieve from + * @return the actual represented ItemStack + */ + public static @NotNull ItemStack getRepresentedStack(@NotNull ItemStack stack) { + if (ae2Handler != null && ae2Handler.canHandleStack(stack)) { + return ae2Handler.getActualStack(stack); + } + if (rsHandler != null && rsHandler.canHandleStack(stack)) { + return rsHandler.getActualStack(stack); + } + return stack; + } + + /** + * An extractor to retrieve a represented stack from an ItemStack + */ + public interface RepresentativeStackExtractor { + + /** + * @param stack the stack to test + * @return if the extractor can handle the stack + */ + boolean canHandleStack(@NotNull ItemStack stack); + + /** + * @param stack the stack to retrieve from + * @return the represented stack + */ + @NotNull + ItemStack getActualStack(@NotNull ItemStack stack); + } + + /** + * Extracts the output stack from AE2 Patterns + */ + private static final class AE2StackExtractor implements RepresentativeStackExtractor { + + public static @Nullable ItemRenderCompat.AE2StackExtractor create() { + if (!Mods.AppliedEnergistics2.isModLoaded()) return null; + GTLog.logger.info("AppliedEnergistics2 found; enabling render integration."); + return new AE2StackExtractor(); + } + + @Override + public boolean canHandleStack(@NotNull ItemStack stack) { + return stack.getItem() instanceof ItemEncodedPattern; + } + + @Override + public @NotNull ItemStack getActualStack(@NotNull ItemStack stack) { + if (stack.isEmpty()) return ItemStack.EMPTY; + if (stack.getItem() instanceof ItemEncodedPattern encodedPattern) { + return encodedPattern.getOutput(stack); + } + return stack; + } + } + + /** + * Extracts the output stack from RS Patterns + */ + @SuppressWarnings("ClassCanBeRecord") + private static final class RSStackExtractor implements RepresentativeStackExtractor { + + private final MethodHandle getPatternFromCacheHandle; + private final MethodHandle getOutputsHandle; + private final Class itemPatternClass; + + private RSStackExtractor(MethodHandle getPatternFromCacheHandle, MethodHandle getOutputsHandle, + Class itemPatternClass) { + this.getPatternFromCacheHandle = getPatternFromCacheHandle; + this.getOutputsHandle = getOutputsHandle; + this.itemPatternClass = itemPatternClass; + } + + public static @Nullable ItemRenderCompat.RSStackExtractor create() { + if (!Mods.RefinedStorage.isModLoaded()) return null; + + Class clazz; + try { + clazz = Class.forName("com.raoulvdberge.refinedstorage.item.ItemPattern"); + GTLog.logger.info("RefinedStorage found; enabling render integration."); + } catch (ClassNotFoundException ignored) { + GTLog.logger.error("RefinedStorage classes not found; skipping render integration."); + return null; + } + + try { + Method method = clazz.getMethod("getPatternFromCache", World.class, ItemStack.class); + + MethodHandles.Lookup lookup = MethodHandles.publicLookup(); + + MethodHandle getPatternFromCacheHandle = lookup.unreflect(method); + + method = method.getReturnType().getMethod("getOutputs"); + MethodHandle getOutputsHandle = lookup.unreflect(method); + + return new RSStackExtractor(getPatternFromCacheHandle, getOutputsHandle, clazz); + } catch (NoSuchMethodException | IllegalAccessException e) { + GTLog.logger.error("Failed to enable RefinedStorage integration", e); + return null; + } + } + + @Override + public boolean canHandleStack(@NotNull ItemStack stack) { + return itemPatternClass.isAssignableFrom(stack.getItem().getClass()); + } + + @SuppressWarnings("unchecked") + @Override + public @NotNull ItemStack getActualStack(@NotNull ItemStack stack) { + if (stack.isEmpty()) return ItemStack.EMPTY; + + List outputs; + try { + // ItemPattern.getPatternFromCache: (World, ItemStack) -> CraftingPattern + Object craftingPattern = getPatternFromCacheHandle.invoke(DummyWorld.INSTANCE, stack); + // CraftingPattern#getOutputs: () -> List + outputs = (List) getOutputsHandle.invoke(craftingPattern); + } catch (Throwable e) { + GTLog.logger.error("Failed to obtain item from ItemPattern", e); + return stack; + } + + if (outputs.isEmpty()) { + return stack; + } + return outputs.get(0); + } + } +} diff --git a/src/main/java/gregtech/client/utils/RenderUtil.java b/src/main/java/gregtech/client/utils/RenderUtil.java index ed91be4e57e..070ff054c10 100644 --- a/src/main/java/gregtech/client/utils/RenderUtil.java +++ b/src/main/java/gregtech/client/utils/RenderUtil.java @@ -153,6 +153,9 @@ public static void useStencil(Runnable mask, Runnable renderInMask, boolean shou renderInMask.run(); GL11.glDisable(GL11.GL_STENCIL_TEST); + GL11.glClearStencil(0); + GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT); + GL11.glStencilFunc(GL11.GL_ALWAYS, 0, 0xFF); } public static void useLightMap(float x, float y, Runnable codeBlock) { diff --git a/src/main/java/gregtech/common/CommonProxy.java b/src/main/java/gregtech/common/CommonProxy.java index 4c583437a4a..3eeb6685922 100644 --- a/src/main/java/gregtech/common/CommonProxy.java +++ b/src/main/java/gregtech/common/CommonProxy.java @@ -156,6 +156,8 @@ public static void registerBlocks(RegistryEvent.Register event) { registry.register(RUBBER_WOOD_DOOR); registry.register(TREATED_WOOD_DOOR); registry.register(BRITTLE_CHARCOAL); + registry.register(POWDERBARREL); + registry.register(ITNT); registry.register(METAL_SHEET); registry.register(LARGE_METAL_SHEET); registry.register(STUDS); @@ -281,6 +283,8 @@ public static void registerItems(RegistryEvent.Register event) { registry.register(createItemBlock(RUBBER_LOG, ItemBlock::new)); registry.register(createItemBlock(RUBBER_LEAVES, ItemBlock::new)); registry.register(createItemBlock(RUBBER_SAPLING, ItemBlock::new)); + registry.register(createItemBlock(POWDERBARREL, ItemBlock::new)); + registry.register(createItemBlock(ITNT, ItemBlock::new)); for (BlockCompressed block : COMPRESSED_BLOCKS) { registry.register(createItemBlock(block, b -> new MaterialItemBlock(b, OrePrefix.block))); diff --git a/src/main/java/gregtech/common/ConfigHolder.java b/src/main/java/gregtech/common/ConfigHolder.java index 54863fecb57..27f1ab4e170 100644 --- a/src/main/java/gregtech/common/ConfigHolder.java +++ b/src/main/java/gregtech/common/ConfigHolder.java @@ -90,6 +90,9 @@ public static class MachineOptions { "1.0 means 1L Steam -> 1 EU. 0.5 means 2L Steam -> 1 EU.", "Default: 0.5" }) public double multiblockSteamToEU = 0.5; + @Config.Comment({ "Nuclear Max Power multiplier for balancing purposes", "Default: 2.0" }) + public double nuclearPowerMultiplier = 2.0; + @Config.Comment({ "Whether machines or boilers damage the terrain when they explode.", "Note machines and boilers always explode when overloaded with power or met with special conditions, regardless of this config.", "Default: true" }) @@ -156,6 +159,11 @@ public static class MachineOptions { "Default: false" }) @Config.RequiresMcRestart public boolean highTierContent = false; + + @Config.Comment({ "Whether tick acceleration effects are allowed to affect GT machines.", + "This does NOT apply to the World Accelerator, but to external effects like Time in a Bottle.", + "Default: true" }) + public boolean allowTickAcceleration = true; } public static class WorldGenOptions { @@ -399,7 +407,7 @@ public static class ClientOptions { @Config.Comment({ "Whether or not to enable Emissive Textures for Electric Blast Furnace Coils when the multiblock is working.", - "Default: false" }) + "Default: true" }) public boolean coilsActiveEmissiveTextures = true; @Config.Comment({ "Whether or not sounds should be played when using tools outside of crafting.", @@ -451,6 +459,10 @@ public static class ClientOptions { @Config.Comment({ "Prevent optical and laser cables from animating when active.", "Default: false" }) public boolean preventAnimatedCables = false; + @Config.Comment({ "Enable the fancy rendering for Super/Quantum Chests/Tanks.", + "Default: true" }) + public boolean enableFancyChestRender = true; + public static class GuiConfig { @Config.Comment({ "The scrolling speed of widgets", "Default: 13" }) diff --git a/src/main/java/gregtech/common/EventHandlers.java b/src/main/java/gregtech/common/EventHandlers.java index da32dd83ca5..8fa23091b99 100644 --- a/src/main/java/gregtech/common/EventHandlers.java +++ b/src/main/java/gregtech/common/EventHandlers.java @@ -12,8 +12,10 @@ import gregtech.api.util.BlockUtility; import gregtech.api.util.CapesRegistry; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.api.util.VirtualTankRegistry; import gregtech.api.worldgen.bedrockFluids.BedrockFluidVeinSaveData; +import gregtech.common.entities.EntityGTExplosive; import gregtech.common.items.MetaItems; import gregtech.common.items.armor.IStepAssist; import gregtech.common.items.armor.PowerlessJetpack; @@ -22,10 +24,12 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.client.entity.EntityOtherPlayerMP; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.ai.attributes.IAttributeInstance; +import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.monster.EntityEnderman; import net.minecraft.entity.monster.EntityZombie; import net.minecraft.entity.player.EntityPlayer; @@ -48,6 +52,7 @@ import net.minecraftforge.event.entity.player.AdvancementEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.furnace.FurnaceFuelBurnTimeEvent; +import net.minecraftforge.event.world.ExplosionEvent; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fml.common.Mod; @@ -60,6 +65,8 @@ import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.ItemHandlerHelper; +import appeng.entity.EntitySingularity; + @Mod.EventBusSubscriber(modid = GTValues.MODID) public class EventHandlers { @@ -373,4 +380,17 @@ public static void onFurnaceFuelBurnTime(FurnaceFuelBurnTimeEvent event) { event.setBurnTime(6400); } } + + @SubscribeEvent + public static void onExplosionDetonate(ExplosionEvent.Detonate event) { + if (event.getExplosion().exploder instanceof EntityGTExplosive explosive) { + if (explosive.dropsAllBlocks()) { + event.getAffectedEntities().removeIf(entity -> entity instanceof EntityItem && !checkAEEntity(entity)); + } + } + } + + private static boolean checkAEEntity(Entity entity) { + return Mods.AppliedEnergistics2.isModLoaded() && entity instanceof EntitySingularity; + } } diff --git a/src/main/java/gregtech/common/MetaEntities.java b/src/main/java/gregtech/common/MetaEntities.java index 00efb35f87d..965ce3bfb18 100644 --- a/src/main/java/gregtech/common/MetaEntities.java +++ b/src/main/java/gregtech/common/MetaEntities.java @@ -4,10 +4,13 @@ import gregtech.api.util.GTUtility; import gregtech.client.renderer.handler.DynamiteRenderer; import gregtech.client.renderer.handler.GTBoatRenderer; +import gregtech.client.renderer.handler.GTExplosiveRenderer; import gregtech.client.renderer.handler.PortalRenderer; import gregtech.common.entities.DynamiteEntity; import gregtech.common.entities.GTBoatEntity; +import gregtech.common.entities.ITNTEntity; import gregtech.common.entities.PortalEntity; +import gregtech.common.entities.PowderbarrelEntity; import net.minecraft.client.Minecraft; import net.minecraftforge.fml.client.registry.RenderingRegistry; @@ -24,6 +27,10 @@ public static void init() { GregTechAPI.instance, 64, 5, true); EntityRegistry.registerModEntity(GTUtility.gregtechId("gtboat"), GTBoatEntity.class, "GTBoat", 3, GregTechAPI.instance, 64, 2, true); + EntityRegistry.registerModEntity(GTUtility.gregtechId("powderbarrel"), PowderbarrelEntity.class, "Powderbarrel", + 4, GregTechAPI.instance, 64, 3, true); + EntityRegistry.registerModEntity(GTUtility.gregtechId("itnt"), ITNTEntity.class, "ITNT", 5, + GregTechAPI.instance, 64, 3, true); } @SideOnly(Side.CLIENT) @@ -32,5 +39,7 @@ public static void initRenderers() { manager -> new DynamiteRenderer(manager, Minecraft.getMinecraft().getRenderItem())); RenderingRegistry.registerEntityRenderingHandler(PortalEntity.class, PortalRenderer::new); RenderingRegistry.registerEntityRenderingHandler(GTBoatEntity.class, GTBoatRenderer::new); + RenderingRegistry.registerEntityRenderingHandler(PowderbarrelEntity.class, GTExplosiveRenderer::new); + RenderingRegistry.registerEntityRenderingHandler(ITNTEntity.class, GTExplosiveRenderer::new); } } diff --git a/src/main/java/gregtech/common/ToolEventHandlers.java b/src/main/java/gregtech/common/ToolEventHandlers.java index 65d407e9635..62195e49791 100644 --- a/src/main/java/gregtech/common/ToolEventHandlers.java +++ b/src/main/java/gregtech/common/ToolEventHandlers.java @@ -477,6 +477,8 @@ private static void drawGridOverlays(@NotNull AxisAlignedBB box) { @SideOnly(Side.CLIENT) private static void drawGridOverlays(EnumFacing facing, AxisAlignedBB box, Predicate test) { + if (facing == null) return; + Tessellator tessellator = Tessellator.getInstance(); BufferBuilder buffer = tessellator.getBuffer(); buffer.begin(3, DefaultVertexFormats.POSITION_COLOR); diff --git a/src/main/java/gregtech/common/blocks/BlockAsphalt.java b/src/main/java/gregtech/common/blocks/BlockAsphalt.java index 281e47c76b8..728245fcd90 100644 --- a/src/main/java/gregtech/common/blocks/BlockAsphalt.java +++ b/src/main/java/gregtech/common/blocks/BlockAsphalt.java @@ -1,8 +1,8 @@ package gregtech.common.blocks; -import gregtech.api.GregTechAPI; import gregtech.api.block.IStateHarvestLevel; import gregtech.api.block.VariantBlock; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; @@ -23,7 +23,7 @@ public BlockAsphalt() { setResistance(10.0f); setSoundType(SoundType.STONE); setDefaultState(getState(BlockType.ASPHALT)); - setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); } @Override diff --git a/src/main/java/gregtech/common/blocks/BlockCompressed.java b/src/main/java/gregtech/common/blocks/BlockCompressed.java index 18b71b293d6..9f2fb91fb16 100644 --- a/src/main/java/gregtech/common/blocks/BlockCompressed.java +++ b/src/main/java/gregtech/common/blocks/BlockCompressed.java @@ -1,6 +1,5 @@ package gregtech.common.blocks; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.info.MaterialIconType; @@ -9,6 +8,7 @@ import gregtech.client.model.modelfactories.MaterialBlockModelLoader; import gregtech.common.ConfigHolder; import gregtech.common.blocks.properties.PropertyMaterial; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.SoundType; import net.minecraft.block.state.IBlockState; @@ -46,7 +46,7 @@ private BlockCompressed() { setTranslationKey("compressed"); setHardness(5.0f); setResistance(10.0f); - setCreativeTab(GregTechAPI.TAB_GREGTECH_MATERIALS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_MATERIALS); } @Override diff --git a/src/main/java/gregtech/common/blocks/BlockFrame.java b/src/main/java/gregtech/common/blocks/BlockFrame.java index f4bb81f675d..88bbf3c2374 100644 --- a/src/main/java/gregtech/common/blocks/BlockFrame.java +++ b/src/main/java/gregtech/common/blocks/BlockFrame.java @@ -1,6 +1,5 @@ package gregtech.common.blocks; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; import gregtech.api.items.toolitem.ToolHelper; import gregtech.api.pipenet.block.BlockPipe; @@ -15,6 +14,7 @@ import gregtech.client.model.modelfactories.MaterialBlockModelLoader; import gregtech.common.ConfigHolder; import gregtech.common.blocks.properties.PropertyMaterial; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.Block; import net.minecraft.block.SoundType; @@ -68,7 +68,7 @@ private BlockFrame() { setTranslationKey("frame"); setHardness(3.0f); setResistance(6.0f); - setCreativeTab(GregTechAPI.TAB_GREGTECH_MATERIALS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_MATERIALS); } @Override diff --git a/src/main/java/gregtech/common/blocks/BlockGregStairs.java b/src/main/java/gregtech/common/blocks/BlockGregStairs.java index f04cddbe6df..e8b2a12f2c7 100644 --- a/src/main/java/gregtech/common/blocks/BlockGregStairs.java +++ b/src/main/java/gregtech/common/blocks/BlockGregStairs.java @@ -1,7 +1,7 @@ package gregtech.common.blocks; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.BlockStairs; import net.minecraft.block.state.IBlockState; @@ -15,7 +15,7 @@ public class BlockGregStairs extends BlockStairs { public BlockGregStairs(IBlockState state) { super(state); - setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); this.useNeighborBrightness = true; this.setHarvestLevel(ToolClasses.AXE, 0); } diff --git a/src/main/java/gregtech/common/blocks/BlockLamp.java b/src/main/java/gregtech/common/blocks/BlockLamp.java index 3cc7c273ddc..28d26cfd41a 100644 --- a/src/main/java/gregtech/common/blocks/BlockLamp.java +++ b/src/main/java/gregtech/common/blocks/BlockLamp.java @@ -1,13 +1,13 @@ package gregtech.common.blocks; import gregtech.api.GTValues; -import gregtech.api.GregTechAPI; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.MarkerMaterials; import gregtech.api.unification.ore.OrePrefix; import gregtech.client.model.lamp.LampBakedModel; import gregtech.client.model.lamp.LampModelType; import gregtech.client.utils.BloomEffectUtil; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.Block; import net.minecraft.block.SoundType; @@ -66,7 +66,7 @@ public BlockLamp(EnumDyeColor color) { .withProperty(LIGHT, true) .withProperty(INVERTED, false) .withProperty(POWERED, false)); - setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); } public boolean isLightEnabled(ItemStack stack) { diff --git a/src/main/java/gregtech/common/blocks/BlockOre.java b/src/main/java/gregtech/common/blocks/BlockOre.java index c0fc037097b..db69901b8ff 100644 --- a/src/main/java/gregtech/common/blocks/BlockOre.java +++ b/src/main/java/gregtech/common/blocks/BlockOre.java @@ -1,6 +1,5 @@ package gregtech.common.blocks; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.info.MaterialFlags; @@ -13,6 +12,7 @@ import gregtech.client.model.OreBakedModel; import gregtech.client.utils.BloomEffectUtil; import gregtech.common.blocks.properties.PropertyStoneType; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.Block; import net.minecraft.block.SoundType; @@ -54,7 +54,7 @@ public BlockOre(Material material, StoneType[] allowedValues) { this.material = Objects.requireNonNull(material, "Material in BlockOre can not be null!"); STONE_TYPE = PropertyStoneType.create("stone_type", allowedValues); initBlockState(); - setCreativeTab(GregTechAPI.TAB_GREGTECH_ORES); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_ORES); } @NotNull @@ -173,7 +173,7 @@ public boolean isFireSource(@NotNull World world, @NotNull BlockPos pos, @NotNul @Override public void getSubBlocks(@NotNull CreativeTabs tab, @NotNull NonNullList list) { - if (tab == CreativeTabs.SEARCH || tab == GregTechAPI.TAB_GREGTECH_ORES) { + if (tab == CreativeTabs.SEARCH || tab == GTCreativeTabs.TAB_GREGTECH_ORES) { blockState.getValidStates().stream() .filter(state -> state.getValue(STONE_TYPE).shouldBeDroppedAsItem) .forEach(blockState -> list.add(GTUtility.toItem(blockState))); diff --git a/src/main/java/gregtech/common/blocks/BlockWarningSign.java b/src/main/java/gregtech/common/blocks/BlockWarningSign.java index e452e203528..4fdf97dd2fd 100644 --- a/src/main/java/gregtech/common/blocks/BlockWarningSign.java +++ b/src/main/java/gregtech/common/blocks/BlockWarningSign.java @@ -1,8 +1,8 @@ package gregtech.common.blocks; -import gregtech.api.GregTechAPI; import gregtech.api.block.VariantBlock; import gregtech.api.items.toolitem.ToolClasses; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; @@ -24,7 +24,7 @@ public BlockWarningSign() { setSoundType(SoundType.METAL); setHarvestLevel(ToolClasses.WRENCH, 1); setDefaultState(getState(SignType.YELLOW_STRIPES)); - setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); } @Override diff --git a/src/main/java/gregtech/common/blocks/BlockWarningSign1.java b/src/main/java/gregtech/common/blocks/BlockWarningSign1.java index b25d74c9397..199a892d781 100644 --- a/src/main/java/gregtech/common/blocks/BlockWarningSign1.java +++ b/src/main/java/gregtech/common/blocks/BlockWarningSign1.java @@ -1,8 +1,8 @@ package gregtech.common.blocks; -import gregtech.api.GregTechAPI; import gregtech.api.block.VariantBlock; import gregtech.api.items.toolitem.ToolClasses; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; @@ -24,7 +24,7 @@ public BlockWarningSign1() { setSoundType(SoundType.METAL); setHarvestLevel(ToolClasses.WRENCH, 1); setDefaultState(getState(SignType.MOB_SPAWNER_HAZARD)); - setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); } @Override diff --git a/src/main/java/gregtech/common/blocks/MetaBlocks.java b/src/main/java/gregtech/common/blocks/MetaBlocks.java index 3be87d6b0f5..c9bb35e3405 100644 --- a/src/main/java/gregtech/common/blocks/MetaBlocks.java +++ b/src/main/java/gregtech/common/blocks/MetaBlocks.java @@ -24,6 +24,8 @@ import gregtech.client.renderer.pipe.LaserPipeRenderer; import gregtech.client.renderer.pipe.OpticalPipeRenderer; import gregtech.common.ConfigHolder; +import gregtech.common.blocks.explosive.BlockITNT; +import gregtech.common.blocks.explosive.BlockPowderbarrel; import gregtech.common.blocks.foam.BlockFoam; import gregtech.common.blocks.foam.BlockPetrifiedFoam; import gregtech.common.blocks.wood.BlockGregFence; @@ -167,6 +169,8 @@ private MetaBlocks() {} public static BlockFenceGate TREATED_WOOD_FENCE_GATE; public static BlockWoodenDoor RUBBER_WOOD_DOOR; public static BlockWoodenDoor TREATED_WOOD_DOOR; + public static BlockPowderbarrel POWDERBARREL; + public static BlockITNT ITNT; public static BlockBrittleCharcoal BRITTLE_CHARCOAL; @@ -322,6 +326,10 @@ public static void init() { RUBBER_WOOD_DOOR.setRegistryName("rubber_wood_door").setTranslationKey("rubber_wood_door"); TREATED_WOOD_DOOR = new BlockWoodenDoor(() -> MetaItems.TREATED_WOOD_DOOR.getStackForm()); TREATED_WOOD_DOOR.setRegistryName("treated_wood_door").setTranslationKey("treated_wood_door"); + POWDERBARREL = new BlockPowderbarrel(); + POWDERBARREL.setRegistryName("powderbarrel").setTranslationKey("powderbarrel"); + ITNT = new BlockITNT(); + ITNT.setRegistryName("itnt").setTranslationKey("itnt"); BRITTLE_CHARCOAL = new BlockBrittleCharcoal(); BRITTLE_CHARCOAL.setRegistryName("brittle_charcoal"); @@ -496,6 +504,8 @@ public static void registerItemModels() { new ModelResourceLocation(Objects.requireNonNull(TREATED_WOOD_FENCE_GATE.getRegistryName()), "inventory")); registerItemModel(BRITTLE_CHARCOAL); + registerItemModel(POWDERBARREL); + registerItemModel(ITNT); registerItemModel(METAL_SHEET); registerItemModel(LARGE_METAL_SHEET); diff --git a/src/main/java/gregtech/common/blocks/StoneVariantBlock.java b/src/main/java/gregtech/common/blocks/StoneVariantBlock.java index 39194eea2a0..72fcb6d5180 100644 --- a/src/main/java/gregtech/common/blocks/StoneVariantBlock.java +++ b/src/main/java/gregtech/common/blocks/StoneVariantBlock.java @@ -1,11 +1,11 @@ package gregtech.common.blocks; -import gregtech.api.GregTechAPI; import gregtech.api.block.VariantBlock; import gregtech.api.items.toolitem.ToolClasses; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.Materials; import gregtech.api.unification.ore.OrePrefix; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.SoundType; import net.minecraft.block.material.MapColor; @@ -40,7 +40,7 @@ public StoneVariantBlock(@NotNull StoneVariant stoneVariant) { setSoundType(SoundType.STONE); setHarvestLevel(ToolClasses.PICKAXE, 0); setDefaultState(getState(StoneType.BLACK_GRANITE)); - setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); } @NotNull diff --git a/src/main/java/gregtech/common/blocks/explosive/BlockGTExplosive.java b/src/main/java/gregtech/common/blocks/explosive/BlockGTExplosive.java new file mode 100644 index 00000000000..e18a97abbbf --- /dev/null +++ b/src/main/java/gregtech/common/blocks/explosive/BlockGTExplosive.java @@ -0,0 +1,175 @@ +package gregtech.common.blocks.explosive; + +import gregtech.common.creativetab.GTCreativeTabs; +import gregtech.common.entities.EntityGTExplosive; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.init.SoundEvents; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.Explosion; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +@SuppressWarnings("deprecation") +public abstract class BlockGTExplosive extends Block { + + private final boolean canRedstoneActivate; + private final boolean explodeOnMine; + private final int fuseLength; + + /** + * @param canRedstoneActivate whether redstone signal can prime this explosive + * @param explodeOnMine whether mining this block should prime it (sneak mine to drop normally) + * @param fuseLength explosion countdown after priming. Vanilla TNT is 80. + */ + public BlockGTExplosive(Material materialIn, boolean canRedstoneActivate, boolean explodeOnMine, int fuseLength) { + super(materialIn); + this.canRedstoneActivate = canRedstoneActivate; + this.explodeOnMine = explodeOnMine; + this.fuseLength = fuseLength; + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS); + } + + protected abstract EntityGTExplosive createEntity(World world, BlockPos pos, EntityLivingBase exploder); + + @Override + public float getExplosionResistance(@NotNull Entity exploder) { + return 1.0f; + } + + @Override + public boolean canBeReplacedByLeaves(@NotNull IBlockState state, @NotNull IBlockAccess world, + @NotNull BlockPos pos) { + return false; + } + + @Override + public boolean isNormalCube(@NotNull IBlockState state) { + return true; + } + + @Override + public boolean canCreatureSpawn(@NotNull IBlockState state, @NotNull IBlockAccess world, @NotNull BlockPos pos, + @NotNull EntityLiving.SpawnPlacementType type) { + return false; + } + + @Override + public boolean canDropFromExplosion(@NotNull Explosion explosion) { + return false; + } + + public void explode(World world, BlockPos pos, EntityLivingBase exploder) { + if (!world.isRemote) { + EntityGTExplosive entity = createEntity(world, pos, exploder); + entity.setFuse(fuseLength); + world.spawnEntity(entity); + world.playSound(null, entity.posX, entity.posY, entity.posZ, SoundEvents.ENTITY_TNT_PRIMED, + SoundCategory.BLOCKS, 1.0f, 1.0f); + } + } + + @Override + public void onExplosionDestroy(@NotNull World world, @NotNull BlockPos pos, @NotNull Explosion explosion) { + if (!world.isRemote) { + EntityGTExplosive entity = createEntity(world, pos, explosion.getExplosivePlacedBy()); + entity.setFuse(world.rand.nextInt(fuseLength / 4) + fuseLength / 8); + world.spawnEntity(entity); + } + } + + @Override + public boolean onBlockActivated(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState state, + @NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull EnumFacing facing, + float hitX, float hitY, float hitZ) { + ItemStack stack = player.getHeldItem(hand); + if (!stack.isEmpty() && (stack.getItem() == Items.FLINT_AND_STEEL || stack.getItem() == Items.FIRE_CHARGE)) { + this.explode(world, pos, player); + world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11); + if (stack.getItem() == Items.FLINT_AND_STEEL) { + stack.damageItem(1, player); + } else if (!player.capabilities.isCreativeMode) { + stack.shrink(1); + } + return true; + } + return super.onBlockActivated(world, pos, state, player, hand, facing, hitX, hitY, hitZ); + } + + @Override + public void dropBlockAsItemWithChance(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState state, + float chance, int fortune) { + if (explodeOnMine) { + EntityPlayer player = this.harvesters.get(); + if (!player.isSneaking()) { + this.explode(world, pos, player); + return; + } + } + super.dropBlockAsItemWithChance(world, pos, state, chance, fortune); + } + + @Override + public void onEntityCollision(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState state, + @NotNull Entity entity) { + if (!world.isRemote && entity instanceof EntityArrow arrow) { + if (arrow.isBurning()) { + this.explode(world, pos, arrow.shootingEntity instanceof EntityLivingBase living ? living : null); + world.setBlockToAir(pos); + } + } + } + + @Override + public void onBlockAdded(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState state) { + super.onBlockAdded(world, pos, state); + if (canRedstoneActivate) { + if (world.isBlockPowered(pos)) { + explode(world, pos, null); + world.setBlockToAir(pos); + } + } + } + + @Override + public void neighborChanged(@NotNull IBlockState state, @NotNull World world, @NotNull BlockPos pos, + @NotNull Block block, @NotNull BlockPos fromPos) { + if (canRedstoneActivate) { + if (world.isBlockPowered(pos)) { + explode(world, pos, null); + world.setBlockToAir(pos); + } + } + } + + @Override + public void addInformation(@NotNull ItemStack stack, @Nullable World world, @NotNull List tooltip, + @NotNull ITooltipFlag flag) { + if (explodeOnMine) { + tooltip.add(I18n.format("tile.gt_explosive.breaking_tooltip")); + } + if (!canRedstoneActivate) { + tooltip.add(I18n.format("tile.gt_explosive.lighting_tooltip")); + } + } +} diff --git a/src/main/java/gregtech/common/blocks/explosive/BlockITNT.java b/src/main/java/gregtech/common/blocks/explosive/BlockITNT.java new file mode 100644 index 00000000000..91a9614d4c4 --- /dev/null +++ b/src/main/java/gregtech/common/blocks/explosive/BlockITNT.java @@ -0,0 +1,40 @@ +package gregtech.common.blocks.explosive; + +import gregtech.common.entities.EntityGTExplosive; +import gregtech.common.entities.ITNTEntity; + +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class BlockITNT extends BlockGTExplosive { + + public BlockITNT() { + super(Material.TNT, true, true, 40); + setHardness(0); + setSoundType(SoundType.PLANT); + } + + @Override + protected EntityGTExplosive createEntity(World world, BlockPos pos, EntityLivingBase exploder) { + float x = pos.getX() + 0.5F, y = pos.getY(), z = pos.getZ() + 0.5F; + return new ITNTEntity(world, x, y, z, exploder); + } + + @Override + public void addInformation(@NotNull ItemStack stack, @Nullable World world, @NotNull List tooltip, + @NotNull ITooltipFlag flag) { + tooltip.add(I18n.format("tile.itnt.drops_tooltip")); + super.addInformation(stack, world, tooltip, flag); + } +} diff --git a/src/main/java/gregtech/common/blocks/explosive/BlockPowderbarrel.java b/src/main/java/gregtech/common/blocks/explosive/BlockPowderbarrel.java new file mode 100644 index 00000000000..a2549ad7ee5 --- /dev/null +++ b/src/main/java/gregtech/common/blocks/explosive/BlockPowderbarrel.java @@ -0,0 +1,42 @@ +package gregtech.common.blocks.explosive; + +import gregtech.api.items.toolitem.ToolClasses; +import gregtech.common.blocks.material.GTBlockMaterials; +import gregtech.common.entities.EntityGTExplosive; +import gregtech.common.entities.PowderbarrelEntity; + +import net.minecraft.block.SoundType; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class BlockPowderbarrel extends BlockGTExplosive { + + public BlockPowderbarrel() { + super(GTBlockMaterials.POWDERBARREL, false, true, 100); + setHarvestLevel(ToolClasses.AXE, 1); + setHardness(0.5F); + setSoundType(SoundType.WOOD); + } + + @Override + protected EntityGTExplosive createEntity(World world, BlockPos pos, EntityLivingBase exploder) { + float x = pos.getX() + 0.5F, y = pos.getY(), z = pos.getZ() + 0.5F; + return new PowderbarrelEntity(world, x, y, z, exploder); + } + + @Override + public void addInformation(@NotNull ItemStack stack, @Nullable World world, @NotNull List tooltip, + @NotNull ITooltipFlag flag) { + tooltip.add(I18n.format("tile.powderbarrel.drops_tooltip")); + super.addInformation(stack, world, tooltip, flag); + } +} diff --git a/src/main/java/gregtech/common/blocks/material/GTBlockMaterials.java b/src/main/java/gregtech/common/blocks/material/GTBlockMaterials.java new file mode 100644 index 00000000000..213ba58fdd9 --- /dev/null +++ b/src/main/java/gregtech/common/blocks/material/GTBlockMaterials.java @@ -0,0 +1,18 @@ +package gregtech.common.blocks.material; + +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; + +public class GTBlockMaterials { + + public static final Material POWDERBARREL = new PowderbarrelMaterial(); + + private static class PowderbarrelMaterial extends Material { + + public PowderbarrelMaterial() { + super(MapColor.STONE); + setAdventureModeExempt(); + setImmovableMobility(); + } + } +} diff --git a/src/main/java/gregtech/common/blocks/wood/BlockGregFence.java b/src/main/java/gregtech/common/blocks/wood/BlockGregFence.java index 975c0708a22..ba3188cac78 100644 --- a/src/main/java/gregtech/common/blocks/wood/BlockGregFence.java +++ b/src/main/java/gregtech/common/blocks/wood/BlockGregFence.java @@ -1,7 +1,7 @@ package gregtech.common.blocks.wood; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.BlockFence; import net.minecraft.block.SoundType; @@ -15,7 +15,7 @@ public BlockGregFence() { setHardness(2.0F); setResistance(5.0F); setSoundType(SoundType.WOOD); - setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); setHarvestLevel(ToolClasses.AXE, 0); } } diff --git a/src/main/java/gregtech/common/blocks/wood/BlockGregFenceGate.java b/src/main/java/gregtech/common/blocks/wood/BlockGregFenceGate.java index 29c539eca35..aff946015e2 100644 --- a/src/main/java/gregtech/common/blocks/wood/BlockGregFenceGate.java +++ b/src/main/java/gregtech/common/blocks/wood/BlockGregFenceGate.java @@ -1,7 +1,7 @@ package gregtech.common.blocks.wood; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.BlockFenceGate; import net.minecraft.block.BlockPlanks; @@ -14,7 +14,7 @@ public BlockGregFenceGate() { setHardness(2.0F); setResistance(5.0F); setSoundType(SoundType.WOOD); - setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); setHarvestLevel(ToolClasses.AXE, 0); } } diff --git a/src/main/java/gregtech/common/blocks/wood/BlockGregWoodSlab.java b/src/main/java/gregtech/common/blocks/wood/BlockGregWoodSlab.java index acab4c9dd43..d2cc8e2b96e 100644 --- a/src/main/java/gregtech/common/blocks/wood/BlockGregWoodSlab.java +++ b/src/main/java/gregtech/common/blocks/wood/BlockGregWoodSlab.java @@ -1,8 +1,8 @@ package gregtech.common.blocks.wood; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; import gregtech.common.blocks.MetaBlocks; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.BlockSlab; import net.minecraft.block.SoundType; @@ -35,7 +35,7 @@ public BlockGregWoodSlab() { setResistance(5.0F); setSoundType(SoundType.WOOD); setHarvestLevel(ToolClasses.AXE, 0); - setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); this.useNeighborBrightness = true; } diff --git a/src/main/java/gregtech/common/blocks/wood/BlockRubberLeaves.java b/src/main/java/gregtech/common/blocks/wood/BlockRubberLeaves.java index 533cf4249d2..2149165afa4 100644 --- a/src/main/java/gregtech/common/blocks/wood/BlockRubberLeaves.java +++ b/src/main/java/gregtech/common/blocks/wood/BlockRubberLeaves.java @@ -1,7 +1,7 @@ package gregtech.common.blocks.wood; -import gregtech.api.GregTechAPI; import gregtech.common.blocks.MetaBlocks; +import gregtech.common.creativetab.GTCreativeTabs; import gregtech.core.CoreModule; import net.minecraft.block.BlockLeaves; @@ -31,7 +31,7 @@ public BlockRubberLeaves() { .withProperty(CHECK_DECAY, true) .withProperty(DECAYABLE, true)); setTranslationKey("rubber_leaves"); - setCreativeTab(GregTechAPI.TAB_GREGTECH); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH); Blocks.FIRE.setFireInfo(this, 30, 60); } diff --git a/src/main/java/gregtech/common/blocks/wood/BlockRubberLog.java b/src/main/java/gregtech/common/blocks/wood/BlockRubberLog.java index bd89801a699..7c2f2b09f85 100644 --- a/src/main/java/gregtech/common/blocks/wood/BlockRubberLog.java +++ b/src/main/java/gregtech/common/blocks/wood/BlockRubberLog.java @@ -1,7 +1,7 @@ package gregtech.common.blocks.wood; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; +import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.items.MetaItems; import net.minecraft.block.BlockLog; @@ -27,7 +27,7 @@ public BlockRubberLog() { .withProperty(LOG_AXIS, BlockLog.EnumAxis.Y) .withProperty(NATURAL, false)); setTranslationKey("rubber_log"); - setCreativeTab(GregTechAPI.TAB_GREGTECH); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH); setHarvestLevel(ToolClasses.AXE, 0); } diff --git a/src/main/java/gregtech/common/blocks/wood/BlockRubberSapling.java b/src/main/java/gregtech/common/blocks/wood/BlockRubberSapling.java index cd9b35d8232..653a31fc9a8 100644 --- a/src/main/java/gregtech/common/blocks/wood/BlockRubberSapling.java +++ b/src/main/java/gregtech/common/blocks/wood/BlockRubberSapling.java @@ -1,6 +1,6 @@ package gregtech.common.blocks.wood; -import gregtech.api.GregTechAPI; +import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.worldgen.WorldGenRubberTree; import net.minecraft.block.BlockBush; @@ -28,7 +28,7 @@ public BlockRubberSapling() { this.setDefaultState(this.blockState.getBaseState() .withProperty(STAGE, 0)); setTranslationKey("rubber_sapling"); - setCreativeTab(GregTechAPI.TAB_GREGTECH); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH); setHardness(0.0F); setSoundType(SoundType.PLANT); } diff --git a/src/main/java/gregtech/common/covers/CoverBehaviors.java b/src/main/java/gregtech/common/covers/CoverBehaviors.java index 3e5779fb3bf..78413327163 100644 --- a/src/main/java/gregtech/common/covers/CoverBehaviors.java +++ b/src/main/java/gregtech/common/covers/CoverBehaviors.java @@ -8,10 +8,6 @@ import gregtech.api.util.GTLog; import gregtech.client.renderer.texture.Textures; import gregtech.common.covers.detector.*; -import gregtech.common.covers.filter.OreDictionaryItemFilter; -import gregtech.common.covers.filter.SimpleFluidFilter; -import gregtech.common.covers.filter.SimpleItemFilter; -import gregtech.common.covers.filter.SmartItemFilter; import gregtech.common.items.MetaItems; import gregtech.common.items.behaviors.CoverDigitalInterfaceWirelessPlaceBehaviour; @@ -67,12 +63,12 @@ public static void init() { registerBehavior(gregtechId("ore_dictionary_filter"), MetaItems.ORE_DICTIONARY_FILTER, (def, tile, side) -> new CoverItemFilter(def, tile, side, "cover.ore_dictionary_filter.title", - Textures.ORE_DICTIONARY_FILTER_OVERLAY, new OreDictionaryItemFilter())); + Textures.ORE_DICTIONARY_FILTER_OVERLAY)); registerBehavior(gregtechId("item_filter"), MetaItems.ITEM_FILTER, (def, tile, side) -> new CoverItemFilter(def, - tile, side, "cover.item_filter.title", Textures.ITEM_FILTER_FILTER_OVERLAY, new SimpleItemFilter())); + tile, side, "cover.item_filter.title", Textures.ITEM_FILTER_FILTER_OVERLAY)); registerBehavior(gregtechId("fluid_filter"), MetaItems.FLUID_FILTER, (def, tile, side) -> new CoverFluidFilter(def, tile, side, "cover.fluid_filter.title", - Textures.FLUID_FILTER_OVERLAY, new SimpleFluidFilter())); + Textures.FLUID_FILTER_OVERLAY)); registerBehavior(gregtechId("shutter"), MetaItems.COVER_SHUTTER, CoverShutter::new); registerBehavior(gregtechId("solar_panel.basic"), MetaItems.COVER_SOLAR_PANEL, @@ -100,7 +96,7 @@ public static void init() { CoverMachineController::new); registerBehavior(gregtechId("smart_filter"), MetaItems.SMART_FILTER, (def, tile, side) -> new CoverItemFilter(def, tile, side, "cover.smart_item_filter.title", - Textures.SMART_FILTER_FILTER_OVERLAY, new SmartItemFilter())); + Textures.SMART_FILTER_FILTER_OVERLAY)); registerBehavior(gregtechId("facade"), MetaItems.COVER_FACADE, CoverFacade::new); registerBehavior(gregtechId("screen"), MetaItems.COVER_SCREEN, CoverScreen::new); diff --git a/src/main/java/gregtech/common/covers/CoverConveyor.java b/src/main/java/gregtech/common/covers/CoverConveyor.java index 1408ae77c56..127c852fb83 100644 --- a/src/main/java/gregtech/common/covers/CoverConveyor.java +++ b/src/main/java/gregtech/common/covers/CoverConveyor.java @@ -1,6 +1,5 @@ package gregtech.common.covers; -import gregtech.api.GTValues; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IControllable; @@ -9,9 +8,8 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverWithUI; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.*; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.ItemStackHashStrategy; import gregtech.client.renderer.texture.Textures; @@ -26,7 +24,12 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.*; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.IStringSerializable; +import net.minecraft.util.ITickable; import net.minecraft.util.math.MathHelper; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fml.relauncher.Side; @@ -39,10 +42,24 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.utils.MouseData; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.IntSyncValue; +import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.ButtonWidget; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; import org.jetbrains.annotations.NotNull; @@ -76,7 +93,7 @@ public CoverConveyor(@NotNull CoverDefinition definition, @NotNull CoverableView } public void setTransferRate(int transferRate) { - this.transferRate = transferRate; + this.transferRate = MathHelper.clamp(transferRate, 1, maxItemTransferRate); CoverableView coverable = getCoverableView(); coverable.markDirty(); @@ -168,7 +185,7 @@ protected int doTransferItemsAny(IItemHandler itemHandler, IItemHandler myItemHa } protected int doTransferItemsByGroup(IItemHandler itemHandler, IItemHandler myItemHandler, - Map itemInfos, int maxTransferAmount) { + Map itemInfos, int maxTransferAmount) { if (conveyorMode == ConveyorMode.IMPORT) { return moveInventoryItems(itemHandler, myItemHandler, itemInfos, maxTransferAmount); } else if (conveyorMode == ConveyorMode.EXPORT) { @@ -177,8 +194,8 @@ protected int doTransferItemsByGroup(IItemHandler itemHandler, IItemHandler myIt return 0; } - protected Map doCountDestinationInventoryItemsByMatchIndex(IItemHandler itemHandler, - IItemHandler myItemHandler) { + protected Map doCountDestinationInventoryItemsByMatchIndex(IItemHandler itemHandler, + IItemHandler myItemHandler) { if (conveyorMode == ConveyorMode.IMPORT) { return countInventoryItemsByMatchSlot(myItemHandler); } else if (conveyorMode == ConveyorMode.EXPORT) { @@ -265,15 +282,17 @@ protected static boolean moveInventoryItemsExact(IItemHandler sourceInventory, I } protected int moveInventoryItems(IItemHandler sourceInventory, IItemHandler targetInventory, - Map itemInfos, int maxTransferAmount) { + Map itemInfos, int maxTransferAmount) { int itemsLeftToTransfer = maxTransferAmount; for (int i = 0; i < sourceInventory.getSlots(); i++) { ItemStack itemStack = sourceInventory.getStackInSlot(i); if (itemStack.isEmpty()) { continue; } - Object matchSlotIndex = itemFilterContainer.matchItemStack(itemStack); - if (matchSlotIndex == null || !itemInfos.containsKey(matchSlotIndex)) { + + var matchResult = itemFilterContainer.match(itemStack); + int matchSlotIndex = matchResult.getFilterIndex(); + if (!matchResult.isMatched() || !itemInfos.containsKey(matchSlotIndex)) { continue; } @@ -317,9 +336,10 @@ protected int moveInventoryItems(IItemHandler sourceInventory, IItemHandler targ if (sourceStack.isEmpty()) { continue; } - if (!itemFilterContainer.testItemStack(sourceStack)) { - continue; - } + + var result = itemFilterContainer.match(sourceStack); + if (!result.isMatched()) continue; + ItemStack remainder = GTTransferUtils.insertItem(targetInventory, sourceStack, true); int amountToInsert = sourceStack.getCount() - remainder.getCount(); @@ -341,11 +361,11 @@ protected int moveInventoryItems(IItemHandler sourceInventory, IItemHandler targ protected static class TypeItemInfo { public final ItemStack itemStack; - public final Object filterSlot; + public final int filterSlot; public final IntList slots; public int totalCount; - public TypeItemInfo(ItemStack itemStack, Object filterSlot, IntList slots, int totalCount) { + public TypeItemInfo(ItemStack itemStack, int filterSlot, IntList slots, int totalCount) { this.itemStack = itemStack; this.filterSlot = filterSlot; this.slots = slots; @@ -355,11 +375,11 @@ public TypeItemInfo(ItemStack itemStack, Object filterSlot, IntList slots, int t protected static class GroupItemInfo { - public final Object filterSlot; + public final int filterSlot; public final Set itemStackTypes; public int totalCount; - public GroupItemInfo(Object filterSlot, Set itemStackTypes, int totalCount) { + public GroupItemInfo(int filterSlot, Set itemStackTypes, int totalCount) { this.filterSlot = filterSlot; this.itemStackTypes = itemStackTypes; this.totalCount = totalCount; @@ -375,12 +395,13 @@ protected Map countInventoryItemsByType(@NotNull IItemH if (itemStack.isEmpty()) { continue; } - Object transferSlotIndex = itemFilterContainer.matchItemStack(itemStack); - if (transferSlotIndex == null) { - continue; - } + + var matchResult = itemFilterContainer.match(itemStack); + if (!matchResult.isMatched()) continue; + if (!result.containsKey(itemStack)) { - TypeItemInfo itemInfo = new TypeItemInfo(itemStack.copy(), transferSlotIndex, new IntArrayList(), 0); + TypeItemInfo itemInfo = new TypeItemInfo(itemStack.copy(), matchResult.getFilterIndex(), + new IntArrayList(), 0); itemInfo.totalCount += itemStack.getCount(); itemInfo.slots.add(srcIndex); result.put(itemStack.copy(), itemInfo); @@ -394,28 +415,30 @@ protected Map countInventoryItemsByType(@NotNull IItemH } @NotNull - protected Map countInventoryItemsByMatchSlot(@NotNull IItemHandler inventory) { - Map result = new Object2ObjectOpenHashMap<>(); + protected Map countInventoryItemsByMatchSlot(@NotNull IItemHandler inventory) { + Map result = new Int2ObjectOpenHashMap<>(); for (int srcIndex = 0; srcIndex < inventory.getSlots(); srcIndex++) { ItemStack itemStack = inventory.getStackInSlot(srcIndex); if (itemStack.isEmpty()) { continue; } - Object transferSlotIndex = itemFilterContainer.matchItemStack(itemStack); - if (transferSlotIndex == null) { - continue; - } - if (!result.containsKey(transferSlotIndex)) { - GroupItemInfo itemInfo = new GroupItemInfo(transferSlotIndex, + + var matchResult = itemFilterContainer.match(itemStack); + if (!matchResult.isMatched()) continue; + int matchedSlot = matchResult.getFilterIndex(); + + if (!result.containsKey(matchedSlot)) { + GroupItemInfo itemInfo = new GroupItemInfo(matchedSlot, new ObjectOpenCustomHashSet<>(ItemStackHashStrategy.comparingAllButCount()), 0); itemInfo.itemStackTypes.add(itemStack.copy()); itemInfo.totalCount += itemStack.getCount(); - result.put(transferSlotIndex, itemInfo); + result.put(matchedSlot, itemInfo); } else { - GroupItemInfo itemInfo = result.get(transferSlotIndex); + GroupItemInfo itemInfo = result.get(matchedSlot); itemInfo.itemStackTypes.add(itemStack.copy()); itemInfo.totalCount += itemStack.getCount(); } + } return result; } @@ -432,7 +455,7 @@ public boolean canInteractWithOutputSide() { @Override public void onRemoval() { - dropInventoryContents(itemFilterContainer.getFilterInventory()); + dropInventoryContents(itemFilterContainer); } @Override @@ -473,57 +496,123 @@ public T getCapability(Capability capability, T defaultValue) { return defaultValue; } - protected String getUITitle() { - return "cover.conveyor.title"; + @Override + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(SidedPosGuiData guiData, GuiSyncManager guiSyncManager) { + var panel = GTGuis.createPanel(this, 176, 192 + 18); + + getItemFilterContainer().setMaxTransferSize(getMaxStackSize()); + + return panel.child(CoverWithUI.createTitleRow(getPickItem())) + .child(createUI(panel, guiSyncManager)) + .bindPlayerInventory(); + } + + protected ParentWidget createUI(ModularPanel mainPanel, GuiSyncManager guiSyncManager) { + var column = new Column().top(24).margin(7, 0) + .widthRel(1f).coverChildrenHeight(); + + EnumSyncValue manualIOmode = new EnumSyncValue<>(ManualImportExportMode.class, + this::getManualImportExportMode, this::setManualImportExportMode); + + EnumSyncValue conveyorMode = new EnumSyncValue<>(ConveyorMode.class, + this::getConveyorMode, this::setConveyorMode); + + IntSyncValue throughput = new IntSyncValue(this::getTransferRate, this::setTransferRate); + throughput.updateCacheFromSource(true); + + StringSyncValue formattedThroughput = new StringSyncValue(throughput::getStringValue, + throughput::setStringValue); + + EnumSyncValue distributionMode = new EnumSyncValue<>(DistributionMode.class, + this::getDistributionMode, this::setDistributionMode); + + guiSyncManager.syncValue("manual_io", manualIOmode); + guiSyncManager.syncValue("conveyor_mode", conveyorMode); + guiSyncManager.syncValue("distribution_mode", distributionMode); + guiSyncManager.syncValue("throughput", throughput); + + if (createThroughputRow()) + column.child(new Row().coverChildrenHeight() + .marginBottom(2).widthRel(1f) + .child(new ButtonWidget<>() + .left(0).width(18) + .onMousePressed(mouseButton -> { + int val = throughput.getValue() - getIncrementValue(MouseData.create(mouseButton)); + throughput.setValue(val, true, true); + Interactable.playButtonClickSound(); + return true; + }) + .onUpdateListener(w -> w.overlay(createAdjustOverlay(false)))) + .child(new TextFieldWidget() + .left(18).right(18) + .setTextColor(Color.WHITE.darker(1)) + .setNumbers(1, maxItemTransferRate) + .value(formattedThroughput) + .background(GTGuiTextures.DISPLAY)) + .child(new ButtonWidget<>() + .right(0).width(18) + .onMousePressed(mouseButton -> { + int val = throughput.getValue() + getIncrementValue(MouseData.create(mouseButton)); + throughput.setValue(val, true, true); + Interactable.playButtonClickSound(); + return true; + }) + .onUpdateListener(w -> w.overlay(createAdjustOverlay(true))))); + + if (createFilterRow()) + column.child(getItemFilterContainer().initUI(mainPanel, guiSyncManager)); + + if (createManualIOModeRow()) + column.child(new EnumRowBuilder<>(ManualImportExportMode.class) + .value(manualIOmode) + .lang("cover.generic.manual_io") + .overlay(GTGuiTextures.MANUAL_IO_OVERLAY) + .build()); + + if (createConveyorModeRow()) + column.child(new EnumRowBuilder<>(ConveyorMode.class) + .value(conveyorMode) + .lang("cover.generic.io") + .overlay(GTGuiTextures.CONVEYOR_MODE_OVERLAY) + .build()); + + if (createDistributionModeRow()) + column.child(new EnumRowBuilder<>(DistributionMode.class) + .value(distributionMode) + .overlay(16, GTGuiTextures.DISTRIBUTION_MODE_OVERLAY) + .lang("cover.conveyor.distribution.name") + .build()); + + return column; + } + + protected boolean createThroughputRow() { + return true; } - protected ModularUI buildUI(ModularUI.Builder builder, EntityPlayer player) { - return builder.build(this, player); + protected boolean createFilterRow() { + return true; } - @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup primaryGroup = new WidgetGroup(); - primaryGroup.addWidget(new LabelWidget(10, 5, getUITitle(), GTValues.VN[tier])); - - primaryGroup.addWidget(new IncrementButtonWidget(136, 20, 30, 20, 1, 8, 64, 512, this::adjustTransferRate) - .setDefaultTooltip() - .setShouldClientCallback(false)); - primaryGroup.addWidget(new IncrementButtonWidget(10, 20, 30, 20, -1, -8, -64, -512, this::adjustTransferRate) - .setDefaultTooltip() - .setShouldClientCallback(false)); - - primaryGroup.addWidget(new ImageWidget(40, 20, 96, 20, GuiTextures.DISPLAY)); - primaryGroup.addWidget(new TextFieldWidget2(42, 26, 92, 20, () -> String.valueOf(transferRate), val -> { - if (val != null && !val.isEmpty()) - setTransferRate(MathHelper.clamp(Integer.parseInt(val), 1, maxItemTransferRate)); - }) - .setNumbersOnly(1, maxItemTransferRate) - .setMaxLength(4) - .setPostFix("cover.conveyor.transfer_rate")); - - primaryGroup.addWidget(new CycleButtonWidget(10, 45, 75, 20, - ConveyorMode.class, this::getConveyorMode, this::setConveyorMode)); - primaryGroup.addWidget(new CycleButtonWidget(7, 166, 116, 20, - ManualImportExportMode.class, this::getManualImportExportMode, this::setManualImportExportMode) - .setTooltipHoverString("cover.universal.manual_import_export.mode.description")); - - if (getTileEntityHere() instanceof TileEntityItemPipe || - getNeighbor(getAttachedSide()) instanceof TileEntityItemPipe) { - final ImageCycleButtonWidget distributionModeButton = new ImageCycleButtonWidget(149, 166, 20, 20, - GuiTextures.DISTRIBUTION_MODE, 3, - () -> distributionMode.ordinal(), - val -> setDistributionMode(DistributionMode.values()[val])) - .setTooltipHoverString(val -> DistributionMode.values()[val].getName()); - primaryGroup.addWidget(distributionModeButton); - } + protected boolean createManualIOModeRow() { + return true; + } - this.itemFilterContainer.initUI(70, primaryGroup::addWidget); + protected boolean createConveyorModeRow() { + return true; + } + + protected boolean createDistributionModeRow() { + return true; + } - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, 190 + 82) - .widget(primaryGroup) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 190); - return buildUI(builder, player); + protected int getMaxStackSize() { + return 1; } @Override @@ -546,17 +635,23 @@ public void readCustomData(int discriminator, @NotNull PacketBuffer buf) { } @Override - public void writeInitialSyncData(PacketBuffer packetBuffer) { + public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { super.writeInitialSyncData(packetBuffer); - packetBuffer.writeEnumValue(conveyorMode); - packetBuffer.writeEnumValue(distributionMode); + packetBuffer.writeInt(transferRate); + packetBuffer.writeByte(conveyorMode.ordinal()); + packetBuffer.writeByte(distributionMode.ordinal()); + packetBuffer.writeByte(manualImportExportMode.ordinal()); + getItemFilterContainer().writeInitialSyncData(packetBuffer); } @Override public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { super.readInitialSyncData(packetBuffer); - this.conveyorMode = packetBuffer.readEnumValue(ConveyorMode.class); - this.distributionMode = packetBuffer.readEnumValue(DistributionMode.class); + this.transferRate = packetBuffer.readInt(); + this.conveyorMode = ConveyorMode.VALUES[packetBuffer.readByte()]; + this.distributionMode = DistributionMode.VALUES[packetBuffer.readByte()]; + this.manualImportExportMode = ManualImportExportMode.VALUES[packetBuffer.readByte()]; + getItemFilterContainer().readInitialSyncData(packetBuffer); } @Override @@ -574,11 +669,12 @@ public void writeToNBT(@NotNull NBTTagCompound tagCompound) { public void readFromNBT(@NotNull NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); this.transferRate = tagCompound.getInteger("TransferRate"); - this.conveyorMode = ConveyorMode.values()[tagCompound.getInteger("ConveyorMode")]; - this.distributionMode = DistributionMode.values()[tagCompound.getInteger("DistributionMode")]; + this.conveyorMode = ConveyorMode.VALUES[tagCompound.getInteger("ConveyorMode")]; + this.distributionMode = DistributionMode.VALUES[tagCompound.getInteger("DistributionMode")]; this.isWorkingAllowed = tagCompound.getBoolean("WorkingAllowed"); - this.manualImportExportMode = ManualImportExportMode.values()[tagCompound.getInteger("ManualImportExportMode")]; + this.manualImportExportMode = ManualImportExportMode.VALUES[tagCompound.getInteger("ManualImportExportMode")]; this.itemFilterContainer.deserializeNBT(tagCompound.getCompoundTag("Filter")); + this.itemFilterContainer.handleLegacyNBT(tagCompound.getCompoundTag("Filter")); } @Override @@ -592,6 +688,7 @@ public enum ConveyorMode implements IStringSerializable, IIOMode { IMPORT("cover.conveyor.mode.import"), EXPORT("cover.conveyor.mode.export"); + public static final ConveyorMode[] VALUES = values(); public final String localeName; ConveyorMode(String localeName) { @@ -623,7 +720,7 @@ public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate return stack; } if (manualImportExportMode == ManualImportExportMode.FILTERED && - !itemFilterContainer.testItemStack(stack)) { + !itemFilterContainer.test(stack)) { return stack; } return super.insertItem(slot, stack, simulate); @@ -637,7 +734,7 @@ public ItemStack extractItem(int slot, int amount, boolean simulate) { } if (manualImportExportMode == ManualImportExportMode.FILTERED) { ItemStack result = super.extractItem(slot, amount, true); - if (result.isEmpty() || !itemFilterContainer.testItemStack(result)) { + if (result.isEmpty() || !itemFilterContainer.test(result)) { return ItemStack.EMPTY; } return simulate ? result : super.extractItem(slot, amount, false); diff --git a/src/main/java/gregtech/common/covers/CoverDigitalInterface.java b/src/main/java/gregtech/common/covers/CoverDigitalInterface.java index 7455688d164..d4950ca4ac7 100644 --- a/src/main/java/gregtech/common/covers/CoverDigitalInterface.java +++ b/src/main/java/gregtech/common/covers/CoverDigitalInterface.java @@ -19,6 +19,7 @@ import gregtech.api.util.TextFormattingUtil; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.RenderUtil; +import gregtech.common.metatileentities.multi.electric.MetaTileEntityPowerSubstation; import gregtech.common.terminal.app.prospector.widget.WidgetOreList; import net.minecraft.client.Minecraft; @@ -228,7 +229,7 @@ public void onAttachment(@NotNull CoverableView coverableView, @NotNull EnumFaci } else if (getItemCapability() != null) { items = new ItemStack[getItemCapability().getSlots()]; this.mode = MODE.ITEM; - } else if (getEnergyCapability() != null) { + } else if (getEnergyCapability() != null || getCoverableView() instanceof MetaTileEntityPowerSubstation) { this.mode = MODE.ENERGY; } else if (getMachineCapability() != null) { this.mode = MODE.MACHINE; @@ -579,22 +580,19 @@ private void syncAllInfo() { } } if (this.mode == MODE.ENERGY || (mode == MODE.PROXY && proxyMode[2] > 0)) { - IEnergyContainer energyContainer = this.getEnergyCapability(); - if (energyContainer != null) { - // TODO, figure out what to do when values exceed Long.MAX_VALUE, ie with multiple Ultimate batteries - if (energyStored != energyContainer.getEnergyStored() || - energyCapability != energyContainer.getEnergyCapacity()) { - energyStored = energyContainer.getEnergyStored(); - energyCapability = energyContainer.getEnergyCapacity(); + if (getCoverableView() instanceof MetaTileEntityPowerSubstation pss) { + if (energyStored != pss.getStoredLong() || energyCapability != pss.getCapacityLong()) { + energyStored = pss.getStoredLong(); + energyCapability = pss.getCapacityLong(); writeCustomData(GregtechDataCodes.UPDATE_ENERGY, packetBuffer -> { packetBuffer.writeLong(energyStored); packetBuffer.writeLong(energyCapability); }); } - if (this.getOffsetTimer() % 20 == 0) { // per second + if (this.getOffsetTimer() % 20 == 0) { writeCustomData(GregtechDataCodes.UPDATE_ENERGY_PER, packetBuffer -> { - packetBuffer.writeLong(energyContainer.getInputPerSec()); - packetBuffer.writeLong(energyContainer.getOutputPerSec()); + packetBuffer.writeLong(pss.getAverageInLastSec() * 20L); + packetBuffer.writeLong(pss.getAverageOutLastSec() * 20L); inputEnergyList.add(energyInputPerDur); outputEnergyList.add(energyOutputPerDur); if (inputEnergyList.size() > 13) { @@ -603,6 +601,33 @@ private void syncAllInfo() { } }); } + } else { + IEnergyContainer energyContainer = this.getEnergyCapability(); + if (energyContainer != null) { + // TODO, figure out what to do when values exceed Long.MAX_VALUE, ie with multiple Ultimate + // batteries + if (energyStored != energyContainer.getEnergyStored() || + energyCapability != energyContainer.getEnergyCapacity()) { + energyStored = energyContainer.getEnergyStored(); + energyCapability = energyContainer.getEnergyCapacity(); + writeCustomData(GregtechDataCodes.UPDATE_ENERGY, packetBuffer -> { + packetBuffer.writeLong(energyStored); + packetBuffer.writeLong(energyCapability); + }); + } + if (this.getOffsetTimer() % 20 == 0) { // per second + writeCustomData(GregtechDataCodes.UPDATE_ENERGY_PER, packetBuffer -> { + packetBuffer.writeLong(energyContainer.getInputPerSec()); + packetBuffer.writeLong(energyContainer.getOutputPerSec()); + inputEnergyList.add(energyInputPerDur); + outputEnergyList.add(energyOutputPerDur); + if (inputEnergyList.size() > 13) { + inputEnergyList.remove(0); + outputEnergyList.remove(0); + } + }); + } + } } } if (this.mode == MODE.MACHINE || (mode == MODE.PROXY && proxyMode[3] > 0)) { @@ -626,17 +651,28 @@ private void syncAllInfo() { }); } if (this.getOffsetTimer() % 20 == 0) { - IEnergyContainer energyContainer = this.getEnergyCapability(); - if (energyContainer != null) { - if (energyStored != energyContainer.getEnergyStored() || - energyCapability != energyContainer.getEnergyCapacity()) { - energyStored = energyContainer.getEnergyStored(); - energyCapability = energyContainer.getEnergyCapacity(); + if (getCoverableView() instanceof MetaTileEntityPowerSubstation pss) { + if (energyStored != pss.getStoredLong() || energyCapability != pss.getCapacityLong()) { + energyStored = pss.getStoredLong(); + energyCapability = pss.getCapacityLong(); writeCustomData(GregtechDataCodes.UPDATE_ENERGY, packetBuffer -> { packetBuffer.writeLong(energyStored); packetBuffer.writeLong(energyCapability); }); } + } else { + IEnergyContainer energyContainer = this.getEnergyCapability(); + if (energyContainer != null) { + if (energyStored != energyContainer.getEnergyStored() || + energyCapability != energyContainer.getEnergyCapacity()) { + energyStored = energyContainer.getEnergyStored(); + energyCapability = energyContainer.getEnergyCapacity(); + writeCustomData(GregtechDataCodes.UPDATE_ENERGY, packetBuffer -> { + packetBuffer.writeLong(energyStored); + packetBuffer.writeLong(energyCapability); + }); + } + } } } } @@ -861,6 +897,7 @@ public boolean canCapabilityAttach() { return getFluidCapability() != null || getItemCapability() != null || getEnergyCapability() != null || + getCoverableView() instanceof MetaTileEntityPowerSubstation || getMachineCapability() != null; } diff --git a/src/main/java/gregtech/common/covers/CoverEnderFluidLink.java b/src/main/java/gregtech/common/covers/CoverEnderFluidLink.java index b34348c69bb..ffe2f9ed8a0 100644 --- a/src/main/java/gregtech/common/covers/CoverEnderFluidLink.java +++ b/src/main/java/gregtech/common/covers/CoverEnderFluidLink.java @@ -6,9 +6,8 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverWithUI; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.*; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; import gregtech.api.util.FluidTankSwitchShim; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.VirtualTankRegistry; @@ -20,7 +19,11 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; -import net.minecraft.util.*; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.ITickable; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; @@ -30,6 +33,22 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.drawable.DynamicDrawable; +import com.cleanroommc.modularui.drawable.Rectangle; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.FluidSlotSyncHandler; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.widgets.FluidSlot; +import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -106,7 +125,7 @@ public void onAttachment(@NotNull CoverableView coverableView, @NotNull EnumFaci @Override public void onRemoval() { - dropInventoryContents(fluidFilter.getFilterInventory()); + dropInventoryContents(fluidFilter); } @Override @@ -121,9 +140,9 @@ protected void transferFluids() { getAttachedSide()); if (fluidHandler == null) return; if (pumpMode == CoverPump.PumpMode.IMPORT) { - GTTransferUtils.transferFluids(fluidHandler, linkedTank, TRANSFER_RATE, fluidFilter::testFluidStack); + GTTransferUtils.transferFluids(fluidHandler, linkedTank, TRANSFER_RATE, fluidFilter::test); } else if (pumpMode == CoverPump.PumpMode.EXPORT) { - GTTransferUtils.transferFluids(linkedTank, fluidHandler, TRANSFER_RATE, fluidFilter::testFluidStack); + GTTransferUtils.transferFluids(linkedTank, fluidHandler, TRANSFER_RATE, fluidFilter::test); } } @@ -143,36 +162,86 @@ public void openUI(EntityPlayerMP player) { } @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup widgetGroup = new WidgetGroup(); - widgetGroup.addWidget(new LabelWidget(10, 5, "cover.ender_fluid_link.title")); - widgetGroup.addWidget(new ToggleButtonWidget(12, 18, 18, 18, GuiTextures.BUTTON_PUBLIC_PRIVATE, - this::isPrivate, this::setPrivate) - .setTooltipText("cover.ender_fluid_link.private.tooltip")); - widgetGroup.addWidget(new SyncableColorRectWidget(35, 18, 18, 18, () -> color) - .setBorderWidth(1) - .drawCheckerboard(4, 4)); - widgetGroup.addWidget(new TextFieldWidget(58, 13, 58, 18, true, - this::getColorStr, this::updateColor, 8) - .setValidator(str -> COLOR_INPUT_PATTERN.matcher(str).matches())); - widgetGroup.addWidget(new TankWidget(this.linkedTank, 123, 18, 18, 18) - .setContainerClicking(true, true) - .setBackgroundTexture(GuiTextures.FLUID_SLOT).setAlwaysShowFull(true)); - widgetGroup.addWidget(new ImageWidget(147, 19, 16, 16) - .setImage(GuiTextures.INFO_ICON) - .setPredicate(() -> isColorTemp) - .setTooltip("cover.ender_fluid_link.incomplete_hex") - .setIgnoreColor(true)); - widgetGroup.addWidget(new CycleButtonWidget(10, 42, 75, 18, - CoverPump.PumpMode.class, this::getPumpMode, this::setPumpMode)); - widgetGroup.addWidget(new CycleButtonWidget(92, 42, 75, 18, - this::isIoEnabled, this::setIoEnabled, "cover.ender_fluid_link.iomode.disabled", - "cover.ender_fluid_link.iomode.enabled")); - this.fluidFilter.initUI(65, widgetGroup::addWidget); - return ModularUI.builder(GuiTextures.BACKGROUND, 176, 221) - .widget(widgetGroup) - .bindPlayerInventory(player.inventory, 139) - .build(this, player); + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(SidedPosGuiData guiData, GuiSyncManager guiSyncManager) { + var panel = GTGuis.createPanel(this, 176, 192); + + getFluidFilterContainer().setMaxTransferSize(1); + + return panel.child(CoverWithUI.createTitleRow(getPickItem())) + .child(createWidgets(panel, guiSyncManager)) + .bindPlayerInventory(); + } + + protected Column createWidgets(ModularPanel panel, GuiSyncManager syncManager) { + var isPrivate = new BooleanSyncValue(this::isPrivate, this::setPrivate); + isPrivate.updateCacheFromSource(true); + + var color = new StringSyncValue(this::getColorStr, this::updateColor); + color.updateCacheFromSource(true); + + var pumpMode = new EnumSyncValue<>(CoverPump.PumpMode.class, this::getPumpMode, this::setPumpMode); + syncManager.syncValue("pump_mode", pumpMode); + pumpMode.updateCacheFromSource(true); + + var ioEnabled = new BooleanSyncValue(this::isIOEnabled, this::setIoEnabled); + + var fluidTank = new FluidSlotSyncHandler(this.linkedTank); + fluidTank.updateCacheFromSource(true); + + return new Column().coverChildrenHeight().top(24) + .margin(7, 0).widthRel(1f) + .child(new Row().marginBottom(2) + .coverChildrenHeight() + .child(new ToggleButton() + .tooltip(tooltip -> tooltip.setAutoUpdate(true)) + .background(GTGuiTextures.PRIVATE_MODE_BUTTON[0]) + .hoverBackground(GTGuiTextures.PRIVATE_MODE_BUTTON[0]) + .selectedBackground(GTGuiTextures.PRIVATE_MODE_BUTTON[1]) + .selectedHoverBackground(GTGuiTextures.PRIVATE_MODE_BUTTON[1]) + .tooltipBuilder(tooltip -> tooltip.addLine(IKey.lang(this.isPrivate ? + "cover.ender_fluid_link.private.tooltip.enabled" : + "cover.ender_fluid_link.private.tooltip.disabled"))) + .marginRight(2) + .value(isPrivate)) + .child(new DynamicDrawable(() -> new Rectangle() + .setColor(this.color) + .asIcon().size(16)) + .asWidget() + .background(GTGuiTextures.SLOT) + .size(18).marginRight(2)) + .child(new TextFieldWidget().height(18) + .value(color) + .setValidator(s -> { + if (s.length() != 8) { + return color.getStringValue(); + } + return s; + }) + .setPattern(COLOR_INPUT_PATTERN) + .widthRel(0.5f).marginRight(2)) + .child(new FluidSlot().size(18) + .syncHandler(fluidTank))) + .child(new Row().marginBottom(2) + .coverChildrenHeight() + .child(new ToggleButton() + .value(ioEnabled) + .overlay(IKey.dynamic(() -> IKey.lang(this.ioEnabled ? + "behaviour.soft_hammer.enabled" : + "behaviour.soft_hammer.disabled").get()) + .color(Color.WHITE.darker(1))) + .widthRel(0.6f) + .left(0))) + .child(getFluidFilterContainer().initUI(panel, syncManager)) + .child(new EnumRowBuilder<>(CoverPump.PumpMode.class) + .value(pumpMode) + .overlay(GTGuiTextures.CONVEYOR_MODE_OVERLAY) + .lang("cover.pump.mode") + .build()); } public void updateColor(String str) { diff --git a/src/main/java/gregtech/common/covers/CoverFluidFilter.java b/src/main/java/gregtech/common/covers/CoverFluidFilter.java index cd5d06ee5a4..648968c90dc 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidFilter.java +++ b/src/main/java/gregtech/common/covers/CoverFluidFilter.java @@ -5,19 +5,19 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverWithUI; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.CycleButtonWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.WidgetGroup; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; -import gregtech.common.covers.filter.FluidFilter; -import gregtech.common.covers.filter.FluidFilterWrapper; +import gregtech.client.utils.TooltipHelper; +import gregtech.common.covers.filter.BaseFilter; +import gregtech.common.covers.filter.FluidFilterContainer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; @@ -32,26 +32,34 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.drawable.Rectangle; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.layout.Column; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.IOException; + public class CoverFluidFilter extends CoverBase implements CoverWithUI { protected final String titleLocale; protected final SimpleOverlayRenderer texture; - protected final FluidFilterWrapper fluidFilter; + protected final FluidFilterContainer fluidFilterContainer; protected FluidFilterMode filterMode; protected FluidHandlerFiltered fluidHandler; public CoverFluidFilter(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, - @NotNull EnumFacing attachedSide, String titleLocale, SimpleOverlayRenderer texture, - FluidFilter fluidFilter) { + @NotNull EnumFacing attachedSide, String titleLocale, SimpleOverlayRenderer texture) { super(definition, coverableView, attachedSide); + this.fluidFilterContainer = new FluidFilterContainer(this); this.filterMode = FluidFilterMode.FILTER_FILL; this.titleLocale = titleLocale; this.texture = texture; - this.fluidFilter = new FluidFilterWrapper(this); - this.fluidFilter.setFluidFilter(fluidFilter); } public void setFilterMode(FluidFilterMode filterMode) { @@ -59,16 +67,51 @@ public void setFilterMode(FluidFilterMode filterMode) { this.getCoverableView().markDirty(); } - public FluidFilterMode getFilterMode() { - return filterMode; + @Override + public void onAttachment(@NotNull CoverableView coverableView, @NotNull EnumFacing side, + @Nullable EntityPlayer player, @NotNull ItemStack itemStack) { + super.onAttachment(coverableView, side, player, itemStack); + var dropStack = GTUtility.copy(1, itemStack); + this.fluidFilterContainer.setFilterStack(dropStack); } - public FluidFilterWrapper getFluidFilter() { - return this.fluidFilter; + @Override + public @NotNull ItemStack getPickItem() { + if (TooltipHelper.isCtrlDown()) + return getCoverableView().getStackForm(); + + return this.fluidFilterContainer.getFilterStack(); } - public boolean testFluidStack(FluidStack stack) { - return fluidFilter.testFluidStack(stack); + @Override + public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { + packetBuffer.writeByte(this.filterMode.ordinal()); + packetBuffer.writeBoolean(this.fluidFilterContainer.hasFilter()); + if (this.fluidFilterContainer.hasFilter()) { + packetBuffer.writeItemStack(this.fluidFilterContainer.getFilterStack()); + } + } + + @Override + public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { + this.filterMode = FluidFilterMode.VALUES[packetBuffer.readByte()]; + if (!packetBuffer.readBoolean()) return; + try { + this.fluidFilterContainer.setFilterStack(packetBuffer.readItemStack()); + } catch (IOException e) { + GTLog.logger.error("Failed to read filter for CoverFluidFilter! %s", getPos().toString()); + } + } + + public FluidFilterMode getFilterMode() { + return filterMode; + } + + @SuppressWarnings("DataFlowIssue") // this cover always has a filter + public @NotNull BaseFilter getFilter() { + return this.fluidFilterContainer.hasFilter() ? + this.fluidFilterContainer.getFilter() : + BaseFilter.ERROR_FILTER; } @Override @@ -89,18 +132,32 @@ public boolean canPipePassThrough() { return EnumActionResult.SUCCESS; } - public ModularUI createUI(EntityPlayer player) { - WidgetGroup fluidFilterGroup = new WidgetGroup(); - fluidFilterGroup.addWidget(new LabelWidget(10, 5, "cover.fluid_filter.title")); - fluidFilterGroup.addWidget(new CycleButtonWidget(10, 20, 110, 20, - GTUtility.mapToString(FluidFilterMode.values(), (it) -> it.localeName), () -> this.filterMode.ordinal(), - (newMode) -> this.setFilterMode(FluidFilterMode.values()[newMode]))); - this.fluidFilter.initUI(45, fluidFilterGroup::addWidget); - this.fluidFilter.blacklistUI(45, fluidFilterGroup::addWidget, () -> true); - return ModularUI.builder(GuiTextures.BACKGROUND, 176, 105 + 82) - .widget(fluidFilterGroup) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 105) - .build(this, player); + @Override + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(SidedPosGuiData guiData, GuiSyncManager guiSyncManager) { + var filteringMode = new EnumSyncValue<>(FluidFilterMode.class, this::getFilterMode, this::setFilterMode); + + guiSyncManager.syncValue("filtering_mode", filteringMode); + this.fluidFilterContainer.setMaxTransferSize(1); + getFilter().getFilterReader().readStack(this.fluidFilterContainer.getFilterStack()); + + return getFilter().createPanel(guiSyncManager) + .size(176, 194).padding(7) + .child(CoverWithUI.createTitleRow(getPickItem())) + .child(new Column().widthRel(1f).align(Alignment.TopLeft).top(22).coverChildrenHeight() + .child(new EnumRowBuilder<>(FluidFilterMode.class) + .value(filteringMode) + .lang("cover.filter.mode.title") + .overlay(16, GTGuiTextures.FILTER_MODE_OVERLAY) + .build()) + .child(new Rectangle().setColor(UI_TEXT_COLOR).asWidget() + .height(1).widthRel(0.95f).margin(0, 4)) + .child(getFilter().createWidgets(guiSyncManager))) + .child(SlotGroupWidget.playerInventory().bottom(7).left(7)); } @Override @@ -127,18 +184,21 @@ public T getCapability(@NotNull Capability capability, @Nullable T defaul public void writeToNBT(@NotNull NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); tagCompound.setInteger("FilterMode", this.filterMode.ordinal()); - tagCompound.setBoolean("IsBlacklist", this.fluidFilter.isBlacklistFilter()); - NBTTagCompound filterComponent = new NBTTagCompound(); - this.fluidFilter.getFluidFilter().writeToNBT(filterComponent); - tagCompound.setTag("Filter", filterComponent); + tagCompound.setTag("Filter", this.fluidFilterContainer.serializeNBT()); } @Override public void readFromNBT(@NotNull NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); this.filterMode = FluidFilterMode.values()[tagCompound.getInteger("FilterMode")]; - this.fluidFilter.setBlacklistFilter(tagCompound.getBoolean("IsBlacklist")); - this.fluidFilter.getFluidFilter().readFromNBT(tagCompound.getCompoundTag("Filter")); + var filterTag = tagCompound.getCompoundTag("Filter"); + if (!filterTag.hasKey("FilterInventory")) { + this.fluidFilterContainer.setFilterStack(getDefinition().getDropItemStack()); + } else { + this.fluidFilterContainer.deserializeNBT(filterTag); + } + + this.fluidFilterContainer.handleLegacyNBT(tagCompound); } private class FluidHandlerFiltered extends FluidHandlerDelegate { @@ -148,7 +208,7 @@ public FluidHandlerFiltered(@NotNull IFluidHandler delegate) { } public int fill(FluidStack resource, boolean doFill) { - if (getFilterMode() == FluidFilterMode.FILTER_DRAIN || !fluidFilter.testFluidStack(resource)) { + if (getFilterMode() == FluidFilterMode.FILTER_DRAIN || !fluidFilterContainer.test(resource)) { return 0; } return super.fill(resource, doFill); @@ -156,7 +216,7 @@ public int fill(FluidStack resource, boolean doFill) { @Nullable public FluidStack drain(FluidStack resource, boolean doDrain) { - if (getFilterMode() == FluidFilterMode.FILTER_FILL || !fluidFilter.testFluidStack(resource)) { + if (getFilterMode() == FluidFilterMode.FILTER_FILL || !fluidFilterContainer.test(resource)) { return null; } return super.drain(resource, doDrain); @@ -166,7 +226,7 @@ public FluidStack drain(FluidStack resource, boolean doDrain) { public FluidStack drain(int maxDrain, boolean doDrain) { if (getFilterMode() != FluidFilterMode.FILTER_FILL) { FluidStack result = super.drain(maxDrain, false); - if (result == null || result.amount <= 0 || !fluidFilter.testFluidStack(result)) { + if (result == null || result.amount <= 0 || !fluidFilterContainer.test(result)) { return null; } return doDrain ? super.drain(maxDrain, true) : result; diff --git a/src/main/java/gregtech/common/covers/CoverFluidRegulator.java b/src/main/java/gregtech/common/covers/CoverFluidRegulator.java index 553f2734b46..dc55702148d 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidRegulator.java +++ b/src/main/java/gregtech/common/covers/CoverFluidRegulator.java @@ -2,38 +2,37 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.*; +import gregtech.api.mui.GTGuiTextures; import gregtech.api.util.GTTransferUtils; -import gregtech.api.util.TextFormattingUtil; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleSidedCubeRenderer; -import gregtech.common.covers.filter.FluidFilter; import gregtech.common.covers.filter.FluidFilterContainer; +import gregtech.common.covers.filter.SimpleFluidFilter; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TextComponentString; -import net.minecraft.util.text.TextComponentTranslation; -import net.minecraft.util.text.event.HoverEvent; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidTankProperties; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import com.google.common.math.IntMath; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.apache.logging.log4j.message.FormattedMessage; import org.jetbrains.annotations.NotNull; import java.util.Arrays; -import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Predicate; @@ -41,21 +40,11 @@ public class CoverFluidRegulator extends CoverPump { protected TransferMode transferMode = TransferMode.TRANSFER_ANY; - protected int transferAmount = 0; public CoverFluidRegulator(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, @NotNull EnumFacing attachedSide, int tier, int mbPerTick) { super(definition, coverableView, attachedSide, tier, mbPerTick); - this.fluidFilter = new FluidFilterContainer(this, this::shouldShowTip, maxFluidTransferRate * 100); - } - - @Override - protected boolean shouldShowTip() { - return transferMode != TransferMode.TRANSFER_ANY; - } - - public int getTransferAmount() { - return transferAmount; + this.fluidFilterContainer = new FluidFilterContainer(this); } @Override @@ -75,11 +64,12 @@ protected int doTransferFluidsInternal(IFluidHandler myFluidHandler, IFluidHandl } return switch (transferMode) { case TRANSFER_ANY -> GTTransferUtils.transferFluids(sourceHandler, destHandler, transferLimit, - fluidFilter::testFluidStack); - case KEEP_EXACT -> doKeepExact(transferLimit, sourceHandler, destHandler, fluidFilter::testFluidStack, - this.transferAmount); + fluidFilterContainer::test); + case KEEP_EXACT -> doKeepExact(transferLimit, sourceHandler, destHandler, + fluidFilterContainer::test, + this.fluidFilterContainer.getTransferSize()); case TRANSFER_EXACT -> doTransferExact(transferLimit, sourceHandler, destHandler, - fluidFilter::testFluidStack, this.transferAmount); + fluidFilterContainer::test, this.fluidFilterContainer.getTransferSize()); }; } @@ -88,9 +78,8 @@ protected int doTransferExact(int transferLimit, IFluidHandler sourceHandler, IF int fluidLeftToTransfer = transferLimit; for (IFluidTankProperties tankProperties : sourceHandler.getTankProperties()) { FluidStack sourceFluid = tankProperties.getContents(); - if (this.fluidFilter.getFilterWrapper().getFluidFilter() != null && - transferMode != TransferMode.TRANSFER_ANY) { - supplyAmount = this.fluidFilter.getFilterWrapper().getFluidFilter().getFluidTransferLimit(sourceFluid); + if (this.fluidFilterContainer.hasFilter()) { + supplyAmount = this.fluidFilterContainer.getFilter().getTransferLimit(sourceFluid, supplyAmount); } if (fluidLeftToTransfer < supplyAmount) break; @@ -132,9 +121,8 @@ protected int doKeepExact(final int transferLimit, if (transferred >= transferLimit) break; - if (this.fluidFilter.getFilterWrapper().getFluidFilter() != null && - transferMode != TransferMode.TRANSFER_ANY) { - keepAmount = this.fluidFilter.getFilterWrapper().getFluidFilter().getFluidTransferLimit(fluidStack); + if (this.fluidFilterContainer.hasFilter()) { + keepAmount = this.fluidFilterContainer.getFilter().getTransferLimit(fluidStack, keepAmount); } // if fluid needs to be moved to meet the Keep Exact value @@ -235,8 +223,11 @@ private static Map collectDistinctFluids(IFluidHandler hand } public void setTransferMode(TransferMode transferMode) { - this.transferMode = transferMode; - this.markDirty(); + if (this.transferMode != transferMode) { + this.transferMode = transferMode; + this.fluidFilterContainer.setMaxTransferSize(getMaxTransferRate()); + this.markDirty(); + } } public TransferMode getTransferMode() { @@ -244,122 +235,87 @@ public TransferMode getTransferMode() { } private boolean shouldDisplayAmountSlider() { - if (this.fluidFilter.getFilterWrapper().getFluidFilter() != null) { + if (transferMode == TransferMode.TRANSFER_ANY) { return false; } - return this.transferMode == TransferMode.TRANSFER_EXACT || this.transferMode == TransferMode.KEEP_EXACT; - } - - public String getTransferAmountString() { - return Integer.toString(this.bucketMode == BucketMode.BUCKET ? transferAmount / 1000 : transferAmount); - } - - private String getTransferSizeString() { - int val = transferAmount; - if (this.bucketMode == BucketMode.BUCKET) { - val /= 1000; - } - return val == -1 ? "" : TextFormattingUtil.formatLongToCompactString(val); - } - - protected void getHoverString(List textList) { - ITextComponent keepComponent = new TextComponentString(getTransferSizeString()); - TextComponentTranslation hoverKeep = new TextComponentTranslation( - "cover.fluid_regulator." + transferMode.name().toLowerCase(), this.transferAmount); - keepComponent.getStyle().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hoverKeep)); - textList.add(keepComponent); + return fluidFilterContainer.showGlobalTransferLimitSlider(); } @Override - public void setBucketMode(BucketMode bucketMode) { - super.setBucketMode(bucketMode); - if (this.bucketMode == BucketMode.BUCKET) { - setTransferAmount(transferAmount / 1000 * 1000); - } + public ModularPanel buildUI(SidedPosGuiData guiData, GuiSyncManager guiSyncManager) { + return super.buildUI(guiData, guiSyncManager).height(192 + 36); } - private void adjustTransferSize(int amount) { - if (bucketMode == BucketMode.BUCKET) - amount *= 1000; - switch (this.transferMode) { - case TRANSFER_EXACT -> setTransferAmount( - MathHelper.clamp(this.transferAmount + amount, 0, this.maxFluidTransferRate)); - case KEEP_EXACT -> setTransferAmount(MathHelper.clamp(this.transferAmount + amount, 0, Integer.MAX_VALUE)); - } + @Override + protected ParentWidget createUI(ModularPanel mainPanel, GuiSyncManager syncManager) { + var transferMode = new EnumSyncValue<>(TransferMode.class, this::getTransferMode, this::setTransferMode); + transferMode.updateCacheFromSource(true); + syncManager.syncValue("transfer_mode", transferMode); + + var bucketMode = new EnumSyncValue<>(BucketMode.class, this::getBucketMode, this::setBucketMode); + bucketMode.updateCacheFromSource(true); + syncManager.syncValue("bucket_mode", bucketMode); + + var filterTransferSize = new StringSyncValue(this::getStringTransferRate, this::setStringTransferRate); + filterTransferSize.updateCacheFromSource(true); + + return super.createUI(mainPanel, syncManager) + .child(new EnumRowBuilder<>(TransferMode.class) + .value(transferMode) + .lang("cover.generic.transfer_mode") + .overlay(GTGuiTextures.FLUID_TRANSFER_MODE_OVERLAY) + .build()) + .child(new EnumRowBuilder<>(BucketMode.class) + .value(bucketMode) + .overlay(IKey.str("kL"), IKey.str("L")) + .build() + .child(new TextFieldWidget().widthRel(0.5f).right(0) + .setEnabledIf(w -> shouldDisplayAmountSlider()) + .setNumbers(0, Integer.MAX_VALUE) + .value(filterTransferSize) + .setTextColor(Color.WHITE.darker(1)))); } - private void setTransferAmount(int transferAmount) { - this.transferAmount = transferAmount; - markDirty(); + @Override + public int getMaxTransferRate() { + return switch (this.transferMode) { + case TRANSFER_ANY -> 1; + case TRANSFER_EXACT -> maxFluidTransferRate; + case KEEP_EXACT -> Integer.MAX_VALUE; + }; } @Override - protected String getUITitle() { - return "cover.fluid_regulator.title"; + public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.writeInitialSyncData(packetBuffer); + packetBuffer.writeByte(this.transferMode.ordinal()); } - @SuppressWarnings("UnstableApiUsage") @Override - protected ModularUI buildUI(ModularUI.Builder builder, EntityPlayer player) { - WidgetGroup filterGroup = new WidgetGroup(); - filterGroup.addWidget(new CycleButtonWidget(92, 43, 75, 18, - TransferMode.class, this::getTransferMode, this::setTransferMode) - .setTooltipHoverString("cover.fluid_regulator.transfer_mode.description")); - - ServerWidgetGroup stackSizeGroup = new ServerWidgetGroup(this::shouldDisplayAmountSlider); - stackSizeGroup.addWidget(new ImageWidget(110, 64, 38, 18, GuiTextures.DISPLAY)); - - stackSizeGroup.addWidget(new IncrementButtonWidget(148, 64, 18, 18, 1, 10, 100, 1000, this::adjustTransferSize) - .setDefaultTooltip() - .setTextScale(0.7f) - .setShouldClientCallback(false)); - stackSizeGroup - .addWidget(new IncrementButtonWidget(92, 64, 18, 18, -1, -10, -100, -1000, this::adjustTransferSize) - .setDefaultTooltip() - .setTextScale(0.7f) - .setShouldClientCallback(false)); - - stackSizeGroup.addWidget(new TextFieldWidget2(111, 70, 36, 11, this::getTransferAmountString, val -> { - if (val != null && !val.isEmpty()) { - int amount = Integer.parseInt(val); - if (this.bucketMode == BucketMode.BUCKET) { - amount = IntMath.saturatedMultiply(amount, 1000); - } - setTransferAmount(amount); - } - }) - .setCentered(true) - .setNumbersOnly(1, - transferMode == TransferMode.TRANSFER_EXACT ? maxFluidTransferRate : Integer.MAX_VALUE) - .setMaxLength(10) - .setScale(0.6f)); - - stackSizeGroup - .addWidget(new SimpleTextWidget(129, 78, "", 0xFFFFFF, () -> bucketMode.localeName).setScale(0.6f)); - - return super.buildUI(builder.widget(filterGroup).widget(stackSizeGroup), player); + public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.readInitialSyncData(packetBuffer); + this.transferMode = TransferMode.VALUES[packetBuffer.readByte()]; } @Override public void writeToNBT(@NotNull NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); tagCompound.setInteger("TransferMode", transferMode.ordinal()); - tagCompound.setInteger("TransferAmount", transferAmount); tagCompound.setTag("filterv2", new NBTTagCompound()); } @Override public void readFromNBT(@NotNull NBTTagCompound tagCompound) { + this.transferMode = TransferMode.VALUES[tagCompound.getInteger("TransferMode")]; + this.fluidFilterContainer.setMaxTransferSize(this.transferMode.maxStackSize); super.readFromNBT(tagCompound); - this.transferMode = TransferMode.values()[tagCompound.getInteger("TransferMode")]; // legacy NBT tag if (!tagCompound.hasKey("filterv2") && tagCompound.hasKey("TransferAmount")) { - FluidFilter filter = getFluidFilterContainer().getFilterWrapper().getFluidFilter(); - if (filter != null) { - filter.configureFilterTanks(tagCompound.getInteger("TransferAmount")); + if (this.fluidFilterContainer.getFilter() instanceof SimpleFluidFilter simpleFluidFilter) { + simpleFluidFilter + .configureFilterTanks(tagCompound.getInteger("TransferAmount")); } } - this.transferAmount = tagCompound.getInteger("TransferAmount"); } @Override diff --git a/src/main/java/gregtech/common/covers/CoverFluidVoiding.java b/src/main/java/gregtech/common/covers/CoverFluidVoiding.java index 4c1f097ccee..c781f816bef 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidVoiding.java +++ b/src/main/java/gregtech/common/covers/CoverFluidVoiding.java @@ -3,11 +3,6 @@ import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.CycleButtonWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.WidgetGroup; import gregtech.api.util.GTTransferUtils; import gregtech.client.renderer.texture.Textures; import gregtech.common.covers.filter.FluidFilterContainer; @@ -29,6 +24,15 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.layout.Row; import org.jetbrains.annotations.NotNull; public class CoverFluidVoiding extends CoverPump { @@ -39,7 +43,8 @@ public CoverFluidVoiding(@NotNull CoverDefinition definition, @NotNull Coverable @NotNull EnumFacing attachedSide) { super(definition, coverableView, attachedSide, 0, Integer.MAX_VALUE); this.isWorkingAllowed = false; - this.fluidFilter = new FluidFilterContainer(this, this::shouldShowTip, Integer.MAX_VALUE); + this.fluidFilterContainer = new FluidFilterContainer(this); + this.fluidFilterContainer.setMaxTransferSize(Integer.MAX_VALUE); } @Override @@ -55,39 +60,46 @@ protected void doTransferFluids() { if (myFluidHandler == null) { return; } - GTTransferUtils.transferFluids(myFluidHandler, nullFluidTank, Integer.MAX_VALUE, fluidFilter::testFluidStack); + GTTransferUtils.transferFluids(myFluidHandler, nullFluidTank, Integer.MAX_VALUE, + fluidFilterContainer::test); } @Override - protected String getUITitle() { - return "cover.fluid.voiding.title"; + public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 translation, + IVertexOperation[] pipeline, @NotNull Cuboid6 plateBox, @NotNull BlockRenderLayer layer) { + Textures.FLUID_VOIDING.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup primaryGroup = new WidgetGroup(); - primaryGroup.addWidget(new LabelWidget(10, 5, getUITitle())); - - this.fluidFilter.initUI(20, primaryGroup::addWidget); - - primaryGroup.addWidget(new CycleButtonWidget(10, 92, 80, 18, this::isWorkingEnabled, this::setWorkingEnabled, - "cover.voiding.label.disabled", "cover.voiding.label.enabled") - .setTooltipHoverString("cover.voiding.tooltip")); + public ModularPanel buildUI(SidedPosGuiData guiData, GuiSyncManager guiSyncManager) { + return super.buildUI(guiData, guiSyncManager).height(192 - 22); + } - primaryGroup.addWidget(new CycleButtonWidget(10, 112, 116, 18, - ManualImportExportMode.class, this::getManualImportExportMode, this::setManualImportExportMode) - .setTooltipHoverString("cover.universal.manual_import_export.mode.description")); + @Override + protected ParentWidget createUI(ModularPanel mainPanel, GuiSyncManager syncManager) { + var isWorking = new BooleanSyncValue(this::isWorkingEnabled, this::setWorkingEnabled); + + return super.createUI(mainPanel, syncManager) + .child(new Row().height(18).widthRel(1f) + .marginBottom(2) + .child(new ToggleButton() + .value(isWorking) + .overlay(IKey.dynamic(() -> IKey.lang(this.isWorkingAllowed ? + "behaviour.soft_hammer.enabled" : + "behaviour.soft_hammer.disabled").get()) + .color(Color.WHITE.darker(1))) + .widthRel(0.6f) + .left(0))); + } - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, 100 + 82 + 16 + 24) - .widget(primaryGroup) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 100 + 16 + 24); - return builder.build(this, player); + @Override + protected boolean createPumpModeRow() { + return false; } @Override - public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 translation, - IVertexOperation[] pipeline, @NotNull Cuboid6 plateBox, @NotNull BlockRenderLayer layer) { - Textures.FLUID_VOIDING.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); + protected boolean createThroughputRow() { + return false; } @Override @@ -120,7 +132,7 @@ public NullFluidTank() { @Override public int fill(FluidStack resource, boolean doFill) { - if (fluidFilter.testFluidStack(resource)) { + if (fluidFilterContainer.test(resource)) { return resource.amount; } return 0; diff --git a/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java b/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java index 4d2290aa13b..3af29c03b3b 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java +++ b/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java @@ -2,18 +2,14 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.*; +import gregtech.api.mui.GTGuiTextures; import gregtech.api.util.GTTransferUtils; import gregtech.client.renderer.texture.Textures; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.MathHelper; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; @@ -23,9 +19,17 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; -import java.util.function.Consumer; import java.util.function.Predicate; public class CoverFluidVoidingAdvanced extends CoverFluidVoiding { @@ -38,11 +42,6 @@ public CoverFluidVoidingAdvanced(@NotNull CoverDefinition definition, @NotNull C super(definition, coverableView, attachedSide); } - @Override - protected boolean shouldShowTip() { - return voidingMode != VoidingMode.VOID_ANY; - } - @Override protected void doTransferFluids() { IFluidHandler myFluidHandler = getCoverableView().getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, @@ -52,8 +51,9 @@ protected void doTransferFluids() { } switch (voidingMode) { case VOID_ANY -> GTTransferUtils.transferFluids(myFluidHandler, nullFluidTank, Integer.MAX_VALUE, - fluidFilter::testFluidStack); - case VOID_OVERFLOW -> voidOverflow(myFluidHandler, fluidFilter::testFluidStack, this.transferAmount); + fluidFilterContainer::test); + case VOID_OVERFLOW -> voidOverflow(myFluidHandler, fluidFilterContainer::test, + this.transferAmount); } } @@ -72,45 +72,26 @@ protected void voidOverflow(final IFluidHandler sourceHandler, for (IFluidTankProperties tankProperties : sourceHandler.getTankProperties()) { FluidStack sourceFluid = tankProperties.getContents(); - if (this.fluidFilter.getFilterWrapper().getFluidFilter() != null && + if (this.fluidFilterContainer.hasFilter() && voidingMode == VoidingMode.VOID_OVERFLOW) { - keepAmount = this.fluidFilter.getFilterWrapper().getFluidFilter().getFluidTransferLimit(sourceFluid); + keepAmount = this.fluidFilterContainer.getFilter() + .getTransferLimit(sourceFluid, getMaxTransferRate()); } if (sourceFluid == null || sourceFluid.amount == 0 || - !getFluidFilterContainer().testFluidStack(sourceFluid, true)) + !getFluidFilterContainer().test(sourceFluid)) continue; sourceFluid.amount = sourceFluid.amount - keepAmount; sourceHandler.drain(sourceFluid, true); } } - @Override - public void setBucketMode(BucketMode bucketMode) { - super.setBucketMode(bucketMode); - if (this.bucketMode == BucketMode.BUCKET) { - setTransferAmount(transferAmount / 1000 * 1000); - } - } - - private void adjustTransferSize(int amount) { - if (bucketMode == BucketMode.BUCKET) - amount *= 1000; - if (this.voidingMode == VoidingMode.VOID_OVERFLOW) { - setTransferAmount(MathHelper.clamp(this.transferAmount + amount, 0, Integer.MAX_VALUE)); - } - } - - private void setTransferAmount(int transferAmount) { - this.transferAmount = transferAmount; - markDirty(); - } - public int getTransferAmount() { - return this.transferAmount; + return this.fluidFilterContainer.getTransferSize(); } public void setVoidingMode(VoidingMode transferMode) { this.voidingMode = transferMode; + this.fluidFilterContainer.setMaxTransferSize(getMaxTransferRate()); this.markDirty(); } @@ -118,101 +99,64 @@ public VoidingMode getVoidingMode() { return voidingMode; } - private boolean shouldDisplayAmountSlider() { - if (this.fluidFilter.getFilterWrapper().getFluidFilter() != null) { - return false; - } - - return this.voidingMode == VoidingMode.VOID_OVERFLOW; + @Override + public ModularPanel buildUI(SidedPosGuiData guiData, GuiSyncManager guiSyncManager) { + return super.buildUI(guiData, guiSyncManager).height(192 + 20); } - public String getTransferAmountString() { - return Integer.toString(this.bucketMode == BucketMode.BUCKET ? transferAmount / 1000 : transferAmount); + @Override + protected ParentWidget createUI(ModularPanel mainPanel, GuiSyncManager syncManager) { + var voidingMode = new EnumSyncValue<>(VoidingMode.class, this::getVoidingMode, this::setVoidingMode); + syncManager.syncValue("voiding_mode", voidingMode); + + var bucketMode = new EnumSyncValue<>(BucketMode.class, this::getBucketMode, this::setBucketMode); + bucketMode.updateCacheFromSource(true); + syncManager.syncValue("bucket_mode", bucketMode); + + var filterTransferSize = new StringSyncValue(this::getStringTransferRate, this::setStringTransferRate); + var transferTextField = new TextFieldWidget().widthRel(0.5f).right(0); + transferTextField.setEnabled(this.fluidFilterContainer.showGlobalTransferLimitSlider() && + this.voidingMode == VoidingMode.VOID_OVERFLOW); + + return super.createUI(mainPanel, syncManager) + .child(new EnumRowBuilder<>(VoidingMode.class) + .value(voidingMode) + .lang("cover.voiding.voiding_mode") + .overlay(16, GTGuiTextures.VOIDING_MODE_OVERLAY) + .build()) + .child(new EnumRowBuilder<>(BucketMode.class) + .value(bucketMode) + .overlay(IKey.str("kL"), IKey.str("L")) + .build() + .child(transferTextField + .setEnabledIf(w -> this.fluidFilterContainer.showGlobalTransferLimitSlider() && + this.voidingMode == VoidingMode.VOID_OVERFLOW) + .setNumbers(0, Integer.MAX_VALUE) + .value(filterTransferSize) + .setTextColor(Color.WHITE.darker(1)))); } @Override - protected String getUITitle() { - return "cover.fluid.voiding.advanced.title"; + protected int getMaxTransferRate() { + return getVoidingMode().maxStackSize; } @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup primaryGroup = new WidgetGroup(); - primaryGroup.addWidget(new LabelWidget(10, 5, getUITitle())); - - primaryGroup.addWidget(new CycleButtonWidget(92, 15, 75, 18, - VoidingMode.class, this::getVoidingMode, this::setVoidingMode) - .setTooltipHoverString("cover.voiding.voiding_mode.description")); - - this.initFilterUI(20, primaryGroup::addWidget); - - primaryGroup.addWidget(new CycleButtonWidget(10, 92, 80, 18, this::isWorkingEnabled, this::setWorkingEnabled, - "cover.voiding.label.disabled", "cover.voiding.label.enabled") - .setTooltipHoverString("cover.voiding.tooltip")); - - primaryGroup.addWidget(new CycleButtonWidget(10, 112, 116, 18, - ManualImportExportMode.class, this::getManualImportExportMode, this::setManualImportExportMode) - .setTooltipHoverString("cover.universal.manual_import_export.mode.description")); - - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, 100 + 82 + 16 + 24) - .widget(primaryGroup) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 100 + 16 + 24); - return buildUI(builder, player); + public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 translation, + IVertexOperation[] pipeline, @NotNull Cuboid6 plateBox, @NotNull BlockRenderLayer layer) { + Textures.FLUID_VOIDING_ADVANCED.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } - public void initFilterUI(int y, Consumer widgetGroup) { - widgetGroup.accept(new LabelWidget(10, y, "cover.pump.fluid_filter.title")); - widgetGroup.accept(new SlotWidget(fluidFilter.getFilterInventory(), 0, 10, y + 15) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.FILTER_SLOT_OVERLAY)); - - ServerWidgetGroup stackSizeGroup = new ServerWidgetGroup(this::shouldDisplayAmountSlider); - stackSizeGroup.addWidget(new ImageWidget(110, 34, 38, 18, GuiTextures.DISPLAY)); - - stackSizeGroup.addWidget(new IncrementButtonWidget(148, 34, 18, 18, 1, 10, 100, 1000, this::adjustTransferSize) - .setDefaultTooltip() - .setTextScale(0.7f) - .setShouldClientCallback(false)); - stackSizeGroup - .addWidget(new IncrementButtonWidget(92, 34, 18, 18, -1, -10, -100, -1000, this::adjustTransferSize) - .setDefaultTooltip() - .setTextScale(0.7f) - .setShouldClientCallback(false)); - - stackSizeGroup.addWidget(new TextFieldWidget2(111, 39, 37, 11, this::getTransferAmountString, val -> { - if (val != null && !val.isEmpty()) { - int amount = Integer.parseInt(val); - if (this.bucketMode == BucketMode.BUCKET) { - amount *= 1000; - } - setTransferAmount(amount); - } - }) - .setCentered(true) - .setNumbersOnly(1, Integer.MAX_VALUE) - .setMaxLength(10) - .setScale(0.6f)); - - stackSizeGroup - .addWidget(new SimpleTextWidget(129, 47, "", 0xFFFFFF, () -> bucketMode.localeName).setScale(0.6f)); - - stackSizeGroup.addWidget(new CycleButtonWidget(114, 53, 30, 20, - BucketMode.class, this::getBucketMode, mode -> { - if (mode != bucketMode) { - setBucketMode(mode); - } - })); - - widgetGroup.accept(stackSizeGroup); - - this.fluidFilter.getFilterWrapper().initUI(y + 15, widgetGroup); - this.fluidFilter.getFilterWrapper().blacklistUI(y + 15, widgetGroup, - () -> voidingMode != VoidingMode.VOID_OVERFLOW); + @Override + public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.readInitialSyncData(packetBuffer); + this.voidingMode = VoidingMode.VALUES[packetBuffer.readByte()]; } @Override - public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 translation, - IVertexOperation[] pipeline, @NotNull Cuboid6 plateBox, @NotNull BlockRenderLayer layer) { - Textures.FLUID_VOIDING_ADVANCED.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); + public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.writeInitialSyncData(packetBuffer); + packetBuffer.writeByte(this.voidingMode.ordinal()); } @Override @@ -224,8 +168,9 @@ public void writeToNBT(@NotNull NBTTagCompound tagCompound) { @Override public void readFromNBT(@NotNull NBTTagCompound tagCompound) { - super.readFromNBT(tagCompound); - this.voidingMode = VoidingMode.values()[tagCompound.getInteger("VoidingMode")]; + this.voidingMode = VoidingMode.VALUES[tagCompound.getInteger("VoidingMode")]; + this.fluidFilterContainer.setMaxTransferSize(this.voidingMode.maxStackSize); this.transferAmount = tagCompound.getInteger("TransferAmount"); + super.readFromNBT(tagCompound); } } diff --git a/src/main/java/gregtech/common/covers/CoverItemFilter.java b/src/main/java/gregtech/common/covers/CoverItemFilter.java index 656fe17f5d8..909fb09e481 100644 --- a/src/main/java/gregtech/common/covers/CoverItemFilter.java +++ b/src/main/java/gregtech/common/covers/CoverItemFilter.java @@ -5,20 +5,19 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverWithUI; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.CycleButtonWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.WidgetGroup; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; -import gregtech.common.covers.filter.ItemFilter; -import gregtech.common.covers.filter.ItemFilterWrapper; +import gregtech.client.utils.TooltipHelper; +import gregtech.common.covers.filter.BaseFilter; +import gregtech.common.covers.filter.ItemFilterContainer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; @@ -32,25 +31,69 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.drawable.Rectangle; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.layout.Column; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; public class CoverItemFilter extends CoverBase implements CoverWithUI { protected final String titleLocale; protected final SimpleOverlayRenderer texture; - protected final ItemFilterWrapper itemFilter; + protected final ItemFilterContainer itemFilterContainer; protected ItemFilterMode filterMode = ItemFilterMode.FILTER_INSERT; protected ItemHandlerFiltered itemHandler; public CoverItemFilter(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, - @NotNull EnumFacing attachedSide, String titleLocale, SimpleOverlayRenderer texture, - ItemFilter itemFilter) { + @NotNull EnumFacing attachedSide, String titleLocale, SimpleOverlayRenderer texture) { super(definition, coverableView, attachedSide); this.titleLocale = titleLocale; this.texture = texture; - this.itemFilter = new ItemFilterWrapper(this); - this.itemFilter.setItemFilter(itemFilter); - this.itemFilter.setMaxStackSize(1); + this.itemFilterContainer = new ItemFilterContainer(this); + } + + @Override + public void onAttachment(@NotNull CoverableView coverableView, @NotNull EnumFacing side, + @Nullable EntityPlayer player, @NotNull ItemStack itemStack) { + super.onAttachment(coverableView, side, player, itemStack); + var dropStack = GTUtility.copy(1, itemStack); + this.itemFilterContainer.setFilterStack(dropStack); + } + + @Override + public @NotNull ItemStack getPickItem() { + if (TooltipHelper.isCtrlDown()) + return getCoverableView().getStackForm(); + + return this.itemFilterContainer.getFilterStack(); + } + + @Override + public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { + packetBuffer.writeBoolean(itemFilterContainer.hasFilter()); + if (itemFilterContainer.hasFilter()) { + packetBuffer.writeByte(this.filterMode.ordinal()); + packetBuffer.writeItemStack(this.itemFilterContainer.getFilterStack()); + } + } + + @Override + public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { + if (!packetBuffer.readBoolean()) return; + this.filterMode = ItemFilterMode.VALUES[packetBuffer.readByte()]; + try { + this.itemFilterContainer.setFilterStack(packetBuffer.readItemStack()); + } catch (IOException e) { + GTLog.logger.error("Failed to read filter for CoverItemFilter! %s", getPos().toString()); + } } public void setFilterMode(ItemFilterMode filterMode) { @@ -62,8 +105,11 @@ public ItemFilterMode getFilterMode() { return filterMode; } - public ItemFilterWrapper getItemFilter() { - return this.itemFilter; + @SuppressWarnings("DataFlowIssue") // this cover should always have a filter + public @NotNull BaseFilter getFilter() { + return this.itemFilterContainer.hasFilter() ? + this.itemFilterContainer.getFilter() : + BaseFilter.ERROR_FILTER; } @Override @@ -86,22 +132,34 @@ public boolean canPipePassThrough() { } public boolean testItemStack(ItemStack stack) { - return itemFilter.testItemStack(stack); + return itemFilterContainer.test(stack); } @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup filterGroup = new WidgetGroup(); - filterGroup.addWidget(new LabelWidget(10, 5, titleLocale)); - filterGroup.addWidget(new CycleButtonWidget(10, 20, 110, 20, - GTUtility.mapToString(ItemFilterMode.values(), it -> it.localeName), - () -> filterMode.ordinal(), (newMode) -> setFilterMode(ItemFilterMode.values()[newMode]))); - this.itemFilter.initUI(45, filterGroup::addWidget); - this.itemFilter.blacklistUI(45, filterGroup::addWidget, () -> true); - return ModularUI.builder(GuiTextures.BACKGROUND, 176, 105 + 82) - .widget(filterGroup) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 105) - .build(this, player); + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(SidedPosGuiData guiData, GuiSyncManager guiSyncManager) { + var filteringMode = new EnumSyncValue<>(ItemFilterMode.class, this::getFilterMode, this::setFilterMode); + + guiSyncManager.syncValue("filtering_mode", filteringMode); + getFilter().getFilterReader().readStack(this.itemFilterContainer.getFilterStack()); + + return getFilter().createPanel(guiSyncManager) + .size(176, 194).padding(7) + .child(CoverWithUI.createTitleRow(getPickItem()).left(4)) + .child(new Column().widthRel(1f).align(Alignment.TopLeft).top(22).coverChildrenHeight() + .child(new EnumRowBuilder<>(ItemFilterMode.class) + .value(filteringMode) + .lang("cover.filter.mode.title") + .overlay(16, GTGuiTextures.FILTER_MODE_OVERLAY) + .build()) + .child(new Rectangle().setColor(UI_TEXT_COLOR).asWidget() + .height(1).widthRel(0.95f).margin(0, 4)) + .child(getFilter().createWidgets(guiSyncManager).left(0))) + .child(SlotGroupWidget.playerInventory().bottom(7).left(7)); } @Override @@ -114,18 +172,20 @@ public void renderCover(CCRenderState renderState, Matrix4 translation, IVertexO public void writeToNBT(@NotNull NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); tagCompound.setInteger("FilterMode", filterMode.ordinal()); - tagCompound.setBoolean("IsBlacklist", this.itemFilter.isBlacklistFilter()); - NBTTagCompound filterComponent = new NBTTagCompound(); - this.itemFilter.getItemFilter().writeToNBT(filterComponent); - tagCompound.setTag("Filter", filterComponent); + tagCompound.setTag("Filter", this.itemFilterContainer.serializeNBT()); } @Override public void readFromNBT(@NotNull NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); - this.filterMode = ItemFilterMode.values()[tagCompound.getInteger("FilterMode")]; - this.itemFilter.setBlacklistFilter(tagCompound.getBoolean("IsBlacklist")); - this.itemFilter.getItemFilter().readFromNBT(tagCompound.getCompoundTag("Filter")); + this.filterMode = ItemFilterMode.VALUES[tagCompound.getInteger("FilterMode")]; + var filterTag = tagCompound.getCompoundTag("Filter"); + if (!filterTag.hasKey("FilterInventory")) { + this.itemFilterContainer.setFilterStack(getDefinition().getDropItemStack()); + } else { + this.itemFilterContainer.deserializeNBT(filterTag); + } + this.itemFilterContainer.handleLegacyNBT(tagCompound); } @Override @@ -152,7 +212,7 @@ public ItemHandlerFiltered(IItemHandler delegate) { @NotNull @Override public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { - if (getFilterMode() == ItemFilterMode.FILTER_EXTRACT || !itemFilter.testItemStack(stack)) { + if (getFilterMode() == ItemFilterMode.FILTER_EXTRACT || !itemFilterContainer.test(stack)) { return stack; } return super.insertItem(slot, stack, simulate); @@ -163,7 +223,7 @@ public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate public ItemStack extractItem(int slot, int amount, boolean simulate) { if (getFilterMode() != ItemFilterMode.FILTER_INSERT) { ItemStack result = super.extractItem(slot, amount, true); - if (result.isEmpty() || !itemFilter.testItemStack(result)) { + if (result.isEmpty() || !itemFilterContainer.test(result)) { return ItemStack.EMPTY; } return simulate ? result : super.extractItem(slot, amount, false); diff --git a/src/main/java/gregtech/common/covers/CoverItemVoiding.java b/src/main/java/gregtech/common/covers/CoverItemVoiding.java index 9a515b670d3..977968bbab1 100644 --- a/src/main/java/gregtech/common/covers/CoverItemVoiding.java +++ b/src/main/java/gregtech/common/covers/CoverItemVoiding.java @@ -3,11 +3,6 @@ import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.CycleButtonWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.WidgetGroup; import gregtech.client.renderer.texture.Textures; import net.minecraft.entity.player.EntityPlayer; @@ -26,6 +21,16 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; import org.jetbrains.annotations.NotNull; public class CoverItemVoiding extends CoverConveyor { @@ -60,7 +65,7 @@ void voidAny(IItemHandler myItemHandler) { if (sourceStack.isEmpty()) { continue; } - if (!itemFilterContainer.testItemStack(sourceStack)) { + if (!itemFilterContainer.test(sourceStack)) { continue; } myItemHandler.extractItem(srcIndex, Integer.MAX_VALUE, false); @@ -68,29 +73,40 @@ void voidAny(IItemHandler myItemHandler) { } @Override - protected String getUITitle() { - return "cover.item.voiding.title"; + public ModularPanel buildUI(SidedPosGuiData guiData, GuiSyncManager guiSyncManager) { + return super.buildUI(guiData, guiSyncManager).height(192 - 22); } @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup primaryGroup = new WidgetGroup(); - primaryGroup.addWidget(new LabelWidget(10, 5, getUITitle())); - this.itemFilterContainer.initUI(20, primaryGroup::addWidget); - - primaryGroup - .addWidget(new CycleButtonWidget(10, 92 + 23, 80, 18, this::isWorkingEnabled, this::setWorkingEnabled, - "cover.voiding.label.disabled", "cover.voiding.label.enabled") - .setTooltipHoverString("cover.voiding.tooltip")); - - primaryGroup.addWidget(new CycleButtonWidget(10, 112 + 23, 116, 18, - ManualImportExportMode.class, this::getManualImportExportMode, this::setManualImportExportMode) - .setTooltipHoverString("cover.universal.manual_import_export.mode.description")); - - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, 125 + 82 + 16 + 24) - .widget(primaryGroup) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 125 + 16 + 24); - return builder.build(this, player); + protected ParentWidget createUI(ModularPanel mainPanel, GuiSyncManager guiSyncManager) { + var isWorking = new BooleanSyncValue(this::isWorkingEnabled, this::setWorkingEnabled); + + return super.createUI(mainPanel, guiSyncManager) + .child(new Row().height(18).widthRel(1f) + .marginBottom(2) + .child(new ToggleButton() + .value(isWorking) + .overlay(IKey.dynamic(() -> IKey.lang(this.isWorkingAllowed ? + "behaviour.soft_hammer.enabled" : + "behaviour.soft_hammer.disabled").get()) + .color(Color.WHITE.darker(1))) + .widthRel(0.6f) + .left(0))); + } + + @Override + protected boolean createThroughputRow() { + return false; + } + + @Override + protected boolean createConveyorModeRow() { + return false; + } + + @Override + protected boolean createDistributionModeRow() { + return false; } @Override @@ -137,7 +153,7 @@ public ItemStack getStackInSlot(int slot) { @NotNull @Override public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { - if (!itemFilterContainer.testItemStack(stack)) { + if (!itemFilterContainer.test(stack)) { return stack; } return ItemStack.EMPTY; diff --git a/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java b/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java index 62d2844aaa3..fe7a52f64e5 100644 --- a/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java +++ b/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java @@ -2,18 +2,14 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.*; +import gregtech.api.mui.GTGuiTextures; import gregtech.client.renderer.texture.Textures; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.MathHelper; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; @@ -21,10 +17,19 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; import java.util.Map; -import java.util.function.Consumer; public class CoverItemVoidingAdvanced extends CoverItemVoiding { @@ -34,7 +39,7 @@ public CoverItemVoidingAdvanced(@NotNull CoverDefinition definition, @NotNull Co @NotNull EnumFacing attachedSide) { super(definition, coverableView, attachedSide); this.voidingMode = VoidingMode.VOID_ANY; - this.itemFilterContainer.setMaxStackSize(1); + this.itemFilterContainer.setMaxTransferSize(1); } @Override @@ -56,13 +61,11 @@ protected void voidOverflow(IItemHandler myItemHandler) { for (TypeItemInfo typeItemInfo : itemTypeCount.values()) { int itemToVoidAmount = 0; - if (getItemFilterContainer().getFilterWrapper().getItemFilter() == null) { - itemToVoidAmount = typeItemInfo.totalCount - itemFilterContainer.getTransferStackSize(); + if (!getItemFilterContainer().hasFilter()) { + itemToVoidAmount = typeItemInfo.totalCount - itemFilterContainer.getTransferSize(); } else { - if (itemFilterContainer.testItemStack(typeItemInfo.itemStack)) { - Object matchedSlot = itemFilterContainer.matchItemStack(typeItemInfo.itemStack); - itemToVoidAmount = typeItemInfo.totalCount - itemFilterContainer.getSlotTransferLimit(matchedSlot); - } + var result = itemFilterContainer.match(typeItemInfo.itemStack); + itemToVoidAmount = result.getItemStack().getCount(); } if (itemToVoidAmount <= 0) { @@ -86,75 +89,41 @@ protected void voidOverflow(IItemHandler myItemHandler) { } @Override - protected String getUITitle() { - return "cover.item.voiding.advanced.title"; + public ModularPanel buildUI(SidedPosGuiData guiData, GuiSyncManager guiSyncManager) { + return super.buildUI(guiData, guiSyncManager).height(192 + 18); } @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup primaryGroup = new WidgetGroup(); - primaryGroup.addWidget(new LabelWidget(10, 5, getUITitle())); - - primaryGroup.addWidget(new CycleButtonWidget(91, 14, 75, 20, - VoidingMode.class, this::getVoidingMode, this::setVoidingMode) - .setTooltipHoverString("cover.voiding.voiding_mode.description")); - - this.initFilterUI(20, primaryGroup::addWidget); - - primaryGroup - .addWidget(new CycleButtonWidget(10, 92 + 23, 80, 18, this::isWorkingEnabled, this::setWorkingEnabled, - "cover.voiding.label.disabled", "cover.voiding.label.enabled") - .setTooltipHoverString("cover.voiding.tooltip")); - - primaryGroup.addWidget(new CycleButtonWidget(10, 112 + 23, 116, 18, - ManualImportExportMode.class, this::getManualImportExportMode, this::setManualImportExportMode) - .setTooltipHoverString("cover.universal.manual_import_export.mode.description")); - - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, 125 + 82 + 16 + 24) - .widget(primaryGroup) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 125 + 16 + 24); - return buildUI(builder, player); + protected ParentWidget createUI(ModularPanel mainPanel, GuiSyncManager guiSyncManager) { + var voidingMode = new EnumSyncValue<>(VoidingMode.class, this::getVoidingMode, this::setVoidingMode); + guiSyncManager.syncValue("voiding_mode", voidingMode); + + var filterTransferSize = new StringSyncValue( + () -> String.valueOf(this.itemFilterContainer.getTransferSize()), + s -> this.itemFilterContainer.setTransferSize(Integer.parseInt(s))); + filterTransferSize.updateCacheFromSource(true); + var transferTextField = new TextFieldWidget().widthRel(0.5f).right(0); + transferTextField.setEnabled(this.itemFilterContainer.showGlobalTransferLimitSlider() && + this.voidingMode == VoidingMode.VOID_OVERFLOW); + + return super.createUI(mainPanel, guiSyncManager) + .child(new EnumRowBuilder<>(VoidingMode.class) + .value(voidingMode) + .lang("cover.voiding.voiding_mode") + .overlay(16, GTGuiTextures.VOIDING_MODE_OVERLAY) + .build()) + .child(new Row().right(0).coverChildrenHeight() + .child(transferTextField + .setEnabledIf(w -> this.itemFilterContainer.showGlobalTransferLimitSlider() && + this.voidingMode == VoidingMode.VOID_OVERFLOW) + .setNumbers(0, Integer.MAX_VALUE) + .value(filterTransferSize) + .setTextColor(Color.WHITE.darker(1)))); } - // Basically the item filter container GUI code, with different Y widget positioning - public void initFilterUI(int y, Consumer widgetGroup) { - widgetGroup.accept(new LabelWidget(10, y, "cover.conveyor.item_filter.title")); - widgetGroup.accept(new SlotWidget(itemFilterContainer.getFilterInventory(), 0, 10, y + 15) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.FILTER_SLOT_OVERLAY)); - - ServerWidgetGroup stackSizeGroup = new ServerWidgetGroup( - () -> itemFilterContainer.getFilterWrapper().getItemFilter() == null && - voidingMode == VoidingMode.VOID_OVERFLOW); - stackSizeGroup.addWidget(new ImageWidget(111, 34, 35, 20, GuiTextures.DISPLAY)); - - stackSizeGroup.addWidget( - new IncrementButtonWidget(146, 34, 20, 20, 1, 8, 64, 512, itemFilterContainer::adjustTransferStackSize) - .setDefaultTooltip() - .setTextScale(0.7f) - .setShouldClientCallback(false)); - stackSizeGroup.addWidget(new IncrementButtonWidget(91, 34, 20, 20, -1, -8, -64, -512, - itemFilterContainer::adjustTransferStackSize) - .setDefaultTooltip() - .setTextScale(0.7f) - .setShouldClientCallback(false)); - - stackSizeGroup.addWidget(new TextFieldWidget2(113, 41, 31, 20, - () -> String.valueOf(itemFilterContainer.getTransferStackSize()), val -> { - if (val != null && !val.isEmpty()) - itemFilterContainer.setTransferStackSize( - MathHelper.clamp(Integer.parseInt(val), 1, voidingMode.maxStackSize)); - }) - .setCentered(true) - .setNumbersOnly(1, Integer.MAX_VALUE) - .setMaxLength(10) - .setScale(0.9f)); - - widgetGroup.accept(stackSizeGroup); - - this.itemFilterContainer.getFilterWrapper().initUI(y + 38, widgetGroup); - - this.itemFilterContainer.getFilterWrapper().blacklistUI(y + 38, widgetGroup, - () -> voidingMode != VoidingMode.VOID_OVERFLOW); + @Override + protected int getMaxStackSize() { + return getVoidingMode().maxStackSize; } @Override @@ -165,7 +134,7 @@ public void renderCover(CCRenderState renderState, Matrix4 translation, IVertexO public void setVoidingMode(VoidingMode voidingMode) { this.voidingMode = voidingMode; - this.itemFilterContainer.setMaxStackSize(voidingMode.maxStackSize); + this.itemFilterContainer.setMaxTransferSize(getMaxStackSize()); this.getCoverableView().markDirty(); } @@ -173,6 +142,18 @@ public VoidingMode getVoidingMode() { return voidingMode; } + @Override + public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.writeInitialSyncData(packetBuffer); + packetBuffer.writeByte(this.voidingMode.ordinal()); + } + + @Override + public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.readInitialSyncData(packetBuffer); + this.voidingMode = VoidingMode.VALUES[packetBuffer.readByte()]; + } + @Override public void writeToNBT(NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); @@ -181,7 +162,8 @@ public void writeToNBT(NBTTagCompound tagCompound) { @Override public void readFromNBT(NBTTagCompound tagCompound) { + this.voidingMode = VoidingMode.VALUES[tagCompound.getInteger("VoidMode")]; + this.itemFilterContainer.setMaxTransferSize(this.voidingMode.maxStackSize); super.readFromNBT(tagCompound); - this.voidingMode = VoidingMode.values()[tagCompound.getInteger("VoidMode")]; } } diff --git a/src/main/java/gregtech/common/covers/CoverMachineController.java b/src/main/java/gregtech/common/covers/CoverMachineController.java index 423a44fccd3..517a9bc5711 100644 --- a/src/main/java/gregtech/common/covers/CoverMachineController.java +++ b/src/main/java/gregtech/common/covers/CoverMachineController.java @@ -120,7 +120,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, GuiSyncManager guiSyncManag guiSyncManager.syncValue("inverted", invertedValue); return GTGuis.createPanel(this, 176, 112) - .child(createTitleRow()) + .child(CoverWithUI.createTitleRow(getPickItem())) .child(new Column() .widthRel(1.0f).margin(7, 0) .top(24).coverChildrenHeight() diff --git a/src/main/java/gregtech/common/covers/CoverPump.java b/src/main/java/gregtech/common/covers/CoverPump.java index 961e349be6b..e91a59118a6 100644 --- a/src/main/java/gregtech/common/covers/CoverPump.java +++ b/src/main/java/gregtech/common/covers/CoverPump.java @@ -1,6 +1,5 @@ package gregtech.common.covers; -import gregtech.api.GTValues; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IControllable; @@ -9,14 +8,8 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverWithUI; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.CycleButtonWidget; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.IncrementButtonWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.TextFieldWidget2; -import gregtech.api.gui.widgets.WidgetGroup; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; import gregtech.api.util.GTTransferUtils; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleSidedCubeRenderer; @@ -47,13 +40,23 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; -import com.google.common.math.IntMath; +import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.utils.MouseData; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.IntSyncValue; +import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.ButtonWidget; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.function.Function; -import java.util.function.IntSupplier; - public class CoverPump extends CoverBase implements CoverWithUI, ITickable, IControllable { public final int tier; @@ -65,7 +68,7 @@ public class CoverPump extends CoverBase implements CoverWithUI, ITickable, ICon protected int fluidLeftToTransferLastSecond; private CoverableFluidHandlerWrapper fluidHandlerWrapper; protected boolean isWorkingAllowed = true; - protected FluidFilterContainer fluidFilter; + protected FluidFilterContainer fluidFilterContainer; protected BucketMode bucketMode = BucketMode.MILLI_BUCKET; public CoverPump(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, @@ -75,25 +78,35 @@ public CoverPump(@NotNull CoverDefinition definition, @NotNull CoverableView cov this.maxFluidTransferRate = mbPerTick; this.transferRate = mbPerTick; this.fluidLeftToTransferLastSecond = transferRate; - this.fluidFilter = new FluidFilterContainer(this, this::shouldShowTip); + this.fluidFilterContainer = new FluidFilterContainer(this); + } + + public void setStringTransferRate(String s) { + this.fluidFilterContainer.setTransferSize( + getBucketMode() == BucketMode.MILLI_BUCKET ? + Integer.parseInt(s) : + Integer.parseInt(s) * 1000); } - protected boolean shouldShowTip() { - return false; + public String getStringTransferRate() { + return String.valueOf(getBucketMode() == BucketMode.MILLI_BUCKET ? + this.fluidFilterContainer.getTransferSize() : + this.fluidFilterContainer.getTransferSize() / 1000); } public void setTransferRate(int transferRate) { - this.transferRate = transferRate; + if (bucketMode == BucketMode.BUCKET) transferRate *= 1000; + this.transferRate = MathHelper.clamp(transferRate, 1, maxFluidTransferRate); markDirty(); } public int getTransferRate() { - return transferRate; + return bucketMode == BucketMode.BUCKET ? transferRate / 1000 : transferRate; } protected void adjustTransferRate(int amount) { amount *= this.bucketMode == BucketMode.BUCKET ? 1000 : 1; - setTransferRate(MathHelper.clamp(transferRate + amount, 1, maxFluidTransferRate)); + setTransferRate(this.transferRate + amount); } public void setPumpMode(PumpMode pumpMode) { @@ -127,7 +140,7 @@ protected void setManualImportExportMode(ManualImportExportMode manualImportExpo } public FluidFilterContainer getFluidFilterContainer() { - return fluidFilter; + return fluidFilterContainer; } @Override @@ -157,100 +170,124 @@ protected int doTransferFluidsInternal(IFluidHandler myFluidHandler, IFluidHandl int transferLimit) { if (pumpMode == PumpMode.IMPORT) { return GTTransferUtils.transferFluids(fluidHandler, myFluidHandler, transferLimit, - fluidFilter::testFluidStack); + fluidFilterContainer::test); } else if (pumpMode == PumpMode.EXPORT) { return GTTransferUtils.transferFluids(myFluidHandler, fluidHandler, transferLimit, - fluidFilter::testFluidStack); + fluidFilterContainer::test); } return 0; } protected boolean checkInputFluid(FluidStack fluidStack) { - return fluidFilter.testFluidStack(fluidStack); + return fluidFilterContainer.test(fluidStack); } - protected ModularUI buildUI(ModularUI.Builder builder, EntityPlayer player) { - return builder.build(this, player); + @Override + public boolean usesMui2() { + return true; } - protected String getUITitle() { - return "cover.pump.title"; + @Override + public ModularPanel buildUI(SidedPosGuiData guiData, GuiSyncManager guiSyncManager) { + var panel = GTGuis.createPanel(this, 176, 192); + + getFluidFilterContainer().setMaxTransferSize(getMaxTransferRate()); + + return panel.child(CoverWithUI.createTitleRow(getPickItem())) + .child(createUI(panel, guiSyncManager)) + .bindPlayerInventory(); + } + + protected ParentWidget createUI(ModularPanel mainPanel, GuiSyncManager syncManager) { + var manualIOmode = new EnumSyncValue<>(ManualImportExportMode.class, + this::getManualImportExportMode, this::setManualImportExportMode); + manualIOmode.updateCacheFromSource(true); + + var throughput = new IntSyncValue(this::getTransferRate, this::setTransferRate); + throughput.updateCacheFromSource(true); + + var throughputString = new StringSyncValue( + throughput::getStringValue, + throughput::setStringValue); + throughputString.updateCacheFromSource(true); + + var pumpMode = new EnumSyncValue<>(PumpMode.class, this::getPumpMode, this::setPumpMode); + pumpMode.updateCacheFromSource(true); + + syncManager.syncValue("manual_io", manualIOmode); + syncManager.syncValue("pump_mode", pumpMode); + syncManager.syncValue("throughput", throughput); + + var column = new Column().top(24).margin(7, 0) + .widthRel(1f).coverChildrenHeight(); + + if (createThroughputRow()) + column.child(new Row().coverChildrenHeight() + .marginBottom(2).widthRel(1f) + .child(new ButtonWidget<>() + .left(0).width(18) + .onMousePressed(mouseButton -> { + int val = throughput.getValue() - getIncrementValue(MouseData.create(mouseButton)); + throughput.setValue(val, true, true); + Interactable.playButtonClickSound(); + return true; + }) + .onUpdateListener(w -> w.overlay(createAdjustOverlay(false)))) + .child(new TextFieldWidget() + .left(18).right(18) + .setTextColor(Color.WHITE.darker(1)) + .setNumbers(1, maxFluidTransferRate) + .value(throughputString) + .background(GTGuiTextures.DISPLAY)) + .child(new ButtonWidget<>() + .right(0).width(18) + .onMousePressed(mouseButton -> { + int val = throughput.getValue() + getIncrementValue(MouseData.create(mouseButton)); + throughput.setValue(val, true, true); + Interactable.playButtonClickSound(); + return true; + }) + .onUpdateListener(w -> w.overlay(createAdjustOverlay(true))))); + + if (createFilterRow()) + column.child(getFluidFilterContainer() + .initUI(mainPanel, syncManager)); + + if (createManualIOModeRow()) + column.child(new EnumRowBuilder<>(ManualImportExportMode.class) + .value(manualIOmode) + .lang("cover.generic.manual_io") + .overlay(GTGuiTextures.MANUAL_IO_OVERLAY) + .build()); + + if (createPumpModeRow()) + column.child(new EnumRowBuilder<>(PumpMode.class) + .value(pumpMode) + .lang("cover.pump.mode") + .overlay(GTGuiTextures.CONVEYOR_MODE_OVERLAY) // todo pump mode overlays + .build()); + + return column; + } + + protected boolean createThroughputRow() { + return true; } - @SuppressWarnings("UnstableApiUsage") - @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup primaryGroup = new WidgetGroup(); - primaryGroup.addWidget(new LabelWidget(10, 5, getUITitle(), GTValues.VN[tier])); - - primaryGroup.addWidget(new ImageWidget(44, 20, 62, 20, GuiTextures.DISPLAY)); - - primaryGroup.addWidget(new IncrementButtonWidget(136, 20, 30, 20, 1, 10, 100, 1000, this::adjustTransferRate) - .setDefaultTooltip() - .setShouldClientCallback(false)); - primaryGroup.addWidget(new IncrementButtonWidget(10, 20, 34, 20, -1, -10, -100, -1000, this::adjustTransferRate) - .setDefaultTooltip() - .setShouldClientCallback(false)); - - TextFieldWidget2 textField = new TextFieldWidget2(45, 26, 60, 20, () -> bucketMode == BucketMode.BUCKET ? - Integer.toString(transferRate / 1000) : Integer.toString(transferRate), val -> { - if (val != null && !val.isEmpty()) { - int amount = Integer.parseInt(val); - if (this.bucketMode == BucketMode.BUCKET) { - amount = IntMath.saturatedMultiply(amount, 1000); - } - setTransferRate(amount); - } - }) - .setCentered(true) - .setNumbersOnly(1, - bucketMode == BucketMode.BUCKET ? maxFluidTransferRate / 1000 : maxFluidTransferRate) - .setMaxLength(8); - primaryGroup.addWidget(textField); - - primaryGroup.addWidget(new CycleButtonWidget(106, 20, 30, 20, - BucketMode.class, this::getBucketMode, mode -> { - if (mode != bucketMode) { - setBucketMode(mode); - } - })); - - primaryGroup.addWidget(new CycleButtonWidget(10, 43, 75, 18, - PumpMode.class, this::getPumpMode, this::setPumpMode)); - - primaryGroup.addWidget(new CycleButtonWidget(7, 160, 116, 20, - ManualImportExportMode.class, this::getManualImportExportMode, this::setManualImportExportMode) - .setTooltipHoverString("cover.universal.manual_import_export.mode.description")); - - this.fluidFilter.initUI(88, primaryGroup::addWidget); - - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, 184 + 82) - .widget(primaryGroup) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 184); - return buildUI(builder, player); - } - - public static Function getTextFieldValidator(IntSupplier maxSupplier) { - int min = 1; - return val -> { - if (val.isEmpty()) { - return String.valueOf(min); - } - int max = maxSupplier.getAsInt(); - int num; - try { - num = Integer.parseInt(val); - } catch (NumberFormatException ignored) { - return String.valueOf(max); - } - if (num < min) { - return String.valueOf(min); - } - if (num > max) { - return String.valueOf(max); - } - return val; - }; + protected boolean createFilterRow() { + return true; + } + + protected boolean createManualIOModeRow() { + return true; + } + + protected boolean createPumpModeRow() { + return true; + } + + protected int getMaxTransferRate() { + return 1; } @Override @@ -274,13 +311,15 @@ public void readCustomData(int discriminator, @NotNull PacketBuffer buf) { @Override public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { super.writeInitialSyncData(packetBuffer); - packetBuffer.writeEnumValue(pumpMode); + packetBuffer.writeByte(pumpMode.ordinal()); + getFluidFilterContainer().writeInitialSyncData(packetBuffer); } @Override public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { super.readInitialSyncData(packetBuffer); - this.pumpMode = packetBuffer.readEnumValue(PumpMode.class); + this.pumpMode = PumpMode.VALUES[packetBuffer.readByte()]; + getFluidFilterContainer().readInitialSyncData(packetBuffer); } @Override @@ -295,7 +334,7 @@ public boolean canInteractWithOutputSide() { @Override public void onRemoval() { - dropInventoryContents(fluidFilter.getFilterInventory()); + dropInventoryContents(fluidFilterContainer); } @Override @@ -344,18 +383,21 @@ public void writeToNBT(@NotNull NBTTagCompound tagCompound) { tagCompound.setInteger("DistributionMode", distributionMode.ordinal()); tagCompound.setBoolean("WorkingAllowed", isWorkingAllowed); tagCompound.setInteger("ManualImportExportMode", manualImportExportMode.ordinal()); - tagCompound.setTag("Filter", fluidFilter.serializeNBT()); + tagCompound.setInteger("BucketMode", bucketMode.ordinal()); + tagCompound.setTag("Filter", fluidFilterContainer.serializeNBT()); } @Override public void readFromNBT(@NotNull NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); this.transferRate = tagCompound.getInteger("TransferRate"); - this.pumpMode = PumpMode.values()[tagCompound.getInteger("PumpMode")]; - this.distributionMode = DistributionMode.values()[tagCompound.getInteger("DistributionMode")]; + this.pumpMode = PumpMode.VALUES[tagCompound.getInteger("PumpMode")]; + this.distributionMode = DistributionMode.VALUES[tagCompound.getInteger("DistributionMode")]; this.isWorkingAllowed = tagCompound.getBoolean("WorkingAllowed"); - this.manualImportExportMode = ManualImportExportMode.values()[tagCompound.getInteger("ManualImportExportMode")]; - this.fluidFilter.deserializeNBT(tagCompound.getCompoundTag("Filter")); + this.manualImportExportMode = ManualImportExportMode.VALUES[tagCompound.getInteger("ManualImportExportMode")]; + this.bucketMode = BucketMode.VALUES[tagCompound.getInteger("BucketMode")]; + this.fluidFilterContainer.deserializeNBT(tagCompound.getCompoundTag("Filter")); + this.fluidFilterContainer.handleLegacyNBT(tagCompound); } @Override @@ -369,6 +411,7 @@ public enum PumpMode implements IStringSerializable, IIOMode { IMPORT("cover.pump.mode.import"), EXPORT("cover.pump.mode.export"); + public static final PumpMode[] VALUES = values(); public final String localeName; PumpMode(String localeName) { @@ -392,6 +435,7 @@ public enum BucketMode implements IStringSerializable { BUCKET("cover.bucket.mode.bucket"), MILLI_BUCKET("cover.bucket.mode.milli_bucket"); + public static final BucketMode[] VALUES = values(); public final String localeName; BucketMode(String localeName) { diff --git a/src/main/java/gregtech/common/covers/CoverRoboticArm.java b/src/main/java/gregtech/common/covers/CoverRoboticArm.java index 902ffcd62f4..883fe18f9ec 100644 --- a/src/main/java/gregtech/common/covers/CoverRoboticArm.java +++ b/src/main/java/gregtech/common/covers/CoverRoboticArm.java @@ -1,27 +1,34 @@ package gregtech.common.covers; +import gregtech.api.capability.GregtechDataCodes; import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.ModularUI.Builder; -import gregtech.api.gui.widgets.*; +import gregtech.api.mui.GTGuiTextures; import gregtech.client.renderer.texture.Textures; import gregtech.common.covers.filter.SmartItemFilter; import gregtech.common.pipelike.itempipe.net.ItemNetHandler; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.MathHelper; import net.minecraftforge.items.IItemHandler; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; import java.util.Iterator; @@ -36,7 +43,7 @@ public CoverRoboticArm(@NotNull CoverDefinition definition, @NotNull CoverableVi @NotNull EnumFacing attachedSide, int tier, int itemsPerSecond) { super(definition, coverableView, attachedSide, tier, itemsPerSecond); this.transferMode = TransferMode.TRANSFER_ANY; - this.itemFilterContainer.setMaxStackSize(1); + this.itemFilterContainer.setMaxTransferSize(1); } @Override @@ -72,16 +79,17 @@ protected int doTransferExact(IItemHandler itemHandler, IItemHandler myItemHandl while (iterator.hasNext()) { TypeItemInfo sourceInfo = sourceItemAmount.get(iterator.next()); int itemAmount = sourceInfo.totalCount; - int itemToMoveAmount = itemFilterContainer.getSlotTransferLimit(sourceInfo.filterSlot); + int itemToMoveAmount = itemFilterContainer.getTransferLimit(sourceInfo.itemStack); - // if smart item filter - if (itemFilterContainer.getFilterWrapper().getItemFilter() instanceof SmartItemFilter) { - if (itemFilterContainer.getTransferStackSize() > 1 && itemToMoveAmount * 2 <= itemAmount) { + // if smart item filter and whitelist + if (itemFilterContainer.getFilter() instanceof SmartItemFilter && + !itemFilterContainer.isBlacklistFilter()) { + if (itemFilterContainer.getTransferSize() > 1 && itemToMoveAmount * 2 <= itemAmount) { // get the max we can extract from the item filter variable int maxMultiplier = Math.floorDiv(maxTransferAmount, itemToMoveAmount); // multiply up to the total count of all the items - itemToMoveAmount *= Math.min(itemFilterContainer.getTransferStackSize(), maxMultiplier); + itemToMoveAmount *= Math.min(itemFilterContainer.getTransferSize(), maxMultiplier); } } @@ -115,24 +123,24 @@ protected int doTransferExact(IItemHandler itemHandler, IItemHandler myItemHandl } protected int doKeepExact(IItemHandler itemHandler, IItemHandler myItemHandler, int maxTransferAmount) { - Map currentItemAmount = doCountDestinationInventoryItemsByMatchIndex(itemHandler, + Map currentItemAmount = doCountDestinationInventoryItemsByMatchIndex(itemHandler, myItemHandler); - Map sourceItemAmounts = doCountDestinationInventoryItemsByMatchIndex(myItemHandler, + Map sourceItemAmounts = doCountDestinationInventoryItemsByMatchIndex(myItemHandler, itemHandler); - Iterator iterator = sourceItemAmounts.keySet().iterator(); + Iterator iterator = sourceItemAmounts.keySet().iterator(); while (iterator.hasNext()) { - Object filterSlotIndex = iterator.next(); + int filterSlotIndex = iterator.next(); GroupItemInfo sourceInfo = sourceItemAmounts.get(filterSlotIndex); - int itemToKeepAmount = itemFilterContainer.getSlotTransferLimit(sourceInfo.filterSlot); + int itemToKeepAmount = itemFilterContainer.getTransferLimit(sourceInfo.filterSlot); // only run multiplier for smart item - if (itemFilterContainer.getFilterWrapper().getItemFilter() instanceof SmartItemFilter) { - if (itemFilterContainer.getTransferStackSize() > 1 && itemToKeepAmount * 2 <= sourceInfo.totalCount) { + if (itemFilterContainer.getFilter() instanceof SmartItemFilter) { + if (itemFilterContainer.getTransferSize() > 1 && itemToKeepAmount * 2 <= sourceInfo.totalCount) { // get the max we can keep from the item filter variable int maxMultiplier = Math.floorDiv(sourceInfo.totalCount, itemToKeepAmount); // multiply up to the total count of all the items - itemToKeepAmount *= Math.min(itemFilterContainer.getTransferStackSize(), maxMultiplier); + itemToKeepAmount *= Math.min(itemFilterContainer.getTransferSize(), maxMultiplier); } } @@ -163,9 +171,13 @@ public void clearBuffer() { } public void setTransferMode(TransferMode transferMode) { - this.transferMode = transferMode; - this.getCoverableView().markDirty(); - this.itemFilterContainer.setMaxStackSize(transferMode.maxStackSize); + if (this.transferMode != transferMode) { + this.transferMode = transferMode; + this.getCoverableView().markDirty(); + this.itemFilterContainer.setMaxTransferSize(transferMode.maxStackSize); + writeCustomData(GregtechDataCodes.UPDATE_TRANSFER_MODE, + buffer -> buffer.writeByte(this.transferMode.ordinal())); + } } public TransferMode getTransferMode() { @@ -180,44 +192,60 @@ private boolean shouldDisplayAmountSlider() { } @Override - protected String getUITitle() { - return "cover.robotic_arm.title"; + public ModularPanel buildUI(SidedPosGuiData guiData, GuiSyncManager guiSyncManager) { + return super.buildUI(guiData, guiSyncManager).height(192 + 36 + 18 + 2); + } + + @Override + protected ParentWidget createUI(ModularPanel mainPanel, GuiSyncManager guiSyncManager) { + EnumSyncValue transferMode = new EnumSyncValue<>(TransferMode.class, this::getTransferMode, + this::setTransferMode); + guiSyncManager.syncValue("transfer_mode", transferMode); + + var filterTransferSize = new StringSyncValue( + () -> String.valueOf(this.itemFilterContainer.getTransferSize()), + s -> this.itemFilterContainer.setTransferSize(Integer.parseInt(s))); + filterTransferSize.updateCacheFromSource(true); + + return super.createUI(mainPanel, guiSyncManager) + .child(new EnumRowBuilder<>(TransferMode.class) + .value(transferMode) + .lang("cover.generic.transfer_mode") + .overlay(GTGuiTextures.TRANSFER_MODE_OVERLAY) + .build()) + .child(new Row().right(0).coverChildrenHeight() + .child(new TextFieldWidget().widthRel(0.5f).right(0) + .setEnabledIf(w -> shouldDisplayAmountSlider()) + .setNumbers(0, Integer.MAX_VALUE) + .value(filterTransferSize) + .setTextColor(Color.WHITE.darker(1)))); + } + + @Override + protected int getMaxStackSize() { + return getTransferMode().maxStackSize; } @Override - protected ModularUI buildUI(Builder builder, EntityPlayer player) { - WidgetGroup primaryGroup = new WidgetGroup(); - primaryGroup.addWidget(new CycleButtonWidget(91, 45, 75, 20, - TransferMode.class, this::getTransferMode, this::setTransferMode) - .setTooltipHoverString("cover.robotic_arm.transfer_mode.description")); - - ServerWidgetGroup stackSizeGroup = new ServerWidgetGroup(this::shouldDisplayAmountSlider); - stackSizeGroup.addWidget(new ImageWidget(111, 70, 35, 20, GuiTextures.DISPLAY)); - - stackSizeGroup.addWidget( - new IncrementButtonWidget(146, 70, 20, 20, 1, 8, 64, 512, itemFilterContainer::adjustTransferStackSize) - .setDefaultTooltip() - .setTextScale(0.7f) - .setShouldClientCallback(false)); - stackSizeGroup.addWidget(new IncrementButtonWidget(91, 70, 20, 20, -1, -8, -64, -512, - itemFilterContainer::adjustTransferStackSize) - .setDefaultTooltip() - .setTextScale(0.7f) - .setShouldClientCallback(false)); - - stackSizeGroup.addWidget(new TextFieldWidget2(113, 77, 31, 20, - () -> String.valueOf(itemFilterContainer.getTransferStackSize()), val -> { - if (val != null && !val.isEmpty()) - itemFilterContainer.setTransferStackSize( - MathHelper.clamp(Integer.parseInt(val), 1, transferMode.maxStackSize)); - }) - .setNumbersOnly(1, transferMode.maxStackSize) - .setMaxLength(4) - .setScale(0.9f)); - - primaryGroup.addWidget(stackSizeGroup); - - return super.buildUI(builder.widget(primaryGroup), player); + public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.writeInitialSyncData(packetBuffer); + packetBuffer.writeByte(this.transferMode.ordinal()); + } + + @Override + public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.readInitialSyncData(packetBuffer); + this.transferMode = TransferMode.VALUES[packetBuffer.readByte()]; + this.itemFilterContainer.setMaxTransferSize(this.transferMode.maxStackSize); + } + + @Override + public void readCustomData(int discriminator, @NotNull PacketBuffer buf) { + super.readCustomData(discriminator, buf); + if (discriminator == GregtechDataCodes.UPDATE_TRANSFER_MODE) { + this.transferMode = TransferMode.VALUES[buf.readByte()]; + this.itemFilterContainer.setMaxTransferSize(this.transferMode.maxStackSize); + } } @Override @@ -228,7 +256,8 @@ public void writeToNBT(NBTTagCompound tagCompound) { @Override public void readFromNBT(NBTTagCompound tagCompound) { + this.transferMode = TransferMode.VALUES[tagCompound.getInteger("TransferMode")]; + this.itemFilterContainer.setMaxTransferSize(this.transferMode.maxStackSize); super.readFromNBT(tagCompound); - this.transferMode = TransferMode.values()[tagCompound.getInteger("TransferMode")]; } } diff --git a/src/main/java/gregtech/common/covers/CoverSolarPanel.java b/src/main/java/gregtech/common/covers/CoverSolarPanel.java index 7e2e750439a..e972ef560ad 100644 --- a/src/main/java/gregtech/common/covers/CoverSolarPanel.java +++ b/src/main/java/gregtech/common/covers/CoverSolarPanel.java @@ -13,7 +13,6 @@ import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -50,10 +49,9 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra public void update() { CoverableView coverable = getCoverableView(); World world = coverable.getWorld(); - BlockPos blockPos = coverable.getPos(); - if (GTUtility.canSeeSunClearly(world, blockPos)) { + if (GTUtility.canSeeSunClearly(world, coverable.getPos())) { IEnergyContainer energyContainer = coverable.getCapability(GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER, - null); + getAttachedSide()); if (energyContainer != null) { energyContainer.acceptEnergyFromNetwork(null, EUt, 1); } diff --git a/src/main/java/gregtech/common/covers/DistributionMode.java b/src/main/java/gregtech/common/covers/DistributionMode.java index 24268bdc6a0..c704d045b18 100644 --- a/src/main/java/gregtech/common/covers/DistributionMode.java +++ b/src/main/java/gregtech/common/covers/DistributionMode.java @@ -10,6 +10,7 @@ public enum DistributionMode implements IStringSerializable { ROUND_ROBIN_PRIO("cover.conveyor.distribution.round_robin"), INSERT_FIRST("cover.conveyor.distribution.first_insert"); + public static final DistributionMode[] VALUES = values(); public final String localeName; DistributionMode(String localeName) { diff --git a/src/main/java/gregtech/common/covers/FluidFilterMode.java b/src/main/java/gregtech/common/covers/FluidFilterMode.java index ee372ff8b09..e26c6192e8b 100644 --- a/src/main/java/gregtech/common/covers/FluidFilterMode.java +++ b/src/main/java/gregtech/common/covers/FluidFilterMode.java @@ -1,11 +1,14 @@ package gregtech.common.covers; -public enum FluidFilterMode implements IFilterMode { +import net.minecraft.util.IStringSerializable; + +public enum FluidFilterMode implements IStringSerializable { FILTER_FILL("cover.fluid_filter.mode.filter_fill"), FILTER_DRAIN("cover.fluid_filter.mode.filter_drain"), FILTER_BOTH("cover.fluid_filter.mode.filter_both"); + public static final FluidFilterMode[] VALUES = values(); public final String localeName; FluidFilterMode(String localeName) { diff --git a/src/main/java/gregtech/common/covers/IFilterMode.java b/src/main/java/gregtech/common/covers/IFilterMode.java deleted file mode 100644 index ecc0fde802f..00000000000 --- a/src/main/java/gregtech/common/covers/IFilterMode.java +++ /dev/null @@ -1,6 +0,0 @@ -package gregtech.common.covers; - -public interface IFilterMode { - - String getName(); -} diff --git a/src/main/java/gregtech/common/covers/ItemFilterMode.java b/src/main/java/gregtech/common/covers/ItemFilterMode.java index 2a871e2984e..6d612915161 100644 --- a/src/main/java/gregtech/common/covers/ItemFilterMode.java +++ b/src/main/java/gregtech/common/covers/ItemFilterMode.java @@ -1,11 +1,14 @@ package gregtech.common.covers; -public enum ItemFilterMode implements IFilterMode { +import net.minecraft.util.IStringSerializable; + +public enum ItemFilterMode implements IStringSerializable { FILTER_INSERT("cover.filter.mode.filter_insert"), FILTER_EXTRACT("cover.filter.mode.filter_extract"), FILTER_BOTH("cover.filter.mode.filter_both"); + public static final ItemFilterMode[] VALUES = values(); public final String localeName; ItemFilterMode(String localeName) { diff --git a/src/main/java/gregtech/common/covers/ManualImportExportMode.java b/src/main/java/gregtech/common/covers/ManualImportExportMode.java index d044322425c..df3942d7163 100644 --- a/src/main/java/gregtech/common/covers/ManualImportExportMode.java +++ b/src/main/java/gregtech/common/covers/ManualImportExportMode.java @@ -10,6 +10,7 @@ public enum ManualImportExportMode implements IStringSerializable { FILTERED("cover.universal.manual_import_export.mode.filtered"), UNFILTERED("cover.universal.manual_import_export.mode.unfiltered"); + public static final ManualImportExportMode[] VALUES = values(); public final String localeName; ManualImportExportMode(String localeName) { diff --git a/src/main/java/gregtech/common/covers/TransferMode.java b/src/main/java/gregtech/common/covers/TransferMode.java index ebf708dfdf4..2f278c88ce4 100644 --- a/src/main/java/gregtech/common/covers/TransferMode.java +++ b/src/main/java/gregtech/common/covers/TransferMode.java @@ -8,8 +8,9 @@ public enum TransferMode implements IStringSerializable { TRANSFER_ANY("cover.robotic_arm.transfer_mode.transfer_any", 1), TRANSFER_EXACT("cover.robotic_arm.transfer_mode.transfer_exact", 1024), - KEEP_EXACT("cover.robotic_arm.transfer_mode.keep_exact", 1024); + KEEP_EXACT("cover.robotic_arm.transfer_mode.keep_exact", Integer.MAX_VALUE); + public static final TransferMode[] VALUES = values(); public final String localeName; public final int maxStackSize; diff --git a/src/main/java/gregtech/common/covers/VoidingMode.java b/src/main/java/gregtech/common/covers/VoidingMode.java index 48aa9d0b8de..b7e85666f65 100644 --- a/src/main/java/gregtech/common/covers/VoidingMode.java +++ b/src/main/java/gregtech/common/covers/VoidingMode.java @@ -7,8 +7,9 @@ public enum VoidingMode implements IStringSerializable { VOID_ANY("cover.voiding.voiding_mode.void_any", 1), - VOID_OVERFLOW("cover.voiding.voiding_mode.void_overflow", 1024); + VOID_OVERFLOW("cover.voiding.voiding_mode.void_overflow", Integer.MAX_VALUE); + public static final VoidingMode[] VALUES = values(); public final String localeName; public final int maxStackSize; diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorFluidAdvanced.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorFluidAdvanced.java index 32239be9036..56d7eb246c9 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorFluidAdvanced.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorFluidAdvanced.java @@ -92,7 +92,7 @@ public ModularUI createUI(EntityPlayer player) { // "cover.generic.advanced_detector.invert_label")); group.addWidget( new CycleButtonWidget(10, 3 * (SIZE + PADDING), 4 * SIZE, SIZE, this::isInverted, this::setInverted, - "cover.machine_controller.normal", "cover.machine_controller.inverted") + "cover.advanced_energy_detector.normal", "cover.advanced_energy_detector.inverted") .setTooltipHoverString("cover.generic.advanced_detector.invert_tooltip")); group.addWidget( new CycleButtonWidget(94, 3 * (SIZE + PADDING), 4 * SIZE, SIZE, this::isLatched, this::setLatched, @@ -145,7 +145,7 @@ public void update() { for (IFluidTankProperties properties : tankProperties) { FluidStack contents = properties.getContents(); - if (contents != null && fluidFilter.testFluidStack(contents)) + if (contents != null && fluidFilter.test(contents)) storedFluid += contents.amount; } diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorItemAdvanced.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorItemAdvanced.java index 7d992674a93..e2475756fd5 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorItemAdvanced.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorItemAdvanced.java @@ -78,7 +78,7 @@ public ModularUI createUI(EntityPlayer player) { // "cover.generic.advanced_detector.invert_label")); group.addWidget( new CycleButtonWidget(10, 3 * (SIZE + PADDING), 4 * SIZE, SIZE, this::isInverted, this::setInverted, - "cover.machine_controller.normal", "cover.machine_controller.inverted") + "cover.advanced_energy_detector.normal", "cover.advanced_energy_detector.inverted") .setTooltipHoverString("cover.generic.advanced_detector.invert_tooltip")); // group.addWidget(new LabelWidget(10, 5 + 4 * (SIZE + PADDING), // "cover.generic.advanced_detector.latch_label")); @@ -151,7 +151,7 @@ public void update() { int storedItems = 0; for (int i = 0; i < itemHandler.getSlots(); i++) { - if (itemFilter.testItemStack(itemHandler.getStackInSlot(i))) + if (itemFilter.test(itemHandler.getStackInSlot(i))) storedItems += itemHandler.getStackInSlot(i).getCount(); } diff --git a/src/main/java/gregtech/common/covers/filter/BaseFilter.java b/src/main/java/gregtech/common/covers/filter/BaseFilter.java new file mode 100644 index 00000000000..ae72a78626d --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/BaseFilter.java @@ -0,0 +1,183 @@ +package gregtech.common.covers.filter; + +import gregtech.api.items.metaitem.MetaItem; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; +import gregtech.api.util.IDirtyNotifiable; +import gregtech.common.covers.filter.readers.BaseFilterReader; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fluids.FluidStack; + +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.api.widget.IWidget; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.CycleButtonWidget; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public abstract class BaseFilter implements IFilter { + + public static final BaseFilter ERROR_FILTER = new BaseFilter() { + + private final BaseFilterReader filterReader = new BaseFilterReader(ItemStack.EMPTY, 0); + + @Override + public BaseFilterReader getFilterReader() { + return this.filterReader; + } + + @Override + public @NotNull ModularPanel createPopupPanel(GuiSyncManager syncManager) { + return GTGuis.createPopupPanel("error", 100, 100) + .child(createWidgets(syncManager)); + } + + @Override + public @NotNull ModularPanel createPanel(GuiSyncManager syncManager) { + return GTGuis.createPanel("error", 100, 100) + .child(createWidgets(syncManager)); + } + + @Override + public @NotNull Widget createWidgets(GuiSyncManager syncManager) { + return IKey.lang("INVALID FILTER").alignment(Alignment.Center).asWidget(); + } + + @Override + public FilterType getType() { + return FilterType.ITEM; + } + }; + protected IDirtyNotifiable dirtyNotifiable; + + public abstract BaseFilterReader getFilterReader(); + + public final ItemStack getContainerStack() { + return this.getFilterReader().getContainer(); + } + + public static @Nullable BaseFilter getFilterFromStack(ItemStack stack) { + if (stack.getItem() instanceof MetaItemmetaItem) { + var metaValueItem = metaItem.getItem(stack); + var factory = metaValueItem == null ? null : metaValueItem.getFilterFactory(); + if (factory != null) + return factory.create(stack); + } + return null; + } + + public final void setBlacklistFilter(boolean blacklistFilter) { + this.getFilterReader().setBlacklistFilter(blacklistFilter); + markDirty(); + } + + @Override + public final MatchResult match(Object toMatch) { + if (toMatch instanceof ItemStack stack) { + return matchItem(stack); + } else if (toMatch instanceof FluidStack stack) { + return matchFluid(stack); + } + return MatchResult.NONE; + } + + public MatchResult matchFluid(FluidStack fluidStack) { + return MatchResult.NONE; + } + + public MatchResult matchItem(ItemStack itemStack) { + return MatchResult.NONE; + } + + @Override + public final boolean test(Object toTest) { + boolean b = false; + if (toTest instanceof ItemStack stack) { + b = testItem(stack); + } else if (toTest instanceof FluidStack stack) { + b = testFluid(stack); + } + return b != isBlacklistFilter(); + } + + public boolean testFluid(FluidStack toTest) { + return false; + } + + public boolean testItem(ItemStack toTest) { + return false; + } + + @Override + public final int getTransferLimit(Object o, int transferSize) { + if (o instanceof ItemStack stack) { + return getTransferLimit(stack, transferSize); + } else if (o instanceof FluidStack stack) { + return getTransferLimit(stack, transferSize); + } + return 0; + } + + public int getTransferLimit(FluidStack stack, int transferSize) { + return 0; + } + + public int getTransferLimit(ItemStack stack, int transferSize) { + return 0; + } + + public final boolean isBlacklistFilter() { + return getFilterReader().isBlacklistFilter(); + } + + public IWidget createBlacklistUI() { + return new ParentWidget<>().coverChildren() + .child(new CycleButtonWidget() + .value(new BooleanSyncValue( + this::isBlacklistFilter, + this::setBlacklistFilter)) + .textureGetter(state -> GTGuiTextures.BUTTON_BLACKLIST[state]) + .addTooltip(0, IKey.lang("cover.filter.blacklist.disabled")) + .addTooltip(1, IKey.lang("cover.filter.blacklist.enabled"))); + } + + public final int getMaxTransferSize() { + return this.getFilterReader().getMaxTransferRate(); + } + + public final void setMaxTransferSize(int maxStackSize) { + this.getFilterReader().setMaxTransferRate(maxStackSize); + } + + public boolean showGlobalTransferLimitSlider() { + return isBlacklistFilter(); + } + + public final void setDirtyNotifiable(IDirtyNotifiable dirtyNotifiable) { + this.dirtyNotifiable = dirtyNotifiable; + this.getFilterReader().setDirtyNotifiable(dirtyNotifiable); + } + + public final void markDirty() { + if (dirtyNotifiable != null) { + dirtyNotifiable.markAsDirty(); + } + } + + public void readFromNBT(NBTTagCompound tag) { + this.getFilterReader().deserializeNBT(tag); + markDirty(); + } + + public void writeInitialSyncData(PacketBuffer packetBuffer) {} + + public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) {} +} diff --git a/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java b/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java new file mode 100644 index 00000000000..489fd70659d --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java @@ -0,0 +1,273 @@ +package gregtech.common.covers.filter; + +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.util.IDirtyNotifiable; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.items.ItemStackHandler; + +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.api.widget.IWidget; +import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.drawable.GuiTextures; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.PanelSyncHandler; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widgets.ButtonWidget; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.layout.Row; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; + +public abstract class BaseFilterContainer extends ItemStackHandler { + + private int maxTransferSize = 1; + private int transferSize; + private @Nullable BaseFilter currentFilter; + private @Nullable Runnable onFilterInstanceChange; + private final IDirtyNotifiable dirtyNotifiable; + + protected BaseFilterContainer(IDirtyNotifiable dirtyNotifiable) { + super(); + this.dirtyNotifiable = dirtyNotifiable; + } + + public boolean test(Object toTest) { + return !hasFilter() || getFilter().test(toTest); + } + + public MatchResult match(Object toMatch) { + if (!hasFilter()) + return MatchResult.create(true, toMatch, -1); + + return getFilter().match(toMatch); + } + + public int getTransferLimit(Object stack) { + if (!hasFilter() || isBlacklistFilter()) { + return getTransferSize(); + } + return getFilter().getTransferLimit(stack, getTransferSize()); + } + + @Override + public int getSlotLimit(int slot) { + return 1; + } + + public void onFilterInstanceChange() { + dirtyNotifiable.markAsDirty(); + if (onFilterInstanceChange != null) { + onFilterInstanceChange.run(); + } + } + + public void setOnFilterInstanceChange(@Nullable Runnable onFilterInstanceChange) { + this.onFilterInstanceChange = onFilterInstanceChange; + } + + public final @NotNull ItemStack getFilterStack() { + return this.getStackInSlot(0); + } + + @Override + public void setStackInSlot(int slot, @NotNull ItemStack stack) { + if (ItemStack.areItemStacksEqual(stack, getFilterStack())) + return; + + if (stack.isEmpty()) { + setFilter(null); + } else if (isItemValid(stack)) { + setFilter(BaseFilter.getFilterFromStack(stack)); + } + + super.setStackInSlot(slot, stack); + } + + @Override + public boolean isItemValid(int slot, @NotNull ItemStack stack) { + return isItemValid(stack); + } + + protected abstract boolean isItemValid(ItemStack stack); + + protected abstract String getFilterName(); + + @Override + public @NotNull ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + if (!isItemValid(stack)) return stack; + var remainder = super.insertItem(slot, stack, simulate); + if (!simulate) setFilter(BaseFilter.getFilterFromStack(stack)); + return remainder; + } + + @Override + public @NotNull ItemStack extractItem(int slot, int amount, boolean simulate) { + var extracted = super.extractItem(slot, amount, simulate); + if (!extracted.isEmpty()) { + setFilter(null); + } + return extracted; + } + + public final void setFilterStack(ItemStack stack) { + setStackInSlot(0, stack); + } + + public int getMaxTransferSize() { + return !showGlobalTransferLimitSlider() && hasFilter() ? currentFilter.getMaxTransferSize() : + this.maxTransferSize; + } + + public void setMaxTransferSize(int maxTransferSize) { + this.maxTransferSize = MathHelper.clamp(maxTransferSize, 1, Integer.MAX_VALUE); + this.transferSize = MathHelper.clamp(this.transferSize, 1, this.maxTransferSize); + if (hasFilter()) currentFilter.setMaxTransferSize(this.maxTransferSize); + } + + public final boolean hasFilter() { + return currentFilter != null; + } + + public final @Nullable BaseFilter getFilter() { + return currentFilter; + } + + public final void setFilter(@Nullable BaseFilter newFilter) { + this.currentFilter = newFilter; + if (hasFilter()) { + this.currentFilter.setDirtyNotifiable(this.dirtyNotifiable); + this.currentFilter.setMaxTransferSize(this.maxTransferSize); + } + if (onFilterInstanceChange != null) { + this.onFilterInstanceChange.run(); + } + } + + public boolean showGlobalTransferLimitSlider() { + return this.maxTransferSize > 0 && (!hasFilter() || getFilter().showGlobalTransferLimitSlider()); + } + + public void setBlacklistFilter(boolean blacklistFilter) { + if (hasFilter()) getFilter().setBlacklistFilter(blacklistFilter); + onFilterInstanceChange(); + } + + public final boolean isBlacklistFilter() { + return hasFilter() && getFilter().isBlacklistFilter(); + } + + public int getTransferSize() { + if (!showGlobalTransferLimitSlider()) { + return getMaxTransferSize(); + } + return this.transferSize; + } + + public int getTransferLimit(int slotIndex) { + if (isBlacklistFilter() || !hasFilter()) { + return getTransferSize(); + } + return this.currentFilter.getTransferLimit(slotIndex, getTransferSize()); + } + + public void setTransferSize(int transferSize) { + this.transferSize = MathHelper.clamp(transferSize, 1, getMaxTransferSize()); + onFilterInstanceChange(); + } + + @Override + public NBTTagCompound serializeNBT() { + NBTTagCompound tagCompound = new NBTTagCompound(); + tagCompound.setTag("FilterInventory", super.serializeNBT()); + // tagCompound.setInteger("MaxStackSize", getMaxTransferSize()); + tagCompound.setInteger("TransferStackSize", getTransferSize()); + return tagCompound; + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + super.deserializeNBT(nbt.getCompoundTag("FilterInventory")); + setFilter(BaseFilter.getFilterFromStack(getFilterStack())); + if (nbt.hasKey("TransferStackSize")) + this.transferSize = nbt.getInteger("TransferStackSize"); + } + + public void handleLegacyNBT(NBTTagCompound nbt) { + if (hasFilter()) { + getFilter().getFilterReader().handleLegacyNBT(nbt); + } + } + + /** Uses Cleanroom MUI */ + public IWidget initUI(ModularPanel main, GuiSyncManager manager) { + var panel = new PanelSyncHandler(main) { + + // the panel can't be opened if there's no filter, so `getFilter()` should not be null + @Override + public ModularPanel createUI(ModularPanel mainPanel, GuiSyncManager syncManager) { + var filter = hasFilter() ? getFilter() : BaseFilter.ERROR_FILTER; + filter.setMaxTransferSize(getMaxTransferSize()); + return filter.createPopupPanel(syncManager); + } + }; + + manager.syncValue("filter_panel", panel); + var filterButton = new ButtonWidget<>(); + filterButton.setEnabled(hasFilter()); + + return new Row().coverChildrenHeight() + .marginBottom(2).widthRel(1f) + .child(new ItemSlot() + .slot(SyncHandlers.itemSlot(this, 0) + .filter(this::isItemValid) + .singletonSlotGroup(101) + .changeListener((newItem, onlyAmountChanged, client, init) -> { + if (!isItemValid(newItem) && panel.isPanelOpen()) { + panel.closePanel(); + } + })) + .size(18).marginRight(2) + .background(GTGuiTextures.SLOT, GTGuiTextures.FILTER_SLOT_OVERLAY.asIcon().size(16))) + .child(filterButton + .background(GTGuiTextures.MC_BUTTON, GTGuiTextures.FILTER_SETTINGS_OVERLAY.asIcon().size(16)) + .hoverBackground(GuiTextures.MC_BUTTON_HOVERED, + GTGuiTextures.FILTER_SETTINGS_OVERLAY.asIcon().size(16)) + .setEnabledIf(w -> hasFilter()) + .onMousePressed(i -> { + if (!panel.isPanelOpen()) { + panel.openPanel(); + } else { + panel.closePanel(); + } + Interactable.playButtonClickSound(); + return true; + })) + .child(IKey.dynamic(this::getFilterName) + .alignment(Alignment.CenterRight).asWidget() + .left(36).right(0).height(18)); + } + + public void writeInitialSyncData(PacketBuffer packetBuffer) { + packetBuffer.writeItemStack(this.getFilterStack()); + packetBuffer.writeInt(this.maxTransferSize); + packetBuffer.writeInt(this.transferSize); + } + + public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { + var stack = ItemStack.EMPTY; + try { + stack = packetBuffer.readItemStack(); + } catch (IOException ignore) {} + this.setFilterStack(stack); + this.setMaxTransferSize(packetBuffer.readInt()); + this.setTransferSize(packetBuffer.readInt()); + } +} diff --git a/src/main/java/gregtech/common/covers/filter/FilterTypeRegistry.java b/src/main/java/gregtech/common/covers/filter/FilterTypeRegistry.java deleted file mode 100644 index 633242b05d2..00000000000 --- a/src/main/java/gregtech/common/covers/filter/FilterTypeRegistry.java +++ /dev/null @@ -1,103 +0,0 @@ -package gregtech.common.covers.filter; - -import gregtech.api.unification.stack.ItemAndMetadata; -import gregtech.api.util.GTLog; -import gregtech.common.items.MetaItems; - -import net.minecraft.item.ItemStack; - -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; - -import java.util.Map; - -public class FilterTypeRegistry { - - private static final Map itemFilterIdByStack = new Object2IntOpenHashMap<>(); - private static final Map fluidFilterIdByStack = new Object2IntOpenHashMap<>(); - private static final BiMap> itemFilterById = HashBiMap.create(); - private static final BiMap> fluidFilterById = HashBiMap.create(); - - public static void init() { - registerFluidFilter(1, SimpleFluidFilter.class, MetaItems.FLUID_FILTER.getStackForm()); - registerItemFilter(2, SimpleItemFilter.class, MetaItems.ITEM_FILTER.getStackForm()); - registerItemFilter(3, OreDictionaryItemFilter.class, MetaItems.ORE_DICTIONARY_FILTER.getStackForm()); - registerItemFilter(4, SmartItemFilter.class, MetaItems.SMART_FILTER.getStackForm()); - } - - public static void registerFluidFilter(int id, Class fluidFilterClass, ItemStack itemStack) { - if (fluidFilterById.containsKey(id)) { - throw new IllegalArgumentException("Id is already occupied: " + id); - } - fluidFilterIdByStack.put(new ItemAndMetadata(itemStack), id); - fluidFilterById.put(id, fluidFilterClass); - } - - public static void registerItemFilter(int id, Class itemFilterClass, ItemStack itemStack) { - if (itemFilterById.containsKey(id)) { - throw new IllegalArgumentException("Id is already occupied: " + id); - } - itemFilterIdByStack.put(new ItemAndMetadata(itemStack), id); - itemFilterById.put(id, itemFilterClass); - } - - public static int getIdForItemFilter(ItemFilter itemFilter) { - Integer filterId = itemFilterById.inverse().get(itemFilter.getClass()); - if (filterId == null) { - throw new IllegalArgumentException("Unknown filter type " + itemFilter.getClass()); - } - return filterId; - } - - public static int getIdForFluidFilter(FluidFilter fluidFilter) { - Integer filterId = fluidFilterById.inverse().get(fluidFilter.getClass()); - if (filterId == null) { - throw new IllegalArgumentException("Unknown filter type " + fluidFilter.getClass()); - } - return filterId; - } - - public static ItemFilter createItemFilterById(int filterId) { - Class filterClass = itemFilterById.get(filterId); - if (filterClass == null) { - throw new IllegalArgumentException("Unknown filter id: " + filterId); - } - return createNewFilterInstance(filterClass); - } - - public static FluidFilter createFluidFilterById(int filterId) { - Class filterClass = fluidFilterById.get(filterId); - if (filterClass == null) { - throw new IllegalArgumentException("Unknown filter id: " + filterId); - } - return createNewFilterInstance(filterClass); - } - - public static ItemFilter getItemFilterForStack(ItemStack itemStack) { - Integer filterId = itemFilterIdByStack.get(new ItemAndMetadata(itemStack)); - if (filterId == null) { - return null; - } - Class filterClass = itemFilterById.get(filterId); - return createNewFilterInstance(filterClass); - } - - public static FluidFilter getFluidFilterForStack(ItemStack itemStack) { - Integer filterId = fluidFilterIdByStack.get(new ItemAndMetadata(itemStack)); - if (filterId == null) { - return null; - } - Class filterClass = fluidFilterById.get(filterId); - return createNewFilterInstance(filterClass); - } - - private static T createNewFilterInstance(Class filterClass) { - try { - return filterClass.newInstance(); - } catch (ReflectiveOperationException exception) { - GTLog.logger.error("Failed to create filter instance for class {}", filterClass, exception); - return null; - } - } -} diff --git a/src/main/java/gregtech/common/covers/filter/FluidFilter.java b/src/main/java/gregtech/common/covers/filter/FluidFilter.java deleted file mode 100644 index 6d6dc23254b..00000000000 --- a/src/main/java/gregtech/common/covers/filter/FluidFilter.java +++ /dev/null @@ -1,41 +0,0 @@ -package gregtech.common.covers.filter; - -import gregtech.api.gui.Widget; -import gregtech.api.util.IDirtyNotifiable; - -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.fluids.FluidStack; - -import java.util.function.Consumer; - -public abstract class FluidFilter { - - private IDirtyNotifiable dirtyNotifiable; - boolean showTip; - - public abstract boolean testFluid(FluidStack fluidStack); - - public abstract int getFluidTransferLimit(FluidStack fluidStack); - - public abstract int getMaxOccupiedHeight(); - - public abstract void initUI(Consumer widgetGroup); - - public abstract void writeToNBT(NBTTagCompound tagCompound); - - public abstract void readFromNBT(NBTTagCompound tagCompound); - - public final void setDirtyNotifiable(IDirtyNotifiable dirtyNotifiable) { - this.dirtyNotifiable = dirtyNotifiable; - } - - public abstract void configureFilterTanks(int amount); - - public abstract void setMaxConfigurableFluidSize(int maxStackSize); - - public final void markDirty() { - if (dirtyNotifiable != null) { - dirtyNotifiable.markAsDirty(); - } - } -} diff --git a/src/main/java/gregtech/common/covers/filter/FluidFilterContainer.java b/src/main/java/gregtech/common/covers/filter/FluidFilterContainer.java index 41beb67b6d6..a3793c0ffed 100644 --- a/src/main/java/gregtech/common/covers/filter/FluidFilterContainer.java +++ b/src/main/java/gregtech/common/covers/filter/FluidFilterContainer.java @@ -1,128 +1,64 @@ package gregtech.common.covers.filter; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.SlotWidget; import gregtech.api.util.IDirtyNotifiable; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.common.util.INBTSerializable; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.items.ItemStackHandler; -import org.jetbrains.annotations.NotNull; +import com.cleanroommc.modularui.api.drawable.IKey; +import org.jetbrains.annotations.ApiStatus; +import java.util.function.BooleanSupplier; import java.util.function.Consumer; -import java.util.function.Supplier; -public class FluidFilterContainer implements INBTSerializable { - - private final ItemStackHandler filterInventory; - private final FluidFilterWrapper filterWrapper; - - public FluidFilterContainer(IDirtyNotifiable dirtyNotifiable, int capacity) { - this.filterWrapper = new FluidFilterWrapper(dirtyNotifiable, capacity); - this.filterInventory = new ItemStackHandler(1) { - - @Override - public boolean isItemValid(int slot, @NotNull ItemStack stack) { - return FilterTypeRegistry.getFluidFilterForStack(stack) != null; - } - - @Override - public int getSlotLimit(int slot) { - return 1; - } - - @Override - protected void onLoad() { - onFilterSlotChange(false); - } - - @Override - protected void onContentsChanged(int slot) { - onFilterSlotChange(true); - } - }; - } - - public FluidFilterContainer(IDirtyNotifiable dirtyNotifiable, Supplier showTip, int maxSize) { - this(dirtyNotifiable, maxSize); - filterWrapper.setTipSupplier(showTip); - } - - public FluidFilterContainer(IDirtyNotifiable dirtyNotifiable, Supplier showTip) { - this(dirtyNotifiable, 1000); - filterWrapper.setTipSupplier(showTip); - } +public class FluidFilterContainer extends BaseFilterContainer { public FluidFilterContainer(IDirtyNotifiable dirtyNotifiable) { - this(dirtyNotifiable, 1000); - filterWrapper.setTipSupplier(() -> false); - } - - public ItemStackHandler getFilterInventory() { - return filterInventory; - } - - public FluidFilterWrapper getFilterWrapper() { - return filterWrapper; - } - - public void initUI(int y, Consumer widgetGroup) { - widgetGroup.accept(new LabelWidget(10, y, "cover.pump.fluid_filter.title")); - widgetGroup.accept(new SlotWidget(filterInventory, 0, 10, y + 15) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.FILTER_SLOT_OVERLAY)); - - this.filterWrapper.initUI(y + 15, widgetGroup); - this.filterWrapper.blacklistUI(y + 15, widgetGroup, () -> true); + super(dirtyNotifiable); } - protected void onFilterSlotChange(boolean notify) { - ItemStack filterStack = filterInventory.getStackInSlot(0); - FluidFilter newFluidFilter = FilterTypeRegistry.getFluidFilterForStack(filterStack); - FluidFilter currentFluidFilter = filterWrapper.getFluidFilter(); - if (newFluidFilter == null) { - if (currentFluidFilter != null) { - filterWrapper.setFluidFilter(null); - if (notify) filterWrapper.onFilterInstanceChange(); - } - } else if (currentFluidFilter == null || - newFluidFilter.getClass() != currentFluidFilter.getClass()) { - filterWrapper.setFluidFilter(newFluidFilter); - if (notify) filterWrapper.onFilterInstanceChange(); - } + /** @deprecated uses old builtin MUI */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.10") + public void initUI(int y, Consumer widgetGroup) { + widgetGroup.accept(new gregtech.api.gui.widgets.LabelWidget(10, y, "cover.pump.fluid_filter.title")); + widgetGroup.accept(new gregtech.api.gui.widgets.SlotWidget(this, 0, 10, y + 15) + .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT, + gregtech.api.gui.GuiTextures.FILTER_SLOT_OVERLAY)); + + this.initFilterUI(y + 15, widgetGroup); + this.blacklistUI(y + 15, widgetGroup, () -> true); } - public boolean testFluidStack(FluidStack fluidStack) { - return filterWrapper.testFluidStack(fluidStack); + /** @deprecated uses old builtin MUI */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.10") + public void initFilterUI(int y, Consumer widgetGroup) { + widgetGroup.accept(new WidgetGroupFluidFilter(y, this::getFilter, this::showGlobalTransferLimitSlider)); } - public boolean testFluidStack(FluidStack fluidStack, Boolean whitelist) { - return filterWrapper.testFluidStack(fluidStack, whitelist); + /** @deprecated uses old builtin MUI */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.10") + public void blacklistUI(int y, Consumer widgetGroup, BooleanSupplier showBlacklistButton) { + gregtech.api.gui.widgets.ServerWidgetGroup blacklistButton = new gregtech.api.gui.widgets.ServerWidgetGroup( + this::hasFilter); + blacklistButton.addWidget(new gregtech.api.gui.widgets.ToggleButtonWidget(144, y, 18, 18, + gregtech.api.gui.GuiTextures.BUTTON_BLACKLIST, + this::isBlacklistFilter, this::setBlacklistFilter).setPredicate(showBlacklistButton) + .setTooltipText("cover.filter.blacklist")); + widgetGroup.accept(blacklistButton); } @Override - public NBTTagCompound serializeNBT() { - NBTTagCompound tagCompound = new NBTTagCompound(); - tagCompound.setTag("FilterInventory", filterInventory.serializeNBT()); - tagCompound.setBoolean("IsBlacklist", filterWrapper.isBlacklistFilter()); - if (filterWrapper.getFluidFilter() != null) { - NBTTagCompound filterInventory = new NBTTagCompound(); - filterWrapper.getFluidFilter().writeToNBT(filterInventory); - tagCompound.setTag("Filter", filterInventory); - } - return tagCompound; + protected boolean isItemValid(ItemStack stack) { + var filter = BaseFilter.getFilterFromStack(stack); + return filter != null && filter.getType() == IFilter.FilterType.FLUID; } @Override - public void deserializeNBT(NBTTagCompound tagCompound) { - this.filterInventory.deserializeNBT(tagCompound.getCompoundTag("FilterInventory")); - this.filterWrapper.setBlacklistFilter(tagCompound.getBoolean("IsBlacklist")); - if (filterWrapper.getFluidFilter() != null) { - this.filterWrapper.getFluidFilter().readFromNBT(tagCompound.getCompoundTag("Filter")); - } + protected String getFilterName() { + return hasFilter() ? + getFilterStack().getDisplayName() : + IKey.lang("metaitem.fluid_filter.name").get(); } } diff --git a/src/main/java/gregtech/common/covers/filter/FluidFilterWrapper.java b/src/main/java/gregtech/common/covers/filter/FluidFilterWrapper.java deleted file mode 100644 index 2ef1f76a32e..00000000000 --- a/src/main/java/gregtech/common/covers/filter/FluidFilterWrapper.java +++ /dev/null @@ -1,98 +0,0 @@ -package gregtech.common.covers.filter; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.ServerWidgetGroup; -import gregtech.api.gui.widgets.ToggleButtonWidget; -import gregtech.api.util.IDirtyNotifiable; - -import net.minecraftforge.fluids.FluidStack; - -import java.util.function.BooleanSupplier; -import java.util.function.Consumer; -import java.util.function.Supplier; - -public class FluidFilterWrapper { - - private final IDirtyNotifiable dirtyNotifiable; - private boolean isBlacklistFilter = false; - private FluidFilter currentFluidFilter; - private Supplier showTipSupplier; - private int maxSize = 1000; - - public FluidFilterWrapper(IDirtyNotifiable dirtyNotifiable, int maxSize) { - this.dirtyNotifiable = dirtyNotifiable; - this.maxSize = maxSize; - } - - public FluidFilterWrapper(IDirtyNotifiable dirtyNotifiable) { - this.dirtyNotifiable = dirtyNotifiable; - } - - public void initUI(int y, Consumer widgetGroup) { - widgetGroup.accept(new WidgetGroupFluidFilter(y, this::getFluidFilter, shouldShowTip())); - } - - public void blacklistUI(int y, Consumer widgetGroup, BooleanSupplier showBlacklistButton) { - ServerWidgetGroup blacklistButton = new ServerWidgetGroup(() -> getFluidFilter() != null); - blacklistButton.addWidget(new ToggleButtonWidget(144, y, 18, 18, GuiTextures.BUTTON_BLACKLIST, - this::isBlacklistFilter, this::setBlacklistFilter).setPredicate(showBlacklistButton) - .setTooltipText("cover.filter.blacklist")); - widgetGroup.accept(blacklistButton); - } - - public void setFluidFilter(FluidFilter fluidFilter) { - this.currentFluidFilter = fluidFilter; - if (currentFluidFilter != null) { - currentFluidFilter.setDirtyNotifiable(dirtyNotifiable); - currentFluidFilter.setMaxConfigurableFluidSize(maxSize); - } - } - - private Supplier shouldShowTip() { - return showTipSupplier; - } - - protected void setTipSupplier(Supplier supplier) { - this.showTipSupplier = supplier; - } - - public FluidFilter getFluidFilter() { - return currentFluidFilter; - } - - public void onFilterInstanceChange() { - dirtyNotifiable.markAsDirty(); - } - - public void setBlacklistFilter(boolean blacklistFilter) { - isBlacklistFilter = blacklistFilter; - dirtyNotifiable.markAsDirty(); - } - - public boolean isBlacklistFilter() { - return isBlacklistFilter; - } - - public boolean testFluidStack(FluidStack fluidStack, boolean whitelist) { - boolean result = true; - if (currentFluidFilter != null) { - result = currentFluidFilter.testFluid(fluidStack); - } - if (!whitelist) { - result = !result; - } - return result; - } - - public boolean testFluidStack(FluidStack fluidStack) { - boolean result = true; - if (currentFluidFilter != null) { - result = currentFluidFilter.testFluid(fluidStack); - } - if (isBlacklistFilter) { - result = !result; - } - return result; - } -} diff --git a/src/main/java/gregtech/common/covers/filter/IFilter.java b/src/main/java/gregtech/common/covers/filter/IFilter.java new file mode 100644 index 00000000000..06345143982 --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/IFilter.java @@ -0,0 +1,77 @@ +package gregtech.common.covers.filter; + +import gregtech.api.items.metaitem.stats.IItemComponent; +import gregtech.api.util.IDirtyNotifiable; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.widget.Widget; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Consumer; + +public interface IFilter { + + @Deprecated + default void initUI(Consumer widgetGroup) {} + + /** Uses Cleanroom MUI */ + @NotNull + ModularPanel createPopupPanel(GuiSyncManager syncManager); + + /** Uses Cleanroom MUI */ + @NotNull + ModularPanel createPanel(GuiSyncManager syncManager); + + /** Uses Cleanroom MUI - Creates the widgets standalone so that they can be put into their own panel */ + + @NotNull + Widget createWidgets(GuiSyncManager syncManager); + + ItemStack getContainerStack(); + + void setDirtyNotifiable(@Nullable IDirtyNotifiable dirtyNotifiable); + + void markDirty(); + + int getMaxTransferSize(); + + void setMaxTransferSize(int maxTransferSize); + + boolean showGlobalTransferLimitSlider(); + + MatchResult match(Object toMatch); + + boolean test(Object toTest); + + int getTransferLimit(Object stack, int transferSize); + + default int getTransferLimit(int slot, int transferSize) { + return transferSize; + } + + void readFromNBT(NBTTagCompound tagCompound); + + FilterType getType(); + + enum FilterType { + ITEM, + FLUID + } + + // this only exists so i can pass in the constructor reference as a metaitem componant + static Factory factory(Factory factory) { + return factory; + } + + @FunctionalInterface + interface Factory extends IItemComponent { + + @NotNull + BaseFilter create(@NotNull ItemStack stack); + } +} diff --git a/src/main/java/gregtech/common/covers/filter/ItemFilter.java b/src/main/java/gregtech/common/covers/filter/ItemFilter.java deleted file mode 100644 index a5b350da33d..00000000000 --- a/src/main/java/gregtech/common/covers/filter/ItemFilter.java +++ /dev/null @@ -1,50 +0,0 @@ -package gregtech.common.covers.filter; - -import gregtech.api.gui.Widget; -import gregtech.api.util.IDirtyNotifiable; - -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; - -import java.util.function.Consumer; - -public abstract class ItemFilter { - - private IDirtyNotifiable dirtyNotifiable; - private int maxStackSize = Integer.MAX_VALUE; - - public final int getMaxStackSize() { - return maxStackSize; - } - - public final void setMaxStackSize(int maxStackSize) { - this.maxStackSize = maxStackSize; - onMaxStackSizeChange(); - } - - protected void onMaxStackSizeChange() {} - - public abstract boolean showGlobalTransferLimitSlider(); - - public abstract int getSlotTransferLimit(Object matchSlot, int globalTransferLimit); - - public abstract Object matchItemStack(ItemStack itemStack); - - public abstract int getTotalOccupiedHeight(); - - public abstract void initUI(Consumer widgetGroup); - - public abstract void writeToNBT(NBTTagCompound tagCompound); - - public abstract void readFromNBT(NBTTagCompound tagCompound); - - final void setDirtyNotifiable(IDirtyNotifiable dirtyNotifiable) { - this.dirtyNotifiable = dirtyNotifiable; - } - - public final void markDirty() { - if (dirtyNotifiable != null) { - dirtyNotifiable.markAsDirty(); - } - } -} diff --git a/src/main/java/gregtech/common/covers/filter/ItemFilterContainer.java b/src/main/java/gregtech/common/covers/filter/ItemFilterContainer.java index 71be9ff14d3..d282595253d 100644 --- a/src/main/java/gregtech/common/covers/filter/ItemFilterContainer.java +++ b/src/main/java/gregtech/common/covers/filter/ItemFilterContainer.java @@ -1,165 +1,65 @@ package gregtech.common.covers.filter; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.Widget; import gregtech.api.gui.widgets.LabelWidget; +import gregtech.api.gui.widgets.ServerWidgetGroup; import gregtech.api.gui.widgets.SlotWidget; +import gregtech.api.gui.widgets.ToggleButtonWidget; import gregtech.api.util.IDirtyNotifiable; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.math.MathHelper; -import net.minecraftforge.common.util.INBTSerializable; -import net.minecraftforge.items.ItemStackHandler; -import org.jetbrains.annotations.NotNull; +import com.cleanroommc.modularui.api.drawable.IKey; +import org.jetbrains.annotations.ApiStatus; +import java.util.function.BooleanSupplier; import java.util.function.Consumer; -public class ItemFilterContainer implements INBTSerializable { - - private final ItemStackHandler filterInventory; - private final ItemFilterWrapper filterWrapper; - private int maxStackSizeLimit = 1; - private int transferStackSize; +public class ItemFilterContainer extends BaseFilterContainer { public ItemFilterContainer(IDirtyNotifiable dirtyNotifiable) { - this.filterWrapper = new ItemFilterWrapper(dirtyNotifiable); - this.filterWrapper.setOnFilterInstanceChange(this::onFilterInstanceChange); - this.filterInventory = new ItemStackHandler(1) { - - @Override - public boolean isItemValid(int slot, @NotNull ItemStack stack) { - return FilterTypeRegistry.getItemFilterForStack(stack) != null; - } - - @Override - public int getSlotLimit(int slot) { - return 1; - } - - @Override - protected void onLoad() { - onFilterSlotChange(false); - } - - @Override - protected void onContentsChanged(int slot) { - onFilterSlotChange(true); - } - }; - } - - public ItemStackHandler getFilterInventory() { - return filterInventory; - } - - public ItemFilterWrapper getFilterWrapper() { - return filterWrapper; - } - - private void onFilterInstanceChange() { - this.filterWrapper.setMaxStackSize(getTransferStackSize()); - } - - public int getMaxStackSize() { - return maxStackSizeLimit; - } - - public int getTransferStackSize() { - if (!showGlobalTransferLimitSlider()) { - return getMaxStackSize(); - } - return transferStackSize; + super(dirtyNotifiable); } - public void setTransferStackSize(int transferStackSize) { - this.transferStackSize = MathHelper.clamp(transferStackSize, 1, getMaxStackSize()); - this.filterWrapper.setMaxStackSize(getTransferStackSize()); - } - - public void adjustTransferStackSize(int amount) { - setTransferStackSize(transferStackSize + amount); - } - - public void initUI(int y, Consumer widgetGroup) { + /** @deprecated uses old builtin MUI */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.10") + public void initUI(int y, Consumer widgetGroup) { widgetGroup.accept(new LabelWidget(10, y, "cover.conveyor.item_filter.title")); - widgetGroup.accept(new SlotWidget(filterInventory, 0, 10, y + 15) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.FILTER_SLOT_OVERLAY)); - - this.filterWrapper.initUI(y + 38, widgetGroup); - this.filterWrapper.blacklistUI(y + 38, widgetGroup, () -> true); - } - - protected void onFilterSlotChange(boolean notify) { - ItemStack filterStack = filterInventory.getStackInSlot(0); - ItemFilter newItemFilter = FilterTypeRegistry.getItemFilterForStack(filterStack); - ItemFilter currentItemFilter = filterWrapper.getItemFilter(); - if (newItemFilter == null) { - if (currentItemFilter != null) { - filterWrapper.setItemFilter(null); - filterWrapper.setBlacklistFilter(false); - if (notify) filterWrapper.onFilterInstanceChange(); - } - } else if (currentItemFilter == null || - newItemFilter.getClass() != currentItemFilter.getClass()) { - filterWrapper.setItemFilter(newItemFilter); - if (notify) filterWrapper.onFilterInstanceChange(); - } - } - - public void setMaxStackSize(int maxStackSizeLimit) { - this.maxStackSizeLimit = maxStackSizeLimit; - setTransferStackSize(transferStackSize); - } - - public boolean showGlobalTransferLimitSlider() { - return getMaxStackSize() > 1 && filterWrapper.showGlobalTransferLimitSlider(); - } - - public int getSlotTransferLimit(Object slotIndex) { - return filterWrapper.getSlotTransferLimit(slotIndex, getTransferStackSize()); - } - - public Object matchItemStack(ItemStack itemStack) { - return filterWrapper.matchItemStack(itemStack); - } + widgetGroup.accept(new SlotWidget(this, 0, 10, y + 15) + .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT, + gregtech.api.gui.GuiTextures.FILTER_SLOT_OVERLAY)); - public Object matchItemStack(ItemStack itemStack, boolean whitelist) { - return filterWrapper.matchItemStack(itemStack, whitelist); + this.initFilterUI(y + 38, widgetGroup); } - public boolean testItemStack(ItemStack itemStack) { - return matchItemStack(itemStack) != null; + /** @deprecated uses old builtin MUI */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.10") + public void initFilterUI(int y, Consumer widgetGroup) { + widgetGroup.accept(new WidgetGroupItemFilter(y, this::getFilter)); } - public boolean testItemStack(ItemStack itemStack, boolean whitelist) { - return matchItemStack(itemStack, whitelist) != null; + /** @deprecated uses old builtin MUI */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.10") + public void blacklistUI(int y, Consumer widgetGroup, BooleanSupplier showBlacklistButton) { + ServerWidgetGroup blacklistButton = new ServerWidgetGroup(this::hasFilter); + blacklistButton.addWidget(new ToggleButtonWidget(144, y, 20, 20, gregtech.api.gui.GuiTextures.BUTTON_BLACKLIST, + this::isBlacklistFilter, this::setBlacklistFilter).setPredicate(showBlacklistButton) + .setTooltipText("cover.filter.blacklist")); + widgetGroup.accept(blacklistButton); } @Override - public NBTTagCompound serializeNBT() { - NBTTagCompound tagCompound = new NBTTagCompound(); - tagCompound.setTag("FilterInventory", filterInventory.serializeNBT()); - tagCompound.setBoolean("IsBlacklist", filterWrapper.isBlacklistFilter()); - tagCompound.setInteger("MaxStackSize", maxStackSizeLimit); - tagCompound.setInteger("TransferStackSize", transferStackSize); - if (filterWrapper.getItemFilter() != null) { - NBTTagCompound filterInventory = new NBTTagCompound(); - filterWrapper.getItemFilter().writeToNBT(filterInventory); - tagCompound.setTag("Filter", filterInventory); - } - return tagCompound; + protected boolean isItemValid(ItemStack stack) { + var filter = BaseFilter.getFilterFromStack(stack); + return filter != null && filter.getType() == IFilter.FilterType.ITEM; } @Override - public void deserializeNBT(NBTTagCompound tagCompound) { - this.filterInventory.deserializeNBT(tagCompound.getCompoundTag("FilterInventory")); - this.filterWrapper.setBlacklistFilter(tagCompound.getBoolean("IsBlacklist")); - setMaxStackSize(tagCompound.getInteger("MaxStackSize")); - setTransferStackSize(tagCompound.getInteger("TransferStackSize")); - if (filterWrapper.getItemFilter() != null) { - this.filterWrapper.getItemFilter().readFromNBT(tagCompound.getCompoundTag("Filter")); - } + protected String getFilterName() { + return hasFilter() ? + getFilterStack().getDisplayName() : + IKey.lang("metaitem.item_filter.name").get(); } } diff --git a/src/main/java/gregtech/common/covers/filter/ItemFilterWrapper.java b/src/main/java/gregtech/common/covers/filter/ItemFilterWrapper.java deleted file mode 100644 index d11905e00b5..00000000000 --- a/src/main/java/gregtech/common/covers/filter/ItemFilterWrapper.java +++ /dev/null @@ -1,132 +0,0 @@ -package gregtech.common.covers.filter; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.ServerWidgetGroup; -import gregtech.api.gui.widgets.ToggleButtonWidget; -import gregtech.api.util.IDirtyNotifiable; - -import net.minecraft.item.ItemStack; - -import java.util.function.BooleanSupplier; -import java.util.function.Consumer; - -public class ItemFilterWrapper { - - private static final Object MATCH_RESULT_TRUE = new Object(); - private final IDirtyNotifiable dirtyNotifiable; - private boolean isBlacklistFilter = false; - private int maxStackSize = 1; - private ItemFilter currentItemFilter; - private Runnable onFilterInstanceChange; - - public ItemFilterWrapper(IDirtyNotifiable dirtyNotifiable) { - this.dirtyNotifiable = dirtyNotifiable; - } - - public void initUI(int y, Consumer widgetGroup) { - widgetGroup.accept(new WidgetGroupItemFilter(y, this::getItemFilter)); - } - - public void blacklistUI(int y, Consumer widgetGroup, BooleanSupplier showBlacklistButton) { - ServerWidgetGroup blacklistButton = new ServerWidgetGroup(() -> getItemFilter() != null); - blacklistButton.addWidget(new ToggleButtonWidget(144, y, 20, 20, GuiTextures.BUTTON_BLACKLIST, - this::isBlacklistFilter, this::setBlacklistFilter).setPredicate(showBlacklistButton) - .setTooltipText("cover.filter.blacklist")); - widgetGroup.accept(blacklistButton); - } - - public void setItemFilter(ItemFilter itemFilter) { - this.currentItemFilter = itemFilter; - if (currentItemFilter != null) { - currentItemFilter.setDirtyNotifiable(dirtyNotifiable); - } - if (onFilterInstanceChange != null) { - this.onFilterInstanceChange.run(); - } - } - - public ItemFilter getItemFilter() { - return currentItemFilter; - } - - public void setOnFilterInstanceChange(Runnable onFilterInstanceChange) { - this.onFilterInstanceChange = onFilterInstanceChange; - } - - public void onFilterInstanceChange() { - if (currentItemFilter != null) { - currentItemFilter.setMaxStackSize(getInternalMaxStackSize()); - } - dirtyNotifiable.markAsDirty(); - } - - public void setMaxStackSize(int maxStackSize) { - this.maxStackSize = maxStackSize; - onFilterInstanceChange(); - dirtyNotifiable.markAsDirty(); - } - - public void setBlacklistFilter(boolean blacklistFilter) { - isBlacklistFilter = blacklistFilter; - onFilterInstanceChange(); - dirtyNotifiable.markAsDirty(); - } - - public boolean isBlacklistFilter() { - return isBlacklistFilter; - } - - public int getMaxStackSize() { - return maxStackSize; - } - - private int getInternalMaxStackSize() { - if (isBlacklistFilter()) { - return 1; - } else { - return getMaxStackSize(); - } - } - - public boolean showGlobalTransferLimitSlider() { - return isBlacklistFilter() || currentItemFilter == null || currentItemFilter.showGlobalTransferLimitSlider(); - } - - public int getSlotTransferLimit(Object matchSlot, int globalTransferLimit) { - if (isBlacklistFilter() || currentItemFilter == null) { - return globalTransferLimit; - } - return currentItemFilter.getSlotTransferLimit(matchSlot, globalTransferLimit); - } - - public Object matchItemStack(ItemStack itemStack) { - Object originalResult; - if (currentItemFilter == null) { - originalResult = MATCH_RESULT_TRUE; - } else { - originalResult = currentItemFilter.matchItemStack(itemStack); - } - if (isBlacklistFilter()) { - originalResult = originalResult == null ? MATCH_RESULT_TRUE : null; - } - return originalResult; - } - - public Object matchItemStack(ItemStack itemStack, boolean whitelist) { - Object originalResult; - if (currentItemFilter == null) { - originalResult = MATCH_RESULT_TRUE; - } else { - originalResult = currentItemFilter.matchItemStack(itemStack); - } - if (!whitelist) { - originalResult = originalResult == null ? MATCH_RESULT_TRUE : null; - } - return originalResult; - } - - public boolean testItemStack(ItemStack itemStack) { - return matchItemStack(itemStack) != null; - } -} diff --git a/src/main/java/gregtech/common/covers/filter/MatchResult.java b/src/main/java/gregtech/common/covers/filter/MatchResult.java new file mode 100644 index 00000000000..028da359cb3 --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/MatchResult.java @@ -0,0 +1,46 @@ +package gregtech.common.covers.filter; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class MatchResult { + + public static final MatchResult NONE = new MatchResult(false, null, -1); + public static final MatchResult ANY = new MatchResult(true, null, -1); + private final boolean matched; + private final Object matchedObject; + private final int filterIndex; + + private MatchResult(boolean matched, Object matchedObject, int filterIndex) { + this.matched = matched; + this.matchedObject = matchedObject; + this.filterIndex = filterIndex; + } + + public boolean isMatched() { + return matched; + } + + public Object getMatchedObject() { + return matchedObject; + } + + public @NotNull ItemStack getItemStack() { + return matchedObject instanceof ItemStack stack ? stack : ItemStack.EMPTY; + } + + public @Nullable FluidStack getFluidStack() { + return matchedObject instanceof FluidStack stack ? stack : null; + } + + public int getFilterIndex() { + return filterIndex; + } + + public static MatchResult create(boolean matched, Object matchedStack, int filterIndex) { + return new MatchResult(matched, matchedStack, filterIndex); + } +} diff --git a/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java b/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java index 1db9a6087e3..2a9fcaf402d 100644 --- a/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java @@ -1,78 +1,69 @@ package gregtech.common.covers.filter; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.TextureArea; -import gregtech.api.gui.widgets.DrawableWidget; -import gregtech.api.gui.widgets.ImageCycleButtonWidget; -import gregtech.api.gui.widgets.ImageWidget; +import gregtech.api.cover.CoverWithUI; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.stack.ItemVariantMap; import gregtech.api.unification.stack.MultiItemVariantMap; import gregtech.api.unification.stack.SingleItemVariantMap; -import gregtech.api.util.function.BooleanConsumer; -import gregtech.api.util.oreglob.OreGlob; import gregtech.api.util.oreglob.OreGlobCompileResult; -import gregtech.common.covers.filter.oreglob.impl.ImpossibleOreGlob; -import gregtech.common.gui.widget.HighlightedTextField; -import gregtech.common.gui.widget.orefilter.ItemOreFilterTestSlot; -import gregtech.common.gui.widget.orefilter.OreGlobCompileStatusWidget; +import gregtech.common.covers.filter.readers.OreDictFilterReader; +import gregtech.common.mui.widget.HighlightedTextField; +import gregtech.common.mui.widget.orefilter.OreFilterTestSlot; +import net.minecraft.client.resources.I18n; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.PacketBuffer; import net.minecraft.util.text.TextFormatting; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.drawable.UITexture; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.screen.Tooltip; +import com.cleanroommc.modularui.utils.BooleanConsumer; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.CycleButtonWidget; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.BooleanSupplier; import java.util.function.Consumer; -public class OreDictionaryItemFilter extends ItemFilter { +public class OreDictionaryItemFilter extends BaseFilter { private final Map> matchCache = new Object2ObjectOpenHashMap<>(); private final SingleItemVariantMap noOreDictMatch = new SingleItemVariantMap<>(); + private final OreDictFilterReader filterReader; - protected String expression = ""; - - private OreGlob glob = ImpossibleOreGlob.getInstance(); - private boolean error; - - private boolean caseSensitive; - /** - * {@code false} requires any of the entry to be match in order for the match to be success, {@code true} requires - * all entries to match - */ - private boolean matchAll; + public OreDictionaryItemFilter(ItemStack stack) { + this.filterReader = new OreDictFilterReader(stack); + recompile(); + } - @NotNull - public String getExpression() { - return expression; + @Override + public OreDictFilterReader getFilterReader() { + return filterReader; } @NotNull - public OreGlob getGlob() { - return this.glob; + public String getExpression() { + return this.filterReader.getExpression(); } - protected void recompile(@Nullable Consumer<@Nullable OreGlobCompileResult> callback) { + protected void recompile() { clearCache(); - String expr = this.expression; - if (!expr.isEmpty()) { - OreGlobCompileResult result = OreGlob.compile(expr, !this.caseSensitive); - this.glob = result.getInstance(); - this.error = result.hasError(); - if (callback != null) callback.accept(result); - } else { - this.glob = ImpossibleOreGlob.getInstance(); - this.error = true; - if (callback != null) callback.accept(null); - } + this.filterReader.recompile(); } protected void clearCache() { @@ -81,106 +72,211 @@ protected void clearCache() { } @Override - public void initUI(Consumer widgetGroup) { - ItemOreFilterTestSlot[] testSlot = new ItemOreFilterTestSlot[5]; - for (int i = 0; i < testSlot.length; i++) { - ItemOreFilterTestSlot slot = new ItemOreFilterTestSlot(20 + 22 * i, 0); - slot.setGlob(getGlob()); - slot.setMatchAll(this.matchAll); - widgetGroup.accept(slot); - testSlot[i] = slot; - } - OreGlobCompileStatusWidget compilationStatus = new OreGlobCompileStatusWidget(10, 10); + public void initUI(Consumer widgetGroup) {} - Consumer<@Nullable OreGlobCompileResult> compileCallback = result -> { - compilationStatus.setCompileResult(result); - for (ItemOreFilterTestSlot slot : testSlot) { - slot.setGlob(getGlob()); + @Override + public @NotNull ModularPanel createPopupPanel(GuiSyncManager syncManager) { + return GTGuis.createPopupPanel("ore_dict_filter", 188, 76) + .padding(7) + .child(CoverWithUI.createTitleRow(getContainerStack())) + .child(createWidgets(syncManager).top(22)); + } + + @Override + public @NotNull ModularPanel createPanel(GuiSyncManager syncManager) { + return GTGuis.createPanel("ore_dict_filter", 100, 100); + } + + @Override + public @NotNull Widget createWidgets(GuiSyncManager syncManager) { + List oreSlots = new ArrayList<>(); + var expression = new StringSyncValue(this.filterReader::getExpression, this.filterReader::setExpression); + + BooleanConsumer setCaseSensitive = b -> { + this.filterReader.setCaseSensitive(b); + if (!syncManager.isClient()) return; + for (var slot : oreSlots) { + slot.updatePreview(); } }; - HighlightedTextField textField = new HighlightedTextField(14, 26, 152, 14, () -> this.expression, - s -> { - if (s.equals(this.expression)) return; - this.expression = s; - markDirty(); - recompile(compileCallback); - }); - compilationStatus.setTextField(textField); - - widgetGroup.accept(new ImageWidget(10, 0, 7, 7, GuiTextures.ORE_FILTER_INFO) - .setTooltip("cover.ore_dictionary_filter.info")); - widgetGroup.accept(compilationStatus); - widgetGroup.accept(new DrawableWidget(10, 22, 156, 16) - .setBackgroundDrawer((mouseX, mouseY, partialTicks, context, widget) -> { - Widget.drawGradientRect(widget.getPosition().x, widget.getPosition().y, - widget.getSize().width, widget.getSize().height, - 0xFF808080, 0xFF808080, false); - Widget.drawGradientRect(widget.getPosition().x + 1, widget.getPosition().y + 1, - widget.getSize().width - 2, widget.getSize().height - 2, - 0xFF000000, 0xFF000000, false); - })); - widgetGroup.accept(textField - .setHighlightRule(h -> { - String t = h.getOriginalText(); - for (int i = 0; i < t.length(); i++) { - switch (t.charAt(i)) { - case '|', '&', '^', '(', ')' -> h.format(i, TextFormatting.GOLD); - case '*', '?' -> h.format(i, TextFormatting.GREEN); - case '!' -> h.format(i, TextFormatting.RED); - case '\\' -> h.format(i++, TextFormatting.YELLOW); - case '$' -> { // TODO: remove this switch case in 2.9 - h.format(i, TextFormatting.DARK_GREEN); - for (; i < t.length(); i++) { - switch (t.charAt(i)) { - case ' ', '\t', '\n', '\r' -> {} - case '\\' -> { - i++; - continue; - } - default -> { - continue; - } - } - break; - } + BooleanConsumer setMatchAll = b -> { + this.clearCache(); + this.filterReader.setMatchAll(b); + if (!syncManager.isClient()) return; + for (var slot : oreSlots) { + slot.setMatchAll(b); + } + }; + + var caseSensitive = new BooleanSyncValue(this.filterReader::isCaseSensitive, setCaseSensitive); + var matchAll = new BooleanSyncValue(this.filterReader::shouldMatchAll, setMatchAll); + + return new Column().widthRel(1f).coverChildrenHeight() + .child(new HighlightedTextField() + .setHighlightRule(this::highlightRule) + .onUnfocus(() -> { + for (var slot : oreSlots) { + slot.updatePreview(); + } + }) + .setTextColor(Color.WHITE.darker(1)) + .value(expression).marginBottom(4) + .height(18).widthRel(1f)) + .child(new Row().coverChildrenHeight() + .widthRel(1f) + .child(new Column().height(18) + .coverChildrenWidth().marginRight(2) + .child(GTGuiTextures.OREDICT_INFO.asWidget() + .size(8).top(0) + .addTooltipLine(IKey.lang("cover.ore_dictionary_filter.info"))) + .child(new Widget<>() + .size(8).bottom(0) + .onUpdateListener(this::getStatusIcon) + .tooltipBuilder(this::createStatusTooltip) + .tooltip(tooltip -> tooltip.setAutoUpdate(true)))) + .child(SlotGroupWidget.builder() + .row("XXXXX") + .key('X', i -> { + var slot = new OreFilterTestSlot() + .setGlobSupplier(this.filterReader::getGlob); + slot.setMatchAll(this.filterReader.shouldMatchAll()); + oreSlots.add(slot); + return slot; + }) + .build().marginRight(2)) + .child(new CycleButtonWidget() + .size(18).value(caseSensitive) + .marginRight(2) + .textureGetter(state -> GTGuiTextures.BUTTON_CASE_SENSITIVE[state]) + .addTooltip(0, + IKey.lang("cover.ore_dictionary_filter.button.case_sensitive.disabled")) + .addTooltip(1, + IKey.lang("cover.ore_dictionary_filter.button.case_sensitive.enabled"))) + .child(new CycleButtonWidget() + .size(18).value(matchAll) + .marginRight(2) + .textureGetter(state -> GTGuiTextures.BUTTON_MATCH_ALL[state]) + .addTooltip(0, + IKey.lang("cover.ore_dictionary_filter.button.match_all.disabled")) + .addTooltip(1, + IKey.lang("cover.ore_dictionary_filter.button.match_all.enabled"))) + .child(createBlacklistUI())); + } + + protected void getStatusIcon(Widget widget) { + UITexture texture; + var result = this.filterReader.getResult(); + + if (result == null) { + texture = GTGuiTextures.OREDICT_WAITING; + } else if (result.getReports().length == 0) { + texture = GTGuiTextures.OREDICT_SUCCESS; + } else if (result.hasError()) { + texture = GTGuiTextures.OREDICT_ERROR; + } else { + texture = GTGuiTextures.OREDICT_WARN; + } + widget.background(texture); + } + + protected void createStatusTooltip(Tooltip tooltip) { + var result = this.filterReader.getResult(); + if (result == null) return; + List list = new ArrayList<>(); + + int error = 0, warn = 0; + for (OreGlobCompileResult.Report report : result.getReports()) { + if (report.isError()) error++; + else warn++; + list.add((report.isError() ? TextFormatting.RED : TextFormatting.GOLD) + report.toString()); + } + if (error > 0) { + if (warn > 0) { + list.add(0, I18n.format("cover.ore_dictionary_filter.status.err_warn", error, warn)); + } else { + list.add(0, I18n.format("cover.ore_dictionary_filter.status.err", error)); + } + } else { + if (warn > 0) { + list.add(0, I18n.format("cover.ore_dictionary_filter.status.warn", warn)); + } else { + list.add(I18n.format("cover.ore_dictionary_filter.status.no_issues")); + } + list.add(""); + list.add(I18n.format("cover.ore_dictionary_filter.status.explain")); + list.add(""); + list.addAll(result.getInstance().toFormattedString()); + } + tooltip.addStringLines(list); + } + + protected String highlightRule(String text) { + StringBuilder builder = new StringBuilder(text); + for (int i = 0; i < builder.length(); i++) { + switch (builder.charAt(i)) { + case '|', '&', '^', '(', ')' -> { + builder.insert(i, TextFormatting.GOLD); + i += 2; + } + case '*', '?' -> { + builder.insert(i, TextFormatting.GREEN); + i += 2; + } + case '!' -> { + builder.insert(i, TextFormatting.RED); + i += 2; + } + case '\\' -> { + builder.insert(i++, TextFormatting.YELLOW); + i += 2; + } + case '$' -> { // TODO: remove this switch case in 2.9 + builder.insert(i, TextFormatting.DARK_GREEN); + for (; i < builder.length(); i++) { + switch (builder.charAt(i)) { + case ' ', '\t', '\n', '\r' -> {} + case '\\' -> { + i++; + continue; } default -> { continue; } } - h.format(i + 1, TextFormatting.RESET); - } - }).setMaxLength(64)); - widgetGroup.accept(new ForcedInitialSyncImageCycleButtonWidget(130, 38, 18, 18, - GuiTextures.ORE_FILTER_BUTTON_CASE_SENSITIVE, () -> this.caseSensitive, caseSensitive -> { - if (this.caseSensitive == caseSensitive) return; - this.caseSensitive = caseSensitive; - markDirty(); - recompile(compileCallback); - }).setTooltipHoverString( - i -> "cover.ore_dictionary_filter.button.case_sensitive." + (i == 0 ? "disabled" : "enabled"))); - widgetGroup.accept(new ForcedInitialSyncImageCycleButtonWidget(148, 38, 18, 18, - GuiTextures.ORE_FILTER_BUTTON_MATCH_ALL, () -> this.matchAll, matchAll -> { - if (this.matchAll == matchAll) return; - this.matchAll = matchAll; - markDirty(); - clearCache(); - for (ItemOreFilterTestSlot slot : testSlot) { - slot.setMatchAll(matchAll); + break; } - }).setTooltipHoverString( - i -> "cover.ore_dictionary_filter.button.match_all." + (i == 0 ? "disabled" : "enabled"))); + } + default -> { + continue; + } + } + builder.insert(i + 1, TextFormatting.RESET); + } + return builder.toString(); + } + + @Override + public MatchResult matchItem(ItemStack itemStack) { + // "wtf is this system?? i can put any non null object here and it i will work??? $arch" + // not anymore :thanosdaddy: -ghzdude + var match = matchesItemStack(itemStack); + return MatchResult.create(match != isBlacklistFilter(), match ? itemStack.copy() : ItemStack.EMPTY, -1); + } + + @Override + public boolean testItem(ItemStack toTest) { + return matchesItemStack(toTest); } @Override - public Object matchItemStack(ItemStack itemStack) { - return matchesItemStack(itemStack) ? - "wtf is this system?? i can put any non null object here and it i will work??? $arch" : null; + public FilterType getType() { + return FilterType.ITEM; } public boolean matchesItemStack(@NotNull ItemStack itemStack) { - if (this.error) return false; + var result = this.filterReader.getResult(); + if (result == null || result.hasError()) return false; Item item = itemStack.getItem(); ItemVariantMap> oreDictEntry = OreDictUnifier.getOreDictionaryEntry(item); @@ -188,7 +284,7 @@ public boolean matchesItemStack(@NotNull ItemStack itemStack) { // no oredict entries associated Boolean cached = this.noOreDictMatch.getEntry(); if (cached == null) { - cached = this.glob.matches(""); + cached = this.filterReader.getGlob().matches(""); } this.matchCache.put(item, this.noOreDictMatch); return cached; @@ -205,7 +301,7 @@ public boolean matchesItemStack(@NotNull ItemStack itemStack) { // no oredict entries associated Boolean cached = this.noOreDictMatch.getEntry(); if (cached == null) { - cached = this.glob.matches(""); + cached = this.filterReader.getGlob().matches(""); this.noOreDictMatch.put(cached); } this.matchCache.put(item, this.noOreDictMatch); @@ -217,64 +313,15 @@ public boolean matchesItemStack(@NotNull ItemStack itemStack) { } this.matchCache.put(item, cacheEntry); } - boolean matches = this.matchAll ? this.glob.matchesAll(itemStack) : this.glob.matchesAny(itemStack); + boolean matches = this.filterReader.shouldMatchAll() ? + this.filterReader.getGlob().matchesAll(itemStack) : + this.filterReader.getGlob().matchesAny(itemStack); cacheEntry.put(itemStack, matches); return matches; } - @Override - public int getSlotTransferLimit(Object matchSlot, int globalTransferLimit) { - return globalTransferLimit; - } - @Override public boolean showGlobalTransferLimitSlider() { return true; } - - @Override - public int getTotalOccupiedHeight() { - return 37; - } - - @Override - public void writeToNBT(NBTTagCompound tag) { - tag.setString("OreDictionaryFilter", expression); - if (this.caseSensitive) tag.setBoolean("caseSensitive", true); - if (this.matchAll) tag.setBoolean("matchAll", true); - } - - @Override - public void readFromNBT(NBTTagCompound tag) { - this.expression = tag.getString("OreDictionaryFilter"); - this.caseSensitive = tag.getBoolean("caseSensitive"); - this.matchAll = tag.getBoolean("matchAll"); - recompile(null); - } - - public static class ForcedInitialSyncImageCycleButtonWidget extends ImageCycleButtonWidget { - - private final BooleanConsumer updater; - - public ForcedInitialSyncImageCycleButtonWidget(int xPosition, int yPosition, int width, int height, - TextureArea buttonTexture, BooleanSupplier supplier, - BooleanConsumer updater) { - super(xPosition, yPosition, width, height, buttonTexture, supplier, updater); - this.currentOption = 0; - this.updater = updater; - } - - @Override - public void readUpdateInfo(int id, PacketBuffer buffer) { - if (id == 1) { - int currentOptionCache = this.currentOption; - super.readUpdateInfo(id, buffer); - if (this.currentOption != currentOptionCache) { - this.updater.apply(currentOption >= 1); // call updater to apply necessary state changes - } - } else { - super.readUpdateInfo(id, buffer); - } - } - } } diff --git a/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java b/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java index c3abb86898e..c19a5600d2e 100644 --- a/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java +++ b/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java @@ -1,118 +1,119 @@ package gregtech.common.covers.filter; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.PhantomFluidWidget; +import gregtech.api.cover.CoverWithUI; +import gregtech.api.mui.GTGuis; +import gregtech.api.mui.sync.FixedFluidSlotSH; +import gregtech.common.covers.filter.readers.SimpleFluidFilterReader; -import net.minecraft.nbt.NBTBase; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; +import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTank; -import org.jetbrains.annotations.Nullable; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.FluidSlot; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.layout.Row; +import org.jetbrains.annotations.NotNull; import java.util.function.Consumer; -public class SimpleFluidFilter extends FluidFilter { +public class SimpleFluidFilter extends BaseFilter { private static final int MAX_FLUID_SLOTS = 9; - protected final FluidTank[] fluidFilterTanks = new FluidTank[MAX_FLUID_SLOTS]; + private final SimpleFluidFilterReader filterReader; - public SimpleFluidFilter() { - for (int i = 0; i < MAX_FLUID_SLOTS; ++i) { - fluidFilterTanks[i] = new FluidTank(1000) { - - @Override - public void setFluid(@Nullable FluidStack fluid) { - super.setFluid(fluid); - SimpleFluidFilter.this.markDirty(); - } - }; - } + public SimpleFluidFilter(ItemStack stack) { + filterReader = new SimpleFluidFilterReader(stack, MAX_FLUID_SLOTS); } @Override + public SimpleFluidFilterReader getFilterReader() { + return filterReader; + } + public void configureFilterTanks(int amount) { - for (FluidTank fluidTank : fluidFilterTanks) { - if (fluidTank.getFluid() != null) - fluidTank.getFluid().amount = amount; - } + this.filterReader.setFluidAmounts(amount); this.markDirty(); } @Override - public void setMaxConfigurableFluidSize(int maxSize) { - for (FluidTank fluidTank : fluidFilterTanks) { - fluidTank.setCapacity(maxSize); - } + public @NotNull ModularPanel createPopupPanel(GuiSyncManager syncManager) { + return GTGuis.createPopupPanel("simple_fluid_filter", 98, 81) + .padding(4) + .child(CoverWithUI.createTitleRow(getContainerStack())) + .child(createWidgets(syncManager).top(22)); } @Override - public boolean testFluid(FluidStack fluidStack) { - return checkInputFluid(fluidFilterTanks, fluidStack); + public @NotNull ModularPanel createPanel(GuiSyncManager syncManager) { + return GTGuis.createPanel(getContainerStack(), 176, 168); } @Override - public int getMaxOccupiedHeight() { - return 36; + public @NotNull Widget createWidgets(GuiSyncManager syncManager) { + return new Row().coverChildrenHeight().widthRel(1f) + .child(SlotGroupWidget.builder() + .matrix("FFF", + "FFF", + "FFF") + .key('F', i -> new FluidSlot() + .syncHandler(new FixedFluidSlotSH(filterReader.getFluidTank(i)).phantom(true))) + .build().marginRight(4)) + .child(createBlacklistUI()); } @Override - public void initUI(Consumer widgetGroup) { - for (int i = 0; i < 9; ++i) { - widgetGroup.accept((new PhantomFluidWidget(10 + 18 * (i % 3), 18 * (i / 3), 18, 18, - this.fluidFilterTanks[i])) - .setBackgroundTexture(GuiTextures.SLOT).showTipSupplier(this::shouldShowTip)); + public MatchResult matchFluid(FluidStack fluidStack) { + int index = -1; + FluidStack returnable = null; + for (int i = 0; i < filterReader.getSize(); i++) { + var fluid = filterReader.getFluidStack(i); + if (fluid != null && fluid.isFluidEqual(fluidStack)) { + index = i; + returnable = fluid.copy(); + break; + } } + return MatchResult.create(index != -1, returnable, index); } - private boolean shouldShowTip() { - return showTip; - } - - public void writeToNBT(NBTTagCompound tagCompound) { - NBTTagList filterSlots = new NBTTagList(); - for (int i = 0; i < this.fluidFilterTanks.length; ++i) { - FluidTank fluidTank = this.fluidFilterTanks[i]; - if (fluidTank.getFluid() != null) { - NBTTagCompound stackTag = new NBTTagCompound(); - fluidTank.getFluid().writeToNBT(stackTag); - stackTag.setInteger("Slot", i); - filterSlots.appendTag(stackTag); + @Override + public boolean testFluid(FluidStack toTest) { + for (int i = 0; i < filterReader.getSize(); i++) { + var fluid = filterReader.getFluidStack(i); + if (fluid != null && fluid.isFluidEqual(toTest)) { + return true; } } - tagCompound.setTag("FluidFilter", filterSlots); + return false; } - public void readFromNBT(NBTTagCompound tagCompound) { - NBTTagList filterSlots = tagCompound.getTagList("FluidFilter", 10); - for (NBTBase nbtBase : filterSlots) { - NBTTagCompound stackTag = (NBTTagCompound) nbtBase; - FluidStack fluidStack = FluidStack.loadFluidStackFromNBT(stackTag); - this.fluidFilterTanks[stackTag.getInteger("Slot")].setFluid(fluidStack); + @Override + public void initUI(Consumer widgetGroup) { + for (int i = 0; i < 9; ++i) { + widgetGroup.accept((new gregtech.api.gui.widgets.PhantomFluidWidget(10 + 18 * (i % 3), 18 * (i / 3), 18, 18, + filterReader.getFluidTank(i))) + .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT)); } } - public static boolean checkInputFluid(FluidTank[] fluidFilterTanks, FluidStack fluidStack) { - for (FluidTank fluidTank : fluidFilterTanks) { - if (fluidTank.getFluid() != null && fluidTank.getFluid().isFluidEqual(fluidStack)) { - return true; + @Override + public int getTransferLimit(FluidStack fluidStack, int transferSize) { + int limit = 0; + + for (int i = 0; i < this.filterReader.getSize(); i++) { + var fluid = this.filterReader.getFluidStack(i); + if (fluid != null && fluid.isFluidEqual(fluidStack)) { + limit = fluid.amount; } } - return false; + return isBlacklistFilter() ? transferSize : limit; } @Override - public int getFluidTransferLimit(FluidStack fluidStack) { - int limit = 0; - for (FluidTank fluidTank : fluidFilterTanks) { - if (fluidTank.getFluid() != null && fluidTank.getFluid().isFluidEqual(fluidStack)) { - limit = fluidTank.getFluid().amount; - break; - } - } - return limit; + public FilterType getType() { + return FilterType.FLUID; } } diff --git a/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java b/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java index 864986ca805..8bb4c556753 100644 --- a/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java @@ -1,119 +1,167 @@ package gregtech.common.covers.filter; +import gregtech.api.cover.CoverWithUI; import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.Widget; import gregtech.api.gui.widgets.PhantomSlotWidget; import gregtech.api.gui.widgets.ToggleButtonWidget; -import gregtech.api.util.LargeStackSizeItemStackHandler; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; +import gregtech.api.util.TextFormattingUtil; +import gregtech.common.covers.CoverItemVoidingAdvanced; +import gregtech.common.covers.CoverRoboticArm; +import gregtech.common.covers.TransferMode; +import gregtech.common.covers.VoidingMode; +import gregtech.common.covers.filter.readers.SimpleItemFilterReader; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.items.IItemHandler; -import net.minecraftforge.items.ItemStackHandler; + +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.CycleButtonWidget; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.slot.SlotGroup; +import org.jetbrains.annotations.NotNull; import java.util.function.Consumer; -public class SimpleItemFilter extends ItemFilter { +public class SimpleItemFilter extends BaseFilter { private static final int MAX_MATCH_SLOTS = 9; + private final SimpleItemFilterReader filterReader; - protected final ItemStackHandler itemFilterSlots; - protected boolean ignoreDamage = true; - protected boolean ignoreNBT = true; - - public SimpleItemFilter() { - this.itemFilterSlots = new LargeStackSizeItemStackHandler(MAX_MATCH_SLOTS) { - - @Override - public int getSlotLimit(int slot) { - return getMaxStackSize(); - } - }; + public SimpleItemFilter(ItemStack stack) { + filterReader = new SimpleItemFilterReader(stack, MAX_MATCH_SLOTS); } @Override - protected void onMaxStackSizeChange() { - for (int i = 0; i < itemFilterSlots.getSlots(); i++) { - ItemStack itemStack = itemFilterSlots.getStackInSlot(i); - if (!itemStack.isEmpty()) { - itemStack.setCount(Math.min(itemStack.getCount(), getMaxStackSize())); - } - } - } - - public ItemStackHandler getItemFilterSlots() { - return itemFilterSlots; + public SimpleItemFilterReader getFilterReader() { + return filterReader; } - public boolean isIgnoreDamage() { - return ignoreDamage; - } - - public boolean isIgnoreNBT() { - return ignoreNBT; - } - - protected void setIgnoreDamage(boolean ignoreDamage) { - this.ignoreDamage = ignoreDamage; - markDirty(); - } - - protected void setIgnoreNBT(boolean ignoreNBT) { - this.ignoreNBT = ignoreNBT; - markDirty(); + @Override + public MatchResult matchItem(ItemStack itemStack) { + int matchedSlot = itemFilterMatch(filterReader, filterReader.isIgnoreDamage(), filterReader.isIgnoreNBT(), + itemStack); + return MatchResult.create(matchedSlot != -1 == !isBlacklistFilter(), + filterReader.getStackInSlot(matchedSlot), matchedSlot); } @Override - public Integer matchItemStack(ItemStack itemStack) { - int itemFilterMatchIndex = itemFilterMatch(getItemFilterSlots(), isIgnoreDamage(), isIgnoreNBT(), itemStack); - return itemFilterMatchIndex == -1 ? null : itemFilterMatchIndex; + public boolean testItem(ItemStack toTest) { + int matchedSlot = itemFilterMatch(filterReader, filterReader.isIgnoreDamage(), filterReader.isIgnoreNBT(), + toTest); + return matchedSlot != -1; } @Override - public int getSlotTransferLimit(Object matchSlot, int globalTransferLimit) { - Integer matchSlotIndex = (Integer) matchSlot; - ItemStack stackInFilterSlot = itemFilterSlots.getStackInSlot(matchSlotIndex); - return Math.min(stackInFilterSlot.getCount(), globalTransferLimit); + public int getTransferLimit(int matchSlot, int transferSize) { + ItemStack stackInFilterSlot = filterReader.getStackInSlot(matchSlot); + return Math.min(stackInFilterSlot.getCount(), transferSize); } @Override - public boolean showGlobalTransferLimitSlider() { - return false; + public FilterType getType() { + return FilterType.ITEM; } @Override - public int getTotalOccupiedHeight() { - return 36; + public int getTransferLimit(ItemStack stack, int transferSize) { + int matchedSlot = itemFilterMatch(filterReader, filterReader.isIgnoreDamage(), filterReader.isIgnoreNBT(), + stack); + return getTransferLimit(matchedSlot, transferSize); } @Override - public void initUI(Consumer widgetGroup) { + public void initUI(Consumer widgetGroup) { for (int i = 0; i < 9; i++) { - widgetGroup.accept(new PhantomSlotWidget(itemFilterSlots, i, 10 + 18 * (i % 3), 18 * (i / 3)) + widgetGroup.accept(new PhantomSlotWidget(filterReader, i, 10 + 18 * (i % 3), 18 * (i / 3)) .setBackgroundTexture(GuiTextures.SLOT)); } widgetGroup.accept(new ToggleButtonWidget(74, 0, 20, 20, GuiTextures.BUTTON_FILTER_DAMAGE, - () -> ignoreDamage, this::setIgnoreDamage).setTooltipText("cover.item_filter.ignore_damage")); + filterReader::isIgnoreDamage, filterReader::setIgnoreDamage) + .setTooltipText("cover.item_filter.ignore_damage")); widgetGroup.accept(new ToggleButtonWidget(99, 0, 20, 20, GuiTextures.BUTTON_FILTER_NBT, - () -> ignoreNBT, this::setIgnoreNBT).setTooltipText("cover.item_filter.ignore_nbt")); + filterReader::isIgnoreNBT, filterReader::setIgnoreNBT).setTooltipText("cover.item_filter.ignore_nbt")); } @Override - public void writeToNBT(NBTTagCompound tagCompound) { - tagCompound.setTag("ItemFilter", itemFilterSlots.serializeNBT()); - tagCompound.setBoolean("IgnoreDamage", ignoreDamage); - tagCompound.setBoolean("IgnoreNBT", ignoreNBT); + public @NotNull ModularPanel createPopupPanel(GuiSyncManager syncManager) { + return GTGuis.createPopupPanel("simple_item_filter", 98, 81) + .child(CoverWithUI.createTitleRow(getContainerStack())) + .child(createWidgets(syncManager).top(22).left(4)); } @Override - public void readFromNBT(NBTTagCompound tagCompound) { - this.itemFilterSlots.deserializeNBT(tagCompound.getCompoundTag("ItemFilter")); - this.ignoreDamage = tagCompound.getBoolean("IgnoreDamage"); - this.ignoreNBT = tagCompound.getBoolean("IgnoreNBT"); + public @NotNull ModularPanel createPanel(GuiSyncManager syncManager) { + return GTGuis.createPanel("simple_item_filter", 176, 166); } - public static int itemFilterMatch(IItemHandler filterSlots, boolean ignoreDamage, boolean ignoreNBTData, - ItemStack itemStack) { + @SuppressWarnings("UnstableApiUsage") + @Override + public @NotNull Widget createWidgets(GuiSyncManager syncManager) { + SlotGroup filterInventory = new SlotGroup("filter_inv", 3, 1000, true); + var ignoreDamage = new BooleanSyncValue(this.filterReader::isIgnoreDamage, this.filterReader::setIgnoreDamage); + var ignoreNBT = new BooleanSyncValue(this.filterReader::isIgnoreNBT, this.filterReader::setIgnoreNBT); + + syncManager.registerSlotGroup(filterInventory); + + return new Row().coverChildren() + .child(SlotGroupWidget.builder() + .matrix("XXX", + "XXX", + "XXX") + .key('X', index -> new ItemSlot() + .tooltip(tooltip -> { + tooltip.setAutoUpdate(true); + tooltip.textColor(Color.GREY.main); + }) + .tooltipBuilder(tooltip -> { + if (dirtyNotifiable instanceof CoverRoboticArm coverArm && + coverArm.getTransferMode() != TransferMode.TRANSFER_ANY || + dirtyNotifiable instanceof CoverItemVoidingAdvanced coverItem && + coverItem.getVoidingMode() != VoidingMode.VOID_ANY) { + tooltip.addLine(IKey.lang("cover.item_filter.config_amount")); + int count = this.filterReader.getTagAt(index) + .getInteger(SimpleItemFilterReader.COUNT); + if (count > 0) + tooltip.addLine( + IKey.format("Count: %s", TextFormattingUtil.formatNumbers(count))); + } + }) + .slot(SyncHandlers.phantomItemSlot(this.filterReader, index) + .ignoreMaxStackSize(true) + .slotGroup(filterInventory) + .changeListener((newItem, onlyAmountChanged, client, init) -> { + if (onlyAmountChanged && !init) { + markDirty(); + } + }))) + .build().marginRight(4)) + .child(new Column().width(18).coverChildren() + .child(createBlacklistUI()) + .child(new CycleButtonWidget() + .value(ignoreDamage) + .textureGetter(state -> GTGuiTextures.BUTTON_IGNORE_DAMAGE[state]) + .addTooltip(0, IKey.lang("cover.item_filter.ignore_damage.disabled")) + .addTooltip(1, IKey.lang("cover.item_filter.ignore_damage.enabled"))) + .child(new CycleButtonWidget() + .value(ignoreNBT) + .textureGetter(state -> GTGuiTextures.BUTTON_IGNORE_NBT[state]) + .addTooltip(0, IKey.lang("cover.item_filter.ignore_nbt.disabled")) + .addTooltip(1, IKey.lang("cover.item_filter.ignore_nbt.enabled")))); + } + + public static int itemFilterMatch(IItemHandler filterSlots, boolean ignoreDamage, + boolean ignoreNBTData, ItemStack itemStack) { for (int i = 0; i < filterSlots.getSlots(); i++) { ItemStack filterStack = filterSlots.getStackInSlot(i); if (!filterStack.isEmpty() && areItemsEqual(ignoreDamage, ignoreNBTData, filterStack, itemStack)) { @@ -123,8 +171,8 @@ public static int itemFilterMatch(IItemHandler filterSlots, boolean ignoreDamage return -1; } - private static boolean areItemsEqual(boolean ignoreDamage, boolean ignoreNBTData, ItemStack filterStack, - ItemStack itemStack) { + private static boolean areItemsEqual(boolean ignoreDamage, boolean ignoreNBTData, + ItemStack filterStack, ItemStack itemStack) { if (ignoreDamage) { if (!filterStack.isItemEqualIgnoreDurability(itemStack)) { return false; diff --git a/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java b/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java index a655d22f732..651c768e4dd 100644 --- a/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java @@ -1,95 +1,144 @@ package gregtech.common.covers.filter; -import gregtech.api.gui.Widget; +import gregtech.api.cover.CoverWithUI; import gregtech.api.gui.widgets.CycleButtonWidget; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.RecipeMaps; import gregtech.api.recipes.ingredients.GTRecipeInput; import gregtech.api.unification.stack.ItemAndMetadata; +import gregtech.common.covers.filter.readers.SmartItemFilterReader; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.IStringSerializable; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.BoolValue; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.jetbrains.annotations.NotNull; import java.util.Collections; -import java.util.Map; import java.util.function.Consumer; -public class SmartItemFilter extends ItemFilter { +public class SmartItemFilter extends BaseFilter { - private SmartFilteringMode filteringMode = SmartFilteringMode.ELECTROLYZER; + private final SmartItemFilterReader filterReader; - public SmartFilteringMode getFilteringMode() { - return filteringMode; + public SmartItemFilter(ItemStack stack) { + filterReader = new SmartItemFilterReader(stack); } - public void setFilteringMode(SmartFilteringMode filteringMode) { - this.filteringMode = filteringMode; - markDirty(); + @Override + public SmartItemFilterReader getFilterReader() { + return filterReader; } - @Override - public int getSlotTransferLimit(Object matchSlot, int globalTransferLimit) { - ItemAndMetadataAndStackSize itemAndMetadata = (ItemAndMetadataAndStackSize) matchSlot; - return itemAndMetadata.transferStackSize; + public SmartFilteringMode getFilteringMode() { + return this.filterReader.getFilteringMode(); } @Override - public Object matchItemStack(ItemStack itemStack) { - ItemAndMetadata itemAndMetadata = new ItemAndMetadata(itemStack); - Integer cachedTransferRateValue = filteringMode.transferStackSizesCache.get(itemAndMetadata); + public int getTransferLimit(ItemStack stack, int globalTransferLimit) { + ItemAndMetadata itemAndMetadata = new ItemAndMetadata(stack); + var filterMode = this.filterReader.getFilteringMode(); + int cachedTransferRateValue = filterMode.transferStackSizesCache.getOrDefault(itemAndMetadata, -1); - if (cachedTransferRateValue == null) { - ItemStack infinitelyBigStack = itemStack.copy(); + if (cachedTransferRateValue == -1) { + ItemStack infinitelyBigStack = stack.copy(); infinitelyBigStack.setCount(Integer.MAX_VALUE); - Recipe recipe = filteringMode.recipeMap.findRecipe(Long.MAX_VALUE, + Recipe recipe = filterMode.recipeMap.findRecipe(Long.MAX_VALUE, Collections.singletonList(infinitelyBigStack), Collections.emptyList()); if (recipe == null) { - filteringMode.transferStackSizesCache.put(itemAndMetadata, 0); + filterMode.transferStackSizesCache.put(itemAndMetadata, 0); cachedTransferRateValue = 0; } else { GTRecipeInput inputIngredient = recipe.getInputs().iterator().next(); - filteringMode.transferStackSizesCache.put(itemAndMetadata, inputIngredient.getAmount()); + filterMode.transferStackSizesCache.put(itemAndMetadata, inputIngredient.getAmount()); cachedTransferRateValue = inputIngredient.getAmount(); } } - if (cachedTransferRateValue == 0) { - return null; - } - return new ItemAndMetadataAndStackSize(itemAndMetadata, cachedTransferRateValue); + return cachedTransferRateValue; + } + + @Override + public MatchResult matchItem(ItemStack itemStack) { + var stack = itemStack.copy(); + stack.setCount(getTransferLimit(itemStack, Integer.MAX_VALUE)); + return MatchResult.create(stack.getCount() > 0 != isBlacklistFilter(), stack, + this.getFilteringMode().ordinal()); + } + + @Override + public boolean testItem(ItemStack toTest) { + return getTransferLimit(toTest, Integer.MAX_VALUE) > 0; } @Override - public void initUI(Consumer widgetGroup) { + public FilterType getType() { + return FilterType.ITEM; + } + + @Override + public void initUI(Consumer widgetGroup) { widgetGroup.accept(new CycleButtonWidget(10, 0, 75, 20, - SmartFilteringMode.class, this::getFilteringMode, this::setFilteringMode) + SmartFilteringMode.class, filterReader::getFilteringMode, filterReader::setFilteringMode) .setTooltipHoverString("cover.smart_item_filter.filtering_mode.description")); } @Override - public int getTotalOccupiedHeight() { - return 20; + public @NotNull ModularPanel createPopupPanel(GuiSyncManager syncManager) { + return GTGuis.createPopupPanel("smart_item_filter", 98 + 27, 81) + .child(CoverWithUI.createTitleRow(getContainerStack())) + .child(createWidgets(syncManager).top(22).left(4)); } @Override - public boolean showGlobalTransferLimitSlider() { - return true; + public @NotNull ModularPanel createPanel(GuiSyncManager syncManager) { + return GTGuis.createPanel("smart_item_filter", 100, 100).padding(7); } @Override - public void writeToNBT(NBTTagCompound tagCompound) { - tagCompound.setInteger("FilterMode", filteringMode.ordinal()); + public @NotNull Widget createWidgets(GuiSyncManager syncManager) { + var filterMode = new EnumSyncValue<>(SmartFilteringMode.class, filterReader::getFilteringMode, + filterReader::setFilteringMode); + syncManager.syncValue("filter_mode", filterMode); + + return new Row().coverChildren() + .child(new Column().coverChildren().marginRight(4) + .child(createFilterModeButton(filterMode, SmartFilteringMode.ELECTROLYZER)) + .child(createFilterModeButton(filterMode, SmartFilteringMode.CENTRIFUGE)) + .child(createFilterModeButton(filterMode, SmartFilteringMode.SIFTER))) + .child(createBlacklistUI()); + } + + private Widget createFilterModeButton(EnumSyncValue value, + SmartFilteringMode mode) { + return new ToggleButton().height(18).width(18 * 5) + .value(boolValueOf(value, mode)) + .background(GTGuiTextures.MC_BUTTON) + .selectedBackground(GTGuiTextures.MC_BUTTON_DISABLED) + .overlay(IKey.lang(mode.getName()).color(Color.WHITE.darker(1))); + } + + protected > BoolValue.Dynamic boolValueOf(EnumSyncValue syncValue, T value) { + return new BoolValue.Dynamic(() -> syncValue.getValue() == value, $ -> syncValue.setValue(value)); } @Override - public void readFromNBT(NBTTagCompound tagCompound) { - this.filteringMode = SmartFilteringMode.values()[tagCompound.getInteger("FilterMode")]; + public boolean showGlobalTransferLimitSlider() { + return true; } private static class ItemAndMetadataAndStackSize { @@ -122,7 +171,8 @@ public enum SmartFilteringMode implements IStringSerializable { CENTRIFUGE("cover.smart_item_filter.filtering_mode.centrifuge", RecipeMaps.CENTRIFUGE_RECIPES), SIFTER("cover.smart_item_filter.filtering_mode.sifter", RecipeMaps.SIFTER_RECIPES); - private final Map transferStackSizesCache = new Object2IntOpenHashMap<>(); + public static final SmartFilteringMode[] VALUES = values(); + private final Object2IntOpenHashMap transferStackSizesCache = new Object2IntOpenHashMap<>(); public final String localeName; public final RecipeMap recipeMap; diff --git a/src/main/java/gregtech/common/covers/filter/WidgetGroupFluidFilter.java b/src/main/java/gregtech/common/covers/filter/WidgetGroupFluidFilter.java index f2c08f856b3..c43d7487467 100644 --- a/src/main/java/gregtech/common/covers/filter/WidgetGroupFluidFilter.java +++ b/src/main/java/gregtech/common/covers/filter/WidgetGroupFluidFilter.java @@ -1,19 +1,29 @@ package gregtech.common.covers.filter; import gregtech.api.gui.widgets.AbstractWidgetGroup; +import gregtech.api.util.GTLog; import gregtech.api.util.Position; +import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; +import org.jetbrains.annotations.ApiStatus; + +import java.io.IOException; import java.util.function.Supplier; +/** + * @deprecated in favor of new MUI + */ +@Deprecated +@ApiStatus.ScheduledForRemoval(inVersion = "2.10") public class WidgetGroupFluidFilter extends AbstractWidgetGroup { - private final Supplier fluidFilterSupplier; + private final Supplier fluidFilterSupplier; private final Supplier showTipSupplier; - private FluidFilter fluidFilter; + private BaseFilter fluidFilter; - public WidgetGroupFluidFilter(int yPosition, Supplier fluidFilterSupplier, + public WidgetGroupFluidFilter(int yPosition, Supplier fluidFilterSupplier, Supplier showTipSupplier) { super(new Position(18 + 5, yPosition)); this.fluidFilterSupplier = fluidFilterSupplier; @@ -23,7 +33,7 @@ public WidgetGroupFluidFilter(int yPosition, Supplier fluidFilterSu @Override public void detectAndSendChanges() { super.detectAndSendChanges(); - FluidFilter newFluidFilter = fluidFilterSupplier.get(); + BaseFilter newFluidFilter = fluidFilterSupplier.get(); if (fluidFilter != newFluidFilter) { clearAllWidgets(); this.fluidFilter = newFluidFilter; @@ -33,17 +43,16 @@ public void detectAndSendChanges() { writeUpdateInfo(2, buffer -> { if (fluidFilter != null) { buffer.writeBoolean(true); - int filterId = FilterTypeRegistry.getIdForFluidFilter(fluidFilter); - buffer.writeVarInt(filterId); + buffer.writeItemStack(fluidFilter.getContainerStack()); } else { buffer.writeBoolean(false); } }); } - if (fluidFilter != null && showTipSupplier != null && fluidFilter.showTip != showTipSupplier.get()) { - fluidFilter.showTip = showTipSupplier.get(); - writeUpdateInfo(3, buffer -> buffer.writeBoolean(fluidFilter.showTip)); - } + // if (fluidFilter != null && showTipSupplier != null && fluidFilter.showTip != showTipSupplier.get()) { + // fluidFilter.showTip = showTipSupplier.get(); + // writeUpdateInfo(3, buffer -> buffer.writeBoolean(fluidFilter.showTip)); + // } } @Override @@ -52,12 +61,18 @@ public void readUpdateInfo(int id, PacketBuffer buffer) { if (id == 2) { clearAllWidgets(); if (buffer.readBoolean()) { - int filterId = buffer.readVarInt(); - this.fluidFilter = FilterTypeRegistry.createFluidFilterById(filterId); + ItemStack stack; + try { + stack = buffer.readItemStack(); + } catch (IOException e) { + GTLog.logger.warn(e); + return; + } + this.fluidFilter = BaseFilter.getFilterFromStack(stack); this.fluidFilter.initUI(this::addWidget); } } else if (id == 3) { - fluidFilter.showTip = buffer.readBoolean(); + // fluidFilter.showTip = buffer.readBoolean(); } } } diff --git a/src/main/java/gregtech/common/covers/filter/WidgetGroupItemFilter.java b/src/main/java/gregtech/common/covers/filter/WidgetGroupItemFilter.java index d5601f2b2ab..9f26302fb2f 100644 --- a/src/main/java/gregtech/common/covers/filter/WidgetGroupItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/WidgetGroupItemFilter.java @@ -5,15 +5,23 @@ import net.minecraft.network.PacketBuffer; +import org.jetbrains.annotations.ApiStatus; + +import java.io.IOException; import java.util.function.Supplier; +/** + * @deprecated in favor of new MUI + */ +@Deprecated +@ApiStatus.ScheduledForRemoval(inVersion = "2.10") public class WidgetGroupItemFilter extends AbstractWidgetGroup { - private final Supplier itemFilterSupplier; - private ItemFilter itemFilter; + private final Supplier itemFilterSupplier; + private BaseFilter itemFilter; private int maxStackSize = 1; - public WidgetGroupItemFilter(int yPosition, Supplier itemFilterSupplier) { + public WidgetGroupItemFilter(int yPosition, Supplier itemFilterSupplier) { super(new Position(0, yPosition)); this.itemFilterSupplier = itemFilterSupplier; } @@ -21,7 +29,7 @@ public WidgetGroupItemFilter(int yPosition, Supplier itemFilterSuppl @Override public void detectAndSendChanges() { super.detectAndSendChanges(); - ItemFilter newItemFilter = itemFilterSupplier.get(); + BaseFilter newItemFilter = itemFilterSupplier.get(); if (itemFilter != newItemFilter) { clearAllWidgets(); this.itemFilter = newItemFilter; @@ -31,14 +39,13 @@ public void detectAndSendChanges() { writeUpdateInfo(2, buffer -> { if (itemFilter != null) { buffer.writeBoolean(true); - int filterId = FilterTypeRegistry.getIdForItemFilter(itemFilter); - buffer.writeVarInt(filterId); + buffer.writeItemStack(itemFilter.getContainerStack()); } else { buffer.writeBoolean(false); } }); } - int newMaxStackSize = itemFilter == null ? 1 : itemFilter.getMaxStackSize(); + int newMaxStackSize = itemFilter == null ? 1 : itemFilter.getMaxTransferSize(); if (maxStackSize != newMaxStackSize) { this.maxStackSize = newMaxStackSize; writeUpdateInfo(3, buffer -> buffer.writeVarInt(maxStackSize)); @@ -51,15 +58,19 @@ public void readUpdateInfo(int id, PacketBuffer buffer) { if (id == 2) { clearAllWidgets(); if (buffer.readBoolean()) { - int filterId = buffer.readVarInt(); - this.itemFilter = FilterTypeRegistry.createItemFilterById(filterId); - this.itemFilter.initUI(this::addWidget); - this.itemFilter.setMaxStackSize(maxStackSize); + // int filterId = buffer.readVarInt(); + try { + this.itemFilter = BaseFilter.getFilterFromStack(buffer.readItemStack()); + this.itemFilter.initUI(this::addWidget); + this.itemFilter.setMaxTransferSize(maxStackSize); + } catch (IOException e) { + throw new RuntimeException(e); + } } } else if (id == 3) { this.maxStackSize = buffer.readVarInt(); if (itemFilter != null) { - itemFilter.setMaxStackSize(maxStackSize); + itemFilter.setMaxTransferSize(maxStackSize); } } } diff --git a/src/main/java/gregtech/common/covers/filter/readers/BaseFilterReader.java b/src/main/java/gregtech/common/covers/filter/readers/BaseFilterReader.java new file mode 100644 index 00000000000..eee6a16a52a --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/readers/BaseFilterReader.java @@ -0,0 +1,124 @@ +package gregtech.common.covers.filter.readers; + +import gregtech.api.util.IDirtyNotifiable; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.common.util.INBTSerializable; + +import org.jetbrains.annotations.NotNull; + +public class BaseFilterReader implements FilterReader, INBTSerializable { + + protected ItemStack container; + private IDirtyNotifiable dirtyNotifiable; + private final int size; + private int maxTransferRate = 1; + protected static final String BLACKLIST = "IsBlacklist"; + protected static final String FILTER_CONTENTS = "FilterSlots"; + protected static final String KEY_LEGACY_FILTER = "Filter"; + + public BaseFilterReader(ItemStack container, int slots) { + this.container = container; + this.size = slots; + } + + @Override + public ItemStack getContainer() { + return this.container; + } + + @Override + public void readStack(@NotNull ItemStack stack) { + this.container = stack; + } + + public @NotNull NBTTagList getInventoryNbt() { + var nbt = getStackTag(); + if (!nbt.hasKey(FILTER_CONTENTS)) { + NBTTagList list = new NBTTagList(); + for (int i = 0; i < getSize(); i++) { + list.appendTag(new NBTTagCompound()); + } + nbt.setTag(FILTER_CONTENTS, list); + } + return nbt.getTagList(FILTER_CONTENTS, Constants.NBT.TAG_COMPOUND); + } + + public @NotNull NBTTagCompound getStackTag() { + NBTTagCompound nbt = this.container.getTagCompound(); + if (nbt == null) { + nbt = new NBTTagCompound(); + this.container.setTagCompound(nbt); + } + return nbt; + } + + @Override + public int getSize() { + return this.size; + } + + public final void setDirtyNotifiable(IDirtyNotifiable dirtyNotifiable) { + this.dirtyNotifiable = dirtyNotifiable; + } + + public final void markDirty() { + if (dirtyNotifiable != null) { + dirtyNotifiable.markAsDirty(); + } + } + + public void onTransferRateChange() {} + + public final void setBlacklistFilter(boolean blacklistFilter) { + if (getStackTag().getBoolean(BLACKLIST) != blacklistFilter) { + if (blacklistFilter) + getStackTag().setBoolean(BLACKLIST, true); + else + getStackTag().removeTag(BLACKLIST); + onTransferRateChange(); + markDirty(); + } + } + + public final boolean isBlacklistFilter() { + return getStackTag().getBoolean(BLACKLIST); + } + + public void setMaxTransferRate(int transferRate) { + transferRate = MathHelper.clamp(transferRate, 1, Integer.MAX_VALUE); + if (this.maxTransferRate != transferRate) { + this.maxTransferRate = transferRate; + onTransferRateChange(); + } + } + + public int getMaxTransferRate() { + return isBlacklistFilter() ? 1 : this.maxTransferRate; + } + + @Override + public boolean validateSlotIndex(int slot) { + return slot >= 0 && slot < getSize(); + } + + @Override + public NBTTagCompound serializeNBT() { + return getStackTag(); + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + if (nbt.hasKey(BLACKLIST)) + setBlacklistFilter(nbt.getBoolean(BLACKLIST)); + } + + public void handleLegacyNBT(NBTTagCompound tag) { + if (tag.hasKey(BLACKLIST)) + setBlacklistFilter(tag.getBoolean(BLACKLIST)); + } +} diff --git a/src/main/java/gregtech/common/covers/filter/readers/FilterReader.java b/src/main/java/gregtech/common/covers/filter/readers/FilterReader.java new file mode 100644 index 00000000000..34efe945268 --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/readers/FilterReader.java @@ -0,0 +1,32 @@ +package gregtech.common.covers.filter.readers; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; + +import org.jetbrains.annotations.NotNull; + +public interface FilterReader { + + ItemStack getContainer(); + + void readStack(ItemStack stack); + + @NotNull + NBTTagList getInventoryNbt(); + + @NotNull + NBTTagCompound getStackTag(); + + int getSize(); + + boolean validateSlotIndex(int slot); + + @NotNull + default NBTTagCompound getTagAt(int i) { + if (validateSlotIndex(i)) { + return getInventoryNbt().getCompoundTagAt(i); + } + return new NBTTagCompound(); + } +} diff --git a/src/main/java/gregtech/common/covers/filter/readers/OreDictFilterReader.java b/src/main/java/gregtech/common/covers/filter/readers/OreDictFilterReader.java new file mode 100644 index 00000000000..070ec7fe764 --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/readers/OreDictFilterReader.java @@ -0,0 +1,123 @@ +package gregtech.common.covers.filter.readers; + +import gregtech.api.util.oreglob.OreGlob; +import gregtech.api.util.oreglob.OreGlobCompileResult; +import gregtech.common.covers.filter.oreglob.impl.ImpossibleOreGlob; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import org.jetbrains.annotations.NotNull; + +public class OreDictFilterReader extends SimpleItemFilterReader { + + private static final String EXPRESSION = "OreDictionaryFilter"; + private static final String CASE_SENSITIVE = "caseSensitive"; + private static final String MATCH_ALL = "matchAll"; + + private OreGlob glob = ImpossibleOreGlob.getInstance(); + private OreGlobCompileResult result; + + public OreDictFilterReader(ItemStack container) { + super(container, 0); + } + + public void setExpression(String expression) { + if (getStackTag().getString(EXPRESSION).equals(expression)) + return; + + getStackTag().setString(EXPRESSION, expression); + recompile(); + markDirty(); + } + + public String getExpression() { + return getStackTag().getString(EXPRESSION); + } + + public void setCaseSensitive(boolean caseSensitive) { + if (isCaseSensitive() == caseSensitive) + return; + + if (!caseSensitive) + getStackTag().setBoolean(CASE_SENSITIVE, false); + else + getStackTag().removeTag(CASE_SENSITIVE); + recompile(); + markDirty(); + } + + public boolean isCaseSensitive() { + return !getStackTag().hasKey(CASE_SENSITIVE); + } + + public void setMatchAll(boolean matchAll) { + if (shouldMatchAll() == matchAll) + return; + + if (!matchAll) + getStackTag().setBoolean(MATCH_ALL, false); + else + getStackTag().removeTag(MATCH_ALL); + + markDirty(); + } + + /** + * {@code false} requires any of the entry to be match in order for the match to be success, {@code true} + * requires + * all entries to match + */ + public boolean shouldMatchAll() { + return !getStackTag().hasKey(MATCH_ALL); + } + + @NotNull + public OreGlob getGlob() { + return this.glob; + } + + public OreGlobCompileResult getResult() { + return this.result; + } + + public void recompile() { + String expr = getExpression(); + if (!expr.isEmpty()) { + result = OreGlob.compile(expr, !isCaseSensitive()); + this.glob = result.getInstance(); + } else { + this.glob = ImpossibleOreGlob.getInstance(); + result = null; + } + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + super.deserializeNBT(nbt); + + if (nbt.hasKey(EXPRESSION)) + this.setExpression(nbt.getString(EXPRESSION)); + + if (nbt.hasKey(CASE_SENSITIVE)) + this.setCaseSensitive(nbt.getBoolean(CASE_SENSITIVE)); + + if (nbt.hasKey(MATCH_ALL)) + this.setMatchAll(nbt.getBoolean(MATCH_ALL)); + } + + @Override + public void handleLegacyNBT(NBTTagCompound tag) { + super.handleLegacyNBT(tag); + + var legacyFilter = tag.getCompoundTag(KEY_LEGACY_FILTER); + if (legacyFilter.hasKey(EXPRESSION)) + this.setExpression(legacyFilter.getString(EXPRESSION)); + + if (legacyFilter.hasKey(CASE_SENSITIVE)) + this.setCaseSensitive(legacyFilter.getBoolean(CASE_SENSITIVE)); + + if (legacyFilter.hasKey(MATCH_ALL)) + this.setMatchAll(legacyFilter.getBoolean(MATCH_ALL)); + } +} diff --git a/src/main/java/gregtech/common/covers/filter/readers/SimpleFluidFilterReader.java b/src/main/java/gregtech/common/covers/filter/readers/SimpleFluidFilterReader.java new file mode 100644 index 00000000000..ea38dafd569 --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/readers/SimpleFluidFilterReader.java @@ -0,0 +1,181 @@ +package gregtech.common.covers.filter.readers; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTank; + +import org.jetbrains.annotations.Nullable; + +public class SimpleFluidFilterReader extends BaseFilterReader { + + protected WritableFluidTank[] fluidTanks; + protected static final String CAPACITY = "Capacity"; + + protected static final String LEGACY_FLUIDFILTER_KEY = "FluidFilter"; + + public SimpleFluidFilterReader(ItemStack container, int slots) { + super(container, slots); + fluidTanks = new WritableFluidTank[slots]; + for (int i = 0; i < fluidTanks.length; i++) { + fluidTanks[i] = new WritableFluidTank(this, getInventoryNbt().getCompoundTagAt(i)); + } + setCapacity(getStackTag().hasKey(CAPACITY) ? getCapacity() : 1000); + } + + public final boolean shouldShowAmount() { + return getMaxTransferRate() > 1; + } + + @Nullable + public FluidStack getFluidStack(int i) { + return getFluidTank(i).getFluid(); + } + + public void setCapacity(int capacity) { + getStackTag().setInteger(CAPACITY, capacity); + markDirty(); + } + + public int getCapacity() { + return getStackTag().getInteger(CAPACITY); + } + + public WritableFluidTank getFluidTank(int i) { + return fluidTanks[i]; + } + + public void setFluidAmounts(int amount) { + for (int i = 0; i < getSize(); i++) { + getFluidTank(i).setFluidAmount(amount); + } + } + + @Override + public void onTransferRateChange() { + for (int i = 0; i < getSize(); i++) { + var stack = getFluidStack(i); + if (stack == null) continue; + getFluidTank(i).setFluidAmount(Math.min(stack.amount, getMaxTransferRate())); + } + setCapacity(getMaxTransferRate()); + } + + @Override + public void handleLegacyNBT(NBTTagCompound tag) { + super.handleLegacyNBT(tag); + NBTTagCompound legacyFilter = tag.getCompoundTag(KEY_LEGACY_FILTER); + + NBTTagList filterSlots = legacyFilter.getTagList(LEGACY_FLUIDFILTER_KEY, Constants.NBT.TAG_COMPOUND); + for (int i = 0; i < filterSlots.tagCount(); i++) { + NBTTagCompound stackTag = filterSlots.getCompoundTagAt(i); + FluidStack fluidStack = FluidStack.loadFluidStackFromNBT(stackTag); + if (fluidStack == null) continue; + int slot = stackTag.getInteger("Slot"); + getFluidTank(slot).setFluid(fluidStack); + } + } + + public class WritableFluidTank extends FluidTank { + + private final NBTTagCompound fluidTank; + private final SimpleFluidFilterReader filterReader; + protected static final String FLUID_AMOUNT = "Amount"; + protected static final String FLUID = "Fluid"; + protected static final String EMPTY = "Empty"; + + protected WritableFluidTank(SimpleFluidFilterReader filterReader, NBTTagCompound fluidTank) { + super(0); + this.filterReader = filterReader; + this.fluidTank = fluidTank; + } + + public void setFluidAmount(int amount) { + if (amount <= 0) { + setFluid(null); + } else if (this.fluidTank.hasKey(FLUID)) { + this.fluidTank + .getCompoundTag(FLUID) + .setInteger(FLUID_AMOUNT, amount); + markDirty(); + } + } + + public boolean isEmpty() { + return !this.fluidTank.hasKey(FLUID); + } + + protected @Nullable NBTTagCompound getFluidTag() { + if (isEmpty()) { + return null; + } + + return this.fluidTank.getCompoundTag(FLUID); + } + + @Override + public @Nullable FluidStack getFluid() { + return FluidStack.loadFluidStackFromNBT(getFluidTag()); + } + + @Override + public void setFluid(@Nullable FluidStack stack) { + if (stack == null) { + this.fluidTank.removeTag(FLUID); + } else { + this.fluidTank.setTag(FLUID, stack.writeToNBT(new NBTTagCompound())); + } + markDirty(); + } + + public boolean showAmount() { + return this.filterReader.shouldShowAmount(); + } + + @Override + public int getFluidAmount() { + return this.fluidTank + .getCompoundTag(FLUID) + .getInteger(FLUID_AMOUNT); + } + + @Override + public int getCapacity() { + return this.filterReader.getCapacity(); + } + + // getFluid() is checked for nullability, suppress + @SuppressWarnings("DataFlowIssue") + @Override + public int fill(FluidStack resource, boolean doFill) { + if (isEmpty() || !getFluid().isFluidEqual(resource)) { + setFluid(resource); + if (!showAmount()) setFluidAmount(1); + return resource.amount; + } else if (showAmount()) { + var fluid = getFluid(); + int accepted = Math.min(resource.amount, getCapacity() - fluid.amount); + fluid.amount += accepted; + setFluid(fluid); + return accepted; + } + return 0; + } + + // getFluid() is checked for nullability, suppress + @SuppressWarnings("DataFlowIssue") + @Override + public FluidStack drain(int maxDrain, boolean doDrain) { + if (isEmpty()) return null; + FluidStack fluid = getFluid(); + + fluid.amount -= Math.min(fluid.amount, maxDrain); + + setFluidAmount(fluid.amount); + markDirty(); + return fluid; + } + } +} diff --git a/src/main/java/gregtech/common/covers/filter/readers/SimpleItemFilterReader.java b/src/main/java/gregtech/common/covers/filter/readers/SimpleItemFilterReader.java new file mode 100644 index 00000000000..7e9ea677b3e --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/readers/SimpleItemFilterReader.java @@ -0,0 +1,193 @@ +package gregtech.common.covers.filter.readers; + +import gregtech.api.util.GTUtility; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraftforge.items.IItemHandlerModifiable; +import net.minecraftforge.items.ItemHandlerHelper; +import net.minecraftforge.items.ItemStackHandler; + +import org.jetbrains.annotations.NotNull; + +public class SimpleItemFilterReader extends BaseFilterReader implements IItemHandlerModifiable { + + public static final String COUNT = "Count"; + protected static final String LEGACY_ITEM_KEY = "ItemFilter"; + protected static final String LEGACY_STACK_SIZE = "BigStackSize"; + public static final String RESPECT_NBT = "IgnoreNBT"; + public static final String RESPECT_DAMAGE = "IgnoreDamage"; + + public SimpleItemFilterReader(ItemStack container, int slots) { + super(container, slots); + } + + public void setIgnoreDamage(boolean ignoreDamage) { + if (!getStackTag().getBoolean(RESPECT_DAMAGE) == ignoreDamage) + return; + + if (ignoreDamage) + getStackTag().removeTag(RESPECT_DAMAGE); + else + getStackTag().setBoolean(RESPECT_DAMAGE, true); + markDirty(); + } + + @Override + public int getSlots() { + return getSize(); + } + + public void setIgnoreNBT(boolean ignoreNBT) { + if (!getStackTag().getBoolean(RESPECT_NBT) == ignoreNBT) + return; + + if (ignoreNBT) + getStackTag().removeTag(RESPECT_NBT); + else + getStackTag().setBoolean(RESPECT_NBT, true); + markDirty(); + } + + public boolean isIgnoreDamage() { + return !getStackTag().getBoolean(RESPECT_DAMAGE); + } + + public boolean isIgnoreNBT() { + return !getStackTag().getBoolean(RESPECT_NBT); + } + + @Override + public int getSlotLimit(int slot) { + return getMaxTransferRate(); + } + + @NotNull + @Override + public ItemStack getStackInSlot(int slot) { + if (validateSlotIndex(slot)) { + NBTTagCompound item = getTagAt(slot); + return item.isEmpty() ? ItemStack.EMPTY : new ItemStack(item); + } + return ItemStack.EMPTY; + } + + @Override + public void setStackInSlot(int slot, ItemStack stack) { + if (validateSlotIndex(slot)) { + if (!stack.isEmpty()) { + stack.setCount(Math.min(stack.getCount(), isBlacklistFilter() ? 1 : getMaxTransferRate())); + } + NBTTagList list = getInventoryNbt(); + list.set(slot, stack.isEmpty() ? new NBTTagCompound() : stack.serializeNBT()); + } + } + + @NotNull + @Override + public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + if (stack.isEmpty()) return stack; + ItemStack existing = getStackInSlot(slot); + + int limit = getStackLimit(slot, stack); + + if (!existing.isEmpty()) { + if (!ItemHandlerHelper.canItemStacksStack(stack, existing)) + return stack; + + limit -= existing.getCount(); + } + + if (limit <= 0) return stack; + + boolean reachedLimit = stack.getCount() > limit; + + if (!simulate) { + if (existing.isEmpty()) { + setStackInSlot(slot, reachedLimit ? ItemHandlerHelper.copyStackWithSize(stack, limit) : stack); + } else { + existing.grow(reachedLimit ? limit : stack.getCount()); + setStackInSlot(slot, existing); + } + } + + return reachedLimit ? GTUtility.copy(stack.getCount() - limit, stack) : ItemStack.EMPTY; + } + + @NotNull + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (amount == 0) return ItemStack.EMPTY; + + ItemStack existing = getStackInSlot(slot); + if (existing.isEmpty()) return ItemStack.EMPTY; + + int toExtract = Math.min(amount, existing.getMaxStackSize()); + + if (existing.getCount() <= toExtract) { + if (!simulate) { + setStackInSlot(slot, ItemStack.EMPTY); + } + return existing; + } else { + if (!simulate) { + setStackInSlot(slot, ItemHandlerHelper.copyStackWithSize(existing, existing.getCount() - toExtract)); + } + + return GTUtility.copy(toExtract, existing); + } + } + + protected int getStackLimit(int slot, @NotNull ItemStack stack) { + return Math.min(getSlotLimit(slot), stack.getMaxStackSize()); + } + + @Override + public void onTransferRateChange() { + for (int i = 0; i < getSlots(); i++) { + ItemStack itemStack = getStackInSlot(i); + if (!itemStack.isEmpty()) { + itemStack.setCount(Math.min(itemStack.getCount(), isBlacklistFilter() ? 1 : getMaxTransferRate())); + setStackInSlot(i, itemStack); + } + } + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + super.deserializeNBT(nbt); + + if (nbt.hasKey(RESPECT_DAMAGE)) + this.setIgnoreDamage(nbt.getBoolean(RESPECT_DAMAGE)); + + if (nbt.hasKey(RESPECT_NBT)) + this.setIgnoreNBT(nbt.getBoolean(RESPECT_NBT)); + } + + @Override + public void handleLegacyNBT(NBTTagCompound tag) { + super.handleLegacyNBT(tag); + NBTTagCompound legacyFilter = tag.getCompoundTag(KEY_LEGACY_FILTER); + + if (legacyFilter.hasKey(LEGACY_ITEM_KEY)) { + var temp = new ItemStackHandler(); + var legacyTag = legacyFilter.getCompoundTag(LEGACY_ITEM_KEY); + var stackSizes = legacyTag.getCompoundTag(LEGACY_STACK_SIZE); + + temp.deserializeNBT(legacyTag); + for (int i = 0; i < temp.getSlots(); i++) { + var stack = temp.getStackInSlot(i); + if (stack.isEmpty()) + continue; + + if (stackSizes.hasKey(String.valueOf(i))) + stack.setCount(stackSizes.getInteger(String.valueOf(i))); + + var stackTag = stack.serializeNBT(); + stackTag.setInteger(COUNT, stack.getCount()); + getInventoryNbt().set(i, stackTag); + } + } + } +} diff --git a/src/main/java/gregtech/common/covers/filter/readers/SmartItemFilterReader.java b/src/main/java/gregtech/common/covers/filter/readers/SmartItemFilterReader.java new file mode 100644 index 00000000000..ca96ed549c2 --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/readers/SmartItemFilterReader.java @@ -0,0 +1,40 @@ +package gregtech.common.covers.filter.readers; + +import gregtech.common.covers.filter.SmartItemFilter; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +public class SmartItemFilterReader extends SimpleItemFilterReader { + + private static final String FILTER_MODE = "FilterMode"; + + public SmartItemFilterReader(ItemStack container) { + super(container, 0); + } + + public SmartItemFilter.SmartFilteringMode getFilteringMode() { + if (!getStackTag().hasKey(FILTER_MODE)) + setFilteringMode(SmartItemFilter.SmartFilteringMode.ELECTROLYZER); + + return SmartItemFilter.SmartFilteringMode.VALUES[getStackTag().getInteger(FILTER_MODE)]; + } + + public void setFilteringMode(SmartItemFilter.SmartFilteringMode filteringMode) { + getStackTag().setInteger(FILTER_MODE, filteringMode.ordinal()); + markDirty(); + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + super.deserializeNBT(nbt); + this.setFilteringMode(SmartItemFilter.SmartFilteringMode.VALUES[nbt.getInteger(FILTER_MODE)]); + } + + @Override + public void handleLegacyNBT(NBTTagCompound tag) { + super.handleLegacyNBT(tag); + var legacyFilter = tag.getCompoundTag(KEY_LEGACY_FILTER); + this.setFilteringMode(SmartItemFilter.SmartFilteringMode.VALUES[legacyFilter.getInteger(FILTER_MODE)]); + } +} diff --git a/src/main/java/gregtech/common/creativetab/GTCreativeTabs.java b/src/main/java/gregtech/common/creativetab/GTCreativeTabs.java new file mode 100644 index 00000000000..95d308dde3e --- /dev/null +++ b/src/main/java/gregtech/common/creativetab/GTCreativeTabs.java @@ -0,0 +1,34 @@ +package gregtech.common.creativetab; + +import gregtech.api.GTValues; +import gregtech.api.creativetab.BaseCreativeTab; +import gregtech.api.unification.OreDictUnifier; +import gregtech.api.unification.material.Materials; +import gregtech.api.unification.ore.OrePrefix; +import gregtech.common.blocks.BlockWarningSign; +import gregtech.common.blocks.MetaBlocks; +import gregtech.common.items.MetaItems; +import gregtech.common.items.ToolItems; +import gregtech.common.metatileentities.MetaTileEntities; + +public final class GTCreativeTabs { + + public static final BaseCreativeTab TAB_GREGTECH = new BaseCreativeTab(GTValues.MODID + ".main", + () -> MetaItems.LOGO.getStackForm(), true); + public static final BaseCreativeTab TAB_GREGTECH_MACHINES = new BaseCreativeTab(GTValues.MODID + ".machines", + () -> MetaTileEntities.ELECTRIC_BLAST_FURNACE.getStackForm(), true); + public static final BaseCreativeTab TAB_GREGTECH_CABLES = new BaseCreativeTab(GTValues.MODID + ".cables", + () -> OreDictUnifier.get(OrePrefix.cableGtDouble, Materials.Aluminium), true); + public static final BaseCreativeTab TAB_GREGTECH_PIPES = new BaseCreativeTab(GTValues.MODID + ".pipes", + () -> OreDictUnifier.get(OrePrefix.pipeNormalFluid, Materials.Aluminium), true); + public static final BaseCreativeTab TAB_GREGTECH_TOOLS = new BaseCreativeTab(GTValues.MODID + ".tools", + () -> ToolItems.HARD_HAMMER.get(Materials.Aluminium), true); + public static final BaseCreativeTab TAB_GREGTECH_MATERIALS = new BaseCreativeTab(GTValues.MODID + ".materials", + () -> OreDictUnifier.get(OrePrefix.ingot, Materials.Aluminium), true); + public static final BaseCreativeTab TAB_GREGTECH_ORES = new BaseCreativeTab(GTValues.MODID + ".ores", + () -> OreDictUnifier.get(OrePrefix.ore, Materials.Aluminium), true); + public static final BaseCreativeTab TAB_GREGTECH_DECORATIONS = new BaseCreativeTab(GTValues.MODID + ".decorations", + () -> MetaBlocks.WARNING_SIGN.getItemVariant(BlockWarningSign.SignType.YELLOW_STRIPES), true); + + private GTCreativeTabs() {} +} diff --git a/src/main/java/gregtech/common/entities/EntityGTExplosive.java b/src/main/java/gregtech/common/entities/EntityGTExplosive.java new file mode 100644 index 00000000000..70233d7f17b --- /dev/null +++ b/src/main/java/gregtech/common/entities/EntityGTExplosive.java @@ -0,0 +1,136 @@ +package gregtech.common.entities; + +import gregtech.api.util.BlockUtility; +import gregtech.api.util.GregFakePlayer; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.MoverType; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.item.EntityTNTPrimed; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; + +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; + +public abstract class EntityGTExplosive extends EntityTNTPrimed { + + public EntityGTExplosive(World world, double x, double y, double z, EntityLivingBase exploder) { + super(world, x, y, z, exploder); + } + + @SuppressWarnings("unused") + public EntityGTExplosive(World world) { + super(world); + } + + /** + * @return The strength of the explosive. + */ + protected abstract float getStrength(); + + /** + * @return Whether to drop all blocks, or use default logic + */ + public abstract boolean dropsAllBlocks(); + + /** + * @return The range of the explosive, if {@link #dropsAllBlocks} is true. + */ + protected int getRange() { + return 2; + } + + /** + * @return The block state of the block this explosion entity is created by. + */ + public abstract @NotNull IBlockState getExplosiveState(); + + @Override + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + if (!this.hasNoGravity()) { + this.motionY -= 0.03999999910593033D; + } + + this.move(MoverType.SELF, this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9800000190734863D; + this.motionY *= 0.9800000190734863D; + this.motionZ *= 0.9800000190734863D; + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + this.motionY *= -0.5D; + } + + setFuse(this.getFuse() - 1); + if (this.getFuse() <= 0) { + this.setDead(); + if (!this.world.isRemote) { + this.explodeTNT(); + } + } else { + this.handleWaterMovement(); + this.world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, + 0.0D); + } + } + + protected void explodeTNT() { + this.world.createExplosion(this, this.posX, this.posY + (double) (this.height / 16.0F), this.posZ, + getStrength(), !dropsAllBlocks()); + + // If we don't drop all blocks, then skip the drop capture logic + if (!dropsAllBlocks()) return; + + // Create the fake explosion but don't destroy any blocks in water, per MC behavior + if (this.inWater) return; + + EntityPlayer player = GregFakePlayer.get((WorldServer) world); + + int range = getRange(); + for (BlockPos pos : BlockPos.getAllInBox(this.getPosition().add(-range, -range, -range), + this.getPosition().add(range, range, range))) { + IBlockState state = world.getBlockState(pos); + + if (state.getMaterial() == Material.AIR) continue; + if (state.getMaterial() == Material.WATER || state.getMaterial() == Material.LAVA) continue; + + float hardness = state.getBlockHardness(world, pos); + float resistance = state.getBlock().getExplosionResistance(player); + + if (hardness >= 0.0f && resistance < 100 && world.isBlockModifiable(player, pos)) { + List drops = attemptBreakBlockAndObtainDrops(pos, state, player); + + for (ItemStack stack : drops) { + EntityItem entity = new EntityItem(world, pos.getX(), pos.getY(), pos.getZ(), stack); + entity.setDefaultPickupDelay(); + world.spawnEntity(entity); + } + } + } + } + + private List attemptBreakBlockAndObtainDrops(BlockPos pos, IBlockState state, EntityPlayer player) { + if (state.getBlock().removedByPlayer(state, world, pos, player, true)) { + world.playEvent(null, 2001, pos, Block.getStateId(state)); + state.getBlock().onPlayerDestroy(world, pos, state); + + BlockUtility.startCaptureDrops(); + state.getBlock().harvestBlock(world, player, pos, state, world.getTileEntity(pos), ItemStack.EMPTY); + return BlockUtility.stopCaptureDrops(); + } + return Collections.emptyList(); + } +} diff --git a/src/main/java/gregtech/common/entities/ITNTEntity.java b/src/main/java/gregtech/common/entities/ITNTEntity.java new file mode 100644 index 00000000000..3fa60cf4860 --- /dev/null +++ b/src/main/java/gregtech/common/entities/ITNTEntity.java @@ -0,0 +1,41 @@ +package gregtech.common.entities; + +import gregtech.common.blocks.MetaBlocks; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; + +public class ITNTEntity extends EntityGTExplosive { + + public ITNTEntity(World world, double x, double y, double z, EntityLivingBase exploder) { + super(world, x, y, z, exploder); + } + + @SuppressWarnings("unused") + public ITNTEntity(World world) { + super(world); + } + + @Override + protected float getStrength() { + return 5.0F; + } + + @Override + public boolean dropsAllBlocks() { + return true; + } + + @Override + protected int getRange() { + return 3; + } + + @Override + public @NotNull IBlockState getExplosiveState() { + return MetaBlocks.ITNT.getDefaultState(); + } +} diff --git a/src/main/java/gregtech/common/entities/PowderbarrelEntity.java b/src/main/java/gregtech/common/entities/PowderbarrelEntity.java new file mode 100644 index 00000000000..39f1ed4df56 --- /dev/null +++ b/src/main/java/gregtech/common/entities/PowderbarrelEntity.java @@ -0,0 +1,36 @@ +package gregtech.common.entities; + +import gregtech.common.blocks.MetaBlocks; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; + +public class PowderbarrelEntity extends EntityGTExplosive { + + public PowderbarrelEntity(World world, double x, double y, double z, EntityLivingBase exploder) { + super(world, x, y, z, exploder); + } + + @SuppressWarnings("unused") + public PowderbarrelEntity(World world) { + super(world); + } + + @Override + protected float getStrength() { + return 3.5F; + } + + @Override + public boolean dropsAllBlocks() { + return true; + } + + @Override + public @NotNull IBlockState getExplosiveState() { + return MetaBlocks.POWDERBARREL.getDefaultState(); + } +} diff --git a/src/main/java/gregtech/common/gui/widget/HighlightedTextField.java b/src/main/java/gregtech/common/gui/widget/HighlightedTextField.java deleted file mode 100644 index 8acea5527f7..00000000000 --- a/src/main/java/gregtech/common/gui/widget/HighlightedTextField.java +++ /dev/null @@ -1,127 +0,0 @@ -package gregtech.common.gui.widget; - -import gregtech.api.gui.widgets.TextFieldWidget2; - -import net.minecraft.util.text.TextFormatting; - -import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntList; -import org.jetbrains.annotations.Nullable; - -import java.util.function.Consumer; -import java.util.function.Supplier; - -public class HighlightedTextField extends TextFieldWidget2 { - - @Nullable - private Consumer highlightRule; - @Nullable - private TextHighlighter formatResult; - - public HighlightedTextField(int x, int y, int width, int height, Supplier supplier, - Consumer setter) { - super(x, y, width, height, supplier, setter); - } - - /** - * Text highlighter applied only in rendering text. Only formatting characters can be inserted. - * - * @param highlightRule Consumer for text highlighter - * @return This - */ - public HighlightedTextField setHighlightRule(Consumer highlightRule) { - this.highlightRule = highlightRule; - return this; - } - - @Override - public void setText(String text) { - super.setText(text); - this.formatResult = null; - } - - @Override - protected String getRenderText() { - if (this.formatResult == null) { - if (this.highlightRule == null) { - return getText(); - } - TextHighlighter highlighter = new TextHighlighter(getText()); - this.highlightRule.accept(highlighter); - this.formatResult = highlighter; - return highlighter.getFormattedText(); - } - return this.formatResult.getFormattedText(); - } - - @Override - protected int toOriginalTextIndex(int renderTextIndex) { - return formatResult != null ? formatResult.toOriginalTextIndex(renderTextIndex) : renderTextIndex; - } - - @Override - protected int toRenderTextIndex(int originalTextIndex) { - return formatResult != null ? formatResult.toFormattedTextIndex(originalTextIndex) : originalTextIndex; - } - - public static final class TextHighlighter { - - private final String originalText; - private final StringBuilder formattedTextBuilder; - - private final IntList formatOriginalIndices = new IntArrayList(); - - @Nullable - private String formattedTextCache; - - public TextHighlighter(String originalText) { - this.originalText = originalText; - this.formattedTextBuilder = new StringBuilder(originalText); - } - - public String getOriginalText() { - return this.originalText; - } - - public String getFormattedText() { - if (this.formattedTextCache == null) { - return this.formattedTextCache = this.formattedTextBuilder.toString(); - } - return this.formattedTextCache; - } - - public int toFormattedTextIndex(int originalTextIndex) { - int i = 0; - for (; i < formatOriginalIndices.size(); i++) { - if (formatOriginalIndices.getInt(i) > originalTextIndex) { - break; - } - } - return originalTextIndex + i * 2; - } - - public int toOriginalTextIndex(int formattedTextIndex) { - int i = 0; - for (; i < formatOriginalIndices.size(); i++) { - if (formatOriginalIndices.getInt(i) + i * 2 >= formattedTextIndex) { - break; - } - } - return formattedTextIndex - i * 2; - } - - public void format(int index, TextFormatting format) { - if (index < 0) index = 0; - else if (index > originalText.length()) return; - formattedTextBuilder.insert(toFormattedTextIndex(index), format.toString()); - formattedTextCache = null; - for (int i = 0; i < formatOriginalIndices.size(); i++) { - if (formatOriginalIndices.getInt(i) > index) { - formatOriginalIndices.add(i, index); - return; - } - } - formatOriginalIndices.add(index); - } - } -} diff --git a/src/main/java/gregtech/common/gui/widget/appeng/AEConfigWidget.java b/src/main/java/gregtech/common/gui/widget/appeng/AEConfigWidget.java index 59005459893..1195fa8f34f 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/AEConfigWidget.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/AEConfigWidget.java @@ -6,7 +6,7 @@ import gregtech.api.util.Size; import gregtech.common.gui.widget.appeng.slot.AEConfigSlot; import gregtech.common.gui.widget.appeng.slot.AmountSetSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import appeng.api.storage.data.IAEStack; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; @@ -26,26 +26,34 @@ public abstract class AEConfigWidget> extends AbstractWidg protected Int2ObjectMap> changeMap = new Int2ObjectOpenHashMap<>(); protected IConfigurableSlot[] displayList; protected AmountSetSlot amountSetWidget; + protected final boolean isStocking; protected final static int UPDATE_ID = 1000; - public AEConfigWidget(int x, int y, IConfigurableSlot[] config) { + public AEConfigWidget(int x, int y, IConfigurableSlot[] config, boolean isStocking) { super(new Position(x, y), new Size(config.length * 18, 18 * 2)); + this.isStocking = isStocking; this.config = config; this.init(); - this.amountSetWidget = new AmountSetSlot<>(80, -40, this); - this.addWidget(this.amountSetWidget); - this.addWidget(this.amountSetWidget.getText()); - this.amountSetWidget.setVisible(false); - this.amountSetWidget.getText().setVisible(false); + if (!isStocking()) { + this.amountSetWidget = new AmountSetSlot<>(80, -40, this); + this.addWidget(this.amountSetWidget); + this.addWidget(this.amountSetWidget.getText()); + this.amountSetWidget.setVisible(false); + this.amountSetWidget.getText().setVisible(false); + } } public void enableAmount(int slotIndex) { + // Only allow the amount set widget if not stocking, as amount is useless for stocking + if (isStocking()) return; this.amountSetWidget.setSlotIndex(slotIndex); this.amountSetWidget.setVisible(true); this.amountSetWidget.getText().setVisible(true); } public void disableAmount() { + // Only allow the amount set widget if not stocking, as amount is useless for stocking + if (isStocking()) return; this.amountSetWidget.setSlotIndex(-1); this.amountSetWidget.setVisible(false); this.amountSetWidget.getText().setVisible(false); @@ -53,22 +61,29 @@ public void disableAmount() { @Override public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (this.amountSetWidget.isVisible()) { - if (this.amountSetWidget.getText().mouseClicked(mouseX, mouseY, button)) { - return true; + // Only allow the amount set widget if not stocking, as amount is useless for stocking + if (!isStocking()) { + if (this.amountSetWidget.isVisible()) { + if (this.amountSetWidget.getText().mouseClicked(mouseX, mouseY, button)) { + return true; + } } - } - for (Widget w : this.widgets) { - if (w instanceof AEConfigSlot) { - ((AEConfigSlot) w).setSelect(false); + for (Widget w : this.widgets) { + if (w instanceof AEConfigSlot) { + ((AEConfigSlot) w).setSelect(false); + } } + this.disableAmount(); } - this.disableAmount(); return super.mouseClicked(mouseX, mouseY, button); } abstract void init(); + public boolean isStocking() { + return isStocking; + } + @Override public void detectAndSendChanges() { super.detectAndSendChanges(); diff --git a/src/main/java/gregtech/common/gui/widget/appeng/AEFluidConfigWidget.java b/src/main/java/gregtech/common/gui/widget/appeng/AEFluidConfigWidget.java index 1599217290c..b5f709b0b86 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/AEFluidConfigWidget.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/AEFluidConfigWidget.java @@ -1,39 +1,49 @@ package gregtech.common.gui.widget.appeng; import gregtech.common.gui.widget.appeng.slot.AEFluidConfigSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEInputHatch; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fluids.FluidStack; import appeng.api.storage.data.IAEFluidStack; -/** - * @Author GlodBlock - * @Description Display {@link IAEFluidStack} config - * @Date 2023/4/21-1:45 - */ public class AEFluidConfigWidget extends AEConfigWidget { - public AEFluidConfigWidget(int x, int y, IConfigurableSlot[] config) { - super(x, y, config); + final ExportOnlyAEFluidList fluidList; + + public AEFluidConfigWidget(int x, int y, ExportOnlyAEFluidList fluidList) { + super(x, y, fluidList.getInventory(), fluidList.isStocking()); + this.fluidList = fluidList; } @Override @SuppressWarnings("unchecked") void init() { - int line; + final int size = (int) Math.sqrt(this.config.length); this.displayList = new IConfigurableSlot[this.config.length]; this.cached = new IConfigurableSlot[this.config.length]; - for (int index = 0; index < this.config.length; index++) { - this.displayList[index] = new MetaTileEntityMEInputHatch.ExportOnlyAEFluid(); - this.cached[index] = new MetaTileEntityMEInputHatch.ExportOnlyAEFluid(); - line = index / 8; - this.addWidget(new AEFluidConfigSlot((index - line * 8) * 18, line * (18 * 2 + 2), this, index)); + for (int h = 0; h < size; h++) { + for (int w = 0; w < size; w++) { + final int index = h * size + w; + this.displayList[index] = new ExportOnlyAEFluidSlot(); + this.cached[index] = new ExportOnlyAEFluidSlot(); + this.addWidget(new AEFluidConfigSlot(w * 18, h * 18, this, index)); + } } } + public boolean hasStackInConfig(FluidStack stack) { + return fluidList.hasStackInConfig(stack, true); + } + + public boolean isAutoPull() { + return fluidList.isAutoPull(); + } + @Override public void readUpdateInfo(int id, PacketBuffer buffer) { super.readUpdateInfo(id, buffer); diff --git a/src/main/java/gregtech/common/gui/widget/appeng/AEItemConfigWidget.java b/src/main/java/gregtech/common/gui/widget/appeng/AEItemConfigWidget.java index c3707d4afaf..0f2afe98235 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/AEItemConfigWidget.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/AEItemConfigWidget.java @@ -1,39 +1,49 @@ package gregtech.common.gui.widget.appeng; import gregtech.common.gui.widget.appeng.slot.AEItemConfigSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEInputBus; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; +import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import appeng.api.storage.data.IAEItemStack; -/** - * @Author GlodBlock - * @Description Display {@link IAEItemStack} config - * @Date 2023/4/22-1:02 - */ public class AEItemConfigWidget extends AEConfigWidget { - public AEItemConfigWidget(int x, int y, IConfigurableSlot[] config) { - super(x, y, config); + final ExportOnlyAEItemList itemList; + + public AEItemConfigWidget(int x, int y, ExportOnlyAEItemList itemList) { + super(x, y, itemList.getInventory(), itemList.isStocking()); + this.itemList = itemList; } @Override @SuppressWarnings("unchecked") void init() { - int line; + final int size = (int) Math.sqrt(this.config.length); this.displayList = new IConfigurableSlot[this.config.length]; this.cached = new IConfigurableSlot[this.config.length]; - for (int index = 0; index < this.config.length; index++) { - this.displayList[index] = new MetaTileEntityMEInputBus.ExportOnlyAEItem(); - this.cached[index] = new MetaTileEntityMEInputBus.ExportOnlyAEItem(); - line = index / 8; - this.addWidget(new AEItemConfigSlot((index - line * 8) * 18, line * (18 * 2 + 2), this, index)); + for (int h = 0; h < size; h++) { + for (int w = 0; w < size; w++) { + final int index = h * size + w; + this.displayList[index] = new ExportOnlyAEItemSlot(); + this.cached[index] = new ExportOnlyAEItemSlot(); + this.addWidget(new AEItemConfigSlot(w * 18, h * 18, this, index)); + } } } + public boolean hasStackInConfig(ItemStack stack) { + return itemList.hasStackInConfig(stack, true); + } + + public boolean isAutoPull() { + return itemList.isAutoPull(); + } + @Override public void readUpdateInfo(int id, PacketBuffer buffer) { super.readUpdateInfo(id, buffer); diff --git a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEConfigSlot.java b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEConfigSlot.java index ed1b9145bd7..d663340a451 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEConfigSlot.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEConfigSlot.java @@ -5,7 +5,7 @@ import gregtech.api.util.Position; import gregtech.api.util.Size; import gregtech.common.gui.widget.appeng.AEConfigWidget; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; @@ -17,13 +17,9 @@ import java.util.Collections; import java.util.List; -/** - * @Author GlodBlock - * @Description A configurable slot - * @Date 2023/4/22-0:30 - */ public class AEConfigSlot> extends Widget implements IGhostIngredientTarget { + protected static final int DISPLAY_X_OFFSET = 18 * 5; protected AEConfigWidget parentWidget; protected int index; protected final static int REMOVE_ID = 1000; @@ -43,14 +39,24 @@ public void drawInForeground(int mouseX, int mouseY) { IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); if (slot.getConfig() == null && mouseOverConfig(mouseX, mouseY)) { List hoverStringList = new ArrayList<>(); - hoverStringList.add(I18n.format("gregtech.gui.config_slot")); - hoverStringList.add(I18n.format("gregtech.gui.config_slot.set")); - hoverStringList.add(I18n.format("gregtech.gui.config_slot.scroll")); - hoverStringList.add(I18n.format("gregtech.gui.config_slot.remove")); - drawHoveringText(ItemStack.EMPTY, hoverStringList, -1, mouseX, mouseY); + addHoverText(hoverStringList); + if (!hoverStringList.isEmpty()) { + drawHoveringText(ItemStack.EMPTY, hoverStringList, -1, mouseX, mouseY); + } } } + protected void addHoverText(List hoverText) { + hoverText.add(I18n.format("gregtech.gui.config_slot")); + if (!parentWidget.isStocking()) { + hoverText.add(I18n.format("gregtech.gui.config_slot.set")); + hoverText.add(I18n.format("gregtech.gui.config_slot.scroll")); + } else { + hoverText.add(I18n.format("gregtech.gui.config_slot.set_only")); + } + hoverText.add(I18n.format("gregtech.gui.config_slot.remove")); + } + public void setSelect(boolean val) { this.select = val; } @@ -62,11 +68,15 @@ protected boolean mouseOverConfig(int mouseX, int mouseY) { protected boolean mouseOverStock(int mouseX, int mouseY) { Position position = getPosition(); - return isMouseOver(position.x, position.y + 18, 18, 18, mouseX, mouseY); + return isMouseOver(position.x + DISPLAY_X_OFFSET, position.y, 18, 18, mouseX, mouseY); } @Override public List> getPhantomTargets(Object ingredient) { return Collections.emptyList(); } + + public AEConfigWidget getParentWidget() { + return parentWidget; + } } diff --git a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEFluidConfigSlot.java b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEFluidConfigSlot.java index b4ab7e87beb..2b852fdeb14 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEFluidConfigSlot.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEFluidConfigSlot.java @@ -7,10 +7,11 @@ import gregtech.api.util.Size; import gregtech.api.util.TextFormattingUtil; import gregtech.client.utils.RenderUtil; -import gregtech.common.gui.widget.appeng.AEConfigWidget; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.gui.widget.appeng.AEFluidConfigWidget; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; +import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; @@ -34,27 +35,26 @@ import static gregtech.api.capability.GregtechDataCodes.LOAD_PHANTOM_FLUID_STACK_FROM_NBT; import static gregtech.api.util.GTUtility.getFluidFromContainer; -/** - * @Author GlodBlock - * @Description A configurable slot for {@link IAEFluidStack} - * @Date 2023/4/21-0:50 - */ public class AEFluidConfigSlot extends AEConfigSlot { - public AEFluidConfigSlot(int x, int y, AEConfigWidget widget, int index) { - super(new Position(x, y), new Size(18, 18 * 2), widget, index); + public AEFluidConfigSlot(int x, int y, AEFluidConfigWidget widget, int index) { + super(new Position(x, y), new Size(18 * 6, 18), widget, index); + } + + @Override + public AEFluidConfigWidget getParentWidget() { + return (AEFluidConfigWidget) super.getParentWidget(); } @Override public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { super.drawInBackground(mouseX, mouseY, partialTicks, context); + AEFluidConfigWidget pw = getParentWidget(); Position position = getPosition(); - IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); + IConfigurableSlot slot = pw.getDisplay(this.index); IAEFluidStack config = slot.getConfig(); IAEFluidStack stock = slot.getStock(); - GuiTextures.FLUID_SLOT.draw(position.x, position.y, 18, 18); - GuiTextures.FLUID_SLOT.draw(position.x, position.y + 18, 18, 18); - GuiTextures.CONFIG_ARROW.draw(position.x, position.y, 18, 18); + drawSlots(pw.isAutoPull(), position.x, position.y); if (this.select) { GuiTextures.SELECT_BOX.draw(position.x, position.y, 18, 18); } @@ -62,22 +62,35 @@ public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRender int stackY = position.y + 1; if (config != null) { RenderUtil.drawFluidForGui(config.getFluidStack(), config.getFluidStack().amount, stackX, stackY, 17, 17); - String amountStr = TextFormattingUtil.formatLongToCompactString(config.getStackSize(), 4) + "L"; - drawStringFixedCorner(amountStr, stackX + 17, stackY + 17, 16777215, true, 0.5f); + + if (!pw.isStocking()) { + String amountStr = TextFormattingUtil.formatLongToCompactString(config.getStackSize(), 4) + "L"; + drawStringFixedCorner(amountStr, stackX + 17, stackY + 17, 16777215, true, 0.5f); + } } if (stock != null) { - RenderUtil.drawFluidForGui(stock.getFluidStack(), stock.getFluidStack().amount, stackX, stackY + 18, 17, - 17); + RenderUtil.drawFluidForGui(stock.getFluidStack(), stock.getFluidStack().amount, stackX + DISPLAY_X_OFFSET, + stackY, 17, 17); String amountStr = TextFormattingUtil.formatLongToCompactString(stock.getStackSize(), 4) + "L"; - drawStringFixedCorner(amountStr, stackX + 17, stackY + 18 + 17, 16777215, true, 0.5f); + drawStringFixedCorner(amountStr, stackX + DISPLAY_X_OFFSET + 17, stackY + 17, 16777215, true, 0.5f); } if (mouseOverConfig(mouseX, mouseY)) { drawSelectionOverlay(stackX, stackY, 16, 16); } else if (mouseOverStock(mouseX, mouseY)) { - drawSelectionOverlay(stackX, stackY + 18, 16, 16); + drawSelectionOverlay(stackX + DISPLAY_X_OFFSET, stackY, 16, 16); } } + private void drawSlots(boolean autoPull, int x, int y) { + if (autoPull) { + GuiTextures.SLOT_DARK.draw(x, y, 18, 18); + } else { + GuiTextures.FLUID_SLOT.draw(x, y, 18, 18); + } + GuiTextures.SLOT_DARK.draw(x + DISPLAY_X_OFFSET, y, 18, 18); + GuiTextures.CONFIG_ARROW.draw(x, y, 18, 18); + } + @Override public void drawInForeground(int mouseX, int mouseY) { super.drawInForeground(mouseX, mouseY); @@ -107,13 +120,31 @@ public void drawInForeground(int mouseX, int mouseY) { } } + @Override + protected void addHoverText(List hoverText) { + if (getParentWidget().isAutoPull()) { + hoverText.add(I18n.format("gregtech.gui.config_slot")); + hoverText.add(I18n.format("gregtech.gui.config_slot.auto_pull_managed")); + } else { + super.addHoverText(hoverText); + } + } + @Override public boolean mouseClicked(int mouseX, int mouseY, int button) { + AEFluidConfigWidget pw = getParentWidget(); + if (pw.isAutoPull()) { + return false; + } + if (mouseOverConfig(mouseX, mouseY)) { if (button == 1) { // Right click to clear - this.parentWidget.disableAmount(); writeClientAction(REMOVE_ID, buf -> {}); + + if (!pw.isStocking()) { + this.parentWidget.disableAmount(); + } } else if (button == 0) { // Left click to set/select ItemStack hold = this.gui.entityPlayer.inventory.getItemStack(); @@ -125,8 +156,11 @@ public boolean mouseClicked(int mouseX, int mouseY, int button) { buf.writeVarInt(fluid.amount); }); } - this.parentWidget.enableAmount(this.index); - this.select = true; + + if (!pw.isStocking()) { + this.parentWidget.enableAmount(this.index); + this.select = true; + } } return true; } @@ -145,6 +179,7 @@ public void handleClientAction(int id, PacketBuffer buffer) { if (id == UPDATE_ID) { FluidStack fluid = FluidRegistry.getFluidStack(buffer.readString(Integer.MAX_VALUE / 16), buffer.readVarInt()); + if (!isFluidValidForSlot(fluid)) return; slot.setConfig(WrappedFluidStack.fromFluidStack(fluid)); this.parentWidget.enableAmount(this.index); if (fluid != null) { @@ -198,13 +233,20 @@ public void readUpdateInfo(int id, PacketBuffer buffer) { } } + private boolean isFluidValidForSlot(FluidStack stack) { + if (stack == null) return true; + AEFluidConfigWidget pw = getParentWidget(); + if (!pw.isStocking()) return true; + return !pw.hasStackInConfig(stack); + } + @Override public List> getPhantomTargets(Object ingredient) { if (getFluidFromContainer(ingredient) == null) { return Collections.emptyList(); } Rectangle rectangle = toRectangleBox(); - rectangle.height /= 2; + rectangle.width /= 6; return Lists.newArrayList(new IGhostIngredientHandler.Target<>() { @NotNull @@ -227,9 +269,10 @@ public void accept(@NotNull Object ingredient) { @SideOnly(Side.CLIENT) public boolean mouseWheelMove(int mouseX, int mouseY, int wheelDelta) { + if (parentWidget.isStocking()) return false; IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); Rectangle rectangle = toRectangleBox(); - rectangle.height /= 2; + rectangle.width /= 6; if (slot.getConfig() == null || wheelDelta == 0 || !rectangle.contains(mouseX, mouseY)) { return false; } diff --git a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEItemConfigSlot.java b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEItemConfigSlot.java index 02cad40272b..3dff4140249 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEItemConfigSlot.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEItemConfigSlot.java @@ -5,10 +5,11 @@ import gregtech.api.util.Position; import gregtech.api.util.Size; import gregtech.api.util.TextFormattingUtil; -import gregtech.common.gui.widget.appeng.AEConfigWidget; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.gui.widget.appeng.AEItemConfigWidget; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; +import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import net.minecraftforge.fml.relauncher.Side; @@ -24,27 +25,26 @@ import java.util.Collections; import java.util.List; -/** - * @Author GlodBlock - * @Description A configurable slot for {@link IAEItemStack} - * @Date 2023/4/22-0:48 - */ public class AEItemConfigSlot extends AEConfigSlot { - public AEItemConfigSlot(int x, int y, AEConfigWidget widget, int index) { - super(new Position(x, y), new Size(18, 18 * 2), widget, index); + public AEItemConfigSlot(int x, int y, AEItemConfigWidget widget, int index) { + super(new Position(x, y), new Size(18 * 6, 18), widget, index); + } + + @Override + public AEItemConfigWidget getParentWidget() { + return (AEItemConfigWidget) super.getParentWidget(); } @Override public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { super.drawInBackground(mouseX, mouseY, partialTicks, context); + AEItemConfigWidget pw = getParentWidget(); Position position = getPosition(); - IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); + IConfigurableSlot slot = pw.getDisplay(this.index); IAEItemStack config = slot.getConfig(); IAEItemStack stock = slot.getStock(); - GuiTextures.SLOT.draw(position.x, position.y, 18, 18); - GuiTextures.SLOT.draw(position.x, position.y + 18, 18, 18); - GuiTextures.CONFIG_ARROW_DARK.draw(position.x, position.y, 18, 18); + drawSlots(pw.isAutoPull(), position.x, position.y); if (this.select) { GuiTextures.SELECT_BOX.draw(position.x, position.y, 18, 18); } @@ -54,28 +54,43 @@ public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRender ItemStack stack = config.createItemStack(); stack.setCount(1); drawItemStack(stack, stackX, stackY, null); - String amountStr = TextFormattingUtil.formatLongToCompactString(config.getStackSize(), 4); - drawStringFixedCorner(amountStr, stackX + 17, stackY + 17, 16777215, true, 0.5f); + + // Only draw the config amount if not stocking, as its meaningless when stocking + if (!pw.isStocking()) { + String amountStr = TextFormattingUtil.formatLongToCompactString(config.getStackSize(), 4); + drawStringFixedCorner(amountStr, stackX + 17, stackY + 17, 16777215, true, 0.5f); + } } if (stock != null) { ItemStack stack = stock.createItemStack(); stack.setCount(1); - drawItemStack(stack, stackX, stackY + 18, null); + drawItemStack(stack, stackX + DISPLAY_X_OFFSET, stackY, null); String amountStr = TextFormattingUtil.formatLongToCompactString(stock.getStackSize(), 4); - drawStringFixedCorner(amountStr, stackX + 17, stackY + 18 + 17, 16777215, true, 0.5f); + drawStringFixedCorner(amountStr, stackX + DISPLAY_X_OFFSET + 17, stackY + 17, 16777215, true, 0.5f); } if (mouseOverConfig(mouseX, mouseY)) { drawSelectionOverlay(stackX, stackY, 16, 16); } else if (mouseOverStock(mouseX, mouseY)) { - drawSelectionOverlay(stackX, stackY + 18, 16, 16); + drawSelectionOverlay(stackX + DISPLAY_X_OFFSET, stackY, 16, 16); } } + private void drawSlots(boolean autoPull, int x, int y) { + if (autoPull) { + GuiTextures.SLOT_DARK.draw(x, y, 18, 18); + GuiTextures.CONFIG_ARROW.draw(x, y, 18, 18); + } else { + GuiTextures.SLOT.draw(x, y, 18, 18); + GuiTextures.CONFIG_ARROW_DARK.draw(x, y, 18, 18); + } + GuiTextures.SLOT_DARK.draw(x + DISPLAY_X_OFFSET, y, 18, 18); + } + @Override public void drawInForeground(int mouseX, int mouseY) { super.drawInForeground(mouseX, mouseY); IAEItemStack item = null; - IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); + IConfigurableSlot slot = this.getParentWidget().getDisplay(this.index); if (mouseOverConfig(mouseX, mouseY)) { item = slot.getConfig(); } else if (mouseOverStock(mouseX, mouseY)) { @@ -86,22 +101,45 @@ public void drawInForeground(int mouseX, int mouseY) { } } + @Override + protected void addHoverText(List hoverText) { + if (getParentWidget().isAutoPull()) { + hoverText.add(I18n.format("gregtech.gui.config_slot")); + hoverText.add(I18n.format("gregtech.gui.config_slot.auto_pull_managed")); + } else { + super.addHoverText(hoverText); + } + } + @Override public boolean mouseClicked(int mouseX, int mouseY, int button) { + AEItemConfigWidget pw = getParentWidget(); + // don't allow manual interaction with config slots when auto pull is enabled + if (pw.isAutoPull()) { + return false; + } + if (mouseOverConfig(mouseX, mouseY)) { if (button == 1) { // Right click to clear - this.parentWidget.disableAmount(); writeClientAction(REMOVE_ID, buf -> {}); + + if (!pw.isStocking()) { + pw.disableAmount(); + } } else if (button == 0) { // Left click to set/select ItemStack item = this.gui.entityPlayer.inventory.getItemStack(); if (!item.isEmpty()) { writeClientAction(UPDATE_ID, buf -> buf.writeItemStack(item)); + return true; + } + + if (!pw.isStocking()) { + pw.enableAmount(this.index); + this.select = true; } - this.parentWidget.enableAmount(this.index); - this.select = true; } return true; } @@ -120,6 +158,7 @@ public void handleClientAction(int id, PacketBuffer buffer) { if (id == UPDATE_ID) { try { ItemStack item = buffer.readItemStack(); + if (!isItemValidForSlot(item)) return; slot.setConfig(WrappedItemStack.fromItemStack(item)); this.parentWidget.enableAmount(this.index); if (!item.isEmpty()) { @@ -157,13 +196,21 @@ public void readUpdateInfo(int id, PacketBuffer buffer) { } } + // Method for server-side validation of an attempted new configured item + private boolean isItemValidForSlot(ItemStack stack) { + if (stack == null || stack.isEmpty()) return true; + AEItemConfigWidget pw = getParentWidget(); + if (!pw.isStocking()) return true; + return !pw.hasStackInConfig(stack); + } + @Override public List> getPhantomTargets(Object ingredient) { if (!(ingredient instanceof ItemStack)) { return Collections.emptyList(); } Rectangle rectangle = toRectangleBox(); - rectangle.height /= 2; + rectangle.width /= 6; return Lists.newArrayList(new IGhostIngredientHandler.Target<>() { @NotNull @@ -183,9 +230,11 @@ public void accept(@NotNull Object ingredient) { @SideOnly(Side.CLIENT) public boolean mouseWheelMove(int mouseX, int mouseY, int wheelDelta) { + // Only allow the amount scrolling if not stocking, as amount is useless for stocking + if (parentWidget.isStocking()) return false; IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); Rectangle rectangle = toRectangleBox(); - rectangle.height /= 2; + rectangle.width /= 6; if (slot.getConfig() == null || wheelDelta == 0 || !rectangle.contains(mouseX, mouseY)) { return false; } diff --git a/src/main/java/gregtech/common/gui/widget/appeng/slot/AmountSetSlot.java b/src/main/java/gregtech/common/gui/widget/appeng/slot/AmountSetSlot.java index ccec8521dd7..35063d5638b 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/slot/AmountSetSlot.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/slot/AmountSetSlot.java @@ -6,7 +6,7 @@ import gregtech.api.gui.widgets.TextFieldWidget2; import gregtech.api.util.Position; import gregtech.common.gui.widget.appeng.AEConfigWidget; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import net.minecraft.network.PacketBuffer; diff --git a/src/main/java/gregtech/common/gui/widget/orefilter/ItemOreFilterTestSlot.java b/src/main/java/gregtech/common/gui/widget/orefilter/ItemOreFilterTestSlot.java deleted file mode 100644 index b30a48cd25d..00000000000 --- a/src/main/java/gregtech/common/gui/widget/orefilter/ItemOreFilterTestSlot.java +++ /dev/null @@ -1,111 +0,0 @@ -package gregtech.common.gui.widget.orefilter; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.ingredient.IGhostIngredientTarget; -import gregtech.api.unification.OreDictUnifier; -import gregtech.api.util.Position; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.RenderHelper; -import net.minecraft.client.renderer.RenderItem; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import com.google.common.collect.Lists; -import mezz.jei.api.gui.IGhostIngredientHandler; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.awt.*; -import java.util.Collections; -import java.util.List; -import java.util.Set; - -public class ItemOreFilterTestSlot extends OreFilterTestSlot implements IGhostIngredientTarget { - - @NotNull - private ItemStack testStack = ItemStack.EMPTY; - - public ItemOreFilterTestSlot(int xPosition, int yPosition) { - super(xPosition, yPosition); - } - - @NotNull - public ItemStack getTestStack() { - return testStack; - } - - public void setTestStack(@NotNull ItemStack testStack) { - this.testStack = testStack; - updatePreview(); - } - - @Nullable - @Override - protected Set getTestCandidates() { - return this.testStack.isEmpty() ? null : OreDictUnifier.getOreDictionaryNames(this.testStack); - } - - @Override - protected void renderSlotContents(float partialTicks, IRenderContext context) { - Position pos = getPosition(); - if (!testStack.isEmpty()) { - GlStateManager.enableDepth(); - RenderHelper.enableGUIStandardItemLighting(); - GlStateManager.pushMatrix(); - RenderItem itemRender = Minecraft.getMinecraft().getRenderItem(); - itemRender.renderItemAndEffectIntoGUI(testStack, pos.x + 1, pos.y + 1); - itemRender.renderItemOverlayIntoGUI(Minecraft.getMinecraft().fontRenderer, testStack, pos.x + 1, pos.y + 1, - null); - GlStateManager.popMatrix(); - RenderHelper.disableStandardItemLighting(); - } - } - - @Override - @SideOnly(Side.CLIENT) - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (isMouseOverElement(mouseX, mouseY)) { - EntityPlayer player = Minecraft.getMinecraft().player; - putItem(player.inventory.getItemStack()); - return true; - } - return false; - } - - private void putItem(ItemStack stack) { - ItemStack testStack = getTestStack(); - if ((stack.isEmpty() ^ testStack.isEmpty()) || !testStack.isItemEqual(stack) || - !ItemStack.areItemStackTagsEqual(testStack, stack)) { - ItemStack copy = stack.copy(); - copy.setCount(1); - setTestStack(copy); - } - } - - @Override - public List> getPhantomTargets(Object ingredient) { - if (!(ingredient instanceof ItemStack)) { - return Collections.emptyList(); - } - Rectangle rectangle = toRectangleBox(); - return Lists.newArrayList(new IGhostIngredientHandler.Target() { - - @NotNull - @Override - public Rectangle getArea() { - return rectangle; - } - - @Override - public void accept(@NotNull Object ingredient) { - if (ingredient instanceof ItemStack) { - putItem((ItemStack) ingredient); - } - } - }); - } -} diff --git a/src/main/java/gregtech/common/gui/widget/orefilter/OreFilterTestSlot.java b/src/main/java/gregtech/common/gui/widget/orefilter/OreFilterTestSlot.java deleted file mode 100644 index fd81e80bcd7..00000000000 --- a/src/main/java/gregtech/common/gui/widget/orefilter/OreFilterTestSlot.java +++ /dev/null @@ -1,202 +0,0 @@ -package gregtech.common.gui.widget.orefilter; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.resources.TextureArea; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.util.LocalizationUtils; -import gregtech.api.util.Position; -import gregtech.api.util.function.BooleanConsumer; -import gregtech.api.util.oreglob.OreGlob; - -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.resources.I18n; -import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import it.unimi.dsi.fastutil.objects.Object2BooleanAVLTreeMap; -import it.unimi.dsi.fastutil.objects.Object2BooleanMap; -import it.unimi.dsi.fastutil.objects.Object2BooleanMaps; -import org.jetbrains.annotations.Nullable; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * @author brachy84 - */ -public abstract class OreFilterTestSlot extends WidgetGroup { - - private final ImageWidget match; - private final ImageWidget noMatch; - - @Nullable - private OreGlob glob; - private boolean expectedResult = true; - - @Nullable - private TextureArea slotIcon = GuiTextures.SLOT; - - @Nullable - private BooleanConsumer onMatchChange; - - private Object2BooleanMap testResult; - private MatchType matchType = MatchType.INVALID; - private boolean matchSuccess; - - private boolean initialized = false; - - private boolean matchAll; - - public OreFilterTestSlot(int xPosition, int yPosition) { - super(xPosition, yPosition, 18, 18); - this.match = new ImageWidget(18 - 5, -3, 9, 6, GuiTextures.ORE_FILTER_MATCH); - this.noMatch = new ImageWidget(18 - 5, -3, 7, 7, GuiTextures.ORE_FILTER_NO_MATCH); - addWidget(this.match); - addWidget(this.noMatch); - } - - @Override - public void initWidget() { - this.initialized = true; - updatePreview(); - super.initWidget(); - } - - public boolean isMatchSuccess() { - return matchSuccess; - } - - public OreFilterTestSlot setSlotIcon(@Nullable TextureArea slotIcon) { - this.slotIcon = slotIcon; - return this; - } - - public OreFilterTestSlot setExpectedResult(boolean expectedResult) { - this.expectedResult = expectedResult; - return this; - } - - public OreFilterTestSlot onMatchChange(@Nullable BooleanConsumer onMatchChange) { - this.onMatchChange = onMatchChange; - return this; - } - - public void setGlob(@Nullable OreGlob glob) { - if (this.glob == glob) return; - this.glob = glob; - updatePreview(); - } - - public void setMatchAll(boolean matchAll) { - if (this.matchAll == matchAll) return; - this.matchAll = matchAll; - updatePreview(); - } - - protected void updatePreview() { - if (!this.initialized) return; - Set oreDicts = getTestCandidates(); - if (oreDicts != null) { - OreGlob glob = this.glob; - if (oreDicts.isEmpty()) { - // no oredict entries - this.testResult = Object2BooleanMaps.singleton("", glob != null && glob.matches("")); - this.matchType = MatchType.NO_ORE_DICT_MATCH; - } else { - this.testResult = new Object2BooleanAVLTreeMap<>(); - for (String oreDict : oreDicts) { - boolean matches = glob != null && glob.matches(oreDict); - this.testResult.put(oreDict, matches); - } - this.matchType = MatchType.ORE_DICT_MATCH; - } - boolean success = this.matchAll; - for (var e : testResult.object2BooleanEntrySet()) { - boolean result = e.getBooleanValue(); - if (result == !this.matchAll) { - success = !this.matchAll; - break; - } - } - updateAndNotifyMatchSuccess(this.expectedResult == success); - this.match.setVisible(this.expectedResult == success); - this.noMatch.setVisible(this.expectedResult != success); - return; - } - this.testResult = Object2BooleanMaps.emptyMap(); - this.matchType = MatchType.INVALID; - updateAndNotifyMatchSuccess(false); - this.match.setVisible(false); - this.noMatch.setVisible(false); - } - - private void updateAndNotifyMatchSuccess(boolean newValue) { - if (this.matchSuccess == newValue) return; - this.matchSuccess = newValue; - if (this.onMatchChange != null) { - this.onMatchChange.apply(newValue); - } - } - - /** - * Get each test candidate for current state of test slot. An empty collection indicates that the match is for items - * without any ore dictionary entry. A {@code null} value indicates that the input state is invalid or empty. - * - * @return each test candidate for current state of test slot - */ - @Nullable - protected abstract Set getTestCandidates(); - - @Override - @SideOnly(Side.CLIENT) - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - Position pos = getPosition(); - if (this.slotIcon != null) { - this.slotIcon.draw(pos.x, pos.y, 18, 18); - } - - renderSlotContents(partialTicks, context); - - if (isActive() && isMouseOverElement(mouseX, mouseY)) { - GlStateManager.disableDepth(); - GlStateManager.colorMask(true, true, true, false); - drawSolidRect(getPosition().x + 1, getPosition().y + 1, 16, 16, 0x80ffffff); - GlStateManager.colorMask(true, true, true, true); - GlStateManager.enableBlend(); - } - - GlStateManager.disableDepth(); - super.drawInBackground(mouseX, mouseY, partialTicks, context); - GlStateManager.enableDepth(); - } - - protected abstract void renderSlotContents(float partialTicks, IRenderContext context); - - @Override - public void drawInForeground(int mouseX, int mouseY) { - if (isActive() && isMouseOverElement(mouseX, mouseY)) { - drawHoveringText(ItemStack.EMPTY, switch (this.matchType) { - case NO_ORE_DICT_MATCH -> Collections.singletonList(I18n.format(this.matchSuccess ? - "cover.ore_dictionary_filter.test_slot.no_oredict.matches" : - "cover.ore_dictionary_filter.test_slot.no_oredict.matches_not")); - case ORE_DICT_MATCH -> this.testResult.object2BooleanEntrySet().stream().map( - e -> I18n.format(e.getBooleanValue() ? - "cover.ore_dictionary_filter.test_slot.matches" : - "cover.ore_dictionary_filter.test_slot.matches_not", e.getKey())) - .collect(Collectors.toList()); - default -> Arrays.asList(LocalizationUtils.formatLines("cover.ore_dictionary_filter.test_slot.info")); - }, 300, mouseX, mouseY); - } - } - - private enum MatchType { - NO_ORE_DICT_MATCH, - ORE_DICT_MATCH, - INVALID - } -} diff --git a/src/main/java/gregtech/common/items/MetaItem1.java b/src/main/java/gregtech/common/items/MetaItem1.java index 9620ccaa60b..964f7d41cee 100644 --- a/src/main/java/gregtech/common/items/MetaItem1.java +++ b/src/main/java/gregtech/common/items/MetaItem1.java @@ -3,7 +3,11 @@ import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.capability.impl.CommonFluidFilters; -import gregtech.api.items.metaitem.*; +import gregtech.api.items.metaitem.ElectricStats; +import gregtech.api.items.metaitem.FilteredFluidStats; +import gregtech.api.items.metaitem.FoodStats; +import gregtech.api.items.metaitem.MusicDiscStats; +import gregtech.api.items.metaitem.StandardMetaItem; import gregtech.api.items.metaitem.stats.IItemComponent; import gregtech.api.items.metaitem.stats.IItemContainerItemProvider; import gregtech.api.items.metaitem.stats.ItemFluidContainer; @@ -22,8 +26,36 @@ import gregtech.api.util.RandomPotionEffect; import gregtech.common.ConfigHolder; import gregtech.common.blocks.MetaBlocks; +import gregtech.common.covers.filter.IFilter; +import gregtech.common.covers.filter.OreDictionaryItemFilter; +import gregtech.common.covers.filter.SimpleFluidFilter; +import gregtech.common.covers.filter.SimpleItemFilter; +import gregtech.common.covers.filter.SmartItemFilter; +import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.entities.GTBoatEntity.GTBoatType; -import gregtech.common.items.behaviors.*; +import gregtech.common.items.behaviors.ClipboardBehavior; +import gregtech.common.items.behaviors.ColorSprayBehaviour; +import gregtech.common.items.behaviors.DataItemBehavior; +import gregtech.common.items.behaviors.DoorBehavior; +import gregtech.common.items.behaviors.DynamiteBehaviour; +import gregtech.common.items.behaviors.FacadeItem; +import gregtech.common.items.behaviors.FertilizerBehavior; +import gregtech.common.items.behaviors.FoamSprayerBehavior; +import gregtech.common.items.behaviors.GTBoatBehavior; +import gregtech.common.items.behaviors.IntCircuitBehaviour; +import gregtech.common.items.behaviors.ItemMagnetBehavior; +import gregtech.common.items.behaviors.LighterBehaviour; +import gregtech.common.items.behaviors.MultiblockBuilderBehavior; +import gregtech.common.items.behaviors.NanoSaberBehavior; +import gregtech.common.items.behaviors.ProspectorScannerBehavior; +import gregtech.common.items.behaviors.TerminalBehaviour; +import gregtech.common.items.behaviors.TooltipBehavior; +import gregtech.common.items.behaviors.TricorderBehavior; +import gregtech.common.items.behaviors.TurbineRotorBehavior; +import gregtech.common.items.behaviors.filter.OreDictFilterUIManager; +import gregtech.common.items.behaviors.filter.SimpleFilterUIManager; +import gregtech.common.items.behaviors.filter.SimpleFluidFilterUIManager; +import gregtech.common.items.behaviors.filter.SmartFilterUIManager; import gregtech.common.items.behaviors.monitorplugin.AdvancedMonitorPluginBehavior; import gregtech.common.items.behaviors.monitorplugin.FakeGuiPluginBehavior; import gregtech.common.items.behaviors.monitorplugin.OnlinePicPluginBehavior; @@ -149,53 +181,53 @@ public void registerSubItems() { // out of registry order so it can reference the Empty Spray Can SPRAY_SOLVENT = addItem(60, "spray.solvent").setMaxStackSize(1) .addComponents(new ColorSprayBehaviour(SPRAY_EMPTY.getStackForm(), 1024, -1)) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); for (int i = 0; i < EnumDyeColor.values().length; i++) { SPRAY_CAN_DYES[i] = addItem(62 + i, "spray.can.dyes." + EnumDyeColor.values()[i].getName()) .setMaxStackSize(1) .addComponents(new ColorSprayBehaviour(SPRAY_EMPTY.getStackForm(), 512, i)) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); } // Fluid Cells: ID 78-88 FLUID_CELL = addItem(78, "fluid_cell") .addComponents(new FilteredFluidStats(1000, 1800, true, false, false, false, false), new ItemFluidContainer()) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_UNIVERSAL = addItem(79, "fluid_cell.universal") .addComponents(new FilteredFluidStats(1000, 1800, true, false, false, false, true), new ItemFluidContainer()) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_LARGE_STEEL = addItem(80, "large_fluid_cell.steel") .addComponents(new FilteredFluidStats(8000, Materials.Steel.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, false, false, false, true), new ItemFluidContainer()) .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Steel, M * 4))) // ingot * 4 - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_LARGE_ALUMINIUM = addItem(81, "large_fluid_cell.aluminium") .addComponents(new FilteredFluidStats(32000, Materials.Aluminium.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, false, false, false, true), new ItemFluidContainer()) .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Aluminium, M * 4))) // ingot * 4 - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_LARGE_STAINLESS_STEEL = addItem(82, "large_fluid_cell.stainless_steel") .addComponents(new FilteredFluidStats(64000, Materials.StainlessSteel.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, true, true, false, true), new ItemFluidContainer()) .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.StainlessSteel, M * 6))) // ingot * 6 - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_LARGE_TITANIUM = addItem(83, "large_fluid_cell.titanium") .addComponents(new FilteredFluidStats(128000, Materials.Titanium.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, true, false, false, true), new ItemFluidContainer()) .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Titanium, M * 6))) // ingot * 6 - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_LARGE_TUNGSTEN_STEEL = addItem(84, "large_fluid_cell.tungstensteel") .addComponents(new FilteredFluidStats(512000, @@ -203,36 +235,36 @@ public void registerSubItems() { true, false, false, true), new ItemFluidContainer()) .setMaxStackSize(32) .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.TungstenSteel, M * 8))) // ingot * 8 - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_GLASS_VIAL = addItem(85, "fluid_cell.glass_vial") .addComponents(new FilteredFluidStats(1000, 1200, false, true, false, false, true), new ItemFluidContainer()) .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Glass, M / 4))) // small dust - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); // Limited-Use Items: ID 89-95 TOOL_MATCHES = addItem(89, "tool.matches") .addComponents(new LighterBehaviour(false, false, false)) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); TOOL_MATCHBOX = addItem(90, "tool.matchbox") .addComponents(new LighterBehaviour(false, true, false, Items.PAPER, 16)) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); TOOL_LIGHTER_INVAR = addItem(91, "tool.lighter.invar") .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Invar, M * 2))) .addComponents(new LighterBehaviour(GTUtility.gregtechId("lighter_open"), true, true, true)) .addComponents(new FilteredFluidStats(100, true, CommonFluidFilters.LIGHTER_FUEL)) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); TOOL_LIGHTER_PLATINUM = addItem(92, "tool.lighter.platinum") .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Platinum, M * 2))) .addComponents(new LighterBehaviour(GTUtility.gregtechId("lighter_open"), true, true, true)) .addComponents(new FilteredFluidStats(1000, true, CommonFluidFilters.LIGHTER_FUEL)) .setMaxStackSize(1) .setRarity(EnumRarity.UNCOMMON) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BOTTLE_PURPLE_DRINK = addItem(93, "bottle.purple.drink").addComponents(new FoodStats(8, 0.2F, true, true, new ItemStack(Items.GLASS_BOTTLE), new RandomPotionEffect(MobEffects.HASTE, 800, 1, 90))); @@ -556,14 +588,18 @@ public void registerSubItems() { // Filters: ID 290-300 FLUID_FILTER = addItem(290, "fluid_filter") - .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Zinc, M * 2))); + .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Zinc, M * 2))) + .addComponents(new SimpleFluidFilterUIManager(), IFilter.factory(SimpleFluidFilter::new)); ITEM_FILTER = addItem(291, "item_filter") .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Zinc, M * 2), - new MaterialStack(Materials.Steel, M))); + new MaterialStack(Materials.Steel, M))) + .addComponents(new SimpleFilterUIManager(), IFilter.factory(SimpleItemFilter::new)); ORE_DICTIONARY_FILTER = addItem(292, "ore_dictionary_filter") - .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Zinc, M * 2))); + .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Zinc, M * 2))) + .addComponents(new OreDictFilterUIManager(), IFilter.factory(OreDictionaryItemFilter::new)); SMART_FILTER = addItem(293, "smart_item_filter") - .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Zinc, M * 3 / 2))); + .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Zinc, M * 3 / 2))) + .addComponents(new SmartFilterUIManager(), IFilter.factory(SmartItemFilter::new)); // Functional Covers: ID 301-330 COVER_MACHINE_CONTROLLER = addItem(301, "cover.controller"); @@ -737,69 +773,69 @@ public void registerSubItems() { // Usable Items: ID 460-490 DYNAMITE = addItem(460, "dynamite") .addComponents(new DynamiteBehaviour()) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); INTEGRATED_CIRCUIT = addItem(461, "circuit.integrated").addComponents(new IntCircuitBehaviour()) .setModelAmount(33); FOAM_SPRAYER = addItem(462, "foam_sprayer").addComponents(new FoamSprayerBehavior()) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); NANO_SABER = addItem(463, "nano_saber").addComponents(ElectricStats.createElectricItem(4_000_000L, GTValues.HV)) .addComponents(new NanoSaberBehavior()) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); NANO_SABER.getMetaItem().addPropertyOverride(NanoSaberBehavior.OVERRIDE_KEY_LOCATION, (stack, worldIn, entityIn) -> NanoSaberBehavior.isItemActive(stack) ? 1.0f : 0.0f); CLIPBOARD = addItem(464, "clipboard") .addComponents(new ClipboardBehavior()) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); TERMINAL = addItem(465, "terminal") .addComponents(new HardwareProvider(), new TerminalBehaviour()) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); PROSPECTOR_LV = addItem(466, "prospector.lv") .addComponents(ElectricStats.createElectricItem(100_000L, GTValues.LV), new ProspectorScannerBehavior(2, GTValues.LV)) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); PROSPECTOR_HV = addItem(467, "prospector.hv") .addComponents(ElectricStats.createElectricItem(1_600_000L, GTValues.HV), new ProspectorScannerBehavior(3, GTValues.HV)) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); PROSPECTOR_LUV = addItem(468, "prospector.luv") .addComponents(ElectricStats.createElectricItem(1_000_000_000L, GTValues.LuV), new ProspectorScannerBehavior(5, GTValues.LuV)) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); TRICORDER_SCANNER = addItem(469, "tricorder_scanner") .addComponents(ElectricStats.createElectricItem(100_000L, GTValues.MV), new TricorderBehavior(2)) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); DEBUG_SCANNER = addItem(470, "debug_scanner") .addComponents(new TricorderBehavior(3)) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); ITEM_MAGNET_LV = addItem(471, "item_magnet.lv") .addComponents(ElectricStats.createElectricItem(100_000L, GTValues.LV), new ItemMagnetBehavior(8)) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); ITEM_MAGNET_HV = addItem(472, "item_magnet.hv") .addComponents(ElectricStats.createElectricItem(1_600_000L, GTValues.HV), new ItemMagnetBehavior(32)) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); RUBBER_WOOD_BOAT = addItem(473, "rubber_wood_boat") .addComponents(new GTBoatBehavior(GTBoatType.RUBBER_WOOD_BOAT)).setMaxStackSize(1).setBurnValue(400); TREATED_WOOD_BOAT = addItem(474, "treated_wood_boat") .addComponents(new GTBoatBehavior(GTBoatType.TREATED_WOOD_BOAT)).setMaxStackSize(1).setBurnValue(400); RUBBER_WOOD_DOOR = addItem(475, "rubber_wood_door").addComponents(new DoorBehavior(MetaBlocks.RUBBER_WOOD_DOOR)) - .setBurnValue(200).setCreativeTabs(GregTechAPI.TAB_GREGTECH_DECORATIONS); + .setBurnValue(200).setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); TREATED_WOOD_DOOR = addItem(476, "treated_wood_door") .addComponents(new DoorBehavior(MetaBlocks.TREATED_WOOD_DOOR)).setBurnValue(200) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_DECORATIONS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); // Misc Crafting Items: ID 491-515 ENERGIUM_DUST = addItem(491, "energium_dust"); @@ -976,105 +1012,105 @@ public void registerSubItems() { // Batteries: 731-775 BATTERY_ULV_TANTALUM = addItem(731, "battery.re.ulv.tantalum") .addComponents(ElectricStats.createRechargeableBattery(1000, GTValues.ULV)) - .setUnificationData(OrePrefix.battery, Tier.ULV).setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setUnificationData(OrePrefix.battery, Tier.ULV).setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_LV_SODIUM = addItem(732, "battery.re.lv.sodium") .addComponents(ElectricStats.createRechargeableBattery(80000, GTValues.LV)) .setUnificationData(OrePrefix.battery, Tier.LV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_MV_SODIUM = addItem(733, "battery.re.mv.sodium") .addComponents(ElectricStats.createRechargeableBattery(360000, GTValues.MV)) .setUnificationData(OrePrefix.battery, Tier.MV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_HV_SODIUM = addItem(734, "battery.re.hv.sodium") .addComponents(ElectricStats.createRechargeableBattery(1200000, GTValues.HV)) .setUnificationData(OrePrefix.battery, Tier.HV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_LV_LITHIUM = addItem(735, "battery.re.lv.lithium") .addComponents(ElectricStats.createRechargeableBattery(120000, GTValues.LV)) .setUnificationData(OrePrefix.battery, Tier.LV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_MV_LITHIUM = addItem(736, "battery.re.mv.lithium") .addComponents(ElectricStats.createRechargeableBattery(420000, GTValues.MV)) .setUnificationData(OrePrefix.battery, Tier.MV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_HV_LITHIUM = addItem(737, "battery.re.hv.lithium") .addComponents(ElectricStats.createRechargeableBattery(1800000, GTValues.HV)) .setUnificationData(OrePrefix.battery, Tier.HV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_LV_CADMIUM = addItem(738, "battery.re.lv.cadmium") .addComponents(ElectricStats.createRechargeableBattery(100000, GTValues.LV)) .setUnificationData(OrePrefix.battery, Tier.LV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_MV_CADMIUM = addItem(739, "battery.re.mv.cadmium") .addComponents(ElectricStats.createRechargeableBattery(400000, GTValues.MV)) .setUnificationData(OrePrefix.battery, Tier.MV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_HV_CADMIUM = addItem(740, "battery.re.hv.cadmium") .addComponents(ElectricStats.createRechargeableBattery(1600000, GTValues.HV)) .setUnificationData(OrePrefix.battery, Tier.HV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); ENERGIUM_CRYSTAL = addItem(741, "energy_crystal") .addComponents(ElectricStats.createRechargeableBattery(6_400_000L, GTValues.HV)) .setUnificationData(OrePrefix.battery, Tier.HV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); LAPOTRON_CRYSTAL = addItem(742, "lapotron_crystal") .addComponents(ElectricStats.createRechargeableBattery(25_000_000L, GTValues.EV)) .setUnificationData(OrePrefix.battery, Tier.EV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_EV_VANADIUM = addItem(743, "battery.ev.vanadium") .addComponents(ElectricStats.createRechargeableBattery(10_240_000L, GTValues.EV)) .setUnificationData(OrePrefix.battery, Tier.EV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_IV_VANADIUM = addItem(744, "battery.iv.vanadium") .addComponents(ElectricStats.createRechargeableBattery(40_960_000L, GTValues.IV)) .setUnificationData(OrePrefix.battery, Tier.IV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_LUV_VANADIUM = addItem(745, "battery.luv.vanadium") .addComponents(ElectricStats.createRechargeableBattery(163_840_000L, GTValues.LuV)) .setUnificationData(OrePrefix.battery, Tier.LuV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_ZPM_NAQUADRIA = addItem(746, "battery.zpm.naquadria") .addComponents(ElectricStats.createRechargeableBattery(655_360_000L, GTValues.ZPM)) .setUnificationData(OrePrefix.battery, Tier.ZPM).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_UV_NAQUADRIA = addItem(747, "battery.uv.naquadria") .addComponents(ElectricStats.createRechargeableBattery(2_621_440_000L, GTValues.UV)) .setUnificationData(OrePrefix.battery, Tier.UV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); ENERGY_LAPOTRONIC_ORB = addItem(748, "energy.lapotronic_orb") .addComponents(ElectricStats.createRechargeableBattery(250_000_000L, GTValues.IV)) .setUnificationData(OrePrefix.battery, Tier.IV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); ENERGY_LAPOTRONIC_ORB_CLUSTER = addItem(749, "energy.lapotronic_orb_cluster") .addComponents(ElectricStats.createRechargeableBattery(1_000_000_000L, GTValues.LuV)) .setUnificationData(OrePrefix.battery, Tier.LuV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); ENERGY_MODULE = addItem(750, "energy.module") .addComponents( new IItemComponent[] { ElectricStats.createRechargeableBattery(4_000_000_000L, GTValues.ZPM) }) .setUnificationData(OrePrefix.battery, Tier.ZPM).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); ENERGY_CLUSTER = addItem(751, "energy.cluster") .addComponents( new IItemComponent[] { ElectricStats.createRechargeableBattery(20_000_000_000L, GTValues.UV) }) .setUnificationData(OrePrefix.battery, Tier.UV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); ZERO_POINT_MODULE = addItem(752, "zpm") .addComponents(ElectricStats.createBattery(2000000000000L, GTValues.ZPM, true)).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); ULTIMATE_BATTERY = addItem(753, "max.battery") .addComponents(ElectricStats.createRechargeableBattery(Long.MAX_VALUE, GTValues.UHV)) .setUnificationData(OrePrefix.battery, Tier.UHV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); POWER_THRUSTER = addItem(776, "power_thruster").setRarity(EnumRarity.UNCOMMON); POWER_THRUSTER_ADVANCED = addItem(777, "power_thruster_advanced").setRarity(EnumRarity.RARE); @@ -1109,5 +1145,7 @@ public void registerSubItems() { MULTIBLOCK_BUILDER = addItem(1004, "tool.multiblock_builder").addComponents(new MultiblockBuilderBehavior()) .setMaxStackSize(1); + + ANODE_BASKET = addItem(1005, "basket.anode"); } } diff --git a/src/main/java/gregtech/common/items/MetaItems.java b/src/main/java/gregtech/common/items/MetaItems.java index c2ecd0089e0..0050257395c 100644 --- a/src/main/java/gregtech/common/items/MetaItems.java +++ b/src/main/java/gregtech/common/items/MetaItems.java @@ -564,6 +564,8 @@ private MetaItems() {} public static MetaItem.MetaValueItem MULTIBLOCK_BUILDER; + public static MetaItem.MetaValueItem ANODE_BASKET; + private static final List orePrefixes = new ArrayList<>(); static { @@ -609,6 +611,11 @@ private MetaItems() {} orePrefixes.add(OrePrefix.fuelRod); orePrefixes.add(OrePrefix.fuelRodDepleted); orePrefixes.add(OrePrefix.fuelRodHotDepleted); + orePrefixes.add(OrePrefix.fuelPellet); + orePrefixes.add(OrePrefix.fuelPelletDepleted); + orePrefixes.add(OrePrefix.dustSpentFuel); + orePrefixes.add(OrePrefix.dustBredFuel); + orePrefixes.add(OrePrefix.dustFissionByproduct); } public static void init() { diff --git a/src/main/java/gregtech/common/items/ToolItems.java b/src/main/java/gregtech/common/items/ToolItems.java index 05e2453846b..5545387ef7c 100644 --- a/src/main/java/gregtech/common/items/ToolItems.java +++ b/src/main/java/gregtech/common/items/ToolItems.java @@ -55,6 +55,9 @@ public final class ToolItems { public static IGTTool BUZZSAW; public static IGTTool SCREWDRIVER_LV; public static IGTTool PLUNGER; + public static IGTTool WIRECUTTER_LV; + public static IGTTool WIRECUTTER_HV; + public static IGTTool WIRECUTTER_IV; private ToolItems() {/**/} @@ -319,6 +322,36 @@ public static void init() { .oreDict(ToolOreDict.toolPlunger) .toolClasses(ToolClasses.PLUNGER) .markerItem(() -> ToolHelper.getAndSetToolData(PLUNGER, Materials.Rubber, 255, 1, 4F, 0F))); + WIRECUTTER_LV = register(ItemGTTool.Builder.of(GTValues.MODID, "wire_cutter_lv") + .toolStats(b -> b.blockBreaking().crafting().damagePerCraftingAction(4) + .efficiencyMultiplier(2.0F) + .attackDamage(-1.0F).attackSpeed(-2.4F) + .brokenStack(ToolHelper.SUPPLY_POWER_UNIT_LV)) + .sound(GTSoundEvents.WIRECUTTER_TOOL, true) + .oreDict(ToolOreDict.toolWireCutter) + .secondaryOreDicts("craftingToolWireCutter") + .toolClasses(ToolClasses.WIRE_CUTTER) + .electric(GTValues.LV)); + WIRECUTTER_HV = register(ItemGTTool.Builder.of(GTValues.MODID, "wire_cutter_hv") + .toolStats(b -> b.blockBreaking().crafting().damagePerCraftingAction(4) + .efficiencyMultiplier(3.0F) + .attackDamage(-1.0F).attackSpeed(-2.4F) + .brokenStack(ToolHelper.SUPPLY_POWER_UNIT_LV)) + .sound(GTSoundEvents.WIRECUTTER_TOOL, true) + .oreDict(ToolOreDict.toolWireCutter) + .secondaryOreDicts("craftingToolWireCutter") + .toolClasses(ToolClasses.WIRE_CUTTER) + .electric(GTValues.HV)); + WIRECUTTER_IV = register(ItemGTTool.Builder.of(GTValues.MODID, "wire_cutter_iv") + .toolStats(b -> b.blockBreaking().crafting().damagePerCraftingAction(4) + .efficiencyMultiplier(4.0F) + .attackDamage(-1.0F).attackSpeed(-2.4F) + .brokenStack(ToolHelper.SUPPLY_POWER_UNIT_LV)) + .sound(GTSoundEvents.WIRECUTTER_TOOL, true) + .oreDict(ToolOreDict.toolWireCutter) + .secondaryOreDicts("craftingToolWireCutter") + .toolClasses(ToolClasses.WIRE_CUTTER) + .electric(GTValues.IV)); } public static IGTTool register(@NotNull ToolBuilder builder) { diff --git a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java index 6cda26f8ce5..69bf9e9640c 100644 --- a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java @@ -1,11 +1,11 @@ package gregtech.common.items.behaviors; -import gregtech.api.GTValues; import gregtech.api.items.metaitem.stats.IItemDurabilityManager; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.pipenet.tile.IPipeTile; import gregtech.api.util.GradientUtil; +import gregtech.api.util.Mods; import gregtech.core.sound.GTSoundEvents; import net.minecraft.block.Block; @@ -23,7 +23,6 @@ import net.minecraft.util.*; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraftforge.fml.common.Loader; import appeng.api.util.AEColor; import appeng.tile.networking.TileCableBus; @@ -93,7 +92,7 @@ private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos world.setBlockState(pos, newBlockState); return true; } - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { TileEntity te = world.getTileEntity(pos); if (te instanceof TileCableBus) { TileCableBus cable = (TileCableBus) te; @@ -146,7 +145,7 @@ private static boolean tryStripBlockColor(EntityPlayer player, World world, Bloc } // AE2 cable special case - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { if (te instanceof TileCableBus) { TileCableBus cable = (TileCableBus) te; // do not try to strip color if it is already colorless diff --git a/src/main/java/gregtech/common/items/behaviors/ItemMagnetBehavior.java b/src/main/java/gregtech/common/items/behaviors/ItemMagnetBehavior.java index 15a3ebc2599..f5ce22ba925 100644 --- a/src/main/java/gregtech/common/items/behaviors/ItemMagnetBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/ItemMagnetBehavior.java @@ -5,6 +5,7 @@ import gregtech.api.capability.IElectricItem; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.metaitem.stats.IItemBehaviour; +import gregtech.api.util.Mods; import gregtech.integration.baubles.BaublesModule; import net.minecraft.client.resources.I18n; @@ -26,7 +27,6 @@ import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.item.ItemTossEvent; import net.minecraftforge.event.entity.player.PlayerPickupXpEvent; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import org.jetbrains.annotations.NotNull; @@ -162,7 +162,7 @@ public void onItemToss(@NotNull ItemTossEvent event) { if (event.getPlayer() == null) return; IInventory inventory = event.getPlayer().inventory; - if (Loader.isModLoaded(GTValues.MODID_BAUBLES)) { + if (Mods.Baubles.isModLoaded()) { inventory = BaublesModule.getBaublesWrappedInventory(event.getPlayer()); } diff --git a/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java b/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java index 6dd8d6742c7..bdff9524d0d 100644 --- a/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java @@ -7,6 +7,7 @@ import gregtech.api.unification.material.Materials; import gregtech.api.util.GTUtility; import gregtech.api.util.GradientUtil; +import gregtech.common.blocks.explosive.BlockGTExplosive; import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.block.Block; @@ -120,8 +121,13 @@ public EnumActionResult onItemUseFirst(@NotNull EntityPlayer player, @NotNull Wo SoundCategory.PLAYERS, 1.0F, GTValues.RNG.nextFloat() * 0.4F + 0.8F); IBlockState blockState = world.getBlockState(pos); Block block = blockState.getBlock(); - if (block instanceof BlockTNT) { - ((BlockTNT) block).explode(world, pos, blockState.withProperty(BlockTNT.EXPLODE, true), player); + if (block instanceof BlockTNT tnt) { + tnt.explode(world, pos, blockState.withProperty(BlockTNT.EXPLODE, true), player); + world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11); + return EnumActionResult.SUCCESS; + } + if (block instanceof BlockGTExplosive powderbarrel) { + powderbarrel.explode(world, pos, player); world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11); return EnumActionResult.SUCCESS; } diff --git a/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java b/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java index 344b97231d3..82a2f46c854 100644 --- a/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java @@ -63,7 +63,9 @@ public EnumActionResult onItemUseFirst(EntityPlayer player, World world, BlockPo List info = getScannerInfo(player, world, pos); if (player.isCreative() || drainEnergy(player.getHeldItem(hand), energyCost, true)) { - drainEnergy(player.getHeldItem(hand), energyCost, false); + if (!player.isCreative()) { + drainEnergy(player.getHeldItem(hand), energyCost, false); + } for (ITextComponent line : info) { player.sendMessage(line); } diff --git a/src/main/java/gregtech/common/items/behaviors/filter/BaseFilterUIManager.java b/src/main/java/gregtech/common/items/behaviors/filter/BaseFilterUIManager.java new file mode 100644 index 00000000000..64fa36e7118 --- /dev/null +++ b/src/main/java/gregtech/common/items/behaviors/filter/BaseFilterUIManager.java @@ -0,0 +1,55 @@ +package gregtech.common.items.behaviors.filter; + +import gregtech.api.cover.CoverWithUI; +import gregtech.api.items.gui.ItemUIFactory; +import gregtech.api.items.metaitem.stats.IItemBehaviour; +import gregtech.api.mui.GTGuiTheme; +import gregtech.api.mui.GTGuis; +import gregtech.api.mui.factory.MetaItemGuiFactory; + +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; +import net.minecraft.world.World; + +import com.cleanroommc.modularui.factory.HandGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; + +import java.util.List; + +public abstract class BaseFilterUIManager implements IItemBehaviour, ItemUIFactory { + + @Override + public final ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { + ItemStack heldItem = player.getHeldItem(hand); + if (!world.isRemote && !player.isSneaking()) { + MetaItemGuiFactory.open(player, hand); + } + if (player.isSneaking() && heldItem.hasTagCompound()) { + heldItem.setTagCompound(null); + } + return ActionResult.newResult(EnumActionResult.SUCCESS, heldItem); + } + + @Override + public abstract ModularPanel buildUI(HandGuiData guiData, GuiSyncManager guiSyncManager); + + protected final ModularPanel createBasePanel(ItemStack stack) { + return GTGuis.createPanel(stack, 176, 188) + .child(CoverWithUI.createTitleRow(stack)); + } + + @Override + public GTGuiTheme getUITheme() { + return GTGuiTheme.COVER; + } + + @Override + public void addInformation(ItemStack itemStack, List lines) { + lines.add(I18n.format("behaviour.filter_ui_manager")); + } +} diff --git a/src/main/java/gregtech/common/items/behaviors/filter/OreDictFilterUIManager.java b/src/main/java/gregtech/common/items/behaviors/filter/OreDictFilterUIManager.java new file mode 100644 index 00000000000..2656db4758a --- /dev/null +++ b/src/main/java/gregtech/common/items/behaviors/filter/OreDictFilterUIManager.java @@ -0,0 +1,19 @@ +package gregtech.common.items.behaviors.filter; + +import gregtech.common.covers.filter.BaseFilter; + +import com.cleanroommc.modularui.factory.HandGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; + +public class OreDictFilterUIManager extends BaseFilterUIManager { + + @Override + public ModularPanel buildUI(HandGuiData guiData, GuiSyncManager guiSyncManager) { + var filter = BaseFilter.getFilterFromStack(guiData.getUsedItemStack()); + return createBasePanel(filter.getContainerStack()).height(160) + .child(filter.createWidgets(guiSyncManager).top(22).margin(7, 0)) + .child(SlotGroupWidget.playerInventory().bottom(7).left(7)); + } +} diff --git a/src/main/java/gregtech/common/items/behaviors/filter/SimpleFilterUIManager.java b/src/main/java/gregtech/common/items/behaviors/filter/SimpleFilterUIManager.java new file mode 100644 index 00000000000..2c3b5da39cd --- /dev/null +++ b/src/main/java/gregtech/common/items/behaviors/filter/SimpleFilterUIManager.java @@ -0,0 +1,19 @@ +package gregtech.common.items.behaviors.filter; + +import gregtech.common.covers.filter.BaseFilter; + +import com.cleanroommc.modularui.factory.HandGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; + +public class SimpleFilterUIManager extends BaseFilterUIManager { + + @Override + public ModularPanel buildUI(HandGuiData guiData, GuiSyncManager guiSyncManager) { + var filter = BaseFilter.getFilterFromStack(guiData.getUsedItemStack()); + return createBasePanel(filter.getContainerStack()).padding(4).height(166) + .child(filter.createWidgets(guiSyncManager).top(22).left(7)) + .child(SlotGroupWidget.playerInventory().left(7)); + } +} diff --git a/src/main/java/gregtech/common/items/behaviors/filter/SimpleFluidFilterUIManager.java b/src/main/java/gregtech/common/items/behaviors/filter/SimpleFluidFilterUIManager.java new file mode 100644 index 00000000000..df66b9c5bca --- /dev/null +++ b/src/main/java/gregtech/common/items/behaviors/filter/SimpleFluidFilterUIManager.java @@ -0,0 +1,19 @@ +package gregtech.common.items.behaviors.filter; + +import gregtech.common.covers.filter.BaseFilter; + +import com.cleanroommc.modularui.factory.HandGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; + +public class SimpleFluidFilterUIManager extends BaseFilterUIManager { + + @Override + public ModularPanel buildUI(HandGuiData guiData, GuiSyncManager guiSyncManager) { + var filter = BaseFilter.getFilterFromStack(guiData.getUsedItemStack()); + return createBasePanel(filter.getContainerStack()).padding(4).height(166) + .child(filter.createWidgets(guiSyncManager).top(22).left(7)) + .child(SlotGroupWidget.playerInventory().left(7)); + } +} diff --git a/src/main/java/gregtech/common/items/behaviors/filter/SmartFilterUIManager.java b/src/main/java/gregtech/common/items/behaviors/filter/SmartFilterUIManager.java new file mode 100644 index 00000000000..033fbb2e109 --- /dev/null +++ b/src/main/java/gregtech/common/items/behaviors/filter/SmartFilterUIManager.java @@ -0,0 +1,19 @@ +package gregtech.common.items.behaviors.filter; + +import gregtech.common.covers.filter.BaseFilter; + +import com.cleanroommc.modularui.factory.HandGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; + +public class SmartFilterUIManager extends BaseFilterUIManager { + + @Override + public ModularPanel buildUI(HandGuiData guiData, GuiSyncManager guiSyncManager) { + var filter = BaseFilter.getFilterFromStack(guiData.getUsedItemStack()); + return createBasePanel(filter.getContainerStack()).height(166) + .child(filter.createWidgets(guiSyncManager).left(7).top(22)) + .child(SlotGroupWidget.playerInventory().bottom(7).left(7)); + } +} diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index c530a2cb2c6..6451c39964f 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -13,6 +13,7 @@ import gregtech.api.unification.material.Materials; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; @@ -102,6 +103,8 @@ import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEInputHatch; import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEOutputBus; import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEOutputHatch; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEStockingBus; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEStockingHatch; import gregtech.common.metatileentities.multi.multiblockpart.hpca.MetaTileEntityHPCABridge; import gregtech.common.metatileentities.multi.multiblockpart.hpca.MetaTileEntityHPCAComputation; import gregtech.common.metatileentities.multi.multiblockpart.hpca.MetaTileEntityHPCACooler; @@ -136,7 +139,6 @@ import gregtech.integration.jei.multiblock.MultiblockInfoCategory; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.common.Loader; import java.util.HashMap; import java.util.Map; @@ -147,91 +149,65 @@ public class MetaTileEntities { + // spotless:off + // HULLS public static final MetaTileEntityHull[] HULL = new MetaTileEntityHull[GTValues.V.length]; - public static final MetaTileEntityTransformer[] TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - 1]; // no - // MAX - public static final MetaTileEntityTransformer[] HI_AMP_TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - - 1]; /// no MAX - public static final MetaTileEntityTransformer[] POWER_TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - - 1]; // no MAX + public static final MetaTileEntityTransformer[] TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - 1]; // no MAX + public static final MetaTileEntityTransformer[] HI_AMP_TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - 1]; /// no MAX + public static final MetaTileEntityTransformer[] POWER_TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - 1]; // no MAX public static final MetaTileEntityDiode[] DIODES = new MetaTileEntityDiode[GTValues.V.length]; public static final MetaTileEntityBatteryBuffer[][] BATTERY_BUFFER = new MetaTileEntityBatteryBuffer[3][GTValues.V.length]; public static final MetaTileEntityCharger[] CHARGER = new MetaTileEntityCharger[GTValues.V.length]; + // SIMPLE MACHINES SECTION - public static final SimpleMachineMetaTileEntity[] ELECTRIC_FURNACE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] MACERATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ALLOY_SMELTER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ARC_FURNACE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ASSEMBLER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] AUTOCLAVE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] ELECTRIC_FURNACE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] MACERATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ALLOY_SMELTER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ARC_FURNACE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ASSEMBLER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] AUTOCLAVE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] BENDER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] BREWERY = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] CANNER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] CENTRIFUGE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] CHEMICAL_BATH = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] CHEMICAL_REACTOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] COMPRESSOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] CENTRIFUGE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] CHEMICAL_BATH = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] CHEMICAL_REACTOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] COMPRESSOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] CUTTER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] DISTILLERY = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ELECTROLYZER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ELECTROMAGNETIC_SEPARATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] EXTRACTOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] DISTILLERY = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ELECTROLYZER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ELECTROMAGNETIC_SEPARATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] EXTRACTOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] EXTRUDER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] FERMENTER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] FLUID_HEATER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] FLUID_SOLIDIFIER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] FORGE_HAMMER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] FORMING_PRESS = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] FERMENTER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] FLUID_HEATER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] FLUID_SOLIDIFIER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] FORGE_HAMMER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] FORMING_PRESS = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] LATHE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] MIXER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] ORE_WASHER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] ORE_WASHER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] PACKER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] UNPACKER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] POLARIZER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] LASER_ENGRAVER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] POLARIZER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] LASER_ENGRAVER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] SIFTER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] THERMAL_CENTRIFUGE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] THERMAL_CENTRIFUGE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] WIREMILL = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] CIRCUIT_ASSEMBLER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - // TODO Replication system - // public static final SimpleMachineMetaTileEntity[] MASS_FABRICATOR = new - // SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - // public static final SimpleMachineMetaTileEntity[] REPLICATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - // - 1]; + public static final SimpleMachineMetaTileEntity[] CIRCUIT_ASSEMBLER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + // public static final SimpleMachineMetaTileEntity[] MASS_FABRICATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; // TODO Replication + // public static final SimpleMachineMetaTileEntity[] REPLICATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; // TODO Replication public static final SimpleMachineMetaTileEntity[] SCANNER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] GAS_COLLECTOR = new MetaTileEntityGasCollector[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] GAS_COLLECTOR = new MetaTileEntityGasCollector[GTValues.V.length - 1]; public static final MetaTileEntityRockBreaker[] ROCK_BREAKER = new MetaTileEntityRockBreaker[GTValues.V.length - 1]; public static final MetaTileEntityMiner[] MINER = new MetaTileEntityMiner[GTValues.V.length - 1]; + // GENERATORS SECTION public static final SimpleGeneratorMetaTileEntity[] COMBUSTION_GENERATOR = new SimpleGeneratorMetaTileEntity[4]; public static final SimpleGeneratorMetaTileEntity[] STEAM_TURBINE = new SimpleGeneratorMetaTileEntity[4]; public static final SimpleGeneratorMetaTileEntity[] GAS_TURBINE = new SimpleGeneratorMetaTileEntity[4]; + // MULTIBLOCK PARTS SECTION public static final MetaTileEntityItemBus[] ITEM_IMPORT_BUS = new MetaTileEntityItemBus[GTValues.UHV + 1]; // ULV-UHV public static final MetaTileEntityItemBus[] ITEM_EXPORT_BUS = new MetaTileEntityItemBus[GTValues.UHV + 1]; @@ -242,39 +218,14 @@ public class MetaTileEntities { public static final MetaTileEntityMultiFluidHatch[] QUADRUPLE_EXPORT_HATCH = new MetaTileEntityMultiFluidHatch[6]; // EV-UHV public static final MetaTileEntityMultiFluidHatch[] NONUPLE_EXPORT_HATCH = new MetaTileEntityMultiFluidHatch[6]; // EV-UHV public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH = new MetaTileEntityEnergyHatch[GTValues.V.length]; - public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_4A = new MetaTileEntityEnergyHatch[6]; // EV, IV, - // LuV, - // ZPM, - // UV, UHV - public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_16A = new MetaTileEntityEnergyHatch[5]; // IV, - // LuV, - // ZPM, - // UV, - // UHV + public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_4A = new MetaTileEntityEnergyHatch[6]; // EV, IV, LuV, ZPM, UV, UHV + public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_16A = new MetaTileEntityEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH = new MetaTileEntityEnergyHatch[GTValues.V.length]; - public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_4A = new MetaTileEntityEnergyHatch[6]; // EV, - // IV, - // LuV, - // ZPM, - // UV, - // UHV - public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_16A = new MetaTileEntityEnergyHatch[5]; // IV, - // LuV, - // ZPM, - // UV, - // UHV - public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_INPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[5]; // IV, - // LuV, - // ZPM, - // UV, - // UHV - public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_OUTPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[5]; // IV, - // LuV, - // ZPM, - // UV, - // UHV - public static final MetaTileEntityRotorHolder[] ROTOR_HOLDER = new MetaTileEntityRotorHolder[6]; // HV, EV, IV, LuV, - // ZPM, UV + public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_4A = new MetaTileEntityEnergyHatch[6]; // EV, IV, LuV, ZPM, UV, UHV + public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_16A = new MetaTileEntityEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV + public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_INPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV + public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_OUTPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV + public static final MetaTileEntityRotorHolder[] ROTOR_HOLDER = new MetaTileEntityRotorHolder[6]; // HV, EV, IV, LuV, ZPM, UV public static final MetaTileEntityMufflerHatch[] MUFFLER_HATCH = new MetaTileEntityMufflerHatch[GTValues.UV + 1]; // LV-UV public static final MetaTileEntityFusionReactor[] FUSION_REACTOR = new MetaTileEntityFusionReactor[3]; public static final MetaTileEntityQuantumChest[] QUANTUM_CHEST = new MetaTileEntityQuantumChest[10]; @@ -313,6 +264,7 @@ public class MetaTileEntities { // Used for addons if they wish to disable certain tiers of machines private static final Map MID_TIER = new HashMap<>(); private static final Map HIGH_TIER = new HashMap<>(); + // STEAM AGE SECTION public static SteamCoalBoiler STEAM_BOILER_COAL_BRONZE; public static SteamCoalBoiler STEAM_BOILER_COAL_STEEL; @@ -346,6 +298,7 @@ public class MetaTileEntities { public static MetaTileEntityMaintenanceHatch CONFIGURABLE_MAINTENANCE_HATCH; public static MetaTileEntityAutoMaintenanceHatch AUTO_MAINTENANCE_HATCH; public static MetaTileEntityCleaningMaintenanceHatch CLEANING_MAINTENANCE_HATCH; + // MULTIBLOCKS SECTION public static MetaTileEntityPrimitiveBlastFurnace PRIMITIVE_BLAST_FURNACE; public static MetaTileEntityCokeOven COKE_OVEN; @@ -392,6 +345,7 @@ public class MetaTileEntities { public static MetaTileEntityCoolantImportHatch COOLANT_INPUT; public static MetaTileEntityCoolantExportHatch COOLANT_OUTPUT; public static MetaTileEntityControlRodPort CONTROL_ROD; + public static MetaTileEntityControlRodPort CONTROL_ROD_MODERATED; public static MetaTileEntitySpentFuelPool SPENT_FUEL_POOL; public static MetaTileEntityGasCentrifuge GAS_CENTRIFUGE; @@ -415,6 +369,7 @@ public class MetaTileEntities { public static MetaTileEntityCrate STAINLESS_STEEL_CRATE; public static MetaTileEntityCrate TITANIUM_CRATE; public static MetaTileEntityCrate TUNGSTENSTEEL_CRATE; + // MISC MACHINES SECTION public static MetaTileEntityWorkbench WORKBENCH; public static MetaTileEntityCreativeEnergy CREATIVE_ENERGY; @@ -427,12 +382,16 @@ public class MetaTileEntities { public static MetaTileEntity ITEM_EXPORT_BUS_ME; public static MetaTileEntity FLUID_IMPORT_HATCH_ME; public static MetaTileEntity ITEM_IMPORT_BUS_ME; + public static MetaTileEntity STOCKING_BUS_ME; + public static MetaTileEntity STOCKING_HATCH_ME; public static MetaTileEntityLDItemEndpoint LONG_DIST_ITEM_ENDPOINT; public static MetaTileEntityLDFluidEndpoint LONG_DIST_FLUID_ENDPOINT; public static MetaTileEntityAlarm ALARM; public static MetaTileEntityConverter[][] ENERGY_CONVERTER = new MetaTileEntityConverter[4][GTValues.V.length]; + //spotless:on + public static void init() { GTLog.logger.info("Registering MetaTileEntities"); @@ -1190,8 +1149,8 @@ public static void init() { // IDs 1730-1744 are taken by 4A <-> 16A Transformers. They are grouped with other transformers for // organization. - // ME Hatches, IDs 1745-1748 - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + // ME Hatches, IDs 1745-1748, 1752-1756 + if (Mods.AppliedEnergistics2.isModLoaded()) { FLUID_EXPORT_HATCH_ME = registerMetaTileEntity(1745, new MetaTileEntityMEOutputHatch(gregtechId("me_export_fluid_hatch"))); ITEM_EXPORT_BUS_ME = registerMetaTileEntity(1746, @@ -1200,6 +1159,13 @@ public static void init() { new MetaTileEntityMEInputHatch(gregtechId("me_import_fluid_hatch"))); ITEM_IMPORT_BUS_ME = registerMetaTileEntity(1748, new MetaTileEntityMEInputBus(gregtechId("me_import_item_bus"))); + STOCKING_BUS_ME = registerMetaTileEntity(1752, + new MetaTileEntityMEStockingBus(gregtechId("me_stocking_item_bus"))); + STOCKING_HATCH_ME = registerMetaTileEntity(1753, + new MetaTileEntityMEStockingHatch(gregtechId("me_stocking_fluid_hatch"))); + // 1754: Crafting Input Bus + // 1755: Crafting Input Buffer + // 1756: Crafting Input Slave } LONG_DIST_ITEM_ENDPOINT = registerMetaTileEntity(1749, @@ -1210,15 +1176,17 @@ public static void init() { // Alarm, ID 1751 ALARM = registerMetaTileEntity(1751, new MetaTileEntityAlarm(gregtechId("alarm"))); - // Nuclear hatches, 1752-1756 - FUEL_ROD_INPUT = registerMetaTileEntity(1752, + // Nuclear hatches, 1800-1805 + FUEL_ROD_INPUT = registerMetaTileEntity(1800, new MetaTileEntityFuelRodImportHatch(gregtechId("fuel_rod_input"))); - FUEL_ROD_OUTPUT = registerMetaTileEntity(1753, + FUEL_ROD_OUTPUT = registerMetaTileEntity(1801, new MetaTileEntityFuelRodExportHatch(gregtechId("fuel_rod_output"))); - COOLANT_INPUT = registerMetaTileEntity(1754, new MetaTileEntityCoolantImportHatch(gregtechId("coolant_input"))); - COOLANT_OUTPUT = registerMetaTileEntity(1755, + COOLANT_INPUT = registerMetaTileEntity(1802, new MetaTileEntityCoolantImportHatch(gregtechId("coolant_input"))); + COOLANT_OUTPUT = registerMetaTileEntity(1803, new MetaTileEntityCoolantExportHatch(gregtechId("coolant_output"))); - CONTROL_ROD = registerMetaTileEntity(1756, new MetaTileEntityControlRodPort(gregtechId("control_rod"), false)); + CONTROL_ROD = registerMetaTileEntity(1804, new MetaTileEntityControlRodPort(gregtechId("control_rod"), false)); + CONTROL_ROD_MODERATED = registerMetaTileEntity(1805, + new MetaTileEntityControlRodPort(gregtechId("control_rod_moderated"), true)); // Multi-Fluid Hatches, IDs 1190, 1191, 1205, 1206, 1780-1799 // EV hatches separate because of old names/IDs @@ -1322,7 +1290,7 @@ public static T registerMetaTileEntity(int id, T samp if (sampleMetaTileEntity instanceof IMultiblockAbilityPart abilityPart) { MultiblockAbility.registerMultiblockAbility(abilityPart.getAbility(), sampleMetaTileEntity); } - if (sampleMetaTileEntity instanceof MultiblockControllerBase && Loader.isModLoaded(GTValues.MODID_JEI)) { + if (sampleMetaTileEntity instanceof MultiblockControllerBase && Mods.JustEnoughItems.isModLoaded()) { if (((MultiblockControllerBase) sampleMetaTileEntity).shouldShowInJei()) { MultiblockInfoCategory.registerMultiblock((MultiblockControllerBase) sampleMetaTileEntity); } diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityAlarm.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityAlarm.java index cadf9768286..67751f893e9 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityAlarm.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityAlarm.java @@ -76,15 +76,17 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { return ModularUI.builder(GuiTextures.BACKGROUND, 240, 86) .widget(new LabelWidget(10, 5, getMetaFullName())) .widget(new SelectorWidget(10, 20, 220, 20, - getSounds().stream().map((event) -> event.getSoundName().toString()) + getSounds().stream().map(this::getNameOfSound) .collect(Collectors.toList()), - 0x555555, () -> this.selectedSound.getSoundName().toString(), true).setOnChanged((v) -> { - GregTechAPI.soundManager.stopTileSound(getPos()); + 0x555555, () -> getNameOfSound(this.selectedSound), true).setOnChanged((v) -> { + if (this.getWorld().isRemote) + GregTechAPI.soundManager.stopTileSound(getPos()); SoundEvent newSound = SoundEvent.REGISTRY.getObject(new ResourceLocation(v)); if (this.selectedSound != newSound) { this.selectedSound = SoundEvent.REGISTRY.getObject(new ResourceLocation(v)); this.writeCustomData(GregtechDataCodes.UPDATE_SOUND, - (writer) -> writer.writeResourceLocation(this.selectedSound.getSoundName())); + (writer) -> writer + .writeResourceLocation(getResourceLocationOfSound(this.selectedSound))); } })) .widget(new ImageWidget(10, 54, 220, 20, GuiTextures.DISPLAY)) @@ -168,14 +170,14 @@ public void receiveInitialSyncData(PacketBuffer buf) { public void writeInitialSyncData(PacketBuffer buf) { super.writeInitialSyncData(buf); buf.writeBoolean(this.isActive); - buf.writeResourceLocation(this.selectedSound.getSoundName()); + buf.writeResourceLocation(getResourceLocationOfSound(this.selectedSound)); buf.writeInt(this.radius); } @Override public NBTTagCompound writeToNBT(NBTTagCompound data) { data.setBoolean("isActive", this.isActive); - data.setString("selectedSound", this.selectedSound.getSoundName().toString()); + data.setString("selectedSound", getNameOfSound(this.selectedSound)); data.setInteger("radius", this.radius); return super.writeToNBT(data); } @@ -187,4 +189,12 @@ public void readFromNBT(NBTTagCompound data) { this.radius = data.getInteger("radius"); super.readFromNBT(data); } + + public String getNameOfSound(SoundEvent sound) { + return getResourceLocationOfSound(sound).toString(); + } + + public ResourceLocation getResourceLocationOfSound(SoundEvent sound) { + return SoundEvent.REGISTRY.getNameForObject(sound); + } } diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityGasCollector.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityGasCollector.java index 77bdd3b0485..8300d2b5fc9 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityGasCollector.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityGasCollector.java @@ -1,24 +1,17 @@ package gregtech.common.metatileentities.electric; -import gregtech.api.capability.IEnergyContainer; import gregtech.api.capability.impl.RecipeLogicEnergy; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.SimpleMachineMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.RecipeMaps; -import gregtech.api.recipes.recipeproperties.GasCollectorDimensionProperty; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import net.minecraft.util.ResourceLocation; -import it.unimi.dsi.fastutil.ints.IntLists; -import org.jetbrains.annotations.NotNull; - import java.util.function.Function; -import java.util.function.Supplier; public class MetaTileEntityGasCollector extends SimpleMachineMetaTileEntity { @@ -36,28 +29,6 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { @Override protected RecipeLogicEnergy createWorkable(RecipeMap recipeMap) { - return new GasCollectorRecipeLogic(this, recipeMap, () -> energyContainer); - } - - protected boolean checkRecipe(@NotNull Recipe recipe) { - for (int dimension : recipe.getProperty(GasCollectorDimensionProperty.getInstance(), IntLists.EMPTY_LIST)) { - if (dimension == this.getWorld().provider.getDimension()) { - return true; - } - } - return false; - } - - private static class GasCollectorRecipeLogic extends RecipeLogicEnergy { - - public GasCollectorRecipeLogic(MetaTileEntity metaTileEntity, RecipeMap recipeMap, - Supplier energyContainer) { - super(metaTileEntity, recipeMap, energyContainer); - } - - @Override - public boolean checkRecipe(@NotNull Recipe recipe) { - return ((MetaTileEntityGasCollector) metaTileEntity).checkRecipe(recipe) && super.checkRecipe(recipe); - } + return new RecipeLogicEnergy(this, recipeMap, () -> energyContainer); } } diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java index 926f7386174..f953dff1b4e 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java @@ -9,6 +9,7 @@ import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.IPassthroughHatch; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.util.Mods; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.PipelineUtil; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockPart; @@ -19,7 +20,6 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional; import appeng.api.util.AECableType; @@ -89,21 +89,21 @@ public void addInformation(ItemStack stack, @Nullable World player, List @Override public void update() { super.update(); - if (isFirstTick() && Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (isFirstTick() && Mods.AppliedEnergistics2.isModLoaded()) { if (getProxy() != null) getProxy().onReady(); } } @NotNull @Override - @Optional.Method(modid = GTValues.MODID_APPENG) + @Optional.Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AECableType getCableConnectionType(@NotNull AEPartLocation part) { return AECableType.SMART; } @Nullable @Override - @Optional.Method(modid = GTValues.MODID_APPENG) + @Optional.Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AENetworkProxy getProxy() { if (gridProxy == null && getHolder() instanceof MetaTileEntityHolder) { gridProxy = new AENetworkProxy((MetaTileEntityHolder) getHolder(), "proxy", getStackForm(), true); diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityItemCollector.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityItemCollector.java index d49fb520bf1..1128819ff6d 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityItemCollector.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityItemCollector.java @@ -144,7 +144,7 @@ protected void moveItemsInEffectRange() { double distanceX = (areaCenterPos.getX() + 0.5) - entityItem.posX; double distanceZ = (areaCenterPos.getZ() + 0.5) - entityItem.posZ; double distance = MathHelper.sqrt(distanceX * distanceX + distanceZ * distanceZ); - if (!itemFilter.testItemStack(entityItem.getItem())) { + if (!itemFilter.test(entityItem.getItem())) { continue; } if (distance >= 0.7) { diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityWorldAccelerator.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityWorldAccelerator.java index 09c851400ce..861cdd4c9e9 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityWorldAccelerator.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityWorldAccelerator.java @@ -29,7 +29,6 @@ import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.fml.common.FMLCommonHandler; import codechicken.lib.raytracer.CuboidRayTraceResult; import codechicken.lib.render.CCRenderState; @@ -57,7 +56,6 @@ public class MetaTileEntityWorldAccelerator extends TieredMetaTileEntity impleme private boolean tileMode = false; private boolean isActive = false; private boolean isPaused = false; - private int lastTick; // Variables for Random Tick mode optimization // limit = ((tier - min) / (max - min)) * 2^tier @@ -67,7 +65,6 @@ public class MetaTileEntityWorldAccelerator extends TieredMetaTileEntity impleme public MetaTileEntityWorldAccelerator(ResourceLocation metaTileEntityId, int tier) { super(metaTileEntityId, tier); - this.lastTick = 0; this.speed = (int) Math.pow(2, tier); this.successLimit = SUCCESS_LIMITS[tier - 1]; initializeInventory(); @@ -124,6 +121,11 @@ protected long getTEModeAmperage() { return 6L; } + @Override + public boolean allowTickAcceleration() { + return false; + } + @Override public void update() { super.update(); @@ -131,15 +133,11 @@ public void update() { if (isPaused && isActive) { setActive(false); } else if (!isPaused) { - int currentTick = FMLCommonHandler.instance().getMinecraftServerInstance().getTickCounter(); - if (currentTick != lastTick) { // Prevent other tick accelerators from accelerating us - lastTick = currentTick; - boolean wasSuccessful = isTEMode() ? handleTEMode() : handleRandomTickMode(); - if (!wasSuccessful) { - setActive(false); - } else if (!isActive) { - setActive(true); - } + boolean wasSuccessful = isTEMode() ? handleTEMode() : handleRandomTickMode(); + if (!wasSuccessful) { + setActive(false); + } else if (!isActive) { + setActive(true); } } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityFissionReactor.java b/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityFissionReactor.java index 783182542bc..62f9d19cbfb 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityFissionReactor.java +++ b/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityFissionReactor.java @@ -1,10 +1,17 @@ package gregtech.common.metatileentities.multi; import gregtech.api.GregTechAPI; -import gregtech.api.capability.ICoolantHandler; +import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.IFuelRodHandler; import gregtech.api.capability.ILockableHandler; +import gregtech.api.capability.IMaintenanceHatch; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.ModularUI; import gregtech.api.gui.Widget; +import gregtech.api.gui.widgets.AdvancedTextWidget; +import gregtech.api.gui.widgets.SliderWidget; +import gregtech.api.gui.widgets.ToggleButtonWidget; +import gregtech.api.gui.widgets.UpdatedSliderWidget; import gregtech.api.metatileentity.IDataInfoProvider; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; @@ -19,6 +26,8 @@ import gregtech.api.nuclear.fission.components.ReactorComponent; import gregtech.api.pattern.BlockPattern; import gregtech.api.pattern.FactoryBlockPattern; +import gregtech.api.pattern.MultiblockShapeInfo; +import gregtech.api.pattern.PatternMatchContext; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.Materials; @@ -26,18 +35,27 @@ import gregtech.api.unification.material.properties.PropertyKey; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.MaterialStack; +import gregtech.api.util.GTStringUtils; +import gregtech.api.util.GTUtility; import gregtech.api.util.RelativeDirection; import gregtech.api.util.TextFormattingUtil; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; +import gregtech.common.ConfigHolder; import gregtech.common.blocks.BlockFissionCasing; import gregtech.common.blocks.MetaBlocks; +import gregtech.common.metatileentities.MetaTileEntities; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityControlRodPort; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityCoolantExportHatch; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityCoolantImportHatch; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityFuelRodImportHatch; +import gregtech.core.sound.GTSoundEvents; +import gregtech.core.sound.internal.SoundManager; import net.minecraft.block.state.IBlockState; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; @@ -50,12 +68,15 @@ import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.IVertexOperation; +import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; - -import static gregtech.api.gui.widgets.AdvancedTextWidget.withButton; +import java.util.function.Consumer; public class MetaTileEntityFissionReactor extends MultiblockWithDisplayBase implements IDataInfoProvider { @@ -64,9 +85,19 @@ public class MetaTileEntityFissionReactor extends MultiblockWithDisplayBase impl private int heightTop; private int heightBottom; private int height; - private int flowRate; + private int flowRate = 1; + private double controlRodInsertionValue; private LockingState lockingState = LockingState.UNLOCKED; + private double temperature; + private double maxTemperature; + private double pressure; + private double maxPressure; + private double power; + private double maxPower; + private double kEff; + private NBTTagCompound transientData; + public MetaTileEntityFissionReactor(ResourceLocation metaTileEntityId) { super(metaTileEntityId); } @@ -76,21 +107,108 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { return new MetaTileEntityFissionReactor(metaTileEntityId); } - public boolean isBlockEdge(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing direction) { - return this.isBlockEdge(world, pos, direction, 1); + @Override + protected ModularUI.Builder createUITemplate(EntityPlayer entityPlayer) { + ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 206, 236).shouldColor(false) + .widget(new ToggleButtonWidget(10, 10, 18, 18, this::isLocked, this::tryLocking)) + .widget(new AdvancedTextWidget(35, 14, getLockingStateText(), getLockedTextColor())) + .widget(new UpdatedSliderWidget("gregtech.gui.fission.control_rod_insertion", 10, 30, 165, + 18, 0.0f, 1.0f, + (float) controlRodInsertionValue, this::setControlRodInsertionValue, + () -> (float) this.controlRodInsertionValue) { + + @Override + protected String getDisplayString() { + return I18n.format("gregtech.gui.fission.control_rod_insertion", + String.format("%.2f%%", this.getSliderValue() * 100)); + } + }) + .widget(new SliderWidget("gregtech.gui.fission.coolant_flow", 10, 50, 165, 18, 0.0f, 16000.f, flowRate, + this::setFlowRate)); + builder.widget(new AdvancedTextWidget(10, 90, getStatsText(), 0x2020D0)); + builder.bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT, 22, 148); + return builder; + } + + private void setFlowRate(float flowrate) { + this.flowRate = (int) flowrate; + if (flowRate < 1) flowRate = 1; + } + + private void setControlRodInsertionValue(float value) { + this.controlRodInsertionValue = value; + if (lockingState == LockingState.LOCKED && fissionReactor != null) + fissionReactor.updateControlRodInsertion(controlRodInsertionValue); + } + + private boolean isLocked() { + return lockingState == LockingState.LOCKED; + } + + private int getLockedTextColor() { + if (lockingState == LockingState.LOCKED) + return 0x00A000; + if (lockingState == LockingState.INVALID_COMPONENT) + return 0xC08000; + if (lockingState == LockingState.UNLOCKED) + return 0x0050D0; + if (lockingState == LockingState.MISSING_INPUTS) + return getWorld().getWorldTime() % 2 == 0 ? 0xA00000 : 0xC08000; + return 0x000000; + } + + private void tryLocking(boolean lock) { + if (!isStructureFormed()) + return; + + if (lock) + lockAndPrepareReactor(); + else + unlockAll(); + } + + private Consumer> getLockingStateText() { + return (list) -> { + list.add( + new TextComponentTranslation("gregtech.gui.fission.lock." + lockingState.toString().toLowerCase())); + }; + } + + private Consumer> getStatsText() { + return (list) -> { + list.add(new TextComponentTranslation("gregtech.gui.fission.temperature", + String.format("%.1f", this.temperature) + " / " + String.format("%.1f", this.maxTemperature))); + list.add(new TextComponentTranslation("gregtech.gui.fission.pressure", + String.format("%.0f", this.pressure) + " / " + String.format("%.0f", this.maxPressure))); + list.add(new TextComponentTranslation("gregtech.gui.fission.power", String.format("%.1f", this.power), + String.format("%.1f", this.maxPower))); + list.add(new TextComponentTranslation("gregtech.gui.fission.k_eff", String.format("%.4f", this.kEff))); + }; } public boolean isBlockEdge(@NotNull World world, @NotNull BlockPos pos, @NotNull EnumFacing direction, int steps) { - return world.getBlockState(pos.offset(direction, steps)).getBlock() != MetaBlocks.FISSION_CASING; + BlockPos test = pos.offset(direction, steps); + + if (world.getBlockState(test).getBlock() == MetaBlocks.FISSION_CASING) { + return false; + } + + MetaTileEntity potentialTile = GTUtility.getMetaTileEntity(world, test); + if (potentialTile == null) { + return true; + } + + return !(potentialTile instanceof IFissionReactorHatch || potentialTile instanceof IMaintenanceHatch); } /** - * Uses the layer the controller is on to determine the diameter of the structure + * Uses the upper layer to determine the diameter of the structure */ - public int findDiameter() { + public int findDiameter(int heightAbove) { int i = 1; while (i <= 15) { - if (this.isBlockEdge(this.getWorld(), this.getPos(), this.getFrontFacing().getOpposite(), i)) + if (this.isBlockEdge(this.getWorld(), this.getPos().up(heightAbove), this.getFrontFacing().getOpposite(), + i)) break; i++; } @@ -111,56 +229,66 @@ public int findHeight(boolean top) { } @Override - protected void updateFormedValid() { + public void updateFormedValid() { // Take in coolant, take in fuel, update reactor, output steam - if (this.lockingState == LockingState.LOCKED) { + if (!this.getWorld().isRemote && this.getOffsetTimer() % 20 == 0) { + if (this.lockingState == LockingState.LOCKED) { + // Coolant handling + this.fissionReactor.makeCoolantFlow(flowRate); - // Coolant handling - for (ICoolantHandler coolantImport : this.getAbilities(MultiblockAbility.IMPORT_COOLANT)) { - // TODO: Move into coolant import hatch - this.fissionReactor.heatRemoved += coolantImport.getCoolant().getProperty(PropertyKey.COOLANT) - .getCoolingFactor() * this.flowRate; - coolantImport.getFluidTank().drain(this.flowRate, true); - } - for (ICoolantHandler coolantExport : this.getAbilities(MultiblockAbility.EXPORT_COOLANT)) { - // TODO: Move into coolant export hatch - coolantExport.getFluidTank().fill(coolantExport.getCoolant().getProperty(PropertyKey.COOLANT) - .getHotHPCoolant().getFluid(this.flowRate), true); - } + // Fuel handling + if (this.fissionReactor.fuelDepletion == 1.) { + boolean canWork = true; + for (IFuelRodHandler fuelImport : this.getAbilities(MultiblockAbility.IMPORT_FUEL_ROD)) { + canWork &= !fuelImport.getStackHandler().extractItem(0, 1, true).isEmpty(); + // We still need to know if the output is blocked, even if the recipe doesn't start yet + canWork &= ((MetaTileEntityFuelRodImportHatch) fuelImport).getExportHatch(this.height - 1) + .getExportItems().insertItem(0, + OreDictUnifier.get(OrePrefix.fuelRodHotDepleted, fuelImport.getFuel()), true) + .isEmpty(); + } - // Fuel handling - if (this.fissionReactor.fuelDepletion == 1.) { - boolean hasEmpty = false; - for (IFuelRodHandler fuelImport : this.getAbilities(MultiblockAbility.IMPORT_FUEL_ROD)) { - if (fuelImport.getStackHandler().extractItem(0, 1, true).isEmpty()) hasEmpty = true; - } - if (!hasEmpty) { for (IFuelRodHandler fuelImport : this.getAbilities(MultiblockAbility.IMPORT_FUEL_ROD)) { - fuelImport.getStackHandler().extractItem(0, 1, false); + if (fissionReactor.needsOutput) { + ((MetaTileEntityFuelRodImportHatch) fuelImport).getExportHatch(this.height - 1) + .getExportItems().insertItem(0, + OreDictUnifier.get(OrePrefix.fuelRodHotDepleted, fuelImport.getFuel()), + false); + } + if (canWork) { + fuelImport.getStackHandler().extractItem(0, 1, false); + this.fissionReactor.fuelMass += 60; + fissionReactor.needsOutput = true; + } } + this.fissionReactor.fuelDepletion = 0.; + } } - this.updateReactorState(); + this.syncReactorStats(); + if (this.fissionReactor.checkForMeltdown()) { + SoundManager.getInstance().startTileSound(GTSoundEvents.SUS_RECORD.getSoundName(), 1, this.getPos()); + } if (this.fissionReactor.checkForMeltdown()) { this.performMeltdownEffects(); } - if (this.fissionReactor.checkForExplosion()) { this.performPrimaryExplosion(); - if (this.fissionReactor.checkForSecondaryExplosion()) { - this.performSecondaryExplosion(); + if (this.fissionReactor.accumulatedHydrogen > 1) { + this.performSecondaryExplosion(fissionReactor.accumulatedHydrogen); } } } } protected void performMeltdownEffects() { + this.unlockAll(); BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(this.getPos()); - pos = pos.move(this.getFrontFacing().getOpposite(), Math.floorDiv(diameter, 2)); + pos = pos.move(this.getFrontFacing().getOpposite(), diameter / 2); for (int i = 0; i <= this.heightBottom; i++) { this.getWorld().setBlockState(pos.add(0, -i, 0), Materials.Corium.getFluid().getBlock().getDefaultState()); this.getWorld().setBlockState(pos.add(1, -i, 0), Materials.Corium.getFluid().getBlock().getDefaultState()); @@ -172,19 +300,17 @@ protected void performMeltdownEffects() { } protected void performPrimaryExplosion() { + this.unlockAll(); BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(this.getPos()); - pos = pos.move(this.getFrontFacing().getOpposite(), Math.floorDiv(diameter, 2)); + pos = pos.move(this.getFrontFacing().getOpposite(), diameter / 2); this.getWorld().createExplosion(null, pos.getX(), pos.getY() + heightTop, pos.getZ(), 4.f, true); } - protected void performSecondaryExplosion() { + protected void performSecondaryExplosion(double accumulatedHydrogen) { BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(this.getPos()); - pos = pos.move(this.getFrontFacing().getOpposite(), Math.floorDiv(diameter, 2)); - this.getWorld().newExplosion(null, pos.getX(), pos.getY() + heightTop + 3, pos.getZ(), 10.f, true, true); - } - - public boolean updateStructureDimensions() { - return false; + pos = pos.move(this.getFrontFacing().getOpposite(), diameter / 2); + this.getWorld().newExplosion(null, pos.getX(), pos.getY() + heightTop + 3, pos.getZ(), + 4.f + (float) Math.log(accumulatedHydrogen), true, true); } @NotNull @@ -195,7 +321,7 @@ protected BlockPattern createStructurePattern() { this.height = heightTop + heightBottom + 1; - this.diameter = this.getWorld() != null ? Math.max(Math.min(this.findDiameter(), 15), 5) : 5; + this.diameter = this.getWorld() != null ? Math.max(Math.min(this.findDiameter(heightTop), 15), 5) : 5; int radius = this.diameter % 2 == 0 ? (int) Math.floor(this.diameter / 2.f) : Math.round((this.diameter - 1) / 2.f); @@ -228,15 +354,25 @@ protected BlockPattern createStructurePattern() { interiorSlice[this.diameter - 1] = interiorSlice[0] = interiorSlice[0].replace('A', 'B'); for (int i = 1; i < this.diameter - 1; i++) { for (int j = 0; j < this.diameter; j++) { - if (j > 0 && j + 1 < this.diameter) { - if ((interiorSlice[i].charAt(j) == 'A' && interiorSlice[i].charAt(j - 1) == ' ') || - (interiorSlice[i].charAt(j) == 'A' && interiorSlice[i].charAt(j + 1) == ' ')) { - interiorSlice[i] = interiorSlice[i].substring(0, j) + 'B' + interiorSlice[i].substring(j + 1); - } - } else if (j == 0 && interiorSlice[i].charAt(0) == 'A') { - interiorSlice[i] = 'B' + interiorSlice[i].substring(1); - } else if (j == this.diameter - 1 && interiorSlice[i].charAt(this.diameter - 1) == 'A') { - interiorSlice[i] = interiorSlice[i].substring(0, this.diameter - 1) + 'B'; + if (interiorSlice[i].charAt(j) != 'A') { + continue; + } + + // The integer division is fine here, since we want an odd diameter (say, 5) to go to the middle value + // (2 in this case) + int outerI = i + (int) Math.signum(i - (diameter / 2)); + + if (Math.pow(outerI - Math.floor(this.diameter / 2.), 2) + + Math.pow(j - Math.floor(this.diameter / 2.), 2) > + Math.pow(radius + 0.5f, 2)) { + interiorSlice[i] = GTStringUtils.replace(interiorSlice[i], j, 'B'); + } + + int outerJ = j + (int) Math.signum(j - (diameter / 2)); + if (Math.pow(i - Math.floor(this.diameter / 2.), 2) + + Math.pow(outerJ - Math.floor(this.diameter / 2.), 2) > + Math.pow(radius + 0.5f, 2)) { + interiorSlice[i] = GTStringUtils.replace(interiorSlice[i], j, 'B'); } } } @@ -259,7 +395,8 @@ protected BlockPattern createStructurePattern() { .aisle(topSlice) .where('S', selfPredicate()) // A for interior components - .where('A', states(getFuelChannelState(), getControlRodChannelState(), getCoolantChannelState())) + .where('A', + states(getFuelChannelState(), getControlRodChannelState(), getCoolantChannelState()).or(air())) // I for the inputs on the top .where('I', states(getVesselState()).or(abilities(MultiblockAbility.IMPORT_COOLANT, @@ -272,8 +409,7 @@ protected BlockPattern createStructurePattern() { .where('B', states(getVesselState()) .or(abilities(MultiblockAbility.MAINTENANCE_HATCH).setMinGlobalLimited(1) - .setMaxGlobalLimited(1)) - .or(abilities(MultiblockAbility.EXPORT_FLUIDS).setMinGlobalLimited(1))) + .setMaxGlobalLimited(1))) .where(' ', any()) .build(); } @@ -311,11 +447,6 @@ IBlockState getCoolantChannelState() { return MetaBlocks.FISSION_CASING.getState(BlockFissionCasing.FissionCasingType.COOLANT_CHANNEL); } - @NotNull - IBlockState getTopHatchState() { - return MetaBlocks.FISSION_CASING.getState(BlockFissionCasing.FissionCasingType.COOLANT_CHANNEL); - } - @Override public ICubeRenderer getBaseTexture(IMultiblockPart sourcePart) { return Textures.FISSION_REACTOR_TEXTURE; @@ -325,7 +456,20 @@ public ICubeRenderer getBaseTexture(IMultiblockPart sourcePart) { @NotNull @Override protected ICubeRenderer getFrontOverlay() { - return Textures.ASSEMBLER_OVERLAY; + return Textures.FISSION_REACTOR_OVERLAY; + } + + @Override + public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { + super.renderMetaTileEntity(renderState, translation, pipeline); + + this.getFrontOverlay().renderOrientedState(renderState, translation, pipeline, getFrontFacing(), isActive(), + true); + } + + @Override + public boolean isActive() { + return isStructureFormed() && lockingState == LockingState.LOCKED; } @Override @@ -348,16 +492,38 @@ public void checkStructurePattern() { public void invalidateStructure() { if (lockingState == LockingState.LOCKED) { this.unlockAll(); + this.fissionReactor = null; + this.temperature = 273; + this.maxTemperature = 273; + this.power = 0; + this.kEff = 0; + this.pressure = 0; + this.maxPressure = 0; + this.maxPower = 0; } super.invalidateStructure(); } + @Override + protected void formStructure(PatternMatchContext context) { + super.formStructure(context); + if (fissionReactor == null) { + fissionReactor = new FissionReactor(this.diameter - 2, this.height - 2, controlRodInsertionValue); + } + } + @Override public NBTTagCompound writeToNBT(NBTTagCompound data) { data.setInteger("diameter", this.diameter); data.setInteger("heightTop", this.heightTop); data.setInteger("heightBottom", this.heightBottom); + data.setInteger("flowRate", this.flowRate); + data.setDouble("controlRodInsertion", this.controlRodInsertionValue); data.setBoolean("locked", this.lockingState == LockingState.LOCKED); + if (fissionReactor != null) { + data.setTag("transientData", this.fissionReactor.serializeNBT()); + } + return super.writeToNBT(data); } @@ -367,10 +533,15 @@ public void readFromNBT(NBTTagCompound data) { this.diameter = data.getInteger("diameter"); this.heightTop = data.getInteger("heightTop"); this.heightBottom = data.getInteger("heightBottom"); + this.flowRate = data.getInteger("flowRate"); + this.controlRodInsertionValue = data.getDouble("controlRodInsertion"); this.height = this.heightTop + this.heightBottom + 1; if (data.getBoolean("locked")) { this.lockingState = LockingState.SHOULD_LOCK; - } ; + } + if (data.hasKey("transientData")) { + transientData = data.getCompoundTag("transientData"); + } } @Override @@ -379,8 +550,14 @@ public void writeInitialSyncData(PacketBuffer buf) { buf.writeInt(this.diameter); buf.writeInt(this.heightTop); buf.writeInt(this.heightBottom); + buf.writeInt(this.flowRate); + buf.writeDouble(this.controlRodInsertionValue); if (this.lockingState == LockingState.SHOULD_LOCK) { + if (fissionReactor == null) { + this.fissionReactor = new FissionReactor(this.diameter - 2, this.height - 2, controlRodInsertionValue); + } this.lockAndPrepareReactor(); + this.fissionReactor.deserializeNBT(transientData); } buf.writeBoolean(this.lockingState == LockingState.LOCKED); } @@ -391,37 +568,59 @@ public void receiveInitialSyncData(PacketBuffer buf) { this.diameter = buf.readInt(); this.heightTop = buf.readInt(); this.heightBottom = buf.readInt(); + this.flowRate = buf.readInt(); + this.controlRodInsertionValue = buf.readDouble(); if (buf.readBoolean()) { this.lockingState = LockingState.LOCKED; } } + // TODO: Abstract the stats into its own class + public void syncReactorStats() { + this.temperature = this.fissionReactor.temperature; + this.maxTemperature = this.fissionReactor.maxTemperature; + this.pressure = this.fissionReactor.pressure; + this.maxPressure = this.fissionReactor.maxPressure; + this.power = this.fissionReactor.power; + this.maxPower = this.fissionReactor.maxPower; + this.kEff = this.fissionReactor.kEff; + this.controlRodInsertionValue = this.fissionReactor.controlRodInsertion; + writeCustomData(GregtechDataCodes.SYNC_REACTOR_STATS, (packetBuffer -> { + packetBuffer.writeDouble(this.fissionReactor.temperature); + packetBuffer.writeDouble(this.fissionReactor.maxTemperature); + packetBuffer.writeDouble(this.fissionReactor.pressure); + packetBuffer.writeDouble(this.fissionReactor.maxPressure); + packetBuffer.writeDouble(this.fissionReactor.power); + packetBuffer.writeDouble(this.fissionReactor.maxPower); + packetBuffer.writeDouble(this.fissionReactor.kEff); + packetBuffer.writeDouble(this.fissionReactor.controlRodInsertion); + })); + } + + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + + if (dataId == GregtechDataCodes.SYNC_REACTOR_STATS) { + this.temperature = buf.readDouble(); + this.maxTemperature = buf.readDouble(); + this.pressure = buf.readDouble(); + this.maxPressure = buf.readDouble(); + this.power = buf.readDouble(); + this.maxPower = buf.readDouble(); + this.kEff = buf.readDouble(); + this.controlRodInsertionValue = buf.readDouble(); + } else if (dataId == GregtechDataCodes.SYNC_LOCKING_STATE) { + this.lockingState = buf.readEnumValue(LockingState.class); + } + } + @Override protected void addDisplayText(List textList) { super.addDisplayText(textList); ITextComponent toggleText = null; if (!this.isStructureFormed()) toggleText = new TextComponentTranslation("gregtech.multiblock.fission_reactor.structure_incomplete"); - else { - switch (this.lockingState) { - case LOCKED: - toggleText = new TextComponentTranslation("gregtech.multiblock.fission_reactor.turn_off"); - toggleText.appendSibling(withButton(new TextComponentString(" [Toggle Off]"), "turn_off")); - break; - case UNLOCKED: - toggleText = new TextComponentTranslation("gregtech.multiblock.fission_reactor.turn_on"); - toggleText.appendSibling(withButton(new TextComponentString(" [Toggle On]"), "turn_on")); - break; - case INVALID_COMPONENT: - toggleText = new TextComponentTranslation("gregtech.multiblock.fission_reactor.invalid_component"); - toggleText.appendSibling(withButton(new TextComponentString(" [Retry]"), "turn_on")); - break; - case MISSING_INPUTS: - toggleText = new TextComponentTranslation("gregtech.multiblock.fission_reactor.missing_inputs"); - toggleText.appendSibling(withButton(new TextComponentString(" [Retry]"), "turn_on")); - break; - } - } textList.add(toggleText); } @@ -429,26 +628,29 @@ protected void lockAll() { for (ILockableHandler handler : this.getAbilities(MultiblockAbility.IMPORT_COOLANT)) { handler.setLock(true); } - for (ILockableHandler handler : this.getAbilities(MultiblockAbility.EXPORT_COOLANT)) { - handler.setLock(true); - } for (ILockableHandler handler : this.getAbilities(MultiblockAbility.IMPORT_FUEL_ROD)) { handler.setLock(true); } } protected void unlockAll() { - for (ILockableHandler handler : this.getAbilities(MultiblockAbility.IMPORT_COOLANT)) { - handler.setLock(false); + // Deal with any unused fuel rods + for (IFuelRodHandler fuelImport : this.getAbilities(MultiblockAbility.IMPORT_FUEL_ROD)) { + if (fissionReactor.needsOutput) { + ((MetaTileEntityFuelRodImportHatch) fuelImport).getExportHatch(this.height - 1) + .getExportItems().insertItem(0, + OreDictUnifier.get(OrePrefix.fuelRodHotDepleted, fuelImport.getFuel()), false); + } } - for (ILockableHandler handler : this.getAbilities(MultiblockAbility.EXPORT_COOLANT)) { + fissionReactor.needsOutput = false; + for (ILockableHandler handler : this.getAbilities(MultiblockAbility.IMPORT_COOLANT)) { handler.setLock(false); } for (ILockableHandler handler : this.getAbilities(MultiblockAbility.IMPORT_FUEL_ROD)) { handler.setLock(false); } - this.fissionReactor = null; - this.lockingState = LockingState.UNLOCKED; + this.fissionReactor.turnOff(); + setLockingState(LockingState.UNLOCKED); } @Override @@ -460,15 +662,15 @@ protected void handleDisplayClick(String componentData, Widget.ClickData clickDa private void lockAndPrepareReactor() { this.lockAll(); - fissionReactor = new FissionReactor(this.diameter - 2); - int radius = (int) this.diameter / 2; // This is the floor of the radius, the actual radius is 0.5 blocks - // larger + int radius = this.diameter / 2; // This is the floor of the radius, the actual radius is 0.5 blocks + // larger BlockPos reactorOrigin = this.getPos().offset(this.frontFacing.getOpposite(), radius); radius--; + boolean foundFuel = false; for (int i = -radius; i <= radius; i++) { for (int j = -radius; j <= radius; j++) { if (Math.pow(i, 2) + Math.pow(j, 2) > Math.pow(radius, 2) + radius) // (radius + .5)^2 = - // radius^2 + radius + .25 + // radius^2 + radius + .25 continue; BlockPos currentPos = reactorOrigin.offset(this.frontFacing.rotateYCCW(), i) .offset(this.frontFacing.getOpposite(), j).offset(EnumFacing.UP, height - 2); @@ -483,7 +685,6 @@ private void lockAndPrepareReactor() { Material mat = GregTechAPI.materialManager.getMaterial( coolantIn.getImportFluids().getTankAt(0).getFluid().getFluid().getName()); if (mat != null && mat.hasProperty(PropertyKey.COOLANT)) { - component = new CoolantChannel(0, 0, mat); coolantIn.setCoolant(mat); BlockPos exportHatchPos = currentPos.offset(EnumFacing.DOWN, height - 1); if (getWorld().getTileEntity( @@ -491,6 +692,7 @@ private void lockAndPrepareReactor() { MetaTileEntity coolantOutMTE = coolantOutCandidate.getMetaTileEntity(); if (coolantOutMTE instanceof MetaTileEntityCoolantExportHatch coolantOut) { coolantOut.setCoolant(mat); + component = new CoolantChannel(100050, 0, mat, 1000, coolantIn, coolantOut); } } } @@ -501,12 +703,15 @@ private void lockAndPrepareReactor() { MaterialStack mat = OreDictUnifier.getMaterial(lockedFuel); if (mat != null && OreDictUnifier.getPrefix(lockedFuel) == OrePrefix.fuelRod) { FissionFuelProperty property = mat.material.getProperty(PropertyKey.FISSION_FUEL); - if (property != null) - component = new FuelRod(0, 1, property, 3); + if (property != null) { + component = new FuelRod(property.getMaxTemperature(), 1, property, 650, 3); + fuelIn.setFuel(mat.material); + foundFuel = true; + } } } } else if (mte instanceof MetaTileEntityControlRodPort controlIn) { - component = new ControlRod(0, true, 1, controlIn.getInsertionAmount()); + component = new ControlRod(100000, controlIn.hasModeratorTip(), 1, 800); } else { foundPort = false; } @@ -516,30 +721,41 @@ private void lockAndPrepareReactor() { fissionReactor.addComponent(component, i + radius, j + radius); } else { // Invalid component located this.unlockAll(); - fissionReactor = null; - this.lockingState = LockingState.INVALID_COMPONENT; + setLockingState(LockingState.INVALID_COMPONENT); return; } } else if (foundPort) { // This implies that a port was found, but it didn't generate - // a component because of mismatched inputs + // a component because of mismatched inputs this.unlockAll(); - fissionReactor = null; - this.lockingState = LockingState.MISSING_INPUTS; + setLockingState(LockingState.MISSING_INPUTS); return; } } } } + if (!foundFuel) { + this.unlockAll(); + setLockingState(LockingState.MISSING_FUEL); + return; + } fissionReactor.prepareThermalProperties(); fissionReactor.computeGeometry(); - this.lockingState = LockingState.LOCKED; + setLockingState(LockingState.LOCKED); } private void updateReactorState() { + this.fissionReactor.updatePower(); this.fissionReactor.updateTemperature(); this.fissionReactor.updatePressure(); this.fissionReactor.updateNeutronPoisoning(); - this.fissionReactor.updatePower(); + this.fissionReactor.regulateControlRods(); + } + + protected void setLockingState(LockingState lockingState) { + if (this.lockingState != lockingState) { + writeCustomData(GregtechDataCodes.SYNC_LOCKING_STATE, (buf) -> buf.writeEnumValue(lockingState)); + } + this.lockingState = lockingState; } private enum LockingState { @@ -551,7 +767,130 @@ private enum LockingState { SHOULD_LOCK, // The reactor can't lock because it is missing inputs MISSING_INPUTS, + MISSING_FUEL, // The reactor can't lock because components are flagged as invalid INVALID_COMPONENT } + + public List getMatchingShapes() { + List shapes = new ArrayList<>(); + + for (int diameter = 5; diameter <= 15; diameter += 2) { + int radius = diameter % 2 == 0 ? (int) Math.floor(diameter / 2.f) : + Math.round((diameter - 1) / 2.f); + StringBuilder interiorBuilder = new StringBuilder(); + + String[] interiorSlice = new String[diameter]; + String[] controllerSlice; + String[] topSlice; + String[] bottomSlice; + + // First loop over the matrix + for (int i = 0; i < diameter; i++) { + for (int j = 0; j < diameter; j++) { + if (Math.pow(i - Math.floor(diameter / 2.), 2) + + Math.pow(j - Math.floor(diameter / 2.), 2) < + Math.pow(radius + 0.5f, 2)) { + interiorBuilder.append('A'); + } else { + interiorBuilder.append(' '); + } + } + + interiorSlice[i] = interiorBuilder.toString(); + interiorBuilder.setLength(0); + } + + // Second loop is to detect where to put walls, the controller and I/O + for (int i = 0; i < diameter; i++) { + for (int j = 0; j < diameter; j++) { + if (interiorSlice[i].charAt(j) != 'A') { + continue; + } + + int outerI = i + (int) Math.signum(i - (diameter / 2)); + + if (Math.pow(outerI - Math.floor(diameter / 2.), 2) + + Math.pow(j - Math.floor(diameter / 2.), 2) > + Math.pow(radius + 0.5f, 2)) { + interiorSlice[i] = GTStringUtils.replace(interiorSlice[i], j, 'V'); + } + + int outerJ = j + (int) Math.signum(j - (diameter / 2)); + if (Math.pow(i - Math.floor(diameter / 2.), 2) + + Math.pow(outerJ - Math.floor(diameter / 2.), 2) > + Math.pow(radius + 0.5f, 2)) { + interiorSlice[i] = GTStringUtils.replace(interiorSlice[i], j, 'V'); + } + } + } + + controllerSlice = interiorSlice.clone(); + topSlice = interiorSlice.clone(); + bottomSlice = interiorSlice.clone(); + controllerSlice[0] = controllerSlice[0].substring(0, (int) Math.floor(diameter / 2.)) + "SM" + + controllerSlice[0].substring((int) Math.floor(diameter / 2.) + 2); + + // Example hatches + controllerSlice[1] = controllerSlice[1].substring(0, (int) Math.floor(diameter / 2.) - 1) + "frc" + + controllerSlice[1].substring((int) Math.floor(diameter / 2.) + 2); + controllerSlice[3] = controllerSlice[3].substring(0, (int) Math.floor(diameter / 2.)) + "r" + + controllerSlice[3].substring((int) Math.floor(diameter / 2.) + 1); + + topSlice[1] = topSlice[1].substring(0, (int) Math.floor(diameter / 2.) - 1) + "eqb" + + topSlice[1].substring((int) Math.floor(diameter / 2.) + 2); + topSlice[3] = topSlice[3].substring(0, (int) Math.floor(diameter / 2.)) + "m" + + topSlice[3].substring((int) Math.floor(diameter / 2.) + 1); + + bottomSlice[1] = bottomSlice[1].substring(0, (int) Math.floor(diameter / 2.) - 1) + "gVd" + + bottomSlice[1].substring((int) Math.floor(diameter / 2.) + 2); + + for (int i = 0; i < diameter; i++) { + topSlice[i] = topSlice[i].replace('A', 'V'); + bottomSlice[i] = bottomSlice[i].replace('A', 'V'); + } + MultiblockShapeInfo.Builder builder = MultiblockShapeInfo.builder(RelativeDirection.RIGHT, + RelativeDirection.FRONT, RelativeDirection.UP); + builder.aisle(topSlice); + for (int i = 0; i < heightBottom - 1; i++) { + builder.aisle(interiorSlice); + } + builder.aisle(controllerSlice); + for (int i = 0; i < heightTop - 1; i++) { + builder.aisle(interiorSlice); + } + builder.aisle(bottomSlice); + shapes.add(builder.where('S', MetaTileEntities.FISSION_REACTOR, EnumFacing.NORTH) + // A for interior components, which are air here + .where('A', Blocks.AIR.getDefaultState()) + // Technically a duplicate, but this just makes things easier + .where(' ', Blocks.AIR.getDefaultState()) + // I for the inputs on the top + .where('V', this.getVesselState()) + .where('f', this.getFuelChannelState()) + .where('c', this.getCoolantChannelState()) + .where('r', this.getControlRodChannelState()) + .where('e', MetaTileEntities.FUEL_ROD_INPUT, EnumFacing.UP) + .where('g', MetaTileEntities.FUEL_ROD_OUTPUT, EnumFacing.DOWN) + .where('b', MetaTileEntities.COOLANT_INPUT, EnumFacing.DOWN) + .where('d', MetaTileEntities.COOLANT_OUTPUT, EnumFacing.UP) + .where('q', MetaTileEntities.CONTROL_ROD, EnumFacing.UP) + .where('m', MetaTileEntities.CONTROL_ROD_MODERATED, EnumFacing.DOWN) + + // B for the vessel blocks on the walls + .where('M', () -> ConfigHolder.machines.enableMaintenance ? MetaTileEntities.MAINTENANCE_HATCH : + this.getVesselState(), EnumFacing.NORTH) + .build()); + } + return shapes; + } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + super.addInformation(stack, world, tooltip, advanced); + tooltip.add(I18n.format("gregtech.machine.fission_reactor.tooltip.1")); + tooltip.add(I18n.format("gregtech.machine.fission_reactor.tooltip.2")); + tooltip.add(I18n.format("gregtech.machine.fission_reactor.tooltip.3")); + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java index 0c34ab575ec..c09b9b91203 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java @@ -28,6 +28,7 @@ import gregtech.api.pattern.TraceabilityPredicate; import gregtech.api.util.BlockInfo; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.api.util.TextComponentUtil; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; @@ -64,7 +65,6 @@ import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -543,7 +543,7 @@ public void addInformation(ItemStack stack, @Nullable World player, List tooltip.add(I18n.format("gregtech.machine.cleanroom.tooltip.7")); tooltip.add(I18n.format("gregtech.machine.cleanroom.tooltip.8")); tooltip.add(I18n.format("gregtech.machine.cleanroom.tooltip.9")); - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { tooltip.add(I18n.format(AEConfig.instance().isFeatureEnabled(AEFeature.CHANNELS) ? "gregtech.machine.cleanroom.tooltip.ae2.channels" : "gregtech.machine.cleanroom.tooltip.ae2.no_channels")); diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFluidDrill.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFluidDrill.java index a1501dd6f65..dca07a39e5f 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFluidDrill.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFluidDrill.java @@ -184,7 +184,7 @@ protected void addDisplayText(List textList) { TextFormatting.BLUE, TextFormattingUtil.formatNumbers( minerLogic.getFluidToProduce() * 20L / FluidDrillLogic.MAX_PROGRESS) + - " L/t"); + " L/s"); tl.add(TextComponentUtil.translationWithColor( TextFormatting.GRAY, "gregtech.multiblock.fluid_rig.fluid_amount", diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java index 90b8b70886c..35c06785bab 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java @@ -640,7 +640,7 @@ protected void modifyOverclockPre(int @NotNull [] values, @NotNull IRecipeProper // MK3 reactor can overclock a MK2 recipe once, or a MK1 recipe twice. long euToStart = storage.getRecipePropertyValue(FusionEUToStartProperty.getInstance(), 0L); int fusionTier = FusionEUToStartProperty.getFusionTier(euToStart); - if (fusionTier != 0) fusionTier -= MetaTileEntityFusionReactor.this.tier; + if (fusionTier != 0) fusionTier = MetaTileEntityFusionReactor.this.tier - fusionTier; values[2] = Math.min(fusionTier, values[2]); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java index c6ee87449d2..7814f3dccc9 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java @@ -81,8 +81,10 @@ public class MetaTileEntityPowerSubstation extends MultiblockWithDisplayBase private boolean isActive, isWorkingEnabled = true; // Stats tracked for UI display - private long netIOLastSec; - private long averageIOLastSec; + private long netInLastSec; + private long averageInLastSec; + private long netOutLastSec; + private long averageOutLastSec; public MetaTileEntityPowerSubstation(ResourceLocation metaTileEntityId) { super(metaTileEntityId); @@ -138,8 +140,10 @@ public void invalidateStructure() { inputHatches = null; outputHatches = null; passiveDrain = 0; - netIOLastSec = 0; - averageIOLastSec = 0; + netInLastSec = 0; + averageInLastSec = 0; + netOutLastSec = 0; + averageOutLastSec = 0; super.invalidateStructure(); } @@ -149,25 +153,27 @@ protected void updateFormedValid() { if (getOffsetTimer() % 20 == 0) { // active here is just used for rendering setActive(energyBank.hasEnergy()); - averageIOLastSec = netIOLastSec / 20; - netIOLastSec = 0; + averageInLastSec = netInLastSec / 20; + averageOutLastSec = netOutLastSec / 20; + netInLastSec = 0; + netOutLastSec = 0; } if (isWorkingEnabled()) { // Bank from Energy Input Hatches long energyBanked = energyBank.fill(inputHatches.getEnergyStored()); inputHatches.changeEnergy(-energyBanked); - netIOLastSec += energyBanked; + netInLastSec += energyBanked; // Passive drain long energyPassiveDrained = energyBank.drain(getPassiveDrain()); - netIOLastSec -= energyPassiveDrained; + netOutLastSec += energyPassiveDrained; // Debank to Dynamo Hatches long energyDebanked = energyBank .drain(outputHatches.getEnergyCapacity() - outputHatches.getEnergyStored()); outputHatches.changeEnergy(energyDebanked); - netIOLastSec -= energyDebanked; + netOutLastSec += energyDebanked; } } } @@ -359,44 +365,45 @@ protected void addDisplayText(List textList) { "gregtech.multiblock.power_substation.passive_drain", passiveDrain)); - // Average I/O line - TextFormatting averageIOColor = TextFormatting.GRAY; - if (isActive() && isWorkingEnabled() && averageIOLastSec == 0) { - // only set to yellow on zero if the machine is on, avoids a yellow "warning" - // color when the machine is first formed and not yet plugged in. - averageIOColor = TextFormatting.YELLOW; - } else if (averageIOLastSec > 0) { - averageIOColor = TextFormatting.GREEN; - } else if (averageIOLastSec < 0) { - averageIOColor = TextFormatting.RED; - } - - ITextComponent averageIO = TextComponentUtil.stringWithColor( - averageIOColor, - TextFormattingUtil.formatNumbers(averageIOLastSec) + " EU/t"); - + // Average EU IN line + ITextComponent avgValue = TextComponentUtil.stringWithColor( + TextFormatting.GREEN, + TextFormattingUtil.formatNumbers(averageInLastSec) + " EU/t"); ITextComponent base = TextComponentUtil.translationWithColor( TextFormatting.GRAY, - "gregtech.multiblock.power_substation.average_io", - averageIO); - + "gregtech.multiblock.power_substation.average_in", + avgValue); ITextComponent hover = TextComponentUtil.translationWithColor( TextFormatting.GRAY, - "gregtech.multiblock.power_substation.average_io_hover"); + "gregtech.multiblock.power_substation.average_in_hover"); + tl.add(TextComponentUtil.setHover(base, hover)); + + // Average EU OUT line + avgValue = TextComponentUtil.stringWithColor( + TextFormatting.RED, + TextFormattingUtil.formatNumbers(averageOutLastSec) + " EU/t"); + base = TextComponentUtil.translationWithColor( + TextFormatting.GRAY, + "gregtech.multiblock.power_substation.average_out", + avgValue); + hover = TextComponentUtil.translationWithColor( + TextFormatting.GRAY, + "gregtech.multiblock.power_substation.average_out_hover"); tl.add(TextComponentUtil.setHover(base, hover)); // Time to fill/drain line - if (averageIOLastSec > 0) { + if (averageInLastSec > averageOutLastSec) { ITextComponent timeToFill = getTimeToFillDrainText(energyCapacity.subtract(energyStored) - .divide(BigInteger.valueOf(averageIOLastSec * 20))); + .divide(BigInteger.valueOf((averageInLastSec - averageOutLastSec) * 20))); TextComponentUtil.setColor(timeToFill, TextFormatting.GREEN); tl.add(TextComponentUtil.translationWithColor( TextFormatting.GRAY, "gregtech.multiblock.power_substation.time_to_fill", timeToFill)); - } else if (averageIOLastSec < 0) { + } else if (averageInLastSec < averageOutLastSec) { ITextComponent timeToDrain = getTimeToFillDrainText( - energyStored.divide(BigInteger.valueOf(Math.abs(averageIOLastSec) * 20))); + energyStored.divide(BigInteger.valueOf( + (averageOutLastSec - averageInLastSec) * 20))); TextComponentUtil.setColor(timeToDrain, TextFormatting.RED); tl.add(TextComponentUtil.translationWithColor( TextFormatting.GRAY, @@ -412,9 +419,9 @@ protected void addDisplayText(List textList) { protected void addWarningText(List textList) { super.addWarningText(textList); if (isStructureFormed()) { - if (averageIOLastSec < 0) { // decreasing + if (averageInLastSec < averageOutLastSec) { // decreasing BigInteger timeToDrainSeconds = energyBank.getStored() - .divide(BigInteger.valueOf(Math.abs(averageIOLastSec) * 20)); + .divide(BigInteger.valueOf((averageOutLastSec - averageInLastSec) * 20)); if (timeToDrainSeconds.compareTo(BigInteger.valueOf(60 * 60)) < 0) { // less than 1 hour left textList.add(TextComponentUtil.translationWithColor( TextFormatting.YELLOW, @@ -550,8 +557,12 @@ public String getCapacity() { return TextFormattingUtil.formatNumbers(energyBank.getCapacity()); } - public long getAverageIOLastSec() { - return averageIOLastSec; + public long getAverageInLastSec() { + return averageInLastSec; + } + + public long getAverageOutLastSec() { + return averageOutLastSec; } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java b/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java index a5d37f33c41..46bcafb51d5 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java @@ -202,20 +202,69 @@ private void updateProxyPlugin() { } public int getX() { - if (this.getController() != null) { - if (this.getController().getPos().getX() - this.getPos().getX() != 0) { - return Math.abs(this.getController().getPos().getX() - this.getPos().getX()) - 1; - } else { - return Math.abs(this.getController().getPos().getZ() - this.getPos().getZ()) - 1; + MultiblockControllerBase controller = this.getController(); + if (controller != null) { + EnumFacing spin = controller.getUpwardsFacing(); + switch (controller.getFrontFacing().getAxis()) { + case Y -> { + if (spin.getAxis() == EnumFacing.Axis.X) + return Math.abs(this.getController().getPos().getZ() - this.getPos().getZ()) - 1; + else + return Math.abs(this.getController().getPos().getX() - this.getPos().getX()) - 1; + } + case X -> { + if (spin.getAxis() == EnumFacing.Axis.Z) + return Math.abs(this.getController().getPos().getZ() - this.getPos().getZ()) - 1; + else + return Math.abs(this.getController().getPos().getY() - this.getPos().getY()) - 1; + } + default -> { + if (spin.getAxis() == EnumFacing.Axis.Z) + return Math.abs(this.getController().getPos().getX() - this.getPos().getX()) - 1; + else + return Math.abs(this.getController().getPos().getY() - this.getPos().getY()) - 1; + } } } return -1; } public int getY() { - if (this.getController() != null) { - return ((MetaTileEntityCentralMonitor) this.getController()).height - - (this.getPos().getY() + 1 - this.getController().getPos().getY()) - 1; + MultiblockControllerBase controller = this.getController(); + if (controller != null) { + EnumFacing spin = controller.getUpwardsFacing(); + EnumFacing facing = controller.getFrontFacing(); + int height = ((MetaTileEntityCentralMonitor) this.getController()).height; + switch (facing.getAxis()) { + case Y -> { + if (spin.getAxis() == EnumFacing.Axis.X) + return height - + (Math.abs(controller.getPos().getX() - spin.getXOffset() - this.getPos().getX())) - 1; + else + return height - + (Math.abs(controller.getPos().getZ() - spin.getZOffset() - this.getPos().getZ())) - 1; + } + case X -> { + if (spin.getAxis() == EnumFacing.Axis.Z) + return height - + (Math.abs(controller.getPos().getY() + spin.getZOffset() - this.getPos().getY())) - 1; + else + return height - (Math.abs( + controller.getPos().getZ() + spin.getXOffset() * facing.rotateY().getZOffset() - + this.getPos().getZ())) - + 1; + } + default -> { + if (spin.getAxis() == EnumFacing.Axis.Z) + return height - + (Math.abs(controller.getPos().getY() + spin.getZOffset() - this.getPos().getY())) - 1; + else + return height - (Math.abs( + controller.getPos().getX() + spin.getXOffset() * facing.rotateY().getXOffset() - + this.getPos().getX())) - + 1; + } + } } return -1; } diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java index db414ae4da7..f9f393216e6 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java @@ -131,7 +131,7 @@ protected boolean checkPreviousRecipe() { } @Override - protected boolean prepareRecipe(Recipe recipe) { + public boolean prepareRecipe(Recipe recipe) { IRotorHolder rotorHolder = ((MetaTileEntityLargeTurbine) metaTileEntity).getRotorHolder(); if (rotorHolder == null || !rotorHolder.hasRotor()) return false; diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java index 4b298f25cd0..7d58be463fe 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java @@ -16,6 +16,7 @@ import gregtech.api.pattern.PatternMatchContext; import gregtech.api.recipes.RecipeMaps; import gregtech.api.unification.material.Materials; +import gregtech.api.util.RelativeDirection; import gregtech.api.util.TextComponentUtil; import gregtech.api.util.TextFormattingUtil; import gregtech.client.renderer.ICubeRenderer; @@ -28,7 +29,6 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.ITextComponent; @@ -192,18 +192,19 @@ protected void formStructure(PatternMatchContext context) { } private boolean checkIntakesObstructed() { - EnumFacing facing = this.getFrontFacing(); - boolean permuteXZ = facing.getAxis() == EnumFacing.Axis.Z; - BlockPos centerPos = this.getPos().offset(facing); - for (int x = -1; x < 2; x++) { - for (int y = -1; y < 2; y++) { - // Skip the controller block itself - if (x == 0 && y == 0) + for (int left = -1; left <= 1; left++) { + for (int up = -1; up <= 1; up++) { + if (left == 0 && up == 0) { + // Skip the controller block itself continue; - BlockPos blockPos = centerPos.add(permuteXZ ? x : 0, y, permuteXZ ? 0 : x); - IBlockState blockState = this.getWorld().getBlockState(blockPos); - if (!blockState.getBlock().isAir(blockState, this.getWorld(), blockPos)) + } + + final BlockPos checkPos = RelativeDirection.offsetPos( + getPos(), getFrontFacing(), getUpwardsFacing(), isFlipped(), up, left, 1); + final IBlockState state = getWorld().getBlockState(checkPos); + if (!state.getBlock().isAir(state, getWorld(), checkPos)) { return true; + } } } return false; diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java index 850ea3730be..ae41352ceb2 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java @@ -13,10 +13,13 @@ import gregtech.client.renderer.texture.Textures; import gregtech.common.pipelike.optical.tile.TileEntityOpticalPipe; +import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import codechicken.lib.render.CCRenderState; @@ -166,4 +169,11 @@ public T getCapability(Capability capability, EnumFacing side) { } return super.getCapability(capability, side); } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + super.addInformation(stack, world, tooltip, advanced); + tooltip.add(I18n.format("gregtech.universal.disabled")); + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityControlRodPort.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityControlRodPort.java index e48728461e5..0aef0df4f0a 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityControlRodPort.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityControlRodPort.java @@ -1,6 +1,5 @@ package gregtech.common.metatileentities.multi.multiblockpart; -import gregtech.api.capability.IControllable; import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; @@ -11,40 +10,34 @@ import gregtech.common.blocks.BlockFissionCasing; import gregtech.common.blocks.MetaBlocks; +import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; public class MetaTileEntityControlRodPort extends MetaTileEntityMultiblockNotifiablePart - implements IControllable, IFissionReactorHatch, - IMultiblockAbilityPart, IControlRodPort { - - private boolean workingEnabled; - private boolean valid; + implements IFissionReactorHatch, IControlRodPort, + IMultiblockAbilityPart { - private byte insertion; + private boolean hasModeratorTip; - public MetaTileEntityControlRodPort(ResourceLocation metaTileEntityId, boolean isExportHatch) { + public MetaTileEntityControlRodPort(ResourceLocation metaTileEntityId, boolean hasModeratorTip) { super(metaTileEntityId, 4, false); this.frontFacing = EnumFacing.UP; - } - - @Override - public boolean isWorkingEnabled() { - return workingEnabled; - } - - @Override - public void setWorkingEnabled(boolean isWorkingAllowed) { - this.workingEnabled = isWorkingAllowed; + this.hasModeratorTip = hasModeratorTip; } @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { - return new MetaTileEntityControlRodPort(metaTileEntityId, false); + return new MetaTileEntityControlRodPort(metaTileEntityId, hasModeratorTip); } @Override @@ -52,6 +45,11 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { return null; } + @Override + protected boolean openGUIOnRightClick() { + return false; + } + @Override public void setFrontFacing(EnumFacing frontFacing) { super.setFrontFacing(EnumFacing.UP); @@ -72,9 +70,7 @@ public boolean checkValidity(int depth) { } @Override - public void setValid(boolean valid) { - this.valid = valid; - } + public void setValid(boolean valid) {} @Override public MultiblockAbility getAbility() { @@ -86,8 +82,14 @@ public void registerAbilities(List abilityList) { abilityList.add(this); } + public boolean hasModeratorTip() { + return hasModeratorTip; + } + @Override - public byte getInsertionAmount() { - return this.insertion; + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + super.addInformation(stack, world, tooltip, advanced); + tooltip.add(I18n.format(this.getMetaName() + "tooltip.1")); } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityCoolantExportHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityCoolantExportHatch.java index eea32950feb..d42c5861d21 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityCoolantExportHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityCoolantExportHatch.java @@ -22,6 +22,7 @@ import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fluids.IFluidTank; @@ -117,6 +118,14 @@ public void setLock(boolean isLocked) { writeCustomData(LOCK_UPDATE, (packetBuffer -> packetBuffer.writeBoolean(isLocked))); } + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == LOCK_UPDATE) { + this.fluidTank.setLock(buf.readBoolean()); + } + } + @Override public boolean isLocked() { return fluidTank.isLocked(); diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java index c925716144e..a50acc06ba0 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java @@ -175,6 +175,11 @@ public void addInformation(ItemStack stack, @Nullable World world, @NotNull List } else { tooltip.add(I18n.format("gregtech.machine.data_access_hatch.tooltip.2", getInventorySize())); } + if (canPartShare()) { + tooltip.add(I18n.format("gregtech.universal.enabled")); + } else { + tooltip.add(I18n.format("gregtech.universal.disabled")); + } } @NotNull @@ -199,7 +204,7 @@ public List getDataInfo() { @Override public boolean canPartShare() { - return false; + return isCreative; } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFuelRodExportHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFuelRodExportHatch.java index 23a6eea7e13..472fe4eed0d 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFuelRodExportHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFuelRodExportHatch.java @@ -51,6 +51,14 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { return new MetaTileEntityFuelRodExportHatch(metaTileEntityId); } + @Override + public void update() { + super.update(); + if (!getWorld().isRemote && getOffsetTimer() % 5 == 0) { + pushItemsIntoNearbyHandlers(getFrontFacing()); + } + } + @Override protected IItemHandlerModifiable createExportItemHandler() { return new ItemStackHandler(1); diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFuelRodImportHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFuelRodImportHatch.java index 9aa6e5679ae..56bf823169a 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFuelRodImportHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFuelRodImportHatch.java @@ -16,7 +16,6 @@ import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; import gregtech.common.blocks.BlockFissionCasing; import gregtech.common.blocks.MetaBlocks; -import gregtech.common.metatileentities.MetaTileEntities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; @@ -41,6 +40,8 @@ public class MetaTileEntityFuelRodImportHatch extends MetaTileEntityMultiblockNo private boolean workingEnabled; private boolean valid; + private Material mat; + public MetaTileEntityFuelRodExportHatch pairedHatch; public MetaTileEntityFuelRodImportHatch(ResourceLocation metaTileEntityId) { super(metaTileEntityId, 4, false); @@ -82,6 +83,14 @@ private ModularUI.Builder createUITemplate(EntityPlayer player) { return builder.bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 60); } + @Override + public void update() { + super.update(); + if (!getWorld().isRemote && getOffsetTimer() % 5 == 0) { + pullItemsFromNearbyHandlers(getFrontFacing()); + } + } + @Override protected ModularUI createUI(EntityPlayer entityPlayer) { return createUITemplate(entityPlayer).build(getHolder(), entityPlayer); @@ -116,17 +125,8 @@ public void setFrontFacing(EnumFacing frontFacing) { @Override public boolean checkValidity(int depth) { - BlockPos pos = this.getPos(); - for (int i = 1; i < depth; i++) { - if (getWorld().getBlockState(pos.offset(EnumFacing.DOWN, i)) != - MetaBlocks.FISSION_CASING.getState(BlockFissionCasing.FissionCasingType.FUEL_CHANNEL)) { - return false; - } - } - if (getWorld().getTileEntity(pos.offset(EnumFacing.DOWN, depth)) instanceof IGregTechTileEntity gtTe) { - return gtTe.getMetaTileEntity().metaTileEntityId.equals(MetaTileEntities.FUEL_ROD_OUTPUT.metaTileEntityId); - } - return false; + this.pairedHatch = getExportHatch(depth); + return pairedHatch != null; } @Override @@ -171,14 +171,33 @@ public boolean isLocked() { @Override public Material getFuel() { - return null; + return this.mat; } @Override - public void setFuel(Material material) {} + public void setFuel(Material material) { + this.mat = material; + } @Override public LockableItemStackHandler getStackHandler() { return this.getLockedImport(); } + + public MetaTileEntityFuelRodExportHatch getExportHatch(int depth) { + BlockPos pos = this.getPos(); + for (int i = 1; i < depth; i++) { + if (getWorld().getBlockState(pos.offset(EnumFacing.DOWN, i)) != + MetaBlocks.FISSION_CASING.getState(BlockFissionCasing.FissionCasingType.FUEL_CHANNEL)) { + return null; + } + } + if (getWorld().getTileEntity(pos.offset(EnumFacing.DOWN, depth)) instanceof IGregTechTileEntity gtTe) { + MetaTileEntity mte = gtTe.getMetaTileEntity(); + if (mte instanceof MetaTileEntityFuelRodExportHatch) { + return (MetaTileEntityFuelRodExportHatch) mte; + } + } + return null; + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java index 2f622588c7b..76acce75c33 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java @@ -72,11 +72,6 @@ protected boolean openGUIOnRightClick() { return false; } - @Override - public boolean canPartShare() { - return false; - } - @Override public MultiblockAbility getAbility() { return isOutput ? MultiblockAbility.OUTPUT_LASER : MultiblockAbility.INPUT_LASER; @@ -114,7 +109,7 @@ public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip.add(I18n.format("gregtech.universal.tooltip.amperage_in_till", amperage)); } tooltip.add(I18n.format("gregtech.universal.tooltip.energy_storage_capacity", buffer.getEnergyCapacity())); - tooltip.add(I18n.format("gregtech.universal.disabled")); + tooltip.add(I18n.format("gregtech.universal.enabled")); } @NotNull diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java index 5658841fcda..efb526a0616 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java @@ -18,6 +18,7 @@ import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; +import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -25,12 +26,14 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; import net.minecraftforge.items.IItemHandler; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -207,6 +210,18 @@ public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { heldItems.removeNotifiableMetaTileEntity(controllerBase); } + @Override + public boolean canPartShare() { + return false; + } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + super.addInformation(stack, world, tooltip, advanced); + tooltip.add(I18n.format("gregtech.universal.disabled")); + } + private class ObjectHolderHandler extends NotifiableItemStackHandler { public ObjectHolderHandler(MetaTileEntity metaTileEntity) { diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java index ca4d8d8000c..054cbccfd19 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java @@ -14,16 +14,20 @@ import gregtech.client.renderer.texture.Textures; import gregtech.common.pipelike.optical.tile.TileEntityOpticalPipe; +import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.List; @@ -134,4 +138,11 @@ public MultiblockAbility getAbility() { public void registerAbilities(@NotNull List abilityList) { abilityList.add(this); } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + super.addInformation(stack, world, tooltip, advanced); + tooltip.add(I18n.format("gregtech.universal.disabled")); + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java index 9981538731d..e8cf6d7b59b 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java @@ -63,7 +63,6 @@ public void update() { super.update(); if (!getWorld().isRemote) { fillContainerFromInternalTank(fluidTank); - fillInternalTankFromFluidContainer(fluidTank); if (getOffsetTimer() % 20 == 0) { fluidTank.refillWater(); } @@ -129,7 +128,7 @@ public ModularUI.Builder createTankUI(IFluidTank fluidTank, String title, Entity // Add input/output-specific widgets tankWidget = new TankWidget(fluidTank, 69, 52, 18, 18) - .setAlwaysShowFull(true).setDrawHoveringText(false).setContainerClicking(true, true); + .setAlwaysShowFull(true).setDrawHoveringText(false).setContainerClicking(true, false); builder.image(7, 16, 81, 55, GuiTextures.DISPLAY) .widget(new ImageWidget(91, 36, 14, 15, GuiTextures.TANK_ICON)) @@ -180,47 +179,39 @@ public void addToolUsages(ItemStack stack, @Nullable World world, List t private static class InfiniteWaterTank extends NotifiableFluidTank { - private final FluidStack BIG_WATER = new FluidStack(FluidRegistry.WATER, FLUID_AMOUNT); - public InfiniteWaterTank(int capacity, MetaTileEntity entityToNotify) { super(capacity, entityToNotify, false); - setFluid(BIG_WATER); + // start with the full amount + setFluid(new FluidStack(FluidRegistry.WATER, FLUID_AMOUNT)); + // don't allow external callers to fill this tank + setCanFill(false); } private void refillWater() { - if (BIG_WATER.amount != FLUID_AMOUNT) { - BIG_WATER.amount = FLUID_AMOUNT; - onContentsChanged(); + int fillAmount = Math.max(0, FLUID_AMOUNT - getFluidAmount()); + if (fillAmount > 0) { + // call super since our overrides don't allow any kind of filling + super.fillInternal(new FluidStack(FluidRegistry.WATER, fillAmount), true); } } @Override - public FluidStack drainInternal(int maxDrain, boolean doDrain) { - return new FluidStack(BIG_WATER, maxDrain); - } - - @Nullable - @Override - public FluidStack drainInternal(FluidStack resource, boolean doDrain) { - return new FluidStack(BIG_WATER, resource.amount); + public boolean canDrainFluidType(@Nullable FluidStack fluid) { + return fluid != null && fluid.getFluid() == FluidRegistry.WATER; } + // don't allow external filling @Override public int fillInternal(FluidStack resource, boolean doFill) { - return resource.amount; - } - - @Override - public boolean canDrainFluidType(@Nullable FluidStack fluid) { - return fluid != null && fluid.getFluid() == BIG_WATER.getFluid(); + return 0; } @Override public boolean canFillFluidType(FluidStack fluid) { - return fluid.getFluid() == BIG_WATER.getFluid(); + return false; } - // serialization is unnecessary here, it should always have the same amount of fluid + // serialization is unnecessary here, we can always recreate it completely full since it would refill anyway @Override public FluidTank readFromNBT(NBTTagCompound nbt) { return this; diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java index e36b9bb24d4..d78b7fe5042 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java @@ -12,6 +12,7 @@ import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.util.RelativeDirection; import gregtech.client.renderer.texture.Textures; import gregtech.common.items.behaviors.AbstractMaterialPartBehavior; import gregtech.common.items.behaviors.TurbineRotorBehavior; @@ -163,14 +164,17 @@ public boolean isFrontFaceFree() { } private boolean checkTurbineFaceFree() { - EnumFacing facing = getFrontFacing(); - boolean permuteXZ = facing.getAxis() == EnumFacing.Axis.Z; - BlockPos centerPos = getPos().offset(facing); - for (int x = -1; x < 2; x++) { - for (int y = -1; y < 2; y++) { - BlockPos blockPos = centerPos.add(permuteXZ ? x : 0, y, permuteXZ ? 0 : x); - IBlockState blockState = getWorld().getBlockState(blockPos); - if (!blockState.getBlock().isAir(blockState, getWorld(), blockPos)) { + final EnumFacing front = getFrontFacing(); + // this can be anything really, as long as it is not up/down when on Y axis + final EnumFacing upwards = front.getAxis() == EnumFacing.Axis.Y ? EnumFacing.NORTH : EnumFacing.UP; + + for (int left = -1; left <= 1; left++) { + for (int up = -1; up <= 1; up++) { + // flip doesn't affect anything here since we are checking a square anyway + final BlockPos checkPos = RelativeDirection.offsetPos( + getPos(), front, upwards, false, up, left, 1); + final IBlockState state = getWorld().getBlockState(checkPos); + if (!state.getBlock().isAir(state, getWorld(), checkPos)) { return false; } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java index 7f470e4d0ff..1c8f73e6837 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java @@ -1,10 +1,6 @@ package gregtech.common.metatileentities.multi.multiblockpart.appeng; -import gregtech.api.GTValues; import gregtech.api.capability.IControllable; -import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; -import gregtech.client.renderer.ICubeRenderer; -import gregtech.client.renderer.texture.Textures; import gregtech.common.ConfigHolder; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockNotifiablePart; @@ -19,13 +15,12 @@ import appeng.api.networking.GridFlags; import appeng.api.networking.security.IActionHost; import appeng.api.networking.security.IActionSource; +import appeng.api.storage.IMEMonitor; import appeng.api.storage.IStorageChannel; -import appeng.api.storage.channels.IFluidStorageChannel; -import appeng.api.storage.channels.IItemStorageChannel; -import appeng.api.storage.data.IAEFluidStack; -import appeng.api.storage.data.IAEItemStack; +import appeng.api.storage.data.IAEStack; import appeng.api.util.AECableType; import appeng.api.util.AEPartLocation; +import appeng.me.GridAccessException; import appeng.me.helpers.AENetworkProxy; import appeng.me.helpers.BaseActionSource; import appeng.me.helpers.IGridProxyable; @@ -36,28 +31,21 @@ import java.io.IOException; import java.util.EnumSet; -/** - * @Author GlodBlock - * @Description It can connect to ME network. - * @Date 2023/4/18-23:17 - */ -public abstract class MetaTileEntityAEHostablePart extends MetaTileEntityMultiblockNotifiablePart - implements IControllable { +import static gregtech.api.capability.GregtechDataCodes.UPDATE_ONLINE_STATUS; - protected static final IStorageChannel ITEM_NET = AEApi.instance().storage() - .getStorageChannel(IItemStorageChannel.class); - protected static final IStorageChannel FLUID_NET = AEApi.instance().storage() - .getStorageChannel(IFluidStorageChannel.class); +public abstract class MetaTileEntityAEHostablePart> extends MetaTileEntityMultiblockNotifiablePart + implements IControllable { - private final static int ME_UPDATE_INTERVAL = ConfigHolder.compat.ae2.updateIntervals; + private final Class> storageChannel; private AENetworkProxy aeProxy; private int meUpdateTick; protected boolean isOnline; - private final static int ONLINE_ID = 6666; - public MetaTileEntityAEHostablePart(ResourceLocation metaTileEntityId, int tier, boolean isExportHatch) { + public MetaTileEntityAEHostablePart(ResourceLocation metaTileEntityId, int tier, boolean isExportHatch, + Class> storageChannel) { super(metaTileEntityId, tier, isExportHatch); this.meUpdateTick = 0; + this.storageChannel = storageChannel; } @Override @@ -73,9 +61,7 @@ public void update() { * So there is no need to drop them. */ @Override - public void clearMachineInventory(NonNullList itemBuffer) { - // NO-OP - } + public void clearMachineInventory(NonNullList itemBuffer) {} @Override public void writeInitialSyncData(PacketBuffer buf) { @@ -114,24 +100,9 @@ public void receiveInitialSyncData(PacketBuffer buf) { @Override public void receiveCustomData(int dataId, PacketBuffer buf) { super.receiveCustomData(dataId, buf); - if (dataId == ONLINE_ID) { + if (dataId == UPDATE_ONLINE_STATUS) { this.isOnline = buf.readBoolean(); - } - } - - @Override - public ICubeRenderer getBaseTexture() { - MultiblockControllerBase controller = getController(); - if (controller != null) { - return this.hatchTexture = controller.getBaseTexture(this); - } else if (this.hatchTexture != null) { - if (hatchTexture != Textures.getInactiveTexture(hatchTexture)) { - return this.hatchTexture = Textures.getInactiveTexture(hatchTexture); - } - return this.hatchTexture; - } else { - // Always display as EV casing - return Textures.VOLTAGE_CASINGS[GTValues.EV]; + scheduleRenderUpdate(); } } @@ -165,9 +136,7 @@ public void setFrontFacing(EnumFacing frontFacing) { } @Override - public void gridChanged() { - // NO-OP - } + public void gridChanged() {} /** * Update me network connection status. @@ -180,26 +149,27 @@ public boolean updateMEStatus() { } else { this.isOnline = false; } - writeCustomData(ONLINE_ID, buf -> buf.writeBoolean(this.isOnline)); + if (!getWorld().isRemote) { + writeCustomData(UPDATE_ONLINE_STATUS, buf -> buf.writeBoolean(this.isOnline)); + } return this.isOnline; } protected boolean shouldSyncME() { - return this.meUpdateTick % ME_UPDATE_INTERVAL == 0; + return this.meUpdateTick % ConfigHolder.compat.ae2.updateIntervals == 0; } protected IActionSource getActionSource() { - if (this.getHolder() instanceof IActionHost) { - return new MachineSource((IActionHost) this.getHolder()); + if (this.getHolder() instanceof IActionHost holder) { + return new MachineSource(holder); } return new BaseActionSource(); } @Nullable private AENetworkProxy createProxy() { - if (this.getHolder() instanceof IGridProxyable) { - AENetworkProxy proxy = new AENetworkProxy((IGridProxyable) this.getHolder(), "mte_proxy", - this.getStackForm(), true); + if (this.getHolder() instanceof IGridProxyable holder) { + AENetworkProxy proxy = new AENetworkProxy(holder, "mte_proxy", this.getStackForm(), true); proxy.setFlags(GridFlags.REQUIRE_CHANNEL); proxy.setIdlePowerUsage(ConfigHolder.compat.ae2.meHatchEnergyUsage); proxy.setValidSides(EnumSet.of(this.getFrontFacing())); @@ -207,4 +177,23 @@ private AENetworkProxy createProxy() { } return null; } + + @NotNull + protected IStorageChannel getStorageChannel() { + return AEApi.instance().storage().getStorageChannel(storageChannel); + } + + @Nullable + protected IMEMonitor getMonitor() { + AENetworkProxy proxy = getProxy(); + if (proxy == null) return null; + + IStorageChannel channel = getStorageChannel(); + + try { + return proxy.getStorage().getInventory(channel); + } catch (GridAccessException ignored) { + return null; + } + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java index 18a81b7df3d..3d4fea9abc0 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java @@ -3,15 +3,26 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IDataStickIntractable; +import gregtech.api.capability.IGhostSlotConfigurable; +import gregtech.api.capability.INotifiableHandler; +import gregtech.api.capability.impl.GhostCircuitItemStackHandler; +import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.capability.impl.NotifiableItemStackHandler; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.GhostCircuitSlotWidget; +import gregtech.api.gui.widgets.SlotWidget; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; import gregtech.common.gui.widget.appeng.AEItemConfigWidget; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; import net.minecraft.client.resources.I18n; @@ -23,117 +34,160 @@ import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import appeng.api.config.Actionable; import appeng.api.storage.IMEMonitor; +import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.data.IAEItemStack; -import appeng.me.GridAccessException; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; import java.util.List; -import java.util.function.Consumer; -/** - * @Author GlodBlock - * @Description The Input Bus that can auto fetch item ME storage network. - * @Date 2023/4/22-13:34 - */ -public class MetaTileEntityMEInputBus extends MetaTileEntityAEHostablePart - implements IMultiblockAbilityPart { +public class MetaTileEntityMEInputBus extends MetaTileEntityAEHostablePart + implements IMultiblockAbilityPart, + IGhostSlotConfigurable, IDataStickIntractable { public final static String ITEM_BUFFER_TAG = "ItemSlots"; public final static String WORKING_TAG = "WorkingEnabled"; private final static int CONFIG_SIZE = 16; - private boolean workingEnabled; - private ExportOnlyAEItemList aeItemHandler; + private boolean workingEnabled = true; + protected ExportOnlyAEItemList aeItemHandler; + protected GhostCircuitItemStackHandler circuitInventory; + protected NotifiableItemStackHandler extraSlotInventory; + private ItemHandlerList actualImportItems; public MetaTileEntityMEInputBus(ResourceLocation metaTileEntityId) { - super(metaTileEntityId, GTValues.UHV, false); - this.workingEnabled = true; + this(metaTileEntityId, GTValues.EV); + } + + protected MetaTileEntityMEInputBus(ResourceLocation metaTileEntityId, int tier) { + super(metaTileEntityId, tier, false, IItemStorageChannel.class); + } + + protected ExportOnlyAEItemList getAEItemHandler() { + if (aeItemHandler == null) { + aeItemHandler = new ExportOnlyAEItemList(this, CONFIG_SIZE, this.getController()); + } + return aeItemHandler; } @Override protected void initializeInventory() { - this.aeItemHandler = new ExportOnlyAEItemList(this, CONFIG_SIZE, this.getController()); super.initializeInventory(); - } - - protected IItemHandlerModifiable createImportItemHandler() { - return this.aeItemHandler; + this.aeItemHandler = getAEItemHandler(); + this.circuitInventory = new GhostCircuitItemStackHandler(this); + this.circuitInventory.addNotifiableMetaTileEntity(this); + this.extraSlotInventory = new NotifiableItemStackHandler(this, 1, this, false); + this.extraSlotInventory.addNotifiableMetaTileEntity(this); + this.actualImportItems = new ItemHandlerList( + Arrays.asList(this.aeItemHandler, this.circuitInventory, this.extraSlotInventory)); + this.importItems = this.actualImportItems; } public IItemHandlerModifiable getImportItems() { - this.importItems = this.aeItemHandler; - return super.getImportItems(); + return this.actualImportItems; } @Override public void update() { super.update(); - if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME()) { - if (this.updateMEStatus()) { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(ITEM_NET); - for (ExportOnlyAEItem aeSlot : this.aeItemHandler.inventory) { - // Try to clear the wrong item - IAEItemStack exceedItem = aeSlot.exceedStack(); - if (exceedItem != null) { - long total = exceedItem.getStackSize(); - IAEItemStack notInserted = aeNetwork.injectItems(exceedItem, Actionable.MODULATE, - this.getActionSource()); - if (notInserted != null && notInserted.getStackSize() > 0) { - aeSlot.extractItem(0, (int) (total - notInserted.getStackSize()), false); - continue; - } else { - aeSlot.extractItem(0, (int) total, false); - } - } - // Fill it - IAEItemStack reqItem = aeSlot.requestStack(); - if (reqItem != null) { - IAEItemStack extracted = aeNetwork.extractItems(reqItem, Actionable.MODULATE, - this.getActionSource()); - if (extracted != null) { - aeSlot.addStack(extracted); - } - } - } - } catch (GridAccessException ignore) {} - } + if (!getWorld().isRemote && this.workingEnabled && updateMEStatus() && shouldSyncME()) { + syncME(); } } - @Override - public void onRemoval() { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(ITEM_NET); - for (ExportOnlyAEItem aeSlot : this.aeItemHandler.inventory) { - IAEItemStack stock = aeSlot.stock; - if (stock instanceof WrappedItemStack) { - stock = ((WrappedItemStack) stock).getAEStack(); + protected void syncME() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEItemSlot aeSlot : this.getAEItemHandler().getInventory()) { + // Try to clear the wrong item + IAEItemStack exceedItem = aeSlot.exceedStack(); + if (exceedItem != null) { + long total = exceedItem.getStackSize(); + IAEItemStack notInserted = monitor.injectItems(exceedItem, Actionable.MODULATE, this.getActionSource()); + if (notInserted != null && notInserted.getStackSize() > 0) { + aeSlot.extractItem(0, (int) (total - notInserted.getStackSize()), false); + continue; + } else { + aeSlot.extractItem(0, (int) total, false); } - if (stock != null) { - aeNetwork.injectItems(stock, Actionable.MODULATE, this.getActionSource()); + } + // Fill it + IAEItemStack reqItem = aeSlot.requestStack(); + if (reqItem != null) { + IAEItemStack extracted = monitor.extractItems(reqItem, Actionable.MODULATE, this.getActionSource()); + if (extracted != null) { + aeSlot.addStack(extracted); } } - } catch (GridAccessException ignore) {} + } + } + + @Override + public void onRemoval() { + flushInventory(); super.onRemoval(); } + protected void flushInventory() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEItemSlot aeSlot : this.getAEItemHandler().getInventory()) { + IAEItemStack stock = aeSlot.getStock(); + if (stock instanceof WrappedItemStack) { + stock = ((WrappedItemStack) stock).getAEStack(); + } + if (stock != null) { + monitor.injectItems(stock, Actionable.MODULATE, this.getActionSource()); + } + } + } + @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity iGregTechTileEntity) { - return new MetaTileEntityMEInputBus(this.metaTileEntityId); + return new MetaTileEntityMEInputBus(metaTileEntityId); + } + + @Override + public void addToMultiBlock(MultiblockControllerBase controllerBase) { + super.addToMultiBlock(controllerBase); + for (IItemHandler handler : this.actualImportItems.getBackingHandlers()) { + if (handler instanceof INotifiableHandler notifiable) { + notifiable.addNotifiableMetaTileEntity(controllerBase); + notifiable.addToNotifiedList(this, handler, false); + } + } } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { + public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { + super.removeFromMultiBlock(controllerBase); + for (IItemHandler handler : this.actualImportItems.getBackingHandlers()) { + if (handler instanceof INotifiableHandler notifiable) { + notifiable.removeNotifiableMetaTileEntity(controllerBase); + } + } + } + + @Override + protected final ModularUI createUI(EntityPlayer player) { + ModularUI.Builder builder = createUITemplate(player); + return builder.build(this.getHolder(), player); + } + + protected ModularUI.Builder createUITemplate(EntityPlayer player) { ModularUI.Builder builder = ModularUI .builder(GuiTextures.BACKGROUND, 176, 18 + 18 * 4 + 94) .label(10, 5, getMetaFullName()); @@ -141,13 +195,37 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { builder.dynamicLabel(10, 15, () -> this.isOnline ? I18n.format("gregtech.gui.me_network.online") : I18n.format("gregtech.gui.me_network.offline"), - 0xFFFFFFFF); + 0x404040); // Config slots - builder.widget(new AEItemConfigWidget(16, 25, this.aeItemHandler.inventory)); + builder.widget(new AEItemConfigWidget(7, 25, this.getAEItemHandler())); + + // Ghost circuit slot + SlotWidget circuitSlot = new GhostCircuitSlotWidget(circuitInventory, 0, 7 + 18 * 4, 25 + 18 * 3) + .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.INT_CIRCUIT_OVERLAY); + builder.widget(circuitSlot.setConsumer(w -> { + String configString; + if (circuitInventory == null || + circuitInventory.getCircuitValue() == GhostCircuitItemStackHandler.NO_CONFIG) { + configString = new TextComponentTranslation("gregtech.gui.configurator_slot.no_value") + .getFormattedText(); + } else { + configString = String.valueOf(circuitInventory.getCircuitValue()); + } + + w.setTooltipText("gregtech.gui.configurator_slot.tooltip", configString); + })); - builder.bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT, 7, 18 + 18 * 4 + 12); - return builder.build(this.getHolder(), entityPlayer); + // Extra slot + builder.widget(new SlotWidget(extraSlotInventory, 0, 7 + 18 * 4, 25 + 18 * 2) + .setBackgroundTexture(GuiTextures.SLOT) + .setTooltipText("gregtech.gui.me_bus.extra_slot")); + + // Arrow image + builder.image(7 + 18 * 4, 25 + 18, 18, 18, GuiTextures.ARROW_DOUBLE); + + builder.bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 18 + 18 * 4 + 12); + return builder; } @Override @@ -190,13 +268,16 @@ public NBTTagCompound writeToNBT(NBTTagCompound data) { data.setBoolean(WORKING_TAG, this.workingEnabled); NBTTagList slots = new NBTTagList(); for (int i = 0; i < CONFIG_SIZE; i++) { - ExportOnlyAEItem slot = this.aeItemHandler.inventory[i]; + ExportOnlyAEItemSlot slot = this.getAEItemHandler().getInventory()[i]; NBTTagCompound slotTag = new NBTTagCompound(); slotTag.setInteger("slot", i); slotTag.setTag("stack", slot.serializeNBT()); slots.appendTag(slotTag); } data.setTag(ITEM_BUFFER_TAG, slots); + this.circuitInventory.write(data); + // Extra slot inventory + GTUtility.writeItems(this.extraSlotInventory, "ExtraInventory", data); return data; } @@ -210,10 +291,12 @@ public void readFromNBT(NBTTagCompound data) { NBTTagList slots = (NBTTagList) data.getTag(ITEM_BUFFER_TAG); for (NBTBase nbtBase : slots) { NBTTagCompound slotTag = (NBTTagCompound) nbtBase; - ExportOnlyAEItem slot = this.aeItemHandler.inventory[slotTag.getInteger("slot")]; + ExportOnlyAEItemSlot slot = this.getAEItemHandler().getInventory()[slotTag.getInteger("slot")]; slot.deserializeNBT(slotTag.getCompoundTag("stack")); } } + this.circuitInventory.read(data); + GTUtility.readItems(this.extraSlotInventory, "ExtraInventory", data); this.importItems = createImportItemHandler(); } @@ -221,7 +304,11 @@ public void readFromNBT(NBTTagCompound data) { public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { super.renderMetaTileEntity(renderState, translation, pipeline); if (this.shouldRenderOverlay()) { - Textures.ME_INPUT_BUS.renderSided(getFrontFacing(), renderState, translation, pipeline); + if (isOnline) { + Textures.ME_INPUT_BUS_ACTIVE.renderSided(getFrontFacing(), renderState, translation, pipeline); + } else { + Textures.ME_INPUT_BUS.renderSided(getFrontFacing(), renderState, translation, pipeline); + } } } @@ -231,6 +318,8 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.item_bus.import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.item_import.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me_import_item_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.copy_paste.tooltip")); tooltip.add(I18n.format("gregtech.universal.enabled")); } @@ -241,197 +330,79 @@ public MultiblockAbility getAbility() { @Override public void registerAbilities(List list) { - list.add(this.aeItemHandler); + list.add(this.actualImportItems); } - private static class ExportOnlyAEItemList extends NotifiableItemStackHandler { - - ExportOnlyAEItem[] inventory; - - public ExportOnlyAEItemList(MetaTileEntity holder, int slots, MetaTileEntity entityToNotify) { - super(holder, slots, entityToNotify, false); - this.inventory = new ExportOnlyAEItem[CONFIG_SIZE]; - for (int i = 0; i < CONFIG_SIZE; i++) { - this.inventory[i] = new ExportOnlyAEItem(null, null); - } - for (ExportOnlyAEItem slot : this.inventory) { - slot.trigger = this::onContentsChanged; - } - } - - @Override - public void deserializeNBT(NBTTagCompound nbt) { - for (int index = 0; index < CONFIG_SIZE; index++) { - if (nbt.hasKey("#" + index)) { - NBTTagCompound slotTag = nbt.getCompoundTag("#" + index); - this.inventory[index].deserializeNBT(slotTag); - } - } - } - - @Override - public NBTTagCompound serializeNBT() { - NBTTagCompound nbt = new NBTTagCompound(); - for (int index = 0; index < CONFIG_SIZE; index++) { - NBTTagCompound slot = this.inventory[index].serializeNBT(); - nbt.setTag("#" + index, slot); - } - return nbt; - } - - @Override - public void setStackInSlot(int slot, @NotNull ItemStack stack) { - // NO-OP - } - - @Override - public int getSlots() { - return MetaTileEntityMEInputBus.CONFIG_SIZE; - } - - @NotNull - @Override - public ItemStack getStackInSlot(int slot) { - if (slot >= 0 && slot < CONFIG_SIZE) { - return this.inventory[slot].getStackInSlot(0); - } - return ItemStack.EMPTY; - } - - @NotNull - @Override - public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { - return stack; - } - - @NotNull - @Override - public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (slot >= 0 && slot < CONFIG_SIZE) { - return this.inventory[slot].extractItem(0, amount, simulate); - } - return ItemStack.EMPTY; - } - - @Override - public int getSlotLimit(int slot) { - return Integer.MAX_VALUE; - } - - @Override - protected int getStackLimit(int slot, @NotNull ItemStack stack) { - return Integer.MAX_VALUE; - } + @Override + public boolean hasGhostCircuitInventory() { + return true; } - public static class ExportOnlyAEItem extends ExportOnlyAESlot implements IItemHandlerModifiable { - - private Consumer trigger; - - public ExportOnlyAEItem(IAEItemStack config, IAEItemStack stock) { - super(config, stock); - } - - public ExportOnlyAEItem() { - super(); - } - - @Override - public void deserializeNBT(NBTTagCompound nbt) { - if (nbt.hasKey(CONFIG_TAG)) { - this.config = WrappedItemStack.fromNBT(nbt.getCompoundTag(CONFIG_TAG)); - } - if (nbt.hasKey(STOCK_TAG)) { - this.stock = WrappedItemStack.fromNBT(nbt.getCompoundTag(STOCK_TAG)); - } - } - - @Override - public ExportOnlyAEItem copy() { - return new ExportOnlyAEItem( - this.config == null ? null : this.config.copy(), - this.stock == null ? null : this.stock.copy()); + @Override + public void setGhostCircuitConfig(int config) { + if (this.circuitInventory.getCircuitValue() == config) { + return; } - - @Override - public void setStackInSlot(int slot, @NotNull ItemStack stack) { - // NO-OP + this.circuitInventory.setCircuitValue(config); + if (!getWorld().isRemote) { + markDirty(); } + } - @Override - public int getSlots() { - return 1; - } + @Override + public final void onDataStickLeftClick(EntityPlayer player, ItemStack dataStick) { + NBTTagCompound tag = new NBTTagCompound(); + tag.setTag("MEInputBus", writeConfigToTag()); + dataStick.setTagCompound(tag); + dataStick.setTranslatableName("gregtech.machine.me.item_import.data_stick.name"); + player.sendStatusMessage(new TextComponentTranslation("gregtech.machine.me.import_copy_settings"), true); + } - @NotNull - @Override - public ItemStack getStackInSlot(int slot) { - if (slot == 0 && this.stock != null) { - return this.stock.getDefinition(); + protected NBTTagCompound writeConfigToTag() { + NBTTagCompound tag = new NBTTagCompound(); + NBTTagCompound configStacks = new NBTTagCompound(); + tag.setTag("ConfigStacks", configStacks); + for (int i = 0; i < CONFIG_SIZE; i++) { + var slot = this.aeItemHandler.getInventory()[i]; + IAEItemStack config = slot.getConfig(); + if (config == null) { + continue; } - return ItemStack.EMPTY; + NBTTagCompound stackNbt = new NBTTagCompound(); + config.getDefinition().writeToNBT(stackNbt); + configStacks.setTag(Integer.toString(i), stackNbt); } + tag.setByte("GhostCircuit", (byte) this.circuitInventory.getCircuitValue()); + return tag; + } - @NotNull - @Override - public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { - return stack; + @Override + public final boolean onDataStickRightClick(EntityPlayer player, ItemStack dataStick) { + NBTTagCompound tag = dataStick.getTagCompound(); + if (tag == null || !tag.hasKey("MEInputBus")) { + return false; } + readConfigFromTag(tag.getCompoundTag("MEInputBus")); + syncME(); + player.sendStatusMessage(new TextComponentTranslation("gregtech.machine.me.import_paste_settings"), true); + return true; + } - @NotNull - @Override - public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (slot == 0 && this.stock != null) { - int extracted = (int) Math.min(this.stock.getStackSize(), amount); - ItemStack result = this.stock.createItemStack(); - result.setCount(extracted); - if (!simulate) { - this.stock.decStackSize(extracted); - if (this.stock.getStackSize() == 0) { - this.stock = null; - } - } - if (this.trigger != null) { - this.trigger.accept(0); + protected void readConfigFromTag(NBTTagCompound tag) { + if (tag.hasKey("ConfigStacks")) { + NBTTagCompound configStacks = tag.getCompoundTag("ConfigStacks"); + for (int i = 0; i < CONFIG_SIZE; i++) { + String key = Integer.toString(i); + if (configStacks.hasKey(key)) { + NBTTagCompound configTag = configStacks.getCompoundTag(key); + this.aeItemHandler.getInventory()[i].setConfig(WrappedItemStack.fromNBT(configTag)); + } else { + this.aeItemHandler.getInventory()[i].setConfig(null); } - return result; } - return ItemStack.EMPTY; } - - @Override - public IAEItemStack requestStack() { - IAEItemStack result = super.requestStack(); - if (result instanceof WrappedItemStack) { - return ((WrappedItemStack) result).getAEStack(); - } else { - return result; - } - } - - @Override - public IAEItemStack exceedStack() { - IAEItemStack result = super.exceedStack(); - if (result instanceof WrappedItemStack) { - return ((WrappedItemStack) result).getAEStack(); - } else { - return result; - } - } - - @Override - public void addStack(IAEItemStack stack) { - if (this.stock == null) { - this.stock = WrappedItemStack.fromItemStack(stack.createItemStack()); - } else { - this.stock.add(stack); - } - this.trigger.accept(0); - } - - @Override - public int getSlotLimit(int slot) { - return Integer.MAX_VALUE; + if (tag.hasKey("GhostCircuit")) { + this.setGhostCircuitConfig(tag.getByte("GhostCircuit")); } } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java index 9a6dfa4f6aa..4e510077787 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java @@ -3,16 +3,19 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; -import gregtech.api.capability.INotifiableHandler; +import gregtech.api.capability.IDataStickIntractable; import gregtech.api.capability.impl.FluidTankList; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.ImageWidget; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.client.renderer.texture.Textures; import gregtech.common.gui.widget.appeng.AEFluidConfigWidget; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; import net.minecraft.client.resources.I18n; @@ -24,122 +27,129 @@ import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidTank; -import net.minecraftforge.fluids.capability.FluidTankProperties; -import net.minecraftforge.fluids.capability.IFluidHandler; -import net.minecraftforge.fluids.capability.IFluidTankProperties; import appeng.api.config.Actionable; import appeng.api.storage.IMEMonitor; +import appeng.api.storage.channels.IFluidStorageChannel; import appeng.api.storage.data.IAEFluidStack; -import appeng.me.GridAccessException; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; -/** - * @Author GlodBlock - * @Description The Input Hatch that can auto fetch fluid ME storage network. - * @Date 2023/4/20-21:21 - */ -public class MetaTileEntityMEInputHatch extends MetaTileEntityAEHostablePart - implements IMultiblockAbilityPart { +public class MetaTileEntityMEInputHatch extends MetaTileEntityAEHostablePart + implements IMultiblockAbilityPart, IDataStickIntractable { public final static String FLUID_BUFFER_TAG = "FluidTanks"; public final static String WORKING_TAG = "WorkingEnabled"; private final static int CONFIG_SIZE = 16; - private boolean workingEnabled; - private ExportOnlyAEFluid[] aeFluidTanks; + private boolean workingEnabled = true; + protected ExportOnlyAEFluidList aeFluidHandler; public MetaTileEntityMEInputHatch(ResourceLocation metaTileEntityId) { - super(metaTileEntityId, GTValues.UHV, false); - this.workingEnabled = true; + this(metaTileEntityId, GTValues.EV); + } + + protected MetaTileEntityMEInputHatch(ResourceLocation metaTileEntityId, int tier) { + super(metaTileEntityId, tier, false, IFluidStorageChannel.class); + } + + protected ExportOnlyAEFluidList getAEFluidHandler() { + if (aeFluidHandler == null) { + aeFluidHandler = new ExportOnlyAEFluidList(this, CONFIG_SIZE, this.getController()); + } + return aeFluidHandler; } @Override protected void initializeInventory() { - this.aeFluidTanks = new ExportOnlyAEFluid[CONFIG_SIZE]; - for (int i = 0; i < CONFIG_SIZE; i++) { - this.aeFluidTanks[i] = new ExportOnlyAEFluid(this, null, null, this.getController()); - } + getAEFluidHandler(); // initialize it super.initializeInventory(); } @Override protected FluidTankList createImportFluidHandler() { - return new FluidTankList(false, this.aeFluidTanks); + return new FluidTankList(false, getAEFluidHandler().getInventory()); } @Override public void update() { super.update(); - if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME()) { - if (this.updateMEStatus()) { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(FLUID_NET); - for (ExportOnlyAEFluid aeTank : this.aeFluidTanks) { - // Try to clear the wrong fluid - IAEFluidStack exceedFluid = aeTank.exceedStack(); - if (exceedFluid != null) { - long total = exceedFluid.getStackSize(); - IAEFluidStack notInserted = aeNetwork.injectItems(exceedFluid, Actionable.MODULATE, - this.getActionSource()); - if (notInserted != null && notInserted.getStackSize() > 0) { - aeTank.drain((int) (total - notInserted.getStackSize()), true); - continue; - } else { - aeTank.drain((int) total, true); - } - } - // Fill it - IAEFluidStack reqFluid = aeTank.requestStack(); - if (reqFluid != null) { - IAEFluidStack extracted = aeNetwork.extractItems(reqFluid, Actionable.MODULATE, - this.getActionSource()); - if (extracted != null) { - aeTank.addStack(extracted); - } - } - } - } catch (GridAccessException ignore) {} - } + if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME() && updateMEStatus()) { + syncME(); } } - @Override - public void onRemoval() { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(FLUID_NET); - for (ExportOnlyAEFluid aeTank : this.aeFluidTanks) { - IAEFluidStack stock = aeTank.stock; - if (stock instanceof WrappedFluidStack) { - stock = ((WrappedFluidStack) stock).getAEStack(); + protected void syncME() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEFluidSlot aeTank : this.getAEFluidHandler().getInventory()) { + // Try to clear the wrong fluid + IAEFluidStack exceedFluid = aeTank.exceedStack(); + if (exceedFluid != null) { + long total = exceedFluid.getStackSize(); + IAEFluidStack notInserted = monitor.injectItems(exceedFluid, Actionable.MODULATE, + this.getActionSource()); + if (notInserted != null && notInserted.getStackSize() > 0) { + aeTank.drain((int) (total - notInserted.getStackSize()), true); + continue; + } else { + aeTank.drain((int) total, true); } - if (stock != null) { - aeNetwork.injectItems(stock, Actionable.MODULATE, this.getActionSource()); + } + // Fill it + IAEFluidStack reqFluid = aeTank.requestStack(); + if (reqFluid != null) { + IAEFluidStack extracted = monitor.extractItems(reqFluid, Actionable.MODULATE, this.getActionSource()); + if (extracted != null) { + aeTank.addStack(extracted); } } - } catch (GridAccessException ignore) {} + } + } + + @Override + public void onRemoval() { + flushInventory(); super.onRemoval(); } + protected void flushInventory() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEFluidSlot aeTank : this.getAEFluidHandler().getInventory()) { + IAEFluidStack stock = aeTank.getStock(); + if (stock instanceof WrappedFluidStack) { + stock = ((WrappedFluidStack) stock).getAEStack(); + } + if (stock != null) { + monitor.injectItems(stock, Actionable.MODULATE, this.getActionSource()); + } + } + } + @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity iGregTechTileEntity) { return new MetaTileEntityMEInputHatch(this.metaTileEntityId); } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { + protected final ModularUI createUI(EntityPlayer player) { + ModularUI.Builder builder = createUITemplate(player); + return builder.build(this.getHolder(), player); + } + + protected ModularUI.Builder createUITemplate(EntityPlayer player) { ModularUI.Builder builder = ModularUI .builder(GuiTextures.BACKGROUND, 176, 18 + 18 * 4 + 94) .label(10, 5, getMetaFullName()); @@ -147,13 +157,21 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { builder.dynamicLabel(10, 15, () -> this.isOnline ? I18n.format("gregtech.gui.me_network.online") : I18n.format("gregtech.gui.me_network.offline"), - 0xFFFFFFFF); + 0x404040); // Config slots - builder.widget(new AEFluidConfigWidget(16, 25, this.aeFluidTanks)); + builder.widget(new AEFluidConfigWidget(7, 25, this.getAEFluidHandler())); + + // Arrow image + builder.image(7 + 18 * 4, 25 + 18, 18, 18, GuiTextures.ARROW_DOUBLE); - builder.bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT, 7, 18 + 18 * 4 + 12); - return builder.build(this.getHolder(), entityPlayer); + // GT Logo, cause there's some free real estate + builder.widget(new ImageWidget(7 + 18 * 4, 25 + 18 * 3, 17, 17, + GTValues.XMAS.get() ? GuiTextures.GREGTECH_LOGO_XMAS : GuiTextures.GREGTECH_LOGO) + .setIgnoreColor(true)); + + builder.bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 18 + 18 * 4 + 12); + return builder; } @Override @@ -196,7 +214,7 @@ public NBTTagCompound writeToNBT(NBTTagCompound data) { data.setBoolean(WORKING_TAG, this.workingEnabled); NBTTagList tanks = new NBTTagList(); for (int i = 0; i < CONFIG_SIZE; i++) { - ExportOnlyAEFluid tank = this.aeFluidTanks[i]; + ExportOnlyAEFluidSlot tank = this.getAEFluidHandler().getInventory()[i]; NBTTagCompound tankTag = new NBTTagCompound(); tankTag.setInteger("slot", i); tankTag.setTag("tank", tank.serializeNBT()); @@ -216,7 +234,7 @@ public void readFromNBT(NBTTagCompound data) { NBTTagList tanks = (NBTTagList) data.getTag(FLUID_BUFFER_TAG); for (NBTBase nbtBase : tanks) { NBTTagCompound tankTag = (NBTTagCompound) nbtBase; - ExportOnlyAEFluid tank = this.aeFluidTanks[tankTag.getInteger("slot")]; + ExportOnlyAEFluidSlot tank = this.getAEFluidHandler().getInventory()[tankTag.getInteger("slot")]; tank.deserializeNBT(tankTag.getCompoundTag("tank")); } } @@ -226,7 +244,11 @@ public void readFromNBT(NBTTagCompound data) { public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { super.renderMetaTileEntity(renderState, translation, pipeline); if (this.shouldRenderOverlay()) { - Textures.ME_INPUT_HATCH.renderSided(getFrontFacing(), renderState, translation, pipeline); + if (isOnline) { + Textures.ME_INPUT_HATCH_ACTIVE.renderSided(getFrontFacing(), renderState, translation, pipeline); + } else { + Textures.ME_INPUT_HATCH.renderSided(getFrontFacing(), renderState, translation, pipeline); + } } } @@ -236,6 +258,8 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.fluid_hatch.import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.fluid_import.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me_import_fluid_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.copy_paste.tooltip")); tooltip.add(I18n.format("gregtech.universal.enabled")); } @@ -246,157 +270,59 @@ public MultiblockAbility getAbility() { @Override public void registerAbilities(List list) { - list.addAll(Arrays.asList(this.aeFluidTanks)); + list.addAll(Arrays.asList(this.getAEFluidHandler().getInventory())); } - public static class ExportOnlyAEFluid extends ExportOnlyAESlot - implements IFluidTank, INotifiableHandler, IFluidHandler { - - private final List notifiableEntities = new ArrayList<>(); - private MetaTileEntity holder; - - public ExportOnlyAEFluid(MetaTileEntity holder, IAEFluidStack config, IAEFluidStack stock, MetaTileEntity mte) { - super(config, stock); - this.holder = holder; - this.notifiableEntities.add(mte); - } - - public ExportOnlyAEFluid() { - super(); - } - - @Override - public IAEFluidStack requestStack() { - IAEFluidStack result = super.requestStack(); - if (result instanceof WrappedFluidStack) { - return ((WrappedFluidStack) result).getAEStack(); - } else { - return result; - } - } - - @Override - public IAEFluidStack exceedStack() { - IAEFluidStack result = super.exceedStack(); - if (result instanceof WrappedFluidStack) { - return ((WrappedFluidStack) result).getAEStack(); - } else { - return result; - } - } - - @Override - public void addStack(IAEFluidStack stack) { - if (this.stock == null) { - this.stock = WrappedFluidStack.fromFluidStack(stack.getFluidStack()); - } else { - this.stock.add(stack); - } - trigger(); - } - - @Override - public void deserializeNBT(NBTTagCompound nbt) { - if (nbt.hasKey(CONFIG_TAG)) { - this.config = WrappedFluidStack.fromNBT(nbt.getCompoundTag(CONFIG_TAG)); - } - if (nbt.hasKey(STOCK_TAG)) { - this.stock = WrappedFluidStack.fromNBT(nbt.getCompoundTag(STOCK_TAG)); - } - } - - @Nullable - @Override - public FluidStack getFluid() { - if (this.stock != null && this.stock instanceof WrappedFluidStack) { - return ((WrappedFluidStack) this.stock).getDelegate(); - } - return null; - } - - @Override - public int getFluidAmount() { - return this.stock != null ? (int) this.stock.getStackSize() : 0; - } - - @Override - public int getCapacity() { - // Its capacity is always 0. - return 0; - } - - @Override - public FluidTankInfo getInfo() { - return new FluidTankInfo(this); - } - - @Override - public IFluidTankProperties[] getTankProperties() { - return new IFluidTankProperties[] { - new FluidTankProperties(this.getFluid(), 0) - }; - } - - @Override - public int fill(FluidStack resource, boolean doFill) { - return 0; - } - - @Nullable - @Override - public FluidStack drain(FluidStack resource, boolean doDrain) { - if (this.getFluid() != null && this.getFluid().isFluidEqual(resource)) { - return this.drain(resource.amount, doDrain); - } - return null; - } + @Override + public final void onDataStickLeftClick(EntityPlayer player, ItemStack dataStick) { + NBTTagCompound tag = new NBTTagCompound(); + tag.setTag("MEInputHatch", writeConfigToTag()); + dataStick.setTagCompound(tag); + dataStick.setTranslatableName("gregtech.machine.me.fluid_import.data_stick.name"); + player.sendStatusMessage(new TextComponentTranslation("gregtech.machine.me.import_copy_settings"), true); + } - @Nullable - @Override - public FluidStack drain(int maxDrain, boolean doDrain) { - if (this.stock == null) { - return null; - } - int drained = (int) Math.min(this.stock.getStackSize(), maxDrain); - FluidStack result = new FluidStack(this.stock.getFluid(), drained); - if (doDrain) { - this.stock.decStackSize(drained); - if (this.stock.getStackSize() == 0) { - this.stock = null; - } - trigger(); + protected NBTTagCompound writeConfigToTag() { + NBTTagCompound tag = new NBTTagCompound(); + NBTTagCompound configStacks = new NBTTagCompound(); + tag.setTag("ConfigStacks", configStacks); + for (int i = 0; i < CONFIG_SIZE; i++) { + var slot = this.aeFluidHandler.getInventory()[i]; + IAEFluidStack config = slot.getConfig(); + if (config == null) { + continue; } - return result; - } - - @Override - public void addNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { - this.notifiableEntities.add(metaTileEntity); + NBTTagCompound stackNbt = new NBTTagCompound(); + config.writeToNBT(stackNbt); + configStacks.setTag(Integer.toString(i), stackNbt); } + return tag; + } - @Override - public void removeNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { - this.notifiableEntities.remove(metaTileEntity); + @Override + public final boolean onDataStickRightClick(EntityPlayer player, ItemStack dataStick) { + NBTTagCompound tag = dataStick.getTagCompound(); + if (tag == null || !tag.hasKey("MEInputHatch")) { + return false; } + readConfigFromTag(tag.getCompoundTag("MEInputHatch")); + syncME(); + player.sendStatusMessage(new TextComponentTranslation("gregtech.machine.me.import_paste_settings"), true); + return true; + } - private void trigger() { - for (MetaTileEntity metaTileEntity : this.notifiableEntities) { - if (metaTileEntity != null && metaTileEntity.isValid()) { - this.addToNotifiedList(metaTileEntity, this, false); + protected void readConfigFromTag(NBTTagCompound tag) { + if (tag.hasKey("ConfigStacks")) { + NBTTagCompound configStacks = tag.getCompoundTag("ConfigStacks"); + for (int i = 0; i < CONFIG_SIZE; i++) { + String key = Integer.toString(i); + if (configStacks.hasKey(key)) { + NBTTagCompound configTag = configStacks.getCompoundTag(key); + this.aeFluidHandler.getInventory()[i].setConfig(WrappedFluidStack.fromNBT(configTag)); + } else { + this.aeFluidHandler.getInventory()[i].setConfig(null); } } - if (holder != null) { - holder.markDirty(); - } - } - - @Override - public ExportOnlyAEFluid copy() { - return new ExportOnlyAEFluid( - this.holder, - this.config == null ? null : this.config.copy(), - this.stock == null ? null : this.stock.copy(), - null); } } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java index 92277985603..853321014f9 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java @@ -30,9 +30,9 @@ import appeng.api.config.Actionable; import appeng.api.storage.IMEMonitor; +import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IItemList; -import appeng.me.GridAccessException; import appeng.util.item.AEItemStack; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; @@ -43,22 +43,16 @@ import java.util.ArrayList; import java.util.List; -/** - * @Author GlodBlock - * @Description The Output Bus that can directly send its contents to ME storage network. - * @Date 2023/4/19-20:37 - */ -public class MetaTileEntityMEOutputBus extends MetaTileEntityAEHostablePart +public class MetaTileEntityMEOutputBus extends MetaTileEntityAEHostablePart implements IMultiblockAbilityPart { public final static String ITEM_BUFFER_TAG = "ItemBuffer"; public final static String WORKING_TAG = "WorkingEnabled"; - private boolean workingEnabled; + private boolean workingEnabled = true; private SerializableItemList internalBuffer; public MetaTileEntityMEOutputBus(ResourceLocation metaTileEntityId) { - super(metaTileEntityId, GTValues.UHV, true); - this.workingEnabled = true; + super(metaTileEntityId, GTValues.EV, true, IItemStorageChannel.class); } @Override @@ -70,21 +64,18 @@ protected void initializeInventory() { @Override public void update() { super.update(); - if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME()) { - if (this.updateMEStatus()) { - if (!this.internalBuffer.isEmpty()) { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(ITEM_NET); - for (IAEItemStack item : this.internalBuffer) { - IAEItemStack notInserted = aeNetwork.injectItems(item.copy(), Actionable.MODULATE, - this.getActionSource()); - if (notInserted != null && notInserted.getStackSize() > 0) { - item.setStackSize(notInserted.getStackSize()); - } else { - item.reset(); - } - } - } catch (GridAccessException ignore) {} + if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME() && this.updateMEStatus()) { + if (this.internalBuffer.isEmpty()) return; + + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (IAEItemStack item : this.internalBuffer) { + IAEItemStack notInserted = monitor.injectItems(item.copy(), Actionable.MODULATE, getActionSource()); + if (notInserted != null && notInserted.getStackSize() > 0) { + item.setStackSize(notInserted.getStackSize()); + } else { + item.reset(); } } } @@ -92,12 +83,12 @@ public void update() { @Override public void onRemoval() { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(ITEM_NET); + IMEMonitor monitor = getMonitor(); + if (monitor != null) { for (IAEItemStack item : this.internalBuffer) { - aeNetwork.injectItems(item.copy(), Actionable.MODULATE, this.getActionSource()); + monitor.injectItems(item.copy(), Actionable.MODULATE, this.getActionSource()); } - } catch (GridAccessException ignore) {} + } super.onRemoval(); } @@ -115,7 +106,7 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { builder.dynamicLabel(10, 15, () -> this.isOnline ? I18n.format("gregtech.gui.me_network.online") : I18n.format("gregtech.gui.me_network.offline"), - 0xFFFFFFFF); + 0x404040); builder.label(10, 25, "gregtech.gui.waiting_list", 0xFFFFFFFF); builder.widget(new AEItemGridWidget(10, 35, 3, this.internalBuffer)); @@ -180,7 +171,11 @@ public void readFromNBT(NBTTagCompound data) { public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { super.renderMetaTileEntity(renderState, translation, pipeline); if (this.shouldRenderOverlay()) { - Textures.ME_OUTPUT_BUS.renderSided(getFrontFacing(), renderState, translation, pipeline); + if (isOnline) { + Textures.ME_OUTPUT_BUS_ACTIVE.renderSided(getFrontFacing(), renderState, translation, pipeline); + } else { + Textures.ME_OUTPUT_BUS.renderSided(getFrontFacing(), renderState, translation, pipeline); + } } } @@ -190,7 +185,7 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.item_bus.export.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.item_export.tooltip")); - tooltip.add(I18n.format("gregtech.machine.me.export.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.item_export.tooltip.2")); tooltip.add(I18n.format("gregtech.universal.enabled")); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java index c19e7e1bb51..f22c489909b 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java @@ -32,10 +32,10 @@ import appeng.api.config.Actionable; import appeng.api.storage.IMEMonitor; +import appeng.api.storage.channels.IFluidStorageChannel; import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IItemList; import appeng.fluids.util.AEFluidStack; -import appeng.me.GridAccessException; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; @@ -45,22 +45,16 @@ import java.util.ArrayList; import java.util.List; -/** - * @Author GlodBlock - * @Description The Output Hatch that can directly send its contents to ME storage network. - * @Date 2023/4/19-1:18 - */ -public class MetaTileEntityMEOutputHatch extends MetaTileEntityAEHostablePart +public class MetaTileEntityMEOutputHatch extends MetaTileEntityAEHostablePart implements IMultiblockAbilityPart { public final static String FLUID_BUFFER_TAG = "FluidBuffer"; public final static String WORKING_TAG = "WorkingEnabled"; - private boolean workingEnabled; + private boolean workingEnabled = true; private SerializableFluidList internalBuffer; public MetaTileEntityMEOutputHatch(ResourceLocation metaTileEntityId) { - super(metaTileEntityId, GTValues.UHV, true); - this.workingEnabled = true; + super(metaTileEntityId, GTValues.EV, true, IFluidStorageChannel.class); } @Override @@ -72,21 +66,18 @@ protected void initializeInventory() { @Override public void update() { super.update(); - if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME()) { - if (this.updateMEStatus()) { - if (!this.internalBuffer.isEmpty()) { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(FLUID_NET); - for (IAEFluidStack fluid : this.internalBuffer) { - IAEFluidStack notInserted = aeNetwork.injectItems(fluid.copy(), Actionable.MODULATE, - this.getActionSource()); - if (notInserted != null && notInserted.getStackSize() > 0) { - fluid.setStackSize(notInserted.getStackSize()); - } else { - fluid.reset(); - } - } - } catch (GridAccessException ignore) {} + if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME() && updateMEStatus()) { + if (this.internalBuffer.isEmpty()) return; + + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (IAEFluidStack fluid : this.internalBuffer) { + IAEFluidStack notInserted = monitor.injectItems(fluid.copy(), Actionable.MODULATE, getActionSource()); + if (notInserted != null && notInserted.getStackSize() > 0) { + fluid.setStackSize(notInserted.getStackSize()); + } else { + fluid.reset(); } } } @@ -94,12 +85,12 @@ public void update() { @Override public void onRemoval() { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(FLUID_NET); - for (IAEFluidStack fluid : this.internalBuffer) { - aeNetwork.injectItems(fluid.copy(), Actionable.MODULATE, this.getActionSource()); - } - } catch (GridAccessException ignore) {} + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (IAEFluidStack fluid : this.internalBuffer) { + monitor.injectItems(fluid.copy(), Actionable.MODULATE, this.getActionSource()); + } super.onRemoval(); } @@ -117,7 +108,7 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { builder.dynamicLabel(10, 15, () -> this.isOnline ? I18n.format("gregtech.gui.me_network.online") : I18n.format("gregtech.gui.me_network.offline"), - 0xFFFFFFFF); + 0x404040); builder.label(10, 25, "gregtech.gui.waiting_list", 0xFFFFFFFF); builder.widget(new AEFluidGridWidget(10, 35, 3, this.internalBuffer)); @@ -182,7 +173,11 @@ public void readFromNBT(NBTTagCompound data) { public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { super.renderMetaTileEntity(renderState, translation, pipeline); if (this.shouldRenderOverlay()) { - Textures.ME_OUTPUT_HATCH.renderSided(getFrontFacing(), renderState, translation, pipeline); + if (isOnline) { + Textures.ME_OUTPUT_HATCH_ACTIVE.renderSided(getFrontFacing(), renderState, translation, pipeline); + } else { + Textures.ME_OUTPUT_HATCH.renderSided(getFrontFacing(), renderState, translation, pipeline); + } } } @@ -192,7 +187,7 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.fluid_hatch.export.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.fluid_export.tooltip")); - tooltip.add(I18n.format("gregtech.machine.me.export.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.fluid_export.tooltip.2")); tooltip.add(I18n.format("gregtech.universal.enabled")); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java new file mode 100644 index 00000000000..f8bd7a5850a --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java @@ -0,0 +1,442 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng; + +import gregtech.api.GTValues; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.ImageCycleButtonWidget; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; + +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.world.World; + +import appeng.api.config.Actionable; +import appeng.api.storage.IMEMonitor; +import appeng.api.storage.data.IAEItemStack; +import appeng.api.storage.data.IItemList; +import codechicken.lib.raytracer.CuboidRayTraceResult; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.function.Predicate; + +import static gregtech.api.capability.GregtechDataCodes.UPDATE_AUTO_PULL; + +public class MetaTileEntityMEStockingBus extends MetaTileEntityMEInputBus { + + private static final int CONFIG_SIZE = 16; + private boolean autoPull; + private Predicate autoPullTest; + + public MetaTileEntityMEStockingBus(ResourceLocation metaTileEntityId) { + super(metaTileEntityId, GTValues.LuV); + this.autoPullTest = $ -> false; + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MetaTileEntityMEStockingBus(metaTileEntityId); + } + + @Override + protected ExportOnlyAEStockingItemList getAEItemHandler() { + if (this.aeItemHandler == null) { + this.aeItemHandler = new ExportOnlyAEStockingItemList(this, CONFIG_SIZE, getController()); + } + return (ExportOnlyAEStockingItemList) this.aeItemHandler; + } + + @Override + public void update() { + super.update(); + if (!getWorld().isRemote && isWorkingEnabled() && autoPull && getOffsetTimer() % 100 == 0) { + refreshList(); + syncME(); + } + } + + // Update the visual display for the fake items. This also is important for the item handler's + // getStackInSlot() method, as it uses the cached items set here. + @Override + protected void syncME() { + IMEMonitor monitor = super.getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEStockingItemSlot slot : this.getAEItemHandler().getInventory()) { + if (slot.getConfig() == null) { + slot.setStack(null); + } else { + // Try to fill the slot + IAEItemStack request; + if (slot.getConfig() instanceof WrappedItemStack wis) { + request = wis.getAEStack(); + } else { + request = slot.getConfig().copy(); + } + request.setStackSize(Integer.MAX_VALUE); + IAEItemStack result = monitor.extractItems(request, Actionable.SIMULATE, getActionSource()); + slot.setStack(result); + } + } + } + + @Override + protected void flushInventory() { + // no-op, nothing to send back to the network + } + + @Override + public void addToMultiBlock(MultiblockControllerBase controllerBase) { + super.addToMultiBlock(controllerBase); + // ensure that no other stocking bus on this multiblock is configured to hold the same item. + // that we have in our own bus. + this.autoPullTest = stack -> !this.testConfiguredInOtherBus(stack); + // also ensure that our current config is valid given other inputs + validateConfig(); + } + + @Override + public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { + // block auto-pull from working when not in a formed multiblock + this.autoPullTest = $ -> false; + if (this.autoPull) { + // may as well clear if we are auto-pull, no reason to preserve the config + this.getAEItemHandler().clearConfig(); + } + super.removeFromMultiBlock(controllerBase); + } + + @Override + public void onDistinctChange(boolean newValue) { + super.onDistinctChange(newValue); + if (!getWorld().isRemote && !newValue) { + // Ensure that our configured items won't match any other buses in the multiblock. + // Needed since we allow duplicates in distinct mode on, but not off + validateConfig(); + } + } + + /** + * Test for if any of our configured items are in another stocking bus on the multi + * we are attached to. Prevents dupes in certain situations. + */ + private void validateConfig() { + for (var slot : this.getAEItemHandler().getInventory()) { + if (slot.getConfig() != null) { + ItemStack configuredStack = slot.getConfig().createItemStack(); + if (testConfiguredInOtherBus(configuredStack)) { + slot.setConfig(null); + slot.setStock(null); + } + } + } + } + + /** + * @return True if the passed stack is found as a configuration in any other stocking buses on the multiblock. + */ + private boolean testConfiguredInOtherBus(ItemStack stack) { + if (stack == null || stack.isEmpty()) return false; + MultiblockControllerBase controller = getController(); + if (controller == null) return false; + + // In distinct mode, we don't need to check other buses since only one bus can run a recipe at a time. + if (!(controller instanceof RecipeMapMultiblockController rmmc) || !rmmc.isDistinct()) { + // Otherwise, we need to test for if the item is configured + // in any stocking bus in the multi (besides ourselves). + var abilityList = controller.getAbilities(MultiblockAbility.IMPORT_ITEMS); + for (var ability : abilityList) { + if (ability instanceof ExportOnlyAEStockingItemList aeList) { + // We don't need to check for ourselves, as this case is handled elsewhere. + if (aeList == this.aeItemHandler) continue; + if (aeList.hasStackInConfig(stack, false)) { + return true; + } + } + } + } + return false; + } + + private void setAutoPull(boolean autoPull) { + this.autoPull = autoPull; + markDirty(); + if (!getWorld().isRemote) { + if (!this.autoPull) { + this.getAEItemHandler().clearConfig(); + } else if (updateMEStatus()) { + this.refreshList(); + syncME(); + } + writeCustomData(UPDATE_AUTO_PULL, buf -> buf.writeBoolean(this.autoPull)); + } + } + + /** + * Refresh the configuration list in auto-pull mode. + * Sets the config to the first 16 valid items found in the network. + */ + private void refreshList() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) { + clearInventory(0); + return; + } + + IItemList storageList = monitor.getStorageList(); + if (storageList == null) { + clearInventory(0); + return; + } + + int index = 0; + for (IAEItemStack stack : storageList) { + if (index >= CONFIG_SIZE) break; + if (stack.getStackSize() == 0) continue; + stack = monitor.extractItems(stack, Actionable.SIMULATE, getActionSource()); + if (stack == null || stack.getStackSize() == 0) continue; + + ItemStack itemStack = stack.createItemStack(); + if (itemStack == null || itemStack.isEmpty()) continue; + // Ensure that it is valid to configure with this stack + if (autoPullTest != null && !autoPullTest.test(itemStack)) continue; + IAEItemStack selectedStack = WrappedItemStack.fromItemStack(itemStack); + if (selectedStack == null) continue; + IAEItemStack configStack = selectedStack.copy().setStackSize(1); + var slot = this.getAEItemHandler().getInventory()[index]; + slot.setConfig(configStack); + slot.setStack(selectedStack); + index++; + } + + clearInventory(index); + } + + private void clearInventory(int startIndex) { + for (int i = startIndex; i < CONFIG_SIZE; i++) { + var slot = this.getAEItemHandler().getInventory()[i]; + slot.setConfig(null); + slot.setStack(null); + } + } + + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == UPDATE_AUTO_PULL) { + this.autoPull = buf.readBoolean(); + } + } + + @Override + protected ModularUI.Builder createUITemplate(EntityPlayer player) { + ModularUI.Builder builder = super.createUITemplate(player); + builder.widget(new ImageCycleButtonWidget(7 + 18 * 4 + 1, 26, 16, 16, GuiTextures.BUTTON_AUTO_PULL, + () -> autoPull, this::setAutoPull).setTooltipHoverString("gregtech.gui.me_bus.auto_pull_button")); + return builder; + } + + @Override + public boolean onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, + CuboidRayTraceResult hitResult) { + if (!getWorld().isRemote) { + setAutoPull(!autoPull); + if (autoPull) { + playerIn.sendStatusMessage( + new TextComponentTranslation("gregtech.machine.me.stocking_auto_pull_enabled"), false); + } else { + playerIn.sendStatusMessage( + new TextComponentTranslation("gregtech.machine.me.stocking_auto_pull_disabled"), false); + } + } + return true; + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + data.setBoolean("AutoPull", autoPull); + return data; + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + this.autoPull = data.getBoolean("AutoPull"); + } + + @Override + public void writeInitialSyncData(PacketBuffer buf) { + super.writeInitialSyncData(buf); + buf.writeBoolean(autoPull); + } + + @Override + public void receiveInitialSyncData(PacketBuffer buf) { + super.receiveInitialSyncData(buf); + this.autoPull = buf.readBoolean(); + } + + private static class ExportOnlyAEStockingItemSlot extends ExportOnlyAEItemSlot { + + private final MetaTileEntityMEStockingBus holder; + + public ExportOnlyAEStockingItemSlot(IAEItemStack config, IAEItemStack stock, + MetaTileEntityMEStockingBus holder) { + super(config, stock); + this.holder = holder; + } + + public ExportOnlyAEStockingItemSlot(MetaTileEntityMEStockingBus holder) { + super(); + this.holder = holder; + } + + @Override + public ExportOnlyAEStockingItemSlot copy() { + return new ExportOnlyAEStockingItemSlot( + this.config == null ? null : this.config.copy(), + this.stock == null ? null : this.stock.copy(), + this.holder); + } + + @Override + public @NotNull ItemStack extractItem(int slot, int amount, boolean simulate) { + if (slot == 0 && this.stock != null) { + if (this.config != null) { + // Extract the items from the real net to either validate (simulate) + // or extract (modulate) when this is called + IMEMonitor monitor = holder.getMonitor(); + if (monitor == null) return ItemStack.EMPTY; + + Actionable action = simulate ? Actionable.SIMULATE : Actionable.MODULATE; + IAEItemStack request; + if (this.config instanceof WrappedItemStack wis) { + request = wis.getAEStack(); + } else { + request = this.config.copy(); + } + request.setStackSize(amount); + + IAEItemStack result = monitor.extractItems(request, action, holder.getActionSource()); + if (result != null) { + int extracted = (int) Math.min(result.getStackSize(), amount); + this.stock.decStackSize(extracted); // may as well update the display here + if (this.trigger != null) { + this.trigger.accept(0); + } + if (extracted != 0) { + ItemStack resultStack = this.config.createItemStack(); + resultStack.setCount(extracted); + return resultStack; + } + } + } + } + return ItemStack.EMPTY; + } + } + + @Override + public void addInformation(ItemStack stack, @Nullable World player, @NotNull List tooltip, + boolean advanced) { + tooltip.add(I18n.format("gregtech.machine.item_bus.import.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.stocking_item.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me_import_item_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.copy_paste.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.stocking_item.tooltip.2")); + tooltip.add(I18n.format("gregtech.universal.enabled")); + } + + @Override + protected NBTTagCompound writeConfigToTag() { + if (!autoPull) { + NBTTagCompound tag = super.writeConfigToTag(); + tag.setBoolean("AutoPull", false); + return tag; + } + // if in auto-pull, no need to write actual configured slots, but still need to write the ghost circuit + NBTTagCompound tag = new NBTTagCompound(); + tag.setBoolean("AutoPull", true); + tag.setByte("GhostCircuit", (byte) this.circuitInventory.getCircuitValue()); + return tag; + } + + @Override + protected void readConfigFromTag(NBTTagCompound tag) { + if (tag.getBoolean("AutoPull")) { + // if being set to auto-pull, no need to read the configured slots + this.setAutoPull(true); + this.setGhostCircuitConfig(tag.getByte("GhostCircuit")); + return; + } + // set auto pull first to avoid issues with clearing the config after reading from the data stick + this.setAutoPull(false); + super.readConfigFromTag(tag); + } + + private static class ExportOnlyAEStockingItemList extends ExportOnlyAEItemList { + + private final MetaTileEntityMEStockingBus holder; + + public ExportOnlyAEStockingItemList(MetaTileEntityMEStockingBus holder, int slots, + MetaTileEntity entityToNotify) { + super(holder, slots, entityToNotify); + this.holder = holder; + } + + @Override + protected void createInventory(MetaTileEntity holder) { + if (!(holder instanceof MetaTileEntityMEStockingBus stocking)) { + throw new IllegalArgumentException("Cannot create Stocking Item List for nonstocking MetaTileEntity!"); + } + this.inventory = new ExportOnlyAEStockingItemSlot[size]; + for (int i = 0; i < size; i++) { + this.inventory[i] = new ExportOnlyAEStockingItemSlot(stocking); + } + for (ExportOnlyAEItemSlot slot : this.inventory) { + slot.setTrigger(this::onContentsChanged); + } + } + + @Override + public ExportOnlyAEStockingItemSlot[] getInventory() { + return (ExportOnlyAEStockingItemSlot[]) super.getInventory(); + } + + @Override + public boolean isStocking() { + return true; + } + + @Override + public boolean isAutoPull() { + return holder.autoPull; + } + + @Override + public boolean hasStackInConfig(ItemStack stack, boolean checkExternal) { + boolean inThisBus = super.hasStackInConfig(stack, false); + if (inThisBus) return true; + if (checkExternal) { + return holder.testConfiguredInOtherBus(stack); + } + return false; + } + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java new file mode 100644 index 00000000000..fcc9e1e7d12 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java @@ -0,0 +1,401 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng; + +import gregtech.api.GTValues; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.ImageCycleButtonWidget; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; + +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidStack; + +import appeng.api.config.Actionable; +import appeng.api.storage.IMEMonitor; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IItemList; +import codechicken.lib.raytracer.CuboidRayTraceResult; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.function.Predicate; + +import static gregtech.api.capability.GregtechDataCodes.UPDATE_AUTO_PULL; + +public class MetaTileEntityMEStockingHatch extends MetaTileEntityMEInputHatch { + + private static final int CONFIG_SIZE = 16; + private boolean autoPull; + private Predicate autoPullTest; + + public MetaTileEntityMEStockingHatch(ResourceLocation metaTileEntityId) { + super(metaTileEntityId, GTValues.LuV); + this.autoPullTest = $ -> false; + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MetaTileEntityMEStockingHatch(metaTileEntityId); + } + + @Override + protected ExportOnlyAEStockingFluidList getAEFluidHandler() { + if (this.aeFluidHandler == null) { + this.aeFluidHandler = new ExportOnlyAEStockingFluidList(this, CONFIG_SIZE, getController()); + } + return (ExportOnlyAEStockingFluidList) this.aeFluidHandler; + } + + @Override + public void update() { + super.update(); + if (!getWorld().isRemote && isWorkingEnabled() && autoPull && getOffsetTimer() % 100 == 0) { + refreshList(); + syncME(); + } + } + + @Override + protected void syncME() { + IMEMonitor monitor = super.getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEStockingFluidSlot slot : this.getAEFluidHandler().getInventory()) { + if (slot.getConfig() == null) { + slot.setStack(null); + } else { + // Try to fill the slot + IAEFluidStack request; + if (slot.getConfig() instanceof WrappedFluidStack wfs) { + request = wfs.getAEStack(); + } else { + request = slot.getConfig().copy(); + } + request.setStackSize(Integer.MAX_VALUE); + IAEFluidStack result = monitor.extractItems(request, Actionable.SIMULATE, getActionSource()); + slot.setStack(result); + } + } + } + + @Override + protected void flushInventory() { + // no-op, nothing to send back to the network + } + + @Override + public void addToMultiBlock(MultiblockControllerBase controllerBase) { + super.addToMultiBlock(controllerBase); + this.autoPullTest = stack -> !this.testConfiguredInOtherHatch(stack); + validateConfig(); + } + + @Override + public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { + this.autoPullTest = $ -> false; + if (this.autoPull) { + this.getAEFluidHandler().clearConfig(); + } + super.removeFromMultiBlock(controllerBase); + } + + private void validateConfig() { + for (var slot : this.getAEFluidHandler().getInventory()) { + if (slot.getConfig() != null) { + FluidStack configuredStack = slot.getConfig().getFluidStack(); + if (testConfiguredInOtherHatch(configuredStack)) { + slot.setConfig(null); + slot.setStock(null); + } + } + } + } + + private boolean testConfiguredInOtherHatch(FluidStack stack) { + if (stack == null) return false; + MultiblockControllerBase controller = getController(); + if (controller == null) return false; + + var abilityList = controller.getAbilities(MultiblockAbility.IMPORT_FLUIDS); + for (var ability : abilityList) { + if (ability instanceof ExportOnlyAEStockingFluidSlot aeSlot) { + if (aeSlot.getConfig() == null) continue; + if (getAEFluidHandler().ownsSlot(aeSlot)) continue; + if (aeSlot.getConfig().getFluid().equals(stack.getFluid())) { + return true; + } + } + } + return false; + } + + private void setAutoPull(boolean autoPull) { + this.autoPull = autoPull; + markDirty(); + if (!getWorld().isRemote) { + if (!this.autoPull) { + this.getAEFluidHandler().clearConfig(); + } else if (updateMEStatus()) { + this.refreshList(); + syncME(); + } + writeCustomData(UPDATE_AUTO_PULL, buf -> buf.writeBoolean(this.autoPull)); + } + } + + private void refreshList() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) { + clearInventory(0); + return; + } + + IItemList storageList = monitor.getStorageList(); + if (storageList == null) { + clearInventory(0); + return; + } + + int index = 0; + for (IAEFluidStack stack : storageList) { + if (index >= CONFIG_SIZE) break; + if (stack.getStackSize() == 0) continue; + stack = monitor.extractItems(stack, Actionable.SIMULATE, getActionSource()); + if (stack == null || stack.getStackSize() == 0) continue; + + FluidStack fluidStack = stack.getFluidStack(); + if (fluidStack == null) continue; + if (autoPullTest != null && !autoPullTest.test(fluidStack)) continue; + IAEFluidStack selectedStack = WrappedFluidStack.fromFluidStack(fluidStack); + IAEFluidStack configStack = selectedStack.copy().setStackSize(1); + var slot = this.getAEFluidHandler().getInventory()[index]; + slot.setConfig(configStack); + slot.setStack(selectedStack); + index++; + } + + clearInventory(index); + } + + private void clearInventory(int startIndex) { + for (int i = startIndex; i < CONFIG_SIZE; i++) { + var slot = this.getAEFluidHandler().getInventory()[i]; + slot.setConfig(null); + slot.setStack(null); + } + } + + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == UPDATE_AUTO_PULL) { + this.autoPull = buf.readBoolean(); + } + } + + @Override + protected ModularUI.Builder createUITemplate(EntityPlayer player) { + ModularUI.Builder builder = super.createUITemplate(player); + builder.widget(new ImageCycleButtonWidget(7 + 18 * 4 + 1, 26, 16, 16, GuiTextures.BUTTON_AUTO_PULL, + () -> autoPull, this::setAutoPull).setTooltipHoverString("gregtech.gui.me_bus.auto_pull_button")); + return builder; + } + + @Override + public boolean onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, + CuboidRayTraceResult hitResult) { + if (!getWorld().isRemote) { + setAutoPull(!autoPull); + if (autoPull) { + playerIn.sendStatusMessage( + new TextComponentTranslation("gregtech.machine.me.stocking_auto_pull_enabled"), false); + } else { + playerIn.sendStatusMessage( + new TextComponentTranslation("gregtech.machine.me.stocking_auto_pull_disabled"), false); + } + } + return true; + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + data.setBoolean("AutoPull", autoPull); + return data; + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + this.autoPull = data.getBoolean("AutoPull"); + } + + @Override + public void writeInitialSyncData(PacketBuffer buf) { + super.writeInitialSyncData(buf); + buf.writeBoolean(autoPull); + } + + @Override + public void receiveInitialSyncData(PacketBuffer buf) { + super.receiveInitialSyncData(buf); + this.autoPull = buf.readBoolean(); + } + + @Override + public void addInformation(ItemStack stack, @Nullable World player, @NotNull List tooltip, + boolean advanced) { + tooltip.add(I18n.format("gregtech.machine.fluid_hatch.import.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.stocking_fluid.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me_import_fluid_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.copy_paste.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.stocking_fluid.tooltip.2")); + tooltip.add(I18n.format("gregtech.universal.enabled")); + } + + @Override + protected NBTTagCompound writeConfigToTag() { + if (!autoPull) { + NBTTagCompound tag = super.writeConfigToTag(); + tag.setBoolean("AutoPull", false); + return tag; + } + // if in auto-pull, no need to write actual configured slots, but still need to write the ghost circuit + NBTTagCompound tag = new NBTTagCompound(); + tag.setBoolean("AutoPull", true); + return tag; + } + + @Override + protected void readConfigFromTag(NBTTagCompound tag) { + if (tag.getBoolean("AutoPull")) { + // if being set to auto-pull, no need to read the configured slots + this.setAutoPull(true); + return; + } + // set auto pull first to avoid issues with clearing the config after reading from the data stick + this.setAutoPull(false); + super.readConfigFromTag(tag); + } + + private static class ExportOnlyAEStockingFluidSlot extends ExportOnlyAEFluidSlot { + + public ExportOnlyAEStockingFluidSlot(MetaTileEntityMEStockingHatch holder, IAEFluidStack config, + IAEFluidStack stock, MetaTileEntity entityToNotify) { + super(holder, config, stock, entityToNotify); + } + + public ExportOnlyAEStockingFluidSlot(MetaTileEntityMEStockingHatch holder, MetaTileEntity entityToNotify) { + super(holder, entityToNotify); + } + + @Override + protected MetaTileEntityMEStockingHatch getHolder() { + return (MetaTileEntityMEStockingHatch) super.getHolder(); + } + + @Override + public ExportOnlyAEFluidSlot copy() { + return new ExportOnlyAEStockingFluidSlot( + this.getHolder(), + this.config == null ? null : this.config.copy(), + this.stock == null ? null : this.stock.copy(), + null); + } + + @Override + public @Nullable FluidStack drain(int maxDrain, boolean doDrain) { + if (this.stock == null) { + return null; + } + if (this.config != null) { + IMEMonitor monitor = getHolder().getMonitor(); + if (monitor == null) return null; + + Actionable action = doDrain ? Actionable.MODULATE : Actionable.SIMULATE; + IAEFluidStack request; + if (this.config instanceof WrappedFluidStack wfs) { + request = wfs.getAEStack(); + } else { + request = this.config.copy(); + } + request.setStackSize(maxDrain); + + IAEFluidStack result = monitor.extractItems(request, action, getHolder().getActionSource()); + if (result != null) { + int extracted = (int) Math.min(result.getStackSize(), maxDrain); + this.stock.decStackSize(extracted); + trigger(); + if (extracted != 0) { + FluidStack resultStack = this.config.getFluidStack(); + resultStack.amount = extracted; + return resultStack; + } + } + } + return null; + } + } + + private static class ExportOnlyAEStockingFluidList extends ExportOnlyAEFluidList { + + private final MetaTileEntityMEStockingHatch holder; + + public ExportOnlyAEStockingFluidList(MetaTileEntityMEStockingHatch holder, int slots, + MetaTileEntity entityToNotify) { + super(holder, slots, entityToNotify); + this.holder = holder; + } + + @Override + protected void createInventory(MetaTileEntity holder, MetaTileEntity entityToNotify) { + if (!(holder instanceof MetaTileEntityMEStockingHatch stocking)) { + throw new IllegalArgumentException("Cannot create Stocking Fluid List for nonstocking MetaTileEntity!"); + } + this.inventory = new ExportOnlyAEStockingFluidSlot[size]; + for (int i = 0; i < size; i++) { + this.inventory[i] = new ExportOnlyAEStockingFluidSlot(stocking, entityToNotify); + } + } + + @Override + public ExportOnlyAEStockingFluidSlot[] getInventory() { + return (ExportOnlyAEStockingFluidSlot[]) super.getInventory(); + } + + @Override + public boolean isStocking() { + return true; + } + + @Override + public boolean isAutoPull() { + return holder.autoPull; + } + + @Override + public boolean hasStackInConfig(FluidStack stack, boolean checkExternal) { + boolean inThisHatch = super.hasStackInConfig(stack, false); + if (inThisHatch) return true; + if (checkExternal) { + return holder.testConfiguredInOtherHatch(stack); + } + return false; + } + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidList.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidList.java new file mode 100644 index 00000000000..fd4b40ea7e5 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidList.java @@ -0,0 +1,64 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; + +import gregtech.api.metatileentity.MetaTileEntity; + +import net.minecraftforge.fluids.FluidStack; + +import appeng.api.storage.data.IAEFluidStack; + +public class ExportOnlyAEFluidList { + + protected final int size; + protected ExportOnlyAEFluidSlot[] inventory; + + public ExportOnlyAEFluidList(MetaTileEntity holder, int slots, MetaTileEntity entityToNotify) { + this.size = slots; + createInventory(holder, entityToNotify); + } + + protected void createInventory(MetaTileEntity holder, MetaTileEntity entityToNotify) { + this.inventory = new ExportOnlyAEFluidSlot[size]; + for (int i = 0; i < size; i++) { + this.inventory[i] = new ExportOnlyAEFluidSlot(holder, entityToNotify); + } + } + + public ExportOnlyAEFluidSlot[] getInventory() { + return inventory; + } + + public void clearConfig() { + for (var slot : inventory) { + slot.setConfig(null); + slot.setStock(null); + } + } + + public boolean hasStackInConfig(FluidStack stack, boolean checkExternal) { + if (stack == null) return false; + for (ExportOnlyAEFluidSlot slot : inventory) { + IAEFluidStack config = slot.getConfig(); + if (config != null && config.getFluid().equals(stack.getFluid())) { + return true; + } + } + return false; + } + + public boolean isAutoPull() { + return false; + } + + public boolean isStocking() { + return false; + } + + public boolean ownsSlot(ExportOnlyAEFluidSlot testSlot) { + for (var slot : inventory) { + if (slot == testSlot) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidSlot.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidSlot.java new file mode 100644 index 00000000000..73ad45f9ac4 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidSlot.java @@ -0,0 +1,192 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; + +import gregtech.api.capability.INotifiableHandler; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.FluidTankProperties; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.IFluidTankProperties; + +import appeng.api.storage.data.IAEFluidStack; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public class ExportOnlyAEFluidSlot extends ExportOnlyAESlot + implements IFluidTank, INotifiableHandler, IFluidHandler { + + private final List notifiableEntities = new ArrayList<>(); + private MetaTileEntity holder; + + public ExportOnlyAEFluidSlot(MetaTileEntity holder, IAEFluidStack config, IAEFluidStack stock, MetaTileEntity mte) { + super(config, stock); + this.holder = holder; + this.notifiableEntities.add(mte); + } + + public ExportOnlyAEFluidSlot(MetaTileEntity holder, MetaTileEntity entityToNotify) { + this(holder, null, null, entityToNotify); + } + + public ExportOnlyAEFluidSlot() { + super(); + } + + @Override + public IAEFluidStack requestStack() { + IAEFluidStack result = super.requestStack(); + if (result instanceof WrappedFluidStack) { + return ((WrappedFluidStack) result).getAEStack(); + } else { + return result; + } + } + + @Override + public IAEFluidStack exceedStack() { + IAEFluidStack result = super.exceedStack(); + if (result instanceof WrappedFluidStack) { + return ((WrappedFluidStack) result).getAEStack(); + } else { + return result; + } + } + + @Override + public void addStack(IAEFluidStack stack) { + if (this.stock == null) { + this.stock = WrappedFluidStack.fromFluidStack(stack.getFluidStack()); + } else { + this.stock.add(stack); + } + trigger(); + } + + @Override + public void setStack(IAEFluidStack stack) { + if (this.stock == null && stack == null) { + return; + } else if (stack == null) { + this.stock = null; + } else if (this.stock == null || this.stock.getFluid() != stack.getFluid()) { + this.stock = WrappedFluidStack.fromFluidStack(stack.getFluidStack()); + } else if (this.stock.getStackSize() != stack.getStackSize()) { + this.stock.setStackSize(stack.getStackSize()); + } else return; + trigger(); + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + if (nbt.hasKey(CONFIG_TAG)) { + this.config = WrappedFluidStack.fromNBT(nbt.getCompoundTag(CONFIG_TAG)); + } + if (nbt.hasKey(STOCK_TAG)) { + this.stock = WrappedFluidStack.fromNBT(nbt.getCompoundTag(STOCK_TAG)); + } + } + + @Nullable + @Override + public FluidStack getFluid() { + if (this.stock != null && this.stock instanceof WrappedFluidStack) { + return ((WrappedFluidStack) this.stock).getDelegate(); + } + return null; + } + + @Override + public int getFluidAmount() { + return this.stock != null ? (int) this.stock.getStackSize() : 0; + } + + @Override + public int getCapacity() { + // Its capacity is always 0. + return 0; + } + + @Override + public FluidTankInfo getInfo() { + return new FluidTankInfo(this); + } + + @Override + public IFluidTankProperties[] getTankProperties() { + return new IFluidTankProperties[] { + new FluidTankProperties(this.getFluid(), 0) + }; + } + + @Override + public int fill(FluidStack resource, boolean doFill) { + return 0; + } + + @Nullable + @Override + public FluidStack drain(FluidStack resource, boolean doDrain) { + if (this.getFluid() != null && this.getFluid().isFluidEqual(resource)) { + return this.drain(resource.amount, doDrain); + } + return null; + } + + @Nullable + @Override + public FluidStack drain(int maxDrain, boolean doDrain) { + if (this.stock == null) { + return null; + } + int drained = (int) Math.min(this.stock.getStackSize(), maxDrain); + FluidStack result = new FluidStack(this.stock.getFluid(), drained); + if (doDrain) { + this.stock.decStackSize(drained); + if (this.stock.getStackSize() == 0) { + this.stock = null; + } + trigger(); + } + return result; + } + + @Override + public void addNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { + this.notifiableEntities.add(metaTileEntity); + } + + @Override + public void removeNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { + this.notifiableEntities.remove(metaTileEntity); + } + + protected void trigger() { + for (MetaTileEntity metaTileEntity : this.notifiableEntities) { + if (metaTileEntity != null && metaTileEntity.isValid()) { + this.addToNotifiedList(metaTileEntity, this, false); + } + } + if (holder != null) { + holder.markDirty(); + } + } + + @Override + public ExportOnlyAEFluidSlot copy() { + return new ExportOnlyAEFluidSlot( + this.holder, + this.config == null ? null : this.config.copy(), + this.stock == null ? null : this.stock.copy(), + null); + } + + protected MetaTileEntity getHolder() { + return holder; + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemList.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemList.java new file mode 100644 index 00000000000..995670eff15 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemList.java @@ -0,0 +1,126 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; + +import gregtech.api.capability.impl.NotifiableItemStackHandler; +import gregtech.api.metatileentity.MetaTileEntity; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import appeng.api.storage.data.IAEItemStack; +import org.jetbrains.annotations.NotNull; + +public class ExportOnlyAEItemList extends NotifiableItemStackHandler { + + protected final int size; + protected ExportOnlyAEItemSlot[] inventory; + + public ExportOnlyAEItemList(MetaTileEntity holder, int slots, MetaTileEntity entityToNotify) { + super(holder, slots, entityToNotify, false); + this.size = slots; + createInventory(holder); + } + + protected void createInventory(MetaTileEntity holder) { + this.inventory = new ExportOnlyAEItemSlot[size]; + for (int i = 0; i < size; i++) { + this.inventory[i] = new ExportOnlyAEItemSlot(); + } + for (ExportOnlyAEItemSlot slot : this.inventory) { + slot.setTrigger(this::onContentsChanged); + } + } + + public ExportOnlyAEItemSlot[] getInventory() { + return inventory; + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + for (int index = 0; index < size; index++) { + if (nbt.hasKey("#" + index)) { + NBTTagCompound slotTag = nbt.getCompoundTag("#" + index); + this.inventory[index].deserializeNBT(slotTag); + } + } + } + + @Override + public NBTTagCompound serializeNBT() { + NBTTagCompound nbt = new NBTTagCompound(); + for (int index = 0; index < size; index++) { + NBTTagCompound slot = this.inventory[index].serializeNBT(); + nbt.setTag("#" + index, slot); + } + return nbt; + } + + @Override + public void setStackInSlot(int slot, @NotNull ItemStack stack) { + // NO-OP + } + + @Override + public int getSlots() { + return size; + } + + @NotNull + @Override + public ItemStack getStackInSlot(int slot) { + if (slot >= 0 && slot < size) { + return this.inventory[slot].getStackInSlot(0); + } + return ItemStack.EMPTY; + } + + @NotNull + @Override + public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + return stack; + } + + @NotNull + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (slot >= 0 && slot < size) { + return this.inventory[slot].extractItem(0, amount, simulate); + } + return ItemStack.EMPTY; + } + + @Override + public int getSlotLimit(int slot) { + return Integer.MAX_VALUE; + } + + @Override + protected int getStackLimit(int slot, @NotNull ItemStack stack) { + return Integer.MAX_VALUE; + } + + public void clearConfig() { + for (var slot : inventory) { + slot.setConfig(null); + slot.setStock(null); + } + } + + public boolean hasStackInConfig(ItemStack stack, boolean checkExternal) { + if (stack == null || stack.isEmpty()) return false; + for (ExportOnlyAEItemSlot slot : inventory) { + IAEItemStack config = slot.getConfig(); + if (config != null && config.isSameType(stack)) { + return true; + } + } + return false; + } + + public boolean isAutoPull() { + return false; + } + + public boolean isStocking() { + return false; + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemSlot.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemSlot.java new file mode 100644 index 00000000000..1408d77ad49 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemSlot.java @@ -0,0 +1,138 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; + +import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.items.IItemHandlerModifiable; + +import appeng.api.storage.data.IAEItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Consumer; + +public class ExportOnlyAEItemSlot extends ExportOnlyAESlot implements IItemHandlerModifiable { + + protected Consumer trigger; + + public ExportOnlyAEItemSlot(IAEItemStack config, IAEItemStack stock) { + super(config, stock); + } + + public ExportOnlyAEItemSlot() { + super(); + } + + public void setTrigger(Consumer trigger) { + this.trigger = trigger; + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + if (nbt.hasKey(CONFIG_TAG)) { + this.config = WrappedItemStack.fromNBT(nbt.getCompoundTag(CONFIG_TAG)); + } + if (nbt.hasKey(STOCK_TAG)) { + this.stock = WrappedItemStack.fromNBT(nbt.getCompoundTag(STOCK_TAG)); + } + } + + @Override + public ExportOnlyAEItemSlot copy() { + return new ExportOnlyAEItemSlot( + this.config == null ? null : this.config.copy(), + this.stock == null ? null : this.stock.copy()); + } + + @Override + public void setStackInSlot(int slot, @NotNull ItemStack stack) {} + + @Override + public int getSlots() { + return 1; + } + + @NotNull + @Override + public ItemStack getStackInSlot(int slot) { + if (slot == 0 && this.stock != null) { + return this.stock.getDefinition(); + } + return ItemStack.EMPTY; + } + + @NotNull + @Override + public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + return stack; + } + + @NotNull + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (slot == 0 && this.stock != null) { + int extracted = (int) Math.min(this.stock.getStackSize(), amount); + ItemStack result = this.stock.createItemStack(); + result.setCount(extracted); + if (!simulate) { + this.stock.decStackSize(extracted); + if (this.stock.getStackSize() == 0) { + this.stock = null; + } + } + if (this.trigger != null) { + this.trigger.accept(0); + } + return result; + } + return ItemStack.EMPTY; + } + + @Override + public IAEItemStack requestStack() { + IAEItemStack result = super.requestStack(); + if (result instanceof WrappedItemStack) { + return ((WrappedItemStack) result).getAEStack(); + } else { + return result; + } + } + + @Override + public IAEItemStack exceedStack() { + IAEItemStack result = super.exceedStack(); + if (result instanceof WrappedItemStack) { + return ((WrappedItemStack) result).getAEStack(); + } else { + return result; + } + } + + @Override + public void addStack(IAEItemStack stack) { + if (this.stock == null) { + this.stock = WrappedItemStack.fromItemStack(stack.createItemStack()); + } else { + this.stock.add(stack); + } + this.trigger.accept(0); + } + + @Override + public void setStack(IAEItemStack stack) { + if (this.stock == null && stack == null) { + return; + } else if (stack == null) { + this.stock = null; + } else { + // todo this could maybe be improved with better comparison check + this.stock = WrappedItemStack.fromItemStack(stack.createItemStack()); + } + this.trigger.accept(0); + } + + @Override + public int getSlotLimit(int slot) { + return Integer.MAX_VALUE; + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/ExportOnlyAESlot.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAESlot.java similarity index 94% rename from src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/ExportOnlyAESlot.java rename to src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAESlot.java index 8d5027add51..316a76e422b 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/ExportOnlyAESlot.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAESlot.java @@ -1,4 +1,4 @@ -package gregtech.common.metatileentities.multi.multiblockpart.appeng; +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.util.INBTSerializable; @@ -6,11 +6,6 @@ import appeng.api.storage.data.IAEStack; import org.jetbrains.annotations.Nullable; -/** - * @author GlodBlock - * @Description A export only slot to hold {@link IAEStack} - * @date 2023/4/22-13:42 - */ public abstract class ExportOnlyAESlot> implements IConfigurableSlot, INBTSerializable { @@ -64,7 +59,9 @@ public T exceedStack() { return null; } - abstract void addStack(T stack); + public abstract void addStack(T stack); + + public abstract void setStack(T stack); @Override public NBTTagCompound serializeNBT() { diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/IConfigurableSlot.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/IConfigurableSlot.java similarity index 66% rename from src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/IConfigurableSlot.java rename to src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/IConfigurableSlot.java index 6cc3a48771d..9e4532c8f19 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/IConfigurableSlot.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/IConfigurableSlot.java @@ -1,10 +1,5 @@ -package gregtech.common.metatileentities.multi.multiblockpart.appeng; +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; -/** - * @Author GlodBlock - * @Description A slot that can be set to keep requesting. - * @Date 2023/4/21-0:34 - */ public interface IConfigurableSlot { T getConfig(); diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/stack/WrappedItemStack.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/stack/WrappedItemStack.java index 854996b0db4..274d4aac26c 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/stack/WrappedItemStack.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/stack/WrappedItemStack.java @@ -191,12 +191,18 @@ public boolean sameOre(IAEItemStack iaeItemStack) { @Override public boolean isSameType(IAEItemStack iaeItemStack) { - return false; + if (iaeItemStack == null) return false; + IAEItemStack aeStack = AEItemStack.fromItemStack(this.delegate); + if (aeStack == null) return false; + return aeStack.isSameType(iaeItemStack); } @Override public boolean isSameType(ItemStack itemStack) { - return false; + if (this.delegate.isEmpty()) return itemStack.isEmpty(); + IAEItemStack aeStack = AEItemStack.fromItemStack(this.delegate); + if (aeStack == null) return false; + return aeStack.isSameType(itemStack); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/primitive/MetaTileEntityCharcoalPileIgniter.java b/src/main/java/gregtech/common/metatileentities/primitive/MetaTileEntityCharcoalPileIgniter.java index 56a96fb43ca..1439a5c5554 100644 --- a/src/main/java/gregtech/common/metatileentities/primitive/MetaTileEntityCharcoalPileIgniter.java +++ b/src/main/java/gregtech/common/metatileentities/primitive/MetaTileEntityCharcoalPileIgniter.java @@ -13,6 +13,7 @@ import gregtech.api.metatileentity.multiblock.IMultiblockPart; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.pattern.*; +import gregtech.api.util.Mods; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.TooltipHelper; @@ -449,7 +450,7 @@ public static void addWallBlock(@NotNull Block block) { } @ZenMethod("addWallBlock") - @Optional.Method(modid = GTValues.MODID_CT) + @Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) @SuppressWarnings("unused") public static void addWallBlockCT(@NotNull IBlock block) { WALL_BLOCKS.add(CraftTweakerMC.getBlock(block)); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java index 44859246953..ccd9a9de8fc 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java @@ -46,7 +46,6 @@ import java.util.List; import static gregtech.api.capability.GregtechDataCodes.IS_TAPED; -import static gregtech.api.capability.GregtechDataCodes.TAG_KEY_PAINTING_COLOR; public class MetaTileEntityCrate extends MetaTileEntity { @@ -75,11 +74,6 @@ public boolean hasFrontFacing() { return false; } - @Override - public int getLightOpacity() { - return 1; - } - @Override public String getHarvestTool() { return ModHandler.isMaterialWood(material) ? ToolClasses.AXE : ToolClasses.WRENCH; diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java index 50dd8dc5cbe..e34f104d679 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java @@ -69,7 +69,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, Textures.QUANTUM_STORAGE_RENDERER.renderMachine(renderState, translation, ArrayUtils.add(pipeline, new ColourMultiplier(GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))), - this.getFrontFacing(), this.getTier()); + this); Textures.CREATIVE_CONTAINER_OVERLAY.renderSided(EnumFacing.UP, renderState, translation, pipeline); Textures.PIPE_OUT_OVERLAY.renderSided(this.getOutputFacing(), renderState, translation, pipeline); Textures.ITEM_OUTPUT_OVERLAY.renderSided(this.getOutputFacing(), renderState, translation, pipeline); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java index 1f35630af35..3e93c1bcbd5 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java @@ -52,7 +52,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, Textures.QUANTUM_STORAGE_RENDERER.renderMachine(renderState, translation, ArrayUtils.add(pipeline, new ColourMultiplier(GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))), - this.getFrontFacing(), this.getTier()); + this); Textures.CREATIVE_CONTAINER_OVERLAY.renderSided(EnumFacing.UP, renderState, translation, pipeline); if (this.getOutputFacing() != null) { Textures.PIPE_OUT_OVERLAY.renderSided(this.getOutputFacing(), renderState, translation, pipeline); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java index ae83ad54a49..7a5ef5b4d38 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java @@ -44,6 +44,7 @@ import codechicken.lib.vec.Matrix4; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; @@ -70,16 +71,6 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { return new MetaTileEntityDrum(metaTileEntityId, material, tankSize); } - @Override - public int getLightOpacity() { - return 1; - } - - @Override - public boolean isOpaqueCube() { - return false; - } - @Override public String getHarvestTool() { return ModHandler.isMaterialWood(material) ? ToolClasses.AXE : ToolClasses.WRENCH; @@ -97,7 +88,7 @@ protected void initializeInventory() { IPropertyFluidFilter filter = this.material.getProperty(PropertyKey.FLUID_PIPE); if (filter == null) { throw new IllegalArgumentException( - String.format("Material %s requires FluidPipePropety for Drums", material)); + String.format("Material %s requires FluidPipeProperty for Drums", material)); } this.fluidInventory = this.fluidTank = new FilteredFluidHandler(tankSize).setFilter(filter); } @@ -129,7 +120,7 @@ public ICapabilityProvider initItemStackCapabilities(ItemStack itemStack) { } @Override - public void writeInitialSyncData(PacketBuffer buf) { + public void writeInitialSyncData(@NotNull PacketBuffer buf) { super.writeInitialSyncData(buf); FluidStack fluidStack = fluidTank.getFluid(); buf.writeBoolean(fluidStack != null); @@ -142,7 +133,7 @@ public void writeInitialSyncData(PacketBuffer buf) { } @Override - public void receiveInitialSyncData(PacketBuffer buf) { + public void receiveInitialSyncData(@NotNull PacketBuffer buf) { super.receiveInitialSyncData(buf); FluidStack fluidStack = null; if (buf.readBoolean()) { @@ -156,7 +147,7 @@ public void receiveInitialSyncData(PacketBuffer buf) { } @Override - public void receiveCustomData(int dataId, PacketBuffer buf) { + public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { super.receiveCustomData(dataId, buf); if (dataId == UPDATE_AUTO_OUTPUT) { this.isAutoOutput = buf.readBoolean(); @@ -266,7 +257,7 @@ public void addInformation(ItemStack stack, @Nullable World player, List FluidStack fluidStack = FluidStack.loadFluidStackFromNBT(tagCompound.getCompoundTag("Fluid")); if (fluidStack == null) return; tooltip.add(I18n.format("gregtech.machine.fluid_tank.fluid", fluidStack.amount, - I18n.format(fluidStack.getUnlocalizedName()))); + fluidStack.getFluid().getLocalizedName(fluidStack))); } } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumChest.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumChest.java index be6c63f5dec..bd6dca83fb8 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumChest.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumChest.java @@ -102,7 +102,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, Textures.QUANTUM_STORAGE_RENDERER.renderMachine(renderState, translation, ArrayUtils.add(pipeline, new ColourMultiplier(GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))), - this.getFrontFacing(), this.tier); + this); Textures.QUANTUM_CHEST_OVERLAY.renderSided(EnumFacing.UP, renderState, translation, pipeline); if (outputFacing != null) { Textures.PIPE_OUT_OVERLAY.renderSided(outputFacing, renderState, translation, pipeline); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java index 6e27064a4e3..7e5d244f556 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java @@ -11,7 +11,14 @@ import gregtech.api.cover.CoverRayTracer; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.*; +import gregtech.api.gui.widgets.AdvancedTextWidget; +import gregtech.api.gui.widgets.FluidContainerSlotWidget; +import gregtech.api.gui.widgets.ImageWidget; +import gregtech.api.gui.widgets.LabelWidget; +import gregtech.api.gui.widgets.PhantomTankWidget; +import gregtech.api.gui.widgets.SlotWidget; +import gregtech.api.gui.widgets.TankWidget; +import gregtech.api.gui.widgets.ToggleButtonWidget; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.IFastRenderMetaTileEntity; import gregtech.api.metatileentity.ITieredMetaTileEntity; @@ -33,6 +40,7 @@ import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentTranslation; @@ -127,9 +135,17 @@ public void update() { updatePreviousFluid(null); } else if (previousFluid.getFluid().equals(currentFluid.getFluid()) && previousFluid.amount != currentFluid.amount) { + int currentFill = MathHelper + .floor(16 * ((float) currentFluid.amount) / fluidTank.getCapacity()); + int previousFill = MathHelper + .floor(16 * ((float) previousFluid.amount) / fluidTank.getCapacity()); // tank has fluid with changed amount previousFluid.amount = currentFluid.amount; - writeCustomData(UPDATE_FLUID_AMOUNT, buf -> buf.writeInt(currentFluid.amount)); + writeCustomData(UPDATE_FLUID_AMOUNT, buf -> { + buf.writeInt(currentFluid.amount); + buf.writeBoolean(currentFill != previousFill); + }); + } else if (!previousFluid.equals(currentFluid)) { // tank has a different fluid from before @@ -259,7 +275,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, Textures.QUANTUM_STORAGE_RENDERER.renderMachine(renderState, translation, ArrayUtils.add(pipeline, new ColourMultiplier(GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))), - this.getFrontFacing(), this.tier); + this); Textures.QUANTUM_TANK_OVERLAY.renderSided(EnumFacing.UP, renderState, translation, pipeline); if (outputFacing != null) { Textures.PIPE_OUT_OVERLAY.renderSided(outputFacing, renderState, translation, pipeline); @@ -275,6 +291,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, public void renderMetaTileEntity(double x, double y, double z, float partialTicks) { if (this.fluidTank.getFluid() == null || this.fluidTank.getFluid().amount == 0) return; + QuantumStorageRenderer.renderTankAmount(x, y, z, this.getFrontFacing(), this.fluidTank.getFluid().amount); } @@ -443,15 +460,19 @@ public void receiveCustomData(int dataId, PacketBuffer buf) { try { this.fluidTank.setFluid(FluidStack.loadFluidStackFromNBT(buf.readCompoundTag())); } catch (IOException ignored) { - GTLog.logger.warn("Failed to load fluid from NBT in a quantum tank at " + this.getPos() + - " on a routine fluid update"); + GTLog.logger.warn("Failed to load fluid from NBT in a quantum tank at {} on a routine fluid update", + this.getPos()); } scheduleRenderUpdate(); } else if (dataId == UPDATE_FLUID_AMOUNT) { + // amount must always be read even if it cannot be used to ensure the reader index advances + int amount = buf.readInt(); + boolean updateRendering = buf.readBoolean(); FluidStack stack = fluidTank.getFluid(); if (stack != null) { - stack.amount = Math.min(buf.readInt(), fluidTank.getCapacity()); - scheduleRenderUpdate(); + stack.amount = Math.min(amount, fluidTank.getCapacity()); + if (updateRendering) + scheduleRenderUpdate(); } } else if (dataId == UPDATE_IS_VOIDING) { setVoiding(buf.readBoolean()); diff --git a/src/main/java/gregtech/common/mui/widget/HighlightedTextField.java b/src/main/java/gregtech/common/mui/widget/HighlightedTextField.java new file mode 100644 index 00000000000..3bb6a3e652b --- /dev/null +++ b/src/main/java/gregtech/common/mui/widget/HighlightedTextField.java @@ -0,0 +1,95 @@ +package gregtech.common.mui.widget; + +import com.cleanroommc.modularui.api.value.IStringValue; +import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.widgets.textfield.TextFieldHandler; +import com.cleanroommc.modularui.widgets.textfield.TextFieldRenderer; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; + +import java.util.Map; +import java.util.function.Function; + +public class HighlightedTextField extends TextFieldWidget { + + private StringSyncValue stringSyncValue; + + private final TextHighlighter highlighter; + private Runnable onUnfocus; + + public HighlightedTextField() { + this.highlighter = new TextHighlighter(this.handler); + this.renderer = this.highlighter; + this.handler.setRenderer(this.renderer); + } + + @Override + public void afterInit() { + this.highlighter.runHighlighter(getText()); + } + + /** + * Text highlighter applied only in rendering text. Only formatting characters can be inserted. + * + * @param highlightRule Consumer for text highlighter + * @return This + */ + public HighlightedTextField setHighlightRule(Function highlightRule) { + this.highlighter.setHighlightRule(highlightRule); + return getThis(); + } + + @Override + public HighlightedTextField value(IStringValue stringValue) { + this.stringSyncValue = (StringSyncValue) stringValue; + super.value(stringValue); + return getThis(); + } + + @Override + public HighlightedTextField getThis() { + return this; + } + + @Override + public void onRemoveFocus(GuiContext context) { + super.onRemoveFocus(context); + highlighter.runHighlighter(getText()); + if (isSynced()) + this.stringSyncValue.setStringValue(getText(), true, true); + onUnfocus.run(); + } + + public HighlightedTextField onUnfocus(Runnable onUnfocus) { + this.onUnfocus = onUnfocus; + return getThis(); + } + + public static final class TextHighlighter extends TextFieldRenderer { + + private Function highlightRule = string -> string; + + private Map cacheMap = new Object2ObjectOpenHashMap<>(); + + public TextHighlighter(TextFieldHandler handler) { + super(handler); + } + + public void setHighlightRule(Function highlightRule) { + this.highlightRule = highlightRule; + } + + @Override + protected float draw(String text, float x, float y) { + return super.draw(this.cacheMap.getOrDefault(text, text), x, y); + } + + public void runHighlighter(String text) { + if (this.highlightRule == null) { + return; + } + this.cacheMap.computeIfAbsent(text, string -> this.highlightRule.apply(string)); + } + } +} diff --git a/src/main/java/gregtech/common/mui/widget/orefilter/ItemOreFilterTestSlot.java b/src/main/java/gregtech/common/mui/widget/orefilter/ItemOreFilterTestSlot.java new file mode 100644 index 00000000000..9e16df34dfb --- /dev/null +++ b/src/main/java/gregtech/common/mui/widget/orefilter/ItemOreFilterTestSlot.java @@ -0,0 +1,42 @@ +package gregtech.common.mui.widget.orefilter; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.items.ItemStackHandler; + +import com.cleanroommc.modularui.widgets.slot.ModularSlot; +import org.jetbrains.annotations.NotNull; + +public class ItemOreFilterTestSlot extends ModularSlot { + + OreFilterTestSlot parent; + + public ItemOreFilterTestSlot() { + super(new ItemStackHandler(1), 0, true); + } + + void setParent(OreFilterTestSlot parent) { + this.parent = parent; + } + + @Override + public void putStack(ItemStack stack) { + ItemStack testStack = getStack(); + if ((stack.isEmpty() ^ testStack.isEmpty()) || !testStack.isItemEqual(stack) || + !ItemStack.areItemStackTagsEqual(testStack, stack)) { + ItemStack copy = stack.copy(); + copy.setCount(1); + super.putStack(copy); + this.parent.updatePreview(); + } + } + + @Override + public int getSlotStackLimit() { + return 1; + } + + @Override + public int getItemStackLimit(@NotNull ItemStack stack) { + return 1; + } +} diff --git a/src/main/java/gregtech/common/mui/widget/orefilter/OreFilterTestSlot.java b/src/main/java/gregtech/common/mui/widget/orefilter/OreFilterTestSlot.java new file mode 100644 index 00000000000..1948364bbec --- /dev/null +++ b/src/main/java/gregtech/common/mui/widget/orefilter/OreFilterTestSlot.java @@ -0,0 +1,144 @@ +package gregtech.common.mui.widget.orefilter; + +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.unification.OreDictUnifier; +import gregtech.api.util.function.BooleanConsumer; +import gregtech.api.util.oreglob.OreGlob; +import gregtech.common.covers.filter.oreglob.impl.ImpossibleOreGlob; + +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.theme.WidgetTheme; +import com.cleanroommc.modularui.widgets.ItemSlot; +import it.unimi.dsi.fastutil.objects.Object2BooleanAVLTreeMap; +import it.unimi.dsi.fastutil.objects.Object2BooleanMap; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * @author brachy84 + */ +public class OreFilterTestSlot extends ItemSlot { + + private final ItemOreFilterTestSlot slot; + private Supplier globSupplier = ImpossibleOreGlob::getInstance; + @Nullable + private BooleanConsumer onMatchChange; + private final Object2BooleanMap testResult = new Object2BooleanAVLTreeMap<>(); + private MatchType matchType = MatchType.INVALID; + private boolean matchSuccess; + private boolean matchAll; + + public OreFilterTestSlot() { + this.slot = new ItemOreFilterTestSlot(); + this.slot.setParent(this); + slot(this.slot); + tooltipBuilder(tooltip -> { + if (!isEnabled()) return; + tooltip.addDrawableLines(switch (this.matchType) { + case NO_ORE_DICT_MATCH -> Collections.singletonList(IKey.lang(this.matchSuccess ? + "cover.ore_dictionary_filter.test_slot.no_oredict.matches" : + "cover.ore_dictionary_filter.test_slot.no_oredict.matches_not")); + case ORE_DICT_MATCH -> this.testResult.object2BooleanEntrySet() + .stream().map(e -> IKey.lang(e.getBooleanValue() ? + "cover.ore_dictionary_filter.test_slot.matches" : + "cover.ore_dictionary_filter.test_slot.matches_not", e.getKey())) + .collect(Collectors.toList()); + default -> Collections.singletonList(IKey.lang("cover.ore_dictionary_filter.test_slot.info")); + }); + }); + } + + public OreFilterTestSlot setGlobSupplier(Supplier supplier) { + this.globSupplier = supplier; + this.updatePreview(); + return getThis(); + } + + @Override + public OreFilterTestSlot getThis() { + return this; + } + + public boolean isMatchSuccess() { + return matchSuccess; + } + + public OreFilterTestSlot onMatchChange(@Nullable BooleanConsumer onMatchChange) { + this.onMatchChange = onMatchChange; + return getThis(); + } + + public void setMatchAll(boolean matchAll) { + if (this.matchAll == matchAll) return; + this.matchAll = matchAll; + updatePreview(); + } + + public void updatePreview() { + Set oreDicts = getTestCandidates(); + this.testResult.clear(); + if (oreDicts == null) { + this.matchType = MatchType.INVALID; + updateAndNotifyMatchSuccess(false); + return; + } + OreGlob glob = this.globSupplier.get(); + int success = 0; + if (oreDicts.isEmpty()) { + // no oredict entries + this.testResult.put("", glob != null && glob.matches("")); + this.matchType = MatchType.NO_ORE_DICT_MATCH; + } else { + for (String oreDict : oreDicts) { + boolean matches = glob != null && glob.matches(oreDict); + if (matches) success++; + this.testResult.put(oreDict, matches); + } + this.matchType = MatchType.ORE_DICT_MATCH; + } + updateAndNotifyMatchSuccess(this.matchAll ? success == testResult.size() : success > 0); + this.tooltip().markDirty(); + } + + @Override + public void draw(GuiContext context, WidgetTheme widgetTheme) { + super.draw(context, widgetTheme); + if (this.matchSuccess) { + GTGuiTextures.OREDICT_MATCH + .draw(context, 12, -2, 9, 6, widgetTheme); + } else if (testResult.size() > 0) { + GTGuiTextures.OREDICT_NO_MATCH + .draw(context, 12, -3, 7, 7, widgetTheme); + } + } + + private void updateAndNotifyMatchSuccess(boolean newValue) { + if (this.matchSuccess == newValue) return; + this.matchSuccess = newValue; + if (this.onMatchChange != null) { + this.onMatchChange.apply(newValue); + } + } + + /** + * Get each test candidate for current state of test slot. An empty collection indicates that the match is for items + * without any ore dictionary entry. A {@code null} value indicates that the input state is invalid or empty. + * + * @return each test candidate for current state of test slot + */ + @Nullable + protected Set getTestCandidates() { + return this.slot.getStack().isEmpty() ? null : OreDictUnifier.getOreDictionaryNames(this.slot.getStack()); + } + + private enum MatchType { + NO_ORE_DICT_MATCH, + ORE_DICT_MATCH, + INVALID + } +} diff --git a/src/main/java/gregtech/common/pipelike/cable/BlockCable.java b/src/main/java/gregtech/common/pipelike/cable/BlockCable.java index d384e22e608..204010ed522 100644 --- a/src/main/java/gregtech/common/pipelike/cable/BlockCable.java +++ b/src/main/java/gregtech/common/pipelike/cable/BlockCable.java @@ -1,6 +1,5 @@ package gregtech.common.pipelike.cable; -import gregtech.api.GregTechAPI; import gregtech.api.capability.GregtechCapabilities; import gregtech.api.damagesources.DamageSources; import gregtech.api.items.toolitem.ToolClasses; @@ -14,6 +13,7 @@ import gregtech.api.util.GTUtility; import gregtech.client.renderer.pipe.CableRenderer; import gregtech.client.renderer.pipe.PipeRenderer; +import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.pipelike.cable.net.WorldENet; import gregtech.common.pipelike.cable.tile.TileEntityCable; import gregtech.common.pipelike.cable.tile.TileEntityCableTickable; @@ -54,7 +54,7 @@ public class BlockCable extends BlockMaterialPipe world = new TreeSet<>(); @@ -425,7 +422,7 @@ private boolean addVoxelMapWaypoint(@NotNull BlockPos b) { return false; } - @Optional.Method(modid = GTValues.MODID_XAERO_MINIMAP) + @Optional.Method(modid = Mods.Names.XAEROS_MINIMAP) private boolean addXaeroMapWaypoint(@NotNull BlockPos b) { int red = clampColor(color >> 16 & 0xFF); int green = clampColor(color >> 8 & 0xFF); diff --git a/src/main/java/gregtech/common/terminal/app/worldprospector/WorldProspectorARApp.java b/src/main/java/gregtech/common/terminal/app/worldprospector/WorldProspectorARApp.java index f4b7fe6f2e1..8ead4466af8 100644 --- a/src/main/java/gregtech/common/terminal/app/worldprospector/WorldProspectorARApp.java +++ b/src/main/java/gregtech/common/terminal/app/worldprospector/WorldProspectorARApp.java @@ -17,6 +17,7 @@ import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.stack.MaterialStack; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.client.shader.Shaders; import gregtech.client.utils.DepthTextureUtil; import gregtech.client.utils.RenderBufferHelper; @@ -490,7 +491,7 @@ private static void renderScan(float getPartialTicks) { Minecraft mc = Minecraft.getMinecraft(); World world = mc.world; Entity viewer = mc.getRenderViewEntity(); - if (world != null && viewer != null && !Shaders.isOptiFineShaderPackLoaded()) { + if (world != null && viewer != null && !Mods.Optifine.isModLoaded()) { Framebuffer fbo = mc.getFramebuffer(); diff --git a/src/main/java/gregtech/core/CoreModule.java b/src/main/java/gregtech/core/CoreModule.java index 46eeb3e8335..c05116355f7 100644 --- a/src/main/java/gregtech/core/CoreModule.java +++ b/src/main/java/gregtech/core/CoreModule.java @@ -43,7 +43,6 @@ import gregtech.common.command.CommandShaders; import gregtech.common.command.worldgen.CommandWorldgen; import gregtech.common.covers.CoverBehaviors; -import gregtech.common.covers.filter.FilterTypeRegistry; import gregtech.common.covers.filter.oreglob.impl.OreGlobParser; import gregtech.common.items.MetaItems; import gregtech.common.items.ToolItems; @@ -255,7 +254,6 @@ public void init(FMLInitializationEvent event) { WorldGenRegistry.INSTANCE.initializeRegistry(); LootTableHelper.initialize(); - FilterTypeRegistry.init(); /* Start Cover Definition Registration */ COVER_REGISTRY.unfreeze(); diff --git a/src/main/java/gregtech/integration/IntegrationModule.java b/src/main/java/gregtech/integration/IntegrationModule.java index 15d760b4a63..65f02e3c938 100644 --- a/src/main/java/gregtech/integration/IntegrationModule.java +++ b/src/main/java/gregtech/integration/IntegrationModule.java @@ -2,12 +2,12 @@ import gregtech.api.GTValues; import gregtech.api.modules.GregTechModule; +import gregtech.api.util.Mods; import gregtech.common.items.MetaItems; import gregtech.modules.BaseGregTechModule; import gregtech.modules.GregTechModules; import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -47,13 +47,13 @@ public List> getEventBusSubscribers() { public void init(FMLInitializationEvent event) { super.init(event); - if (Loader.isModLoaded(GTValues.MODID_IE)) { + if (Mods.ImmersiveEngineering.isModLoaded()) { BelljarHandler.registerBasicItemFertilizer(MetaItems.FERTILIZER.getStackForm(), 1.25f); logger.info("Registered Immersive Engineering Compat"); } } - @Optional.Method(modid = GTValues.MODID_EIO) + @Optional.Method(modid = Mods.Names.ENDER_IO) @SubscribeEvent public static void registerFertilizer(@NotNull RegistryEvent.Register event) { event.getRegistry().register(new Bonemeal(MetaItems.FERTILIZER.getStackForm())); diff --git a/src/main/java/gregtech/integration/IntegrationUtil.java b/src/main/java/gregtech/integration/IntegrationUtil.java index 88cfe6ec990..c25edab7be0 100644 --- a/src/main/java/gregtech/integration/IntegrationUtil.java +++ b/src/main/java/gregtech/integration/IntegrationUtil.java @@ -11,6 +11,7 @@ import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -18,9 +19,16 @@ import java.util.Arrays; import java.util.List; +@Deprecated public class IntegrationUtil { - /** Should only be called after {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent} */ + /** + * Should only be called after {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent} + * + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public static void throwIncompatibilityIfLoaded(String modID, String... customMessages) { if (Loader.isModLoaded(modID)) { String modName = TextFormatting.BOLD + modID + TextFormatting.RESET; @@ -31,7 +39,13 @@ public static void throwIncompatibilityIfLoaded(String modID, String... customMe } } - /** Should only be called after {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent} */ + /** + * Should only be called after {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent} + * + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public static void throwIncompatibility(List messages) { if (FMLLaunchHandler.side() == Side.SERVER) { throw new RuntimeException(String.join(",", messages)); @@ -40,16 +54,31 @@ public static void throwIncompatibility(List messages) { } } + /** + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @NotNull public static ItemStack getModItem(@NotNull String modid, @NotNull String name, int meta) { return getModItem(modid, name, meta, 1, null); } + /** + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @NotNull public static ItemStack getModItem(@NotNull String modid, @NotNull String name, int meta, int amount) { return getModItem(modid, name, meta, amount, null); } + /** + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @NotNull public static ItemStack getModItem(@NotNull String modid, @NotNull String name, int meta, int amount, @Nullable String nbt) { diff --git a/src/main/java/gregtech/integration/baubles/BaublesModule.java b/src/main/java/gregtech/integration/baubles/BaublesModule.java index 4371d5a032d..6f725211e8f 100644 --- a/src/main/java/gregtech/integration/baubles/BaublesModule.java +++ b/src/main/java/gregtech/integration/baubles/BaublesModule.java @@ -2,6 +2,7 @@ import gregtech.api.GTValues; import gregtech.api.modules.GregTechModule; +import gregtech.api.util.Mods; import gregtech.common.items.MetaItems; import gregtech.integration.IntegrationSubmodule; import gregtech.modules.GregTechModules; @@ -24,7 +25,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_BAUBLES, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_BAUBLES, + modDependencies = Mods.Names.BAUBLES, name = "GregTech Baubles Integration", description = "Baubles Integration Module") public class BaublesModule extends IntegrationSubmodule { diff --git a/src/main/java/gregtech/integration/chisel/ChiselModule.java b/src/main/java/gregtech/integration/chisel/ChiselModule.java index c6dc3cafe05..c8a5f8d3416 100644 --- a/src/main/java/gregtech/integration/chisel/ChiselModule.java +++ b/src/main/java/gregtech/integration/chisel/ChiselModule.java @@ -5,6 +5,7 @@ import gregtech.api.modules.GregTechModule; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.Materials; +import gregtech.api.util.Mods; import gregtech.common.blocks.BlockColored; import gregtech.common.blocks.BlockCompressed; import gregtech.common.blocks.BlockWarningSign; @@ -31,7 +32,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_CHISEL, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_CHISEL, + modDependencies = Mods.Names.CHISEL, name = "GregTech Chisel Integration", description = "Chisel Integration Module") public class ChiselModule extends IntegrationSubmodule { @@ -110,7 +111,7 @@ private void addVariation(String group, Block block, int meta) { tag.setString("group", group); tag.setString("block", Objects.requireNonNull(block.getRegistryName()).toString()); tag.setInteger("meta", meta); - FMLInterModComms.sendMessage(GTValues.MODID_CHISEL, "add_variation", tag); + FMLInterModComms.sendMessage(Mods.Names.CHISEL, "add_variation", tag); } private boolean doesGroupExist(String group) { diff --git a/src/main/java/gregtech/integration/crafttweaker/CraftTweakerModule.java b/src/main/java/gregtech/integration/crafttweaker/CraftTweakerModule.java index 400c41a1110..37fb6535fe5 100644 --- a/src/main/java/gregtech/integration/crafttweaker/CraftTweakerModule.java +++ b/src/main/java/gregtech/integration/crafttweaker/CraftTweakerModule.java @@ -4,6 +4,7 @@ import gregtech.api.items.metaitem.MetaOreDictItem; import gregtech.api.modules.GregTechModule; import gregtech.api.unification.material.event.MaterialEvent; +import gregtech.api.util.Mods; import gregtech.integration.IntegrationModule; import gregtech.integration.IntegrationSubmodule; import gregtech.integration.crafttweaker.recipe.MetaItemBracketHandler; @@ -27,7 +28,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_CT, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_CT, + modDependencies = Mods.Names.CRAFT_TWEAKER, name = "GregTech CraftTweaker Integration", description = "CraftTweaker Integration Module") public class CraftTweakerModule extends IntegrationSubmodule { diff --git a/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialBuilder.java b/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialBuilder.java index b8dc8e77a9b..d12a134adc5 100644 --- a/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialBuilder.java +++ b/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialBuilder.java @@ -1,6 +1,5 @@ package gregtech.integration.crafttweaker.material; -import gregtech.api.GTValues; import gregtech.api.fluids.FluidBuilder; import gregtech.api.fluids.FluidState; import gregtech.api.fluids.store.FluidStorageKey; @@ -14,6 +13,7 @@ import gregtech.api.unification.material.properties.ToolProperty; import gregtech.api.unification.stack.MaterialStack; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import net.minecraft.enchantment.Enchantment; @@ -264,7 +264,7 @@ public CTMaterialBuilder itemPipeProperties(int priority, float stacksPerSec) { } @ZenMethod - @net.minecraftforge.fml.common.Optional.Method(modid = GTValues.MODID_CT) + @net.minecraftforge.fml.common.Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) public CTMaterialBuilder addDefaultEnchant(IEnchantment enchantment) { Enchantment enchantmentType = (Enchantment) enchantment.getDefinition().getInternal(); backingBuilder.addDefaultEnchant(enchantmentType, enchantment.getLevel()); diff --git a/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java b/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java index ca5d08a1efa..ed66c077a40 100644 --- a/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java +++ b/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java @@ -4,6 +4,7 @@ import gregtech.api.fluids.FluidState; import gregtech.api.unification.material.Material; import gregtech.api.unification.stack.MaterialStack; +import gregtech.integration.groovy.GroovyScriptModule; import com.google.common.collect.ImmutableList; import crafttweaker.CraftTweakerAPI; @@ -17,7 +18,9 @@ protected static ImmutableList validateComponentList(MaterialStac protected static FluidState validateFluidState(String fluidTypeName) { if (fluidTypeName == null || fluidTypeName.equals("fluid")) return FluidState.LIQUID; - + if (GroovyScriptModule.isCurrentlyRunning()) { + return GroovyScriptModule.parseAndValidateEnumValue(FluidState.class, fluidTypeName, "fluid type"); + } if (fluidTypeName.equals("liquid")) return FluidState.LIQUID; if (fluidTypeName.equals("gas")) return FluidState.GAS; if (fluidTypeName.equals("plasma")) return FluidState.PLASMA; diff --git a/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java b/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java index 3f8e854cb29..aeef7c2ac07 100644 --- a/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java +++ b/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java @@ -1,11 +1,11 @@ package gregtech.integration.crafttweaker.material; -import gregtech.api.GTValues; import gregtech.api.fluids.store.FluidStorageKeys; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.info.MaterialFlag; import gregtech.api.unification.material.info.MaterialIconSet; import gregtech.api.unification.material.properties.*; +import gregtech.api.util.Mods; import net.minecraft.enchantment.Enchantment; @@ -65,7 +65,7 @@ public static boolean isGaseous(Material m) { // TODO May need to move this to Material @ZenGetter("fluid") - @net.minecraftforge.fml.common.Optional.Method(modid = GTValues.MODID_CT) + @net.minecraftforge.fml.common.Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) public static ILiquidDefinition getFluid(Material m) { FluidProperty prop = m.getProperty(PropertyKey.FLUID); if (prop != null) { @@ -164,13 +164,13 @@ public static int toolEnchant(Material m) { } @ZenMethod - @net.minecraftforge.fml.common.Optional.Method(modid = GTValues.MODID_CT) + @net.minecraftforge.fml.common.Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) public static void addToolEnchantment(Material m, IEnchantment enchantment) { addScaledToolEnchantment(m, enchantment, 0); } @ZenMethod - @net.minecraftforge.fml.common.Optional.Method(modid = GTValues.MODID_CT) + @net.minecraftforge.fml.common.Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) public static void addScaledToolEnchantment(Material m, IEnchantment enchantment, double levelGrowth) { if (checkFrozen("add tool enchantment")) return; ToolProperty prop = m.getProperty(PropertyKey.TOOL); diff --git a/src/main/java/gregtech/integration/ctm/IFacadeWrapper.java b/src/main/java/gregtech/integration/ctm/IFacadeWrapper.java index 76d76eb64c9..287b9a9e647 100644 --- a/src/main/java/gregtech/integration/ctm/IFacadeWrapper.java +++ b/src/main/java/gregtech/integration/ctm/IFacadeWrapper.java @@ -1,6 +1,6 @@ package gregtech.integration.ctm; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import net.minecraft.block.state.IBlockState; import net.minecraft.util.EnumFacing; @@ -11,7 +11,7 @@ import org.jetbrains.annotations.NotNull; import team.chisel.ctm.api.IFacade; -@Optional.Interface(modid = GTValues.MODID_CTM, iface = "team.chisel.ctm.api.IFacade") +@Optional.Interface(modid = Mods.Names.CONNECTED_TEXTURES_MOD, iface = "team.chisel.ctm.api.IFacade") public interface IFacadeWrapper extends IFacade { @NotNull diff --git a/src/main/java/gregtech/integration/forestry/ForestryModule.java b/src/main/java/gregtech/integration/forestry/ForestryModule.java index e5e8b2227a6..3b86eb2367f 100644 --- a/src/main/java/gregtech/integration/forestry/ForestryModule.java +++ b/src/main/java/gregtech/integration/forestry/ForestryModule.java @@ -15,6 +15,7 @@ import gregtech.api.unification.material.properties.OreProperty; import gregtech.api.unification.material.properties.PropertyKey; import gregtech.api.unification.ore.OrePrefix; +import gregtech.api.util.Mods; import gregtech.common.items.ToolItems; import gregtech.integration.IntegrationModule; import gregtech.integration.IntegrationSubmodule; @@ -31,7 +32,6 @@ import net.minecraft.item.crafting.IRecipe; import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; @@ -52,7 +52,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_FR, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_FR, + modDependencies = Mods.Names.FORESTRY, name = "GregTech Forestry Integration", description = "Forestry Integration Module") public class ForestryModule extends IntegrationSubmodule { @@ -100,7 +100,7 @@ public void preInit(FMLPreInitializationEvent event) { // GT Frames if (ForestryConfig.enableGTFrames) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { FRAME_ACCELERATED = new GTItemFrame(GTFrameType.ACCELERATED); FRAME_MUTAGENIC = new GTItemFrame(GTFrameType.MUTAGENIC); FRAME_WORKING = new GTItemFrame(GTFrameType.WORKING); @@ -126,7 +126,7 @@ public void preInit(FMLPreInitializationEvent event) { // GT Bees if (ForestryConfig.enableGTBees) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { DROPS = new GTDropItem(); COMBS = new GTCombItem(); } else { @@ -137,7 +137,7 @@ public void preInit(FMLPreInitializationEvent event) { // Remove duplicate/conflicting bees from other Forestry addons. // Done in init to have our changes applied before their registration, // since we load after other Forestry addons purposefully. - if (ForestryConfig.disableConflictingBees && ForestryUtil.apicultureEnabled()) { + if (ForestryConfig.disableConflictingBees && Mods.ForestryApiculture.isModLoaded()) { BeeRemovals.init(); } @@ -154,7 +154,7 @@ public void init(FMLInitializationEvent event) { ForestryElectrodeRecipes.onInit(); } - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.harderForestryRecipes) { ForestryMiscRecipes.initRemoval(); } @@ -165,12 +165,12 @@ public void init(FMLInitializationEvent event) { } } - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { registerAlvearyMutators(); } if (event.getSide() == Side.CLIENT) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTBees) { Minecraft.getMinecraft().getItemColors().registerItemColorHandler((stack, tintIndex) -> { if (stack.getItem() instanceof IColoredItem coloredItem) { @@ -185,7 +185,7 @@ public void init(FMLInitializationEvent event) { @Override public void postInit(FMLPostInitializationEvent event) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { getLogger().info("Copying Forestry Centrifuge recipes to GT Centrifuge"); CombRecipes.initForestryCombs(); } @@ -196,7 +196,7 @@ public static void registerItems(RegistryEvent.Register event) { IForgeRegistry registry = event.getRegistry(); // GT Frames - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTFrames) { registry.register(FRAME_ACCELERATED); registry.register(FRAME_MUTAGENIC); @@ -222,20 +222,19 @@ public static void registerItems(RegistryEvent.Register event) { ELECTRODE_OBSIDIAN = forestryMetaItem.addItem(10, "electrode.obsidian"); ELECTRODE_TIN = forestryMetaItem.addItem(11, "electrode.tin"); - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.BinnieCore.isModLoaded()) { ELECTRODE_IRON = forestryMetaItem.addItem(12, "electrode.iron"); } - if (Loader.isModLoaded(GTValues.MODID_XU2)) { + if (Mods.ExtraUtilities2.isModLoaded()) { ELECTRODE_ORCHID = forestryMetaItem.addItem(13, "electrode.orchid"); } - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_TR) || - Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.TechReborn.isModLoaded() || Mods.BinnieCore.isModLoaded()) { ELECTRODE_RUBBER = forestryMetaItem.addItem(14, "electrode.rubber"); } } // GT Drops - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTBees) { registry.register(DROPS); registry.register(COMBS); @@ -246,7 +245,7 @@ public static void registerItems(RegistryEvent.Register event) { @SideOnly(Side.CLIENT) @SubscribeEvent public static void registerModels(ModelRegistryEvent event) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTFrames) { FRAME_ACCELERATED.registerModel(FRAME_ACCELERATED, ForestryAPI.modelManager); FRAME_MUTAGENIC.registerModel(FRAME_MUTAGENIC, ForestryAPI.modelManager); @@ -265,7 +264,7 @@ public static void registerModels(ModelRegistryEvent event) { @SubscribeEvent public static void registerRecipes(RegistryEvent.Register event) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { // GT Frames if (ForestryConfig.enableGTFrames) { ForestryFrameRecipes.init(); @@ -294,7 +293,7 @@ public static void registerRecipes(RegistryEvent.Register event) { @SubscribeEvent public static void registerMaterials(MaterialEvent event) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTFrames) { Materials.TreatedWood.addFlags(MaterialFlags.GENERATE_LONG_ROD); Materials.Uranium235.addFlags(MaterialFlags.GENERATE_LONG_ROD); diff --git a/src/main/java/gregtech/integration/forestry/ForestryUtil.java b/src/main/java/gregtech/integration/forestry/ForestryUtil.java index 32fff8e1e19..1bc2a8df6c0 100644 --- a/src/main/java/gregtech/integration/forestry/ForestryUtil.java +++ b/src/main/java/gregtech/integration/forestry/ForestryUtil.java @@ -1,6 +1,6 @@ package gregtech.integration.forestry; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.integration.IntegrationModule; import gregtech.integration.forestry.bees.GTCombType; import gregtech.integration.forestry.bees.GTDropType; @@ -11,52 +11,39 @@ import forestry.api.apiculture.IAlleleBeeSpecies; import forestry.api.genetics.AlleleManager; import forestry.api.genetics.IAlleleFlowers; -import forestry.modules.ModuleHelper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class ForestryUtil { - public static boolean apicultureEnabled() { - return ModuleHelper.isEnabled("apiculture"); - } - - public static boolean arboricultureEnabled() { - return ModuleHelper.isEnabled("arboriculture"); - } - - public static boolean lepidopterologyEnabled() { - return ModuleHelper.isEnabled("lepidopterology"); - } - @Nullable - public static IAlleleBeeEffect getEffect(@NotNull String modid, @NotNull String name) { - String s = switch (modid) { - case GTValues.MODID_EB -> "extrabees.effect." + name; - case GTValues.MODID_MB -> "magicbees.effect" + name; - case GTValues.MODID -> "gregtech.effect." + name; + public static IAlleleBeeEffect getEffect(@NotNull Mods mod, @NotNull String name) { + String s = switch (mod) { + case ExtraBees -> "extrabees.effect." + name; + case MagicBees -> "magicbees.effect" + name; + case GregTech -> "gregtech.effect." + name; default -> "forestry.effect" + name; }; return (IAlleleBeeEffect) AlleleManager.alleleRegistry.getAllele(s); } @Nullable - public static IAlleleFlowers getFlowers(@NotNull String modid, @NotNull String name) { - String s = switch (modid) { - case GTValues.MODID_EB -> "extrabees.flower." + name; - case GTValues.MODID_MB -> "magicbees.flower" + name; - case GTValues.MODID -> "gregtech.flower." + name; + public static IAlleleFlowers getFlowers(@NotNull Mods mod, @NotNull String name) { + String s = switch (mod) { + case ExtraBees -> "extrabees.flower." + name; + case MagicBees -> "magicbees.flower" + name; + case GregTech -> "gregtech.flower." + name; default -> "forestry.flowers" + name; }; return (IAlleleFlowers) AlleleManager.alleleRegistry.getAllele(s); } @Nullable - public static IAlleleBeeSpecies getSpecies(@NotNull String modid, @NotNull String name) { - String s = switch (modid) { - case GTValues.MODID_EB -> "extrabees.species." + name; - case GTValues.MODID_MB -> "magicbees.species" + name; - case GTValues.MODID -> "gregtech.species." + name; + public static IAlleleBeeSpecies getSpecies(@NotNull Mods mod, @NotNull String name) { + String s = switch (mod) { + case ExtraBees -> "extrabees.species." + name; + case MagicBees -> "magicbees.species" + name; + case GregTech -> "gregtech.species." + name; default -> "forestry.species" + name; }; return (IAlleleBeeSpecies) AlleleManager.alleleRegistry.getAllele(s); @@ -74,7 +61,7 @@ public static ItemStack getCombStack(@NotNull GTCombType type, int amount) { .error("Tried to get GregTech Comb stack, but GregTech Bees config is not enabled!"); return ItemStack.EMPTY; } - if (!apicultureEnabled()) { + if (!Mods.ForestryApiculture.isModLoaded()) { IntegrationModule.logger.error("Tried to get GregTech Comb stack, but Apiculture module is not enabled!"); return ItemStack.EMPTY; } @@ -93,7 +80,7 @@ public static ItemStack getDropStack(@NotNull GTDropType type, int amount) { .error("Tried to get GregTech Drop stack, but GregTech Bees config is not enabled!"); return ItemStack.EMPTY; } - if (!apicultureEnabled()) { + if (!Mods.ForestryApiculture.isModLoaded()) { IntegrationModule.logger.error("Tried to get GregTech Drop stack, but Apiculture module is not enabled!"); return ItemStack.EMPTY; } diff --git a/src/main/java/gregtech/integration/forestry/bees/BeeRemovals.java b/src/main/java/gregtech/integration/forestry/bees/BeeRemovals.java index 65546dfe020..39dcb08e103 100644 --- a/src/main/java/gregtech/integration/forestry/bees/BeeRemovals.java +++ b/src/main/java/gregtech/integration/forestry/bees/BeeRemovals.java @@ -1,10 +1,8 @@ package gregtech.integration.forestry.bees; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.integration.IntegrationModule; -import net.minecraftforge.fml.common.Loader; - import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; @@ -16,10 +14,10 @@ public class BeeRemovals { private static final List EB_REMOVALS = new ArrayList<>(); public static void init() { - if (Loader.isModLoaded(GTValues.MODID_MB)) { + if (Mods.MagicBees.isModLoaded()) { removeMagicBees(); } - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { removeExtraBees(); } } diff --git a/src/main/java/gregtech/integration/forestry/bees/ForestryScannerLogic.java b/src/main/java/gregtech/integration/forestry/bees/ForestryScannerLogic.java index 891a8277bc9..0bd8d25bf53 100644 --- a/src/main/java/gregtech/integration/forestry/bees/ForestryScannerLogic.java +++ b/src/main/java/gregtech/integration/forestry/bees/ForestryScannerLogic.java @@ -3,7 +3,7 @@ import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMaps; import gregtech.api.recipes.machines.IScannerRecipeMap; -import gregtech.integration.forestry.ForestryUtil; +import gregtech.api.util.Mods; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -60,7 +60,7 @@ public List getRepresentativeRecipes() { List recipes = new ArrayList<>(); ItemStack outputStack; - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { outputStack = ModuleApiculture.getItems().beeDroneGE.getItemStack(); outputStack.setTagCompound(BeeDefinition.COMMON.getIndividual().writeToNBT(new NBTTagCompound())); outputStack.setTranslatableName("gregtech.scanner.forestry.drone"); @@ -98,7 +98,7 @@ public List getRepresentativeRecipes() { .duration(DURATION).EUt(EUT).build().getResult()); } - if (ForestryUtil.arboricultureEnabled()) { + if (Mods.ForestryArboriculture.isModLoaded()) { outputStack = ModuleArboriculture.getItems().sapling.getItemStack(); outputStack.setTagCompound(TreeDefinition.Oak.getIndividual().writeToNBT(new NBTTagCompound())); outputStack.setTranslatableName("gregtech.scanner.forestry.sapling"); @@ -118,7 +118,7 @@ public List getRepresentativeRecipes() { .duration(DURATION).EUt(EUT).build().getResult()); } - if (ForestryUtil.lepidopterologyEnabled()) { + if (Mods.ForestryLepidopterology.isModLoaded()) { outputStack = ModuleLepidopterology.getItems().butterflyGE.getItemStack(); outputStack .setTagCompound(ButterflyDefinition.CabbageWhite.getIndividual().writeToNBT(new NBTTagCompound())); diff --git a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java index 97fed7a25c3..d4a967e4bfe 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java @@ -5,8 +5,9 @@ import gregtech.api.unification.material.Materials; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.UnificationEntry; +import gregtech.api.util.Mods; +import gregtech.common.blocks.MetaBlocks; import gregtech.common.items.MetaItems; -import gregtech.integration.IntegrationUtil; import gregtech.integration.forestry.ForestryModule; import gregtech.integration.forestry.ForestryUtil; @@ -14,7 +15,6 @@ import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraftforge.common.BiomeDictionary; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional; import appeng.core.Api; @@ -47,7 +47,7 @@ public enum GTBeeDefinition implements IBeeDefinition { // Organic CLAY(GTBranchDefinition.GT_ORGANIC, "Lutum", true, 0xC8C8DA, 0x0000FF, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(22), 0.30f); // CLAY } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.HONEY), 0.30f); @@ -55,8 +55,8 @@ public enum GTBeeDefinition implements IBeeDefinition { beeSpecies.addProduct(new ItemStack(Items.CLAY_BALL), 0.15f); beeSpecies.setHumidity(EnumHumidity.DAMP); beeSpecies.setTemperature(EnumTemperature.NORMAL); - if (Loader.isModLoaded(GTValues.MODID_BOP)) { - beeSpecies.addSpecialty(IntegrationUtil.getModItem(GTValues.MODID_BOP, "mudball", 0), 0.05f); + if (Mods.BiomesOPlenty.isModLoaded()) { + beeSpecies.addSpecialty(Mods.BiomesOPlenty.getItem("mudball", 0), 0.05f); } }, template -> { @@ -76,10 +76,9 @@ public enum GTBeeDefinition implements IBeeDefinition { beeSpecies.addSpecialty(getGTComb(GTCombType.STICKY), 0.05f); beeSpecies.setHumidity(EnumHumidity.DAMP); beeSpecies.setTemperature(EnumTemperature.NORMAL); - if (Loader.isModLoaded(GTValues.MODID_TCON)) { - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_TCON, "edible", 1), 0.10f); - beeSpecies.addSpecialty(IntegrationUtil.getModItem(GTValues.MODID_TCON, "slime_congealed", 2), - 0.01f); + if (Mods.TinkersConstruct.isModLoaded()) { + beeSpecies.addProduct(Mods.TinkersConstruct.getItem("edible", 1), 0.10f); + beeSpecies.addSpecialty(Mods.TinkersConstruct.getItem("slime_congealed", 2), 0.01f); } else { beeSpecies.addSpecialty(new ItemStack(Blocks.SLIME_BLOCK), 0.01f); } @@ -89,9 +88,9 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, FLOWERING, EnumAllele.Flowering.SLOWER); AlleleHelper.getInstance().set(template, TEMPERATURE_TOLERANCE, EnumAllele.Tolerance.BOTH_1); AlleleHelper.getInstance().set(template, HUMIDITY_TOLERANCE, EnumAllele.Tolerance.BOTH_1); - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { AlleleHelper.getInstance().set(template, FLOWER_PROVIDER, - ForestryUtil.getFlowers(GTValues.MODID_EB, "water")); + ForestryUtil.getFlowers(Mods.ExtraBees, "water")); } }, dis -> { @@ -166,15 +165,15 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER); AlleleHelper.getInstance().set(template, TEMPERATURE_TOLERANCE, EnumAllele.Tolerance.NONE); AlleleHelper.getInstance().set(template, HUMIDITY_TOLERANCE, EnumAllele.Tolerance.NONE); - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { AlleleHelper.getInstance().set(template, FLOWER_PROVIDER, - ForestryUtil.getFlowers(GTValues.MODID_EB, "water")); + ForestryUtil.getFlowers(Mods.ExtraBees, "water")); } }, dis -> dis.registerMutation(COAL, STICKYRESIN, 4)), ASH(GTBranchDefinition.GT_ORGANIC, "Cinis", true, 0x1E1A18, 0xC6C6C6, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(9), 0.30f); // SEED } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.HONEY), 0.30f); @@ -196,7 +195,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }), APATITE(GTBranchDefinition.GT_ORGANIC, "Stercorat", true, 0x7FCEF5, 0x654525, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(9), 0.15f); // SEED } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.HONEY), 0.15f); @@ -210,9 +209,9 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.LONGER); AlleleHelper.getInstance().set(template, FLOWER_PROVIDER, EnumAllele.Flowers.WHEAT); AlleleHelper.getInstance().set(template, FLOWERING, EnumAllele.Flowering.FASTER); - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { AlleleHelper.getInstance().set(template, FLOWER_PROVIDER, - ForestryUtil.getFlowers(GTValues.MODID_EB, "rock")); + ForestryUtil.getFlowers(Mods.ExtraBees, "rock")); } }, dis -> { @@ -238,7 +237,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }), FERTILIZER(GTBranchDefinition.GT_ORGANIC, "Stercorat", true, 0x7FCEF5, 0x654525, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(9), 0.15f); // SEED } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.MOSSY), 0.15f); @@ -246,7 +245,7 @@ public enum GTBeeDefinition implements IBeeDefinition { beeSpecies.addSpecialty(OreDictUnifier.get(OrePrefix.dustTiny, Materials.Ash), 0.2f); beeSpecies.addSpecialty(OreDictUnifier.get(OrePrefix.dustTiny, Materials.DarkAsh), 0.2f); beeSpecies.addSpecialty(MetaItems.FERTILIZER.getStackForm(), 0.3f); - beeSpecies.addSpecialty(IntegrationUtil.getModItem(GTValues.MODID_FR, "fertilizer_compound", 0), 0.3f); + beeSpecies.addSpecialty(Mods.Forestry.getItem("fertilizer_compound", 0), 0.3f); beeSpecies.setHumidity(EnumHumidity.DAMP); beeSpecies.setTemperature(EnumTemperature.WARM); }, @@ -272,16 +271,12 @@ public enum GTBeeDefinition implements IBeeDefinition { }), SANDWICH(GTBranchDefinition.GT_ORGANIC, "Sandwico", true, 0x32CD32, 0xDAA520, beeSpecies -> { - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_GTFO, "gtfo_meta_item", 81), 0.05f); // Cucumber - // Slice - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_GTFO, "gtfo_meta_item", 80), 0.05f); // Onion - // Slice - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_GTFO, "gtfo_meta_item", 79), 0.05f); // Tomato - // Slice + beeSpecies.addProduct(Mods.GregTechFoodOption.getItem("gtfo_meta_item", 81), 0.05f); // Cucumber Slice + beeSpecies.addProduct(Mods.GregTechFoodOption.getItem("gtfo_meta_item", 80), 0.05f); // Onion Slice + beeSpecies.addProduct(Mods.GregTechFoodOption.getItem("gtfo_meta_item", 79), 0.05f); // Tomato Slice beeSpecies.addSpecialty(new ItemStack(Items.COOKED_PORKCHOP), 0.05f); beeSpecies.addSpecialty(new ItemStack(Items.COOKED_BEEF), 0.15f); - beeSpecies.addSpecialty(IntegrationUtil.getModItem(GTValues.MODID_GTFO, "gtfo_meta_item", 97), 0.05f); // Cheddar - // Slice + beeSpecies.addSpecialty(Mods.GregTechFoodOption.getItem("gtfo_meta_item", 97), 0.05f); // Cheddar Slice beeSpecies.setHumidity(EnumHumidity.NORMAL); beeSpecies.setTemperature(EnumTemperature.NORMAL); }, @@ -295,14 +290,13 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, FLOWERING, EnumAllele.Flowering.FASTER); }, dis -> { - if (Loader.isModLoaded(GTValues.MODID_MB)) { - dis.registerMutation(BeeDefinition.AGRARIAN, ForestryUtil.getSpecies(GTValues.MODID_MB, "Batty"), - 10); + if (Mods.MagicBees.isModLoaded()) { + dis.registerMutation(BeeDefinition.AGRARIAN, ForestryUtil.getSpecies(Mods.MagicBees, "Batty"), 10); } else { dis.registerMutation(BeeDefinition.AGRARIAN, BeeDefinition.IMPERIAL, 10); } }, - () -> Loader.isModLoaded(GTValues.MODID_GTFO)), + Mods.GregTechFoodOption::isModLoaded), // Gems REDSTONE(GTBranchDefinition.GT_GEM, "Rubrumlapis", true, 0x7D0F0F, 0xD11919, @@ -356,7 +350,7 @@ public enum GTBeeDefinition implements IBeeDefinition { Api.INSTANCE.definitions().blocks().fluixBlock().maybeBlock() .ifPresent(block -> mutation.requireResource(block.getDefaultState())); }, - () -> Loader.isModLoaded(GTValues.MODID_APPENG)), + Mods.AppliedEnergistics2::isModLoaded), DIAMOND(GTBranchDefinition.GT_GEM, "Adamas", false, 0xCCFFFF, 0xA3CCCC, beeSpecies -> { beeSpecies.addProduct(getGTComb(GTCombType.STONE), 0.30f); @@ -421,7 +415,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }), SPARKLING(GTBranchDefinition.GT_GEM, "Vesperstella", true, 0x7A007A, 0xFFFFFF, beeSpecies -> { - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_MB, "resource", 3), 0.20f); + beeSpecies.addProduct(Mods.MagicBees.getItem("resource", 3), 0.20f); beeSpecies.addSpecialty(getGTComb(GTCombType.SPARKLING), 0.125f); beeSpecies.setHumidity(EnumHumidity.NORMAL); beeSpecies.setTemperature(EnumTemperature.NORMAL); @@ -437,12 +431,12 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation( - ForestryUtil.getSpecies(GTValues.MODID_MB, "Withering"), - ForestryUtil.getSpecies(GTValues.MODID_MB, "Draconic"), 1); + ForestryUtil.getSpecies(Mods.MagicBees, "Withering"), + ForestryUtil.getSpecies(Mods.MagicBees, "Draconic"), 1); mutation.requireResource("blockNetherStar"); mutation.restrictBiomeType(BiomeDictionary.Type.END); }, - () -> Loader.isModLoaded(GTValues.MODID_MB)), + Mods.MagicBees::isModLoaded), // Metals COPPER(GTBranchDefinition.GT_METAL, "Cuprum", true, 0xFF6600, 0xE65C00, @@ -587,9 +581,9 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, TOLERATES_RAIN, true); }, dis -> { - if (Loader.isModLoaded(GTValues.MODID_MB) && Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.MagicBees.isModLoaded() && Mods.AppliedEnergistics2.isModLoaded()) { // MB Skystone bee is only registered if AE2 is also active - dis.registerMutation(IRON, ForestryUtil.getSpecies(GTValues.MODID_MB, "AESkystone"), 17); + dis.registerMutation(IRON, ForestryUtil.getSpecies(Mods.MagicBees, "AESkystone"), 17); } else { dis.registerMutation(IRON, BeeDefinition.IMPERIAL, 17); } @@ -767,7 +761,7 @@ public enum GTBeeDefinition implements IBeeDefinition { // Industrial ENERGY(GTBranchDefinition.GT_INDUSTRIAL, "Industria", false, 0xC11F1F, 0xEBB9B9, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(14), 0.30f); // STATIC } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.SIMMERING), 0.30f); @@ -788,9 +782,9 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { mutation = dis.registerMutation(BeeDefinition.DEMONIC, - ForestryUtil.getSpecies(GTValues.MODID_EB, "volcanic"), 10); + ForestryUtil.getSpecies(Mods.ExtraBees, "volcanic"), 10); } else { mutation = dis.registerMutation(BeeDefinition.DEMONIC, BeeDefinition.FIENDISH, 10); } @@ -821,8 +815,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }), EXPLOSIVE(GTBranchDefinition.GT_INDUSTRIAL, "Explosionis", false, 0x7E270F, 0x747474, beeSpecies -> { - beeSpecies.addProduct(new ItemStack(Blocks.TNT), 0.2f); - // todo if we add a ITNT substitute, put it here instead of TNT + beeSpecies.addProduct(new ItemStack(MetaBlocks.ITNT), 0.2f); beeSpecies.setHumidity(EnumHumidity.ARID); beeSpecies.setTemperature(EnumTemperature.HELLISH); beeSpecies.setHasEffect(); @@ -988,8 +981,8 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_EB)) { - mutation = dis.registerMutation(THORIUM, ForestryUtil.getSpecies(GTValues.MODID_EB, "rotten"), 1); + if (Mods.ExtraBees.isModLoaded()) { + mutation = dis.registerMutation(THORIUM, ForestryUtil.getSpecies(Mods.ExtraBees, "rotten"), 1); } else { mutation = dis.registerMutation(THORIUM, BeeDefinition.IMPERIAL, 1); } @@ -1041,9 +1034,9 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.SHORTEST), dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_MB)) { + if (Mods.MagicBees.isModLoaded()) { mutation = dis.registerMutation(STAINLESSSTEEL, - ForestryUtil.getSpecies(GTValues.MODID_MB, "Watery"), 10); + ForestryUtil.getSpecies(Mods.MagicBees, "Watery"), 10); } else { mutation = dis.registerMutation(STAINLESSSTEEL, BeeDefinition.INDUSTRIOUS, 10); } @@ -1060,9 +1053,8 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.SHORTEST), dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_MB)) { - mutation = dis.registerMutation(HELIUM, ForestryUtil.getSpecies(GTValues.MODID_MB, "Supernatural"), - 8); + if (Mods.MagicBees.isModLoaded()) { + mutation = dis.registerMutation(HELIUM, ForestryUtil.getSpecies(Mods.MagicBees, "Supernatural"), 8); } else { mutation = dis.registerMutation(HELIUM, BeeDefinition.IMPERIAL, 8); } @@ -1092,9 +1084,8 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.SHORTEST), dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_MB)) { - mutation = dis.registerMutation(NEON, ForestryUtil.getSpecies(GTValues.MODID_MB, "Supernatural"), - 4); + if (Mods.MagicBees.isModLoaded()) { + mutation = dis.registerMutation(NEON, ForestryUtil.getSpecies(Mods.MagicBees, "Supernatural"), 4); } else { mutation = dis.registerMutation(NEON, BeeDefinition.AVENGING, 4); } @@ -1139,8 +1130,8 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.SHORTEST), dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_MB)) { - mutation = dis.registerMutation(OXYGEN, ForestryUtil.getSpecies(GTValues.MODID_MB, "Watery"), 15); + if (Mods.MagicBees.isModLoaded()) { + mutation = dis.registerMutation(OXYGEN, ForestryUtil.getSpecies(Mods.MagicBees, "Watery"), 15); } else { mutation = dis.registerMutation(OXYGEN, BeeDefinition.INDUSTRIOUS, 15); } @@ -1233,14 +1224,14 @@ private static ItemStack getForestryComb(EnumHoneyComb type) { return ModuleApiculture.getItems().beeComb.get(type, 1); } - @Optional.Method(modid = GTValues.MODID_EB) + @Optional.Method(modid = Mods.Names.EXTRA_BEES) private static ItemStack getExtraBeesComb(int meta) { - return IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_comb", meta); + return Mods.ExtraBees.getItem("honey_comb", meta); } - @Optional.Method(modid = GTValues.MODID_MB) + @Optional.Method(modid = Mods.Names.MAGIC_BEES) private static ItemStack getMagicBeesComb(int meta) { - return IntegrationUtil.getModItem(GTValues.MODID_MB, "beecomb", meta); + return Mods.MagicBees.getItem("beecomb", meta); } private static ItemStack getGTComb(GTCombType type) { diff --git a/src/main/java/gregtech/integration/forestry/bees/GTCombItem.java b/src/main/java/gregtech/integration/forestry/bees/GTCombItem.java index 0769ad034bf..e037872f2cf 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTCombItem.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTCombItem.java @@ -1,6 +1,7 @@ package gregtech.integration.forestry.bees; import gregtech.api.GTValues; +import gregtech.api.util.Mods; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.creativetab.CreativeTabs; @@ -37,7 +38,7 @@ public GTCombItem() { public void registerModel(@NotNull Item item, IModelManager manager) { manager.registerItemModel(item, 0); for (int i = 0; i < GTCombType.values().length; i++) { - manager.registerItemModel(item, i, GTValues.MODID_FR, "gt.comb"); + manager.registerItemModel(item, i, Mods.Names.FORESTRY, "gt.comb"); } } diff --git a/src/main/java/gregtech/integration/forestry/bees/GTCombType.java b/src/main/java/gregtech/integration/forestry/bees/GTCombType.java index f774e6f68d0..e17fc00a429 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTCombType.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTCombType.java @@ -1,8 +1,6 @@ package gregtech.integration.forestry.bees; -import gregtech.api.GTValues; - -import net.minecraftforge.fml.common.Loader; +import gregtech.api.util.Mods; public enum GTCombType { @@ -27,7 +25,7 @@ public enum GTCombType { // Gem STONE("stone", 0x808080, 0x999999), CERTUS("certus", 0x57CFFB, 0xBBEEFF), - FLUIX("fluix", 0xA375FF, 0xB591FF, Loader.isModLoaded(GTValues.MODID_APPENG)), + FLUIX("fluix", 0xA375FF, 0xB591FF, Mods.AppliedEnergistics2.isModLoaded()), REDSTONE("redstone", 0x7D0F0F, 0xD11919), RAREEARTH("rareearth", 0x555643, 0x343428), LAPIS("lapis", 0x1947D1, 0x476CDA), @@ -38,7 +36,7 @@ public enum GTCombType { EMERALD("emerald", 0x248F24, 0x2EB82E), PYROPE("pyrope", 0x763162, 0x8B8B8B), GROSSULAR("grossular", 0x9B4E00, 0x8B8B8B), - SPARKLING("sparkling", 0x7A007A, 0xFFFFFF, Loader.isModLoaded(GTValues.MODID_MB)), + SPARKLING("sparkling", 0x7A007A, 0xFFFFFF, Mods.MagicBees.isModLoaded()), // Metal SLAG("slag", 0xD4D4D4, 0x58300B), diff --git a/src/main/java/gregtech/integration/forestry/bees/GTDropItem.java b/src/main/java/gregtech/integration/forestry/bees/GTDropItem.java index 45a67068b2a..a8453a6a151 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTDropItem.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTDropItem.java @@ -1,6 +1,7 @@ package gregtech.integration.forestry.bees; import gregtech.api.GTValues; +import gregtech.api.util.Mods; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; @@ -44,7 +45,7 @@ private void setResearchSuitability(@Nullable ISpeciesRoot speciesRoot) { public void registerModel(@NotNull Item item, @NotNull IModelManager manager) { manager.registerItemModel(item, 0); for (int i = 0; i < GTDropType.VALUES.length; i++) { - manager.registerItemModel(item, i, GTValues.MODID_FR, "gt.honey_drop"); + manager.registerItemModel(item, i, Mods.Names.FORESTRY, "gt.honey_drop"); } } diff --git a/src/main/java/gregtech/integration/forestry/frames/GTItemFrame.java b/src/main/java/gregtech/integration/forestry/frames/GTItemFrame.java index 088c5ed7e73..e8f9a46d45e 100644 --- a/src/main/java/gregtech/integration/forestry/frames/GTItemFrame.java +++ b/src/main/java/gregtech/integration/forestry/frames/GTItemFrame.java @@ -1,6 +1,7 @@ package gregtech.integration.forestry.frames; import gregtech.api.GTValues; +import gregtech.api.util.Mods; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.item.Item; @@ -62,7 +63,7 @@ public IBeeModifier getBeeModifier() { @SuppressWarnings("deprecation") @Override public void registerModel(@NotNull Item item, @NotNull IModelManager manager) { - manager.registerItemModel(item, 0, GTValues.MODID_FR, "gt.frame_" + type.getName().toLowerCase()); + manager.registerItemModel(item, 0, Mods.Names.FORESTRY, "gt.frame_" + type.getName().toLowerCase()); } public ItemStack getItemStack() { diff --git a/src/main/java/gregtech/integration/forestry/recipes/CombRecipes.java b/src/main/java/gregtech/integration/forestry/recipes/CombRecipes.java index 33c96a223dc..d0b851af4ac 100644 --- a/src/main/java/gregtech/integration/forestry/recipes/CombRecipes.java +++ b/src/main/java/gregtech/integration/forestry/recipes/CombRecipes.java @@ -12,8 +12,8 @@ import gregtech.api.unification.material.properties.PropertyKey; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.common.items.MetaItems; -import gregtech.integration.IntegrationUtil; import gregtech.integration.forestry.ForestryUtil; import gregtech.integration.forestry.bees.GTCombItem; import gregtech.integration.forestry.bees.GTCombType; @@ -21,7 +21,6 @@ import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.common.Loader; import appeng.core.Api; import com.google.common.collect.ImmutableMap; @@ -98,8 +97,8 @@ public static void initGTCombs() { ModuleCore.getItems().refractoryWax.getItemStack() }, new int[] { 20 * 100, 50 * 100 }, Voltage.HV, 196); ItemStack wax = ModuleCore.getItems().beeswax.getItemStack(); - if (Loader.isModLoaded(GTValues.MODID_MB)) { - wax = IntegrationUtil.getModItem(GTValues.MODID_MB, "wax", 2); + if (Mods.MagicBees.isModLoaded()) { + wax = Mods.MagicBees.getItem("wax", 2); } addCentrifugeToItemStack(GTCombType.LAPOTRON, new ItemStack[] { OreDictUnifier.get(OrePrefix.dust, Materials.Lapotron), wax }, @@ -271,11 +270,10 @@ public static void initGTCombs() { .cleanroom(CleanroomType.CLEANROOM) .duration(3000).EUt(Voltage.UV.getChemicalEnergy()).buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_MB)) { + if (Mods.MagicBees.isModLoaded()) { addProcessGT(GTCombType.SPARKLING, new Material[] { Materials.NetherStar }, Voltage.EV); addCentrifugeToItemStack(GTCombType.SPARKLING, - new ItemStack[] { IntegrationUtil.getModItem(GTValues.MODID_MB, "wax", 0), - IntegrationUtil.getModItem(GTValues.MODID_MB, "resource", 5), + new ItemStack[] { Mods.MagicBees.getItem("wax", 0), Mods.MagicBees.getItem("resource", 5), OreDictUnifier.get(OrePrefix.dustTiny, Materials.NetherStar) }, new int[] { 50 * 100, 10 * 100, 10 * 100 }, Voltage.EV); } @@ -290,7 +288,7 @@ public static void initGTCombs() { addExtractorProcess(GTCombType.HYDROGEN, Materials.Hydrogen.getFluid(500), Voltage.MV, 100); addExtractorProcess(GTCombType.FLUORINE, Materials.Fluorine.getFluid(250), Voltage.MV, 128); - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { ItemStack fluixDust = OreDictUnifier.get("dustFluix"); if (fluixDust == ItemStack.EMPTY) { fluixDust = Api.INSTANCE.definitions().materials().fluixDust().maybeStack(1).orElse(ItemStack.EMPTY); diff --git a/src/main/java/gregtech/integration/forestry/recipes/ForestryElectrodeRecipes.java b/src/main/java/gregtech/integration/forestry/recipes/ForestryElectrodeRecipes.java index 171f575bc32..72014ca62c6 100644 --- a/src/main/java/gregtech/integration/forestry/recipes/ForestryElectrodeRecipes.java +++ b/src/main/java/gregtech/integration/forestry/recipes/ForestryElectrodeRecipes.java @@ -1,14 +1,13 @@ package gregtech.integration.forestry.recipes; -import gregtech.api.GTValues; import gregtech.api.unification.stack.UnificationEntry; +import gregtech.api.util.Mods; import gregtech.integration.forestry.ForestryModule; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.common.Loader; import forestry.api.recipes.RecipeManagers; import forestry.core.ModuleCore; @@ -137,7 +136,7 @@ public static void addGregTechMachineRecipes() { .output(ForestryModule.ELECTRODE_GOLD, 2) .buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.BinnieCore.isModLoaded()) { CIRCUIT_ASSEMBLER_RECIPES.recipeBuilder().duration(150).EUt(16) .input(ForestryModule.ELECTRODE_IRON) .fluidInputs(Glass.getFluid(100)) @@ -176,7 +175,7 @@ public static void addGregTechMachineRecipes() { .output(ForestryModule.ELECTRODE_OBSIDIAN, 4) .buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_XU2)) { + if (Mods.ExtraUtilities2.isModLoaded()) { CIRCUIT_ASSEMBLER_RECIPES.recipeBuilder().duration(150).EUt(16) .input(ForestryModule.ELECTRODE_ORCHID) .fluidInputs(Glass.getFluid(100)) @@ -191,8 +190,7 @@ public static void addGregTechMachineRecipes() { } // todo mixin forestry to allow this tube always, since we have rubber (once mixin port is done) - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_TR) || - Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.TechReborn.isModLoaded() || Mods.BinnieCore.isModLoaded()) { CIRCUIT_ASSEMBLER_RECIPES.recipeBuilder().duration(150).EUt(16) .input(ForestryModule.ELECTRODE_RUBBER) .fluidInputs(Glass.getFluid(100)) @@ -248,7 +246,7 @@ private static void addForestryMachineRecipes() { '#', new UnificationEntry(wireGtSingle, RedAlloy).toString(), 'X', new UnificationEntry(plate, Bronze).toString()); - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.BinnieCore.isModLoaded()) { addFabricatorRecipe(EnumElectronTube.IRON, "SXS", "#X#", "XXX", 'S', new UnificationEntry(screw, Iron).toString(), @@ -301,7 +299,7 @@ private static void addForestryMachineRecipes() { '#', new UnificationEntry(plate, EnderEye).toString(), 'X', new ItemStack(Blocks.END_STONE)); - if (Loader.isModLoaded(GTValues.MODID_XU2)) { + if (Mods.ExtraUtilities2.isModLoaded()) { addFabricatorRecipe(EnumElectronTube.ORCHID, " X ", "#X#", "XXX", '#', new ItemStack(Items.REPEATER), diff --git a/src/main/java/gregtech/integration/forestry/recipes/ForestryExtractorRecipes.java b/src/main/java/gregtech/integration/forestry/recipes/ForestryExtractorRecipes.java index 5a57da584cc..e1face8fe9e 100644 --- a/src/main/java/gregtech/integration/forestry/recipes/ForestryExtractorRecipes.java +++ b/src/main/java/gregtech/integration/forestry/recipes/ForestryExtractorRecipes.java @@ -1,16 +1,14 @@ package gregtech.integration.forestry.recipes; -import gregtech.api.GTValues; import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMaps; import gregtech.api.unification.material.Materials; import gregtech.api.util.GTUtility; -import gregtech.integration.IntegrationUtil; +import gregtech.api.util.Mods; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.common.Loader; import forestry.core.fluids.Fluids; @@ -18,171 +16,107 @@ public class ForestryExtractorRecipes { public static void init() { // Commonly used items - ItemStack mulch = IntegrationUtil.getModItem(GTValues.MODID_FR, "mulch", 0); - ItemStack propolis = IntegrationUtil.getModItem(GTValues.MODID_FR, "propolis", 0); + ItemStack mulch = Mods.Forestry.getItem("mulch"); + ItemStack propolis = Mods.Forestry.getItem("propolis"); // Vanilla Fruit Juice items addFruitJuiceRecipe(new ItemStack(Items.CARROT), 200, GTUtility.copy(mulch), 2000); addFruitJuiceRecipe(new ItemStack(Items.APPLE), 200, GTUtility.copy(mulch), 2000); // Forestry fruits - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 0), 50, GTUtility.copy(mulch), 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 1), 180, GTUtility.copy(mulch), 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 2), 220, GTUtility.copy(mulch), 200); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 3), 400, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 4), 100, GTUtility.copy(mulch), - 6000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 5), 50, GTUtility.copy(mulch), - 2000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 6), 600, GTUtility.copy(mulch), - 1000); + addSeedOilRecipe(Mods.Forestry.getItem("fruits", 0), 50, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.Forestry.getItem("fruits", 1), 180, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.Forestry.getItem("fruits", 2), 220, GTUtility.copy(mulch), 200); + addFruitJuiceRecipe(Mods.Forestry.getItem("fruits", 3), 400, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.Forestry.getItem("fruits", 4), 100, GTUtility.copy(mulch), 6000); + addFruitJuiceRecipe(Mods.Forestry.getItem("fruits", 5), 50, GTUtility.copy(mulch), 2000); + addFruitJuiceRecipe(Mods.Forestry.getItem("fruits", 6), 600, GTUtility.copy(mulch), 1000); // Honey, Honeydew - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "honey_drop", 0), 100, GTUtility.copy(propolis), - 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "honeydew", 0), 100); + addHoneyRecipe(Mods.Forestry.getItem("honey_drop"), 100, GTUtility.copy(propolis), 0); + addHoneyRecipe(Mods.Forestry.getItem("honeydew"), 100); - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { // Propolis - addExtractorRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "propolis", 0), - Materials.Water.getFluid(500)); - addExtractorRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "propolis", 1), - Materials.Oil.getFluid(500)); - addExtractorRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "propolis", 2), - Materials.Creosote.getFluid(500)); + addExtractorRecipe(Mods.ExtraBees.getItem("propolis", 0), Materials.Water.getFluid(500)); + addExtractorRecipe(Mods.ExtraBees.getItem("propolis", 1), Materials.Oil.getFluid(500)); + addExtractorRecipe(Mods.ExtraBees.getItem("propolis", 2), Materials.Creosote.getFluid(500)); // Drops - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 3), 200); - addExtractorRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 6), - Fluids.MILK.getFluid(200)); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 13), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 19), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 14), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 20), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 15), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 21), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 16), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 22), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 17), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 24), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 18), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 23), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 19), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 25), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 20), 200, - new ItemStack(Items.DYE, 1, 14), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 21), 200, - new ItemStack(Items.DYE, 1, 6), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 22), 200, - new ItemStack(Items.DYE, 1, 5), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 23), 200, - new ItemStack(Items.DYE, 1, 8), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 24), 200, - new ItemStack(Items.DYE, 1, 12), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 25), 200, - new ItemStack(Items.DYE, 1, 9), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 26), 200, - new ItemStack(Items.DYE, 1, 10), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 27), 200, - new ItemStack(Items.DYE, 1, 13), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 28), 200, - new ItemStack(Items.DYE, 1, 7), 0); + addFruitJuiceRecipe(Mods.ExtraBees.getItem("honey_drop", 3), 200); + addExtractorRecipe(Mods.ExtraBees.getItem("honey_drop", 6), Fluids.MILK.getFluid(200)); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 13), 200, Mods.ExtraBees.getItem("misc", 19), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 14), 200, Mods.ExtraBees.getItem("misc", 20), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 15), 200, Mods.ExtraBees.getItem("misc", 21), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 16), 200, Mods.ExtraBees.getItem("misc", 22), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 17), 200, Mods.ExtraBees.getItem("misc", 24), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 18), 200, Mods.ExtraBees.getItem("misc", 23), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 19), 200, Mods.ExtraBees.getItem("misc", 25), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 20), 200, new ItemStack(Items.DYE, 1, 14), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 21), 200, new ItemStack(Items.DYE, 1, 6), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 22), 200, new ItemStack(Items.DYE, 1, 5), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 23), 200, new ItemStack(Items.DYE, 1, 8), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 24), 200, new ItemStack(Items.DYE, 1, 12), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 25), 200, new ItemStack(Items.DYE, 1, 9), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 26), 200, new ItemStack(Items.DYE, 1, 10), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 27), 200, new ItemStack(Items.DYE, 1, 13), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 28), 200, new ItemStack(Items.DYE, 1, 7), 0); } - if (Loader.isModLoaded(GTValues.MODID_ET)) { + if (Mods.ExtraTrees.isModLoaded()) { // Fruits - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 0), 150, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 1), 400, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 2), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 3), 300, GTUtility.copy(mulch), - 1000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 4), 50, GTUtility.copy(mulch), 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 5), 50, GTUtility.copy(mulch), 300); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 6), 50, GTUtility.copy(mulch), 500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 7), 50, GTUtility.copy(mulch), - 500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 8), 100, GTUtility.copy(mulch), - 6000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 9), 80, GTUtility.copy(mulch), 500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 10), 150, GTUtility.copy(mulch), - 4000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 11), 500, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 12), 150, GTUtility.copy(mulch), - 4000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 13), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 14), 400, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 15), 400, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 16), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 17), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 18), 400, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 19), 150, GTUtility.copy(mulch), - 4000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 20), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 21), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 22), 300, GTUtility.copy(mulch), - 2000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 23), 200, GTUtility.copy(mulch), - 1000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 24), 150, GTUtility.copy(mulch), - 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 25), 180, GTUtility.copy(mulch), - 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 26), 100, GTUtility.copy(mulch), - 400); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 27), 50, GTUtility.copy(mulch), 200); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 28), 100, GTUtility.copy(mulch), - 3000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 29), 100, GTUtility.copy(mulch), - 3000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 30), 100, GTUtility.copy(mulch), - 4000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 31), 20, GTUtility.copy(mulch), 200); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 32), 50, GTUtility.copy(mulch), 300); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 33), 50, GTUtility.copy(mulch), 300); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 34), 100, GTUtility.copy(mulch), - 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 35), 50, GTUtility.copy(mulch), 300); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 36), 50, GTUtility.copy(mulch), 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 37), 20, GTUtility.copy(mulch), 200); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 38), 300, GTUtility.copy(mulch), - 1500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 39), 25, GTUtility.copy(mulch), 200); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 46), 50, GTUtility.copy(mulch), - 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 50), 300, GTUtility.copy(mulch), - 2500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 51), 150, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 52), 300, GTUtility.copy(mulch), - 1500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 53), 50, GTUtility.copy(mulch), - 1000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 54), 50, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 55), 100, GTUtility.copy(mulch), - 1000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 56), 100, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 57), 400, GTUtility.copy(mulch), - 2000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 58), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 59), 50, GTUtility.copy(mulch), - 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 0), 150, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 1), 400, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 2), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 3), 300, GTUtility.copy(mulch), 1000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 4), 50, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 5), 50, GTUtility.copy(mulch), 300); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 6), 50, GTUtility.copy(mulch), 500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 7), 50, GTUtility.copy(mulch), 500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 8), 100, GTUtility.copy(mulch), 6000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 9), 80, GTUtility.copy(mulch), 500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 10), 150, GTUtility.copy(mulch), 4000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 11), 500, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 12), 150, GTUtility.copy(mulch), 4000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 13), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 14), 400, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 15), 400, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 16), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 17), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 18), 400, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 19), 150, GTUtility.copy(mulch), 4000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 20), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 21), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 22), 300, GTUtility.copy(mulch), 2000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 23), 200, GTUtility.copy(mulch), 1000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 24), 150, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 25), 180, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 26), 100, GTUtility.copy(mulch), 400); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 27), 50, GTUtility.copy(mulch), 200); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 28), 100, GTUtility.copy(mulch), 3000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 29), 100, GTUtility.copy(mulch), 3000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 30), 100, GTUtility.copy(mulch), 4000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 31), 20, GTUtility.copy(mulch), 200); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 32), 50, GTUtility.copy(mulch), 300); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 33), 50, GTUtility.copy(mulch), 300); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 34), 100, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 35), 50, GTUtility.copy(mulch), 300); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 36), 50, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 37), 20, GTUtility.copy(mulch), 200); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 38), 300, GTUtility.copy(mulch), 1500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 39), 25, GTUtility.copy(mulch), 200); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 46), 50, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 50), 300, GTUtility.copy(mulch), 2500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 51), 150, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 52), 300, GTUtility.copy(mulch), 1500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 53), 50, GTUtility.copy(mulch), 1000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 54), 50, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 55), 100, GTUtility.copy(mulch), 1000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 56), 100, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 57), 400, GTUtility.copy(mulch), 2000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 58), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 59), 50, GTUtility.copy(mulch), 1000); } } diff --git a/src/main/java/gregtech/integration/forestry/recipes/ForestryMiscRecipes.java b/src/main/java/gregtech/integration/forestry/recipes/ForestryMiscRecipes.java index 5f4f214c294..85239b0a1a5 100644 --- a/src/main/java/gregtech/integration/forestry/recipes/ForestryMiscRecipes.java +++ b/src/main/java/gregtech/integration/forestry/recipes/ForestryMiscRecipes.java @@ -6,8 +6,8 @@ import gregtech.api.unification.material.Materials; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.common.items.MetaItems; -import gregtech.integration.IntegrationUtil; import gregtech.integration.forestry.ForestryConfig; import gregtech.integration.forestry.ForestryUtil; import gregtech.integration.forestry.bees.GTDropType; @@ -15,7 +15,6 @@ import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.common.Loader; import forestry.api.recipes.RecipeManagers; import forestry.apiculture.ModuleApiculture; @@ -28,7 +27,7 @@ public class ForestryMiscRecipes { public static void init() { - if (ForestryConfig.enableGTBees) { + if (ForestryConfig.enableGTBees && Mods.ForestryApiculture.isModLoaded()) { // Oil Drop ItemStack dropStack = ForestryUtil.getDropStack(GTDropType.OIL); RecipeMaps.EXTRACTOR_RECIPES.recipeBuilder() @@ -45,8 +44,8 @@ public static void init() { // Biomass Drop dropStack = ForestryUtil.getDropStack(GTDropType.BIOMASS); ItemStack propolisStack = ModuleApiculture.getItems().propolis.get(EnumPropolis.NORMAL, 1); - if (Loader.isModLoaded(GTValues.MODID_EB)) { - propolisStack = IntegrationUtil.getModItem(GTValues.MODID_EB, "propolis", 7); + if (Mods.ExtraBees.isModLoaded()) { + propolisStack = Mods.ExtraBees.getItem("propolis", 7); } RecipeMaps.EXTRACTOR_RECIPES.recipeBuilder() .inputs(dropStack) @@ -202,7 +201,7 @@ public static void init() { } // Fertilizer - ItemStack fertilizer = IntegrationUtil.getModItem(GTValues.MODID_FR, "fertilizer_compound", 0); + ItemStack fertilizer = Mods.Forestry.getItem("fertilizer_compound"); RecipeMaps.MIXER_RECIPES.recipeBuilder() .input("sand", 2) .input(OrePrefix.dust, Materials.Apatite) @@ -224,8 +223,8 @@ public static void init() { .outputs(GTUtility.copy(30, fertilizer)) .duration(100).EUt(16).buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_MB)) { - ItemStack concentratedCompound = IntegrationUtil.getModItem(GTValues.MODID_MB, "resource", 2); + if (Mods.MagicBees.isModLoaded()) { + ItemStack concentratedCompound = Mods.MagicBees.getItem("resource", 2); RecipeMaps.MIXER_RECIPES.recipeBuilder() .input("sand", 2) .inputs(GTUtility.copy(concentratedCompound)) @@ -249,7 +248,7 @@ public static void init() { } // Compost - ItemStack compost = IntegrationUtil.getModItem(GTValues.MODID_FR, "fertilizer_bio", 0); + ItemStack compost = Mods.Forestry.getItem("fertilizer_bio"); RecipeMaps.MIXER_RECIPES.recipeBuilder() .input(Blocks.DIRT, 1, true) .input(Items.WHEAT, 4) @@ -279,19 +278,19 @@ public static void init() { // Phosphor RecipeMaps.EXTRACTOR_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "phosphor", 0)) + .inputs(Mods.Forestry.getItem("phosphor")) .chancedOutput(OrePrefix.dust, Materials.Phosphorus, 1000, 0) .fluidOutputs(Materials.Lava.getFluid(800)) .duration(256).EUt(GTValues.VA[GTValues.MV]).buildAndRegister(); // Ice Shard RecipeMaps.MACERATOR_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "crafting_material", 5)) + .inputs(Mods.Forestry.getItem("crafting_material", 5)) .output(OrePrefix.dust, Materials.Ice) .duration(16).EUt(4).buildAndRegister(); // Mulch - ItemStack mulch = IntegrationUtil.getModItem(GTValues.MODID_FR, "mulch", 0); + ItemStack mulch = Mods.Forestry.getItem("mulch"); RecipeMaps.CHEMICAL_BATH_RECIPES.recipeBuilder() .input(MetaItems.BIO_CHAFF) .fluidInputs(Materials.Water.getFluid(750)) @@ -300,9 +299,9 @@ public static void init() { .chancedOutput(GTUtility.copy(4, mulch), 2000, 0) .duration(500).EUt(GTValues.VA[GTValues.LV]).buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_ET)) { + if (Mods.ExtraTrees.isModLoaded()) { RecipeMaps.MIXER_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_ET, "misc", 1)) + .inputs(Mods.ExtraTrees.getItem("misc", 1)) .fluidInputs(Materials.Water.getFluid(500)) .outputs(GTUtility.copy(mulch)) .duration(600).EUt(2).buildAndRegister(); @@ -328,7 +327,7 @@ public static void init() { .duration(900).EUt(10).buildAndRegister(); // Humus - ItemStack humus = IntegrationUtil.getModItem(GTValues.MODID_FR, "humus", 0); + ItemStack humus = Mods.Forestry.getItem("humus"); RecipeMaps.MIXER_RECIPES.recipeBuilder() .inputs(GTUtility.copy(2, mulch)) .input(Blocks.DIRT, 2, true) @@ -362,35 +361,35 @@ public static void init() { .input(OrePrefix.plate, Materials.Tin, 2) .input(Blocks.GLASS_PANE) .circuitMeta(1) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "can", 0)) + .outputs(Mods.Forestry.getItem("can")) .duration(120).EUt(7).buildAndRegister(); RecipeMaps.EXTRUDER_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "beeswax", 0)) + .inputs(Mods.Forestry.getItem("beeswax")) .notConsumable(MetaItems.SHAPE_EXTRUDER_CELL) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "capsule", 0)) + .outputs(Mods.Forestry.getItem("capsule")) .duration(64).EUt(16).buildAndRegister(); RecipeMaps.EXTRUDER_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "refractory_wax", 0)) + .inputs(Mods.Forestry.getItem("refractory_wax")) .notConsumable(MetaItems.SHAPE_EXTRUDER_CELL) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "refractory", 0)) + .outputs(Mods.Forestry.getItem("refractory")) .duration(128).EUt(16).buildAndRegister(); // Propolis RecipeMaps.CENTRIFUGE_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "propolis", 0)) + .inputs(Mods.Forestry.getItem("propolis")) .output(MetaItems.STICKY_RESIN) .duration(128).EUt(5).buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_GENETICS)) { + if (Mods.Genetics.isModLoaded()) { // DNA Dye RecipeMaps.MIXER_RECIPES.recipeBuilder() .input(OrePrefix.dust, Materials.Glowstone) .input("dyePurple") .input("dyeBlue") - .outputs(IntegrationUtil.getModItem(GTValues.MODID_GENETICS, "misc", 1, 8)) + .outputs(Mods.Genetics.getItem("misc", 1, 8)) .duration(100).EUt(GTValues.VA[GTValues.LV]).buildAndRegister(); // Fluorescent Dye @@ -398,14 +397,14 @@ public static void init() { .input(OrePrefix.dust, Materials.Glowstone) .input("dyeOrange") .input("dyeYellow") - .outputs(IntegrationUtil.getModItem(GTValues.MODID_GENETICS, "misc", 2, 2)) + .outputs(Mods.Genetics.getItem("misc", 2, 2)) .duration(100).EUt(GTValues.VA[GTValues.LV]).buildAndRegister(); // Growth Medium RecipeMaps.MIXER_RECIPES.recipeBuilder() .input(OrePrefix.dust, Materials.Sugar) .input(OrePrefix.dust, Materials.Bone) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_GENETICS, "misc", 4, 2)) + .outputs(Mods.Genetics.getItem("misc", 4, 2)) .duration(400).EUt(16).buildAndRegister(); } @@ -413,7 +412,7 @@ public static void init() { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_NUGGET) .fluidInputs(Fluids.FOR_HONEY.getFluid(200)) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "honey_drop", 0)) + .outputs(Mods.Forestry.getItem("honey_drop")) .duration(400).EUt(7).buildAndRegister(); RecipeMaps.CENTRIFUGE_RECIPES.recipeBuilder() @@ -425,7 +424,7 @@ public static void init() { public static void initRemoval() { ModHandler.removeRecipeByName("forestry:sand_to_fertilizer"); ModHandler.removeRecipeByName("forestry:ash_to_fertilizer"); - if (Loader.isModLoaded(GTValues.MODID_MB)) { + if (Mods.MagicBees.isModLoaded()) { ModHandler.removeRecipeByName("magicbees:fertilizer1"); ModHandler.removeRecipeByName("magicbees:fertilizer2"); ModHandler.removeRecipeByName("magicbees:fertilizer3"); @@ -437,7 +436,7 @@ public static void initRemoval() { ModHandler.removeRecipeByName("forestry:tin_can"); ModHandler.removeRecipeByName("forestry:wax_capsule"); ModHandler.removeRecipeByName("forestry:refractory_capsule"); - if (Loader.isModLoaded(GTValues.MODID_GENETICS)) { + if (Mods.Genetics.isModLoaded()) { ModHandler.removeRecipeByName("genetics:dna_dye_from_glowstone"); ModHandler.removeRecipeByName("genetics:dna_dye"); ModHandler.removeRecipeByName("genetics:fluorescent_dye"); diff --git a/src/main/java/gregtech/integration/forestry/tools/ScoopBehavior.java b/src/main/java/gregtech/integration/forestry/tools/ScoopBehavior.java index 221fadaa6f6..6eed93239d8 100644 --- a/src/main/java/gregtech/integration/forestry/tools/ScoopBehavior.java +++ b/src/main/java/gregtech/integration/forestry/tools/ScoopBehavior.java @@ -1,8 +1,8 @@ package gregtech.integration.forestry.tools; -import gregtech.api.GTValues; import gregtech.api.items.toolitem.ToolHelper; import gregtech.api.items.toolitem.behavior.IToolBehavior; +import gregtech.api.util.Mods; import net.minecraft.client.resources.I18n; import net.minecraft.client.util.ITooltipFlag; @@ -13,7 +13,6 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import net.minecraftforge.event.ForgeEventFactory; -import net.minecraftforge.fml.common.Loader; import forestry.api.lepidopterology.EnumFlutterType; import forestry.api.lepidopterology.IAlleleButterflySpecies; @@ -32,7 +31,7 @@ private ScoopBehavior() {/**/} @Override public void hitEntity(@NotNull ItemStack stack, @NotNull EntityLivingBase target, @NotNull EntityLivingBase attacker) { - if (!Loader.isModLoaded(GTValues.MODID_FR)) return; + if (!Mods.Forestry.isModLoaded()) return; if (!(target instanceof IEntityButterfly butterfly)) return; if (!(attacker instanceof EntityPlayer player)) return; if (attacker.world == null || attacker.world.isRemote) return; diff --git a/src/main/java/gregtech/integration/groovy/GroovyExpansions.java b/src/main/java/gregtech/integration/groovy/GroovyExpansions.java new file mode 100644 index 00000000000..e24191091e8 --- /dev/null +++ b/src/main/java/gregtech/integration/groovy/GroovyExpansions.java @@ -0,0 +1,69 @@ +package gregtech.integration.groovy; + +import gregtech.api.fluids.FluidBuilder; +import gregtech.api.fluids.attribute.FluidAttributes; +import gregtech.api.recipes.RecipeBuilder; +import gregtech.api.unification.Element; +import gregtech.api.unification.Elements; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.event.MaterialEvent; +import gregtech.api.unification.material.properties.ToolProperty; + +import net.minecraft.util.ResourceLocation; + +import com.cleanroommc.groovyscript.GroovyScript; +import com.cleanroommc.groovyscript.api.GroovyLog; + +public class GroovyExpansions { + + public static > RecipeBuilder property(RecipeBuilder builder, String key, + Object value) { + if (!builder.applyProperty(key, value)) { + GroovyLog.get().error("Failed to add property '{}' with '{}' to recipe", key, value); + } + return builder; + } + + public static Material.Builder materialBuilder(MaterialEvent event, int id, ResourceLocation resourceLocation) { + return new Material.Builder(id, resourceLocation); + } + + public static Material.Builder materialBuilder(MaterialEvent event, int id, String domain, String path) { + return materialBuilder(event, id, domain, path); + } + + public static Material.Builder materialBuilder(MaterialEvent event, int id, String s) { + String domain, path; + if (s.contains(":")) { + String[] parts = s.split(":", 2); + domain = parts[0]; + path = parts[1]; + } else { + domain = GroovyScript.getRunConfig().getPackId(); + path = s; + } + return materialBuilder(event, id, new ResourceLocation(domain, path)); + } + + public static ToolProperty.Builder toolBuilder(MaterialEvent event, float harvestSpeed, float attackDamage, + int durability, int harvestLevel) { + return ToolProperty.Builder.of(harvestSpeed, attackDamage, durability, harvestLevel); + } + + public static ToolProperty.Builder toolBuilder(MaterialEvent event) { + return toolBuilder(event, 1.0F, 1.0F, 100, 2); + } + + public static FluidBuilder fluidBuilder(MaterialEvent event) { + return new FluidBuilder(); + } + + public static Element addElement(MaterialEvent event, long protons, long neutrons, long halfLifeSeconds, + String decayTo, String name, String symbol, boolean isIsotope) { + return Elements.add(protons, neutrons, halfLifeSeconds, decayTo, name, symbol, isIsotope); + } + + public static FluidBuilder acidic(FluidBuilder builder) { + return builder.attributes(FluidAttributes.ACID); + } +} diff --git a/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java b/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java index 3f5ea4873f4..2b67fa26844 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java +++ b/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java @@ -8,9 +8,14 @@ import gregtech.api.unification.material.info.MaterialFlag; import gregtech.api.unification.material.info.MaterialIconSet; import gregtech.api.unification.material.properties.BlastProperty; +import gregtech.api.unification.material.properties.ToolProperty; +import gregtech.api.unification.stack.MaterialStack; import net.minecraft.util.ResourceLocation; +import com.cleanroommc.groovyscript.api.GroovyLog; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + import java.util.ArrayList; import java.util.List; @@ -85,22 +90,39 @@ public static Material.Builder blastTemp(Material.Builder builder, int temp, Str public static Material.Builder blastTemp(Material.Builder builder, int temp, String raw, int eutOverride, int durationOverride, int vacuumEUtOverride, int vacuumDurationOverride) { - BlastProperty.GasTier gasTier = null; - String name = raw.toUpperCase(); - for (BlastProperty.GasTier gasTier1 : BlastProperty.GasTier.VALUES) { - if (gasTier1.name().equals(name)) { - gasTier = gasTier1; - break; - } - } - final BlastProperty.GasTier finalGasTier = gasTier; - if (GroovyScriptModule.validateNonNull(gasTier, () -> "Can't find gas tier for " + name + - " in material builder. Valid values are 'low', 'mid', 'high', 'higher', 'highest'!")) { + BlastProperty.GasTier gasTier = GroovyScriptModule.parseAndValidateEnumValue(BlastProperty.GasTier.class, raw, + "gas tier"); + if (gasTier != null) { return builder.blast(b -> b - .temp(temp, finalGasTier) + .temp(temp, gasTier) .blastStats(eutOverride, durationOverride) .vacuumStats(vacuumEUtOverride, vacuumDurationOverride)); } return builder; } + + public static Material.Builder components(Material.Builder builder, Object... objects) { + ObjectArrayList materialStacks = new ObjectArrayList<>(); + for (Object o : objects) { + if (o instanceof MaterialStack materialStack) { + materialStacks.add(materialStack); + } else if (o instanceof Material material) { + materialStacks.add(new MaterialStack(material, 1)); + } else { + GroovyLog.get() + .error("Material components must be of type Material or MaterialStack, but was of type {}", + o == null ? null : o.getClass()); + } + } + return builder.components(materialStacks.toArray(new MaterialStack[0])); + } + + public static Material.Builder toolStats(Material.Builder builder, ToolProperty.Builder toolBuilder) { + return builder.toolStats(toolBuilder.build()); + } + + public static Material.Builder toolStats(Material.Builder builder, float harvestSpeed, float attackDamage, + int durability, int harvestLevel) { + return builder.toolStats(ToolProperty.Builder.of(harvestSpeed, attackDamage, durability, harvestLevel).build()); + } } diff --git a/src/main/java/gregtech/integration/groovy/GroovyRecipeBuilderExpansion.java b/src/main/java/gregtech/integration/groovy/GroovyRecipeBuilderExpansion.java deleted file mode 100644 index 90a0dc3753b..00000000000 --- a/src/main/java/gregtech/integration/groovy/GroovyRecipeBuilderExpansion.java +++ /dev/null @@ -1,16 +0,0 @@ -package gregtech.integration.groovy; - -import gregtech.api.recipes.RecipeBuilder; - -import com.cleanroommc.groovyscript.api.GroovyLog; - -public class GroovyRecipeBuilderExpansion { - - public static > RecipeBuilder property(RecipeBuilder builder, String key, - Object value) { - if (!builder.applyProperty(key, value)) { - GroovyLog.get().error("Failed to add property '{}' with '{}' to recipe", key, value); - } - return builder; - } -} diff --git a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java index adb308fe4e6..e5082df1461 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java +++ b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java @@ -2,14 +2,20 @@ import gregtech.api.GTValues; import gregtech.api.GregTechAPI; +import gregtech.api.fluids.FluidBuilder; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.modules.GregTechModule; import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; +import gregtech.api.unification.Element; +import gregtech.api.unification.Elements; import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.event.MaterialEvent; +import gregtech.api.unification.material.event.PostMaterialEvent; import gregtech.api.unification.material.registry.MaterialRegistry; import gregtech.api.unification.ore.OrePrefix; +import gregtech.api.util.Mods; import gregtech.common.blocks.BlockCompressed; import gregtech.common.blocks.BlockFrame; import gregtech.common.blocks.MetaBlocks; @@ -17,8 +23,6 @@ import gregtech.common.pipelike.fluidpipe.BlockFluidPipe; import gregtech.common.pipelike.itempipe.BlockItemPipe; import gregtech.integration.IntegrationSubmodule; -import gregtech.integration.crafttweaker.material.MaterialExpansion; -import gregtech.integration.crafttweaker.material.MaterialPropertyExpansion; import gregtech.modules.GregTechModules; import net.minecraft.item.ItemStack; @@ -32,33 +36,41 @@ import com.cleanroommc.groovyscript.GroovyScript; import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.GroovyPlugin; -import com.cleanroommc.groovyscript.api.IGameObjectHandler; +import com.cleanroommc.groovyscript.api.IGameObjectParser; +import com.cleanroommc.groovyscript.api.Result; import com.cleanroommc.groovyscript.compat.mods.GroovyContainer; -import com.cleanroommc.groovyscript.gameobjects.GameObjectHandlerManager; +import com.cleanroommc.groovyscript.compat.mods.ModPropertyContainer; +import com.cleanroommc.groovyscript.gameobjects.GameObjectHandler; +import com.cleanroommc.groovyscript.helper.EnumHelper; import com.cleanroommc.groovyscript.sandbox.expand.ExpansionHelper; import com.google.common.collect.ImmutableList; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.eclipse.lsp4j.CompletionItem; +import org.eclipse.lsp4j.CompletionItemKind; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Objects; import java.util.function.Supplier; -@Optional.Interface(modid = GTValues.MODID_GROOVYSCRIPT, +@Optional.Interface(modid = Mods.Names.GROOVY_SCRIPT, iface = "com.cleanroommc.groovyscript.api.GroovyPlugin", striprefs = true) @GregTechModule( moduleID = GregTechModules.MODULE_GRS, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_GROOVYSCRIPT, + modDependencies = Mods.Names.GROOVY_SCRIPT, name = "GregTech GroovyScript Integration", description = "GroovyScript Integration Module") public class GroovyScriptModule extends IntegrationSubmodule implements GroovyPlugin { private static GroovyContainer modSupportContainer; - private static final Map> metaItems = new Object2ObjectOpenHashMap<>(); + private static final Object2ObjectOpenHashMap> metaItems = new Object2ObjectOpenHashMap<>(); @NotNull @Override @@ -76,6 +88,26 @@ public static boolean isCurrentlyRunning() { GroovyScript.getSandbox().isRunning(); } + public static > T parseAndValidateEnumValue(Class clazz, String raw, String type) { + return parseAndValidateEnumValue(clazz, raw, type, false); + } + + @Contract("_,_,_,true -> !null") + public static > T parseAndValidateEnumValue(Class clazz, String raw, String type, + boolean crash) { + T t = EnumHelper.valueOfNullable(clazz, raw, false); + if (t == null) { + String msg = GroovyLog.format("Can't find {} for {} in material builder. Valid values are {};", + type, + raw, + Arrays.toString(clazz.getEnumConstants())); + if (crash) throw new NoSuchElementException(msg); + GroovyLog.get().error(msg); + return null; + } + return t; + } + public static GroovyContainer getInstance() { return modSupportContainer; } @@ -190,28 +222,94 @@ public static void loadMetaItemBracketHandler() { } @Override - public @NotNull String getModName() { + public @NotNull String getContainerName() { return "GregTech"; } + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) + @Override + public @Nullable ModPropertyContainer createModPropertyContainer() { + return new PropertyContainer(); + } + @Override public void onCompatLoaded(GroovyContainer groovyContainer) { - modSupportContainer = groovyContainer; - GameObjectHandlerManager.registerGameObjectHandler(GTValues.MODID, "recipemap", - IGameObjectHandler.wrapStringGetter(RecipeMap::getByName)); + GroovyScriptModule.modSupportContainer = groovyContainer; + GameObjectHandler.builder("recipemap", RecipeMap.class) + .mod(GTValues.MODID) + .parser(IGameObjectParser.wrapStringGetter(RecipeMap::getByName)) + .completerOfNamed(RecipeMap::getRecipeMaps, RecipeMap::getUnlocalizedName) + .register(); + GameObjectHandler.builder("material", Material.class) + .mod(GTValues.MODID) + .parser(IGameObjectParser.wrapStringGetter(GregTechAPI.materialManager::getMaterial)) + .completerOfNamed(GregTechAPI.materialManager::getRegisteredMaterials, + mat -> mat.getResourceLocation().toString()) + .register(); - GameObjectHandlerManager.registerGameObjectHandler(GTValues.MODID, "material", - IGameObjectHandler.wrapStringGetter(GregTechAPI.materialManager::getMaterial)); + GameObjectHandler.builder("oreprefix", OrePrefix.class) + .mod(GTValues.MODID) + .parser(IGameObjectParser.wrapStringGetter(OrePrefix::getPrefix)) + .completerOfNamed(OrePrefix::values, v -> v.name) + .register(); - GameObjectHandlerManager.registerGameObjectHandler(GTValues.MODID, "oreprefix", - IGameObjectHandler.wrapStringGetter(OrePrefix::getPrefix)); + GameObjectHandler.builder("metaitem", ItemStack.class) + .mod(GTValues.MODID) + .parser(IGameObjectParser.wrapStringGetter(GroovyScriptModule::getMetaItem)) + .completer((paramIndex, items) -> { + if (paramIndex != 0) return; + for (var iterator = metaItems.object2ObjectEntrySet().fastIterator(); iterator.hasNext();) { + var entry = iterator.next(); + String mod = entry.getKey(); + for (String key : entry.getValue().keySet()) { + var item = new CompletionItem(mod + ":" + key); + item.setKind(CompletionItemKind.Constant); + items.add(item); + } + } + }) + .register(); - GameObjectHandlerManager.registerGameObjectHandler(GTValues.MODID, "metaitem", - IGameObjectHandler.wrapStringGetter(GroovyScriptModule::getMetaItem), ItemStack.EMPTY); + GameObjectHandler.builder("element", Element.class) + .mod(GTValues.MODID) + .parser((s, args) -> { + Element element = Elements.get(s); + if (element != null) return Result.some(element); + if (s.length() <= 6) { + for (Element element1 : Elements.getAllElements()) { + if (element1.symbol.equals(s)) { + return Result.some(element1); + } + } + } + return Result.error(); + }) + .completerOfNamed(Elements::getAllElements, Element::getName) + .register(); ExpansionHelper.mixinClass(Material.class, MaterialExpansion.class); ExpansionHelper.mixinClass(Material.class, MaterialPropertyExpansion.class); ExpansionHelper.mixinClass(Material.Builder.class, GroovyMaterialBuilderExpansion.class); - ExpansionHelper.mixinClass(RecipeBuilder.class, GroovyRecipeBuilderExpansion.class); + ExpansionHelper.mixinMethod(RecipeBuilder.class, GroovyExpansions.class, "property"); + ExpansionHelper.mixinMethod(MaterialEvent.class, GroovyExpansions.class, "materialBuilder"); + ExpansionHelper.mixinMethod(MaterialEvent.class, GroovyExpansions.class, "toolBuilder"); + ExpansionHelper.mixinMethod(MaterialEvent.class, GroovyExpansions.class, "fluidBuilder"); + ExpansionHelper.mixinMethod(PostMaterialEvent.class, GroovyExpansions.class, "toolBuilder"); + ExpansionHelper.mixinMethod(PostMaterialEvent.class, GroovyExpansions.class, "fluidBuilder"); + ExpansionHelper.mixinMethod(FluidBuilder.class, GroovyExpansions.class, "acidic"); + } + + protected static boolean checkFrozen(String description) { + if (!GregTechAPI.materialManager.canModifyMaterials()) { + GroovyLog.get().error("Cannot {} now, must be done in preInit loadStage and material event", description); + return true; + } + return false; + } + + protected static void logError(Material m, String cause, String type) { + GroovyLog.get().error( + "Cannot {0} of a Material with no {1}! Try calling \"add{1}\" in your late material event first if this is intentional. Material: {2}", + cause, type, m.getUnlocalizedName()); } } diff --git a/src/main/java/gregtech/integration/groovy/MaterialExpansion.java b/src/main/java/gregtech/integration/groovy/MaterialExpansion.java new file mode 100644 index 00000000000..70b92dd04d9 --- /dev/null +++ b/src/main/java/gregtech/integration/groovy/MaterialExpansion.java @@ -0,0 +1,225 @@ +package gregtech.integration.groovy; + +import gregtech.api.fluids.store.FluidStorageKeys; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.info.MaterialFlag; +import gregtech.api.unification.material.info.MaterialIconSet; +import gregtech.api.unification.material.properties.BlastProperty; +import gregtech.api.unification.material.properties.DustProperty; +import gregtech.api.unification.material.properties.FluidProperty; +import gregtech.api.unification.material.properties.OreProperty; +import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.api.unification.material.properties.ToolProperty; + +import net.minecraft.enchantment.Enchantment; + +import com.cleanroommc.groovyscript.api.GroovyLog; + +import static gregtech.integration.groovy.GroovyScriptModule.checkFrozen; +import static gregtech.integration.groovy.GroovyScriptModule.logError; + +@SuppressWarnings("unused") +public class MaterialExpansion { + + //////////////////////////////////// + // Material Methods // + //////////////////////////////////// + + public static void setFormula(Material m, String formula) { + setFormula(m, formula, false); + } + + public static void setFormula(Material m, String formula, boolean withFormatting) { + if (checkFrozen("set material chemical formula")) return; + m.setFormula(formula, withFormatting); + } + + public static boolean hasFlag(Material m, String flagName) { + return m.hasFlag(MaterialFlag.getByName(flagName)); + } + + public static void setIconSet(Material m, String iconSetName) { + if (checkFrozen("set material icon set")) return; + m.setMaterialIconSet(MaterialIconSet.getByName(iconSetName)); + } + + public static String getIconSet(Material m) { + return m.getMaterialIconSet().getName(); + } + + //////////////////////////////////// + // Fluid Property // + //////////////////////////////////// + + public static boolean isGaseous(Material m) { + FluidProperty prop = m.getProperty(PropertyKey.FLUID); + return prop != null && prop.getStorage().get(FluidStorageKeys.GAS) != null; + } + + /////////////////////////////////// + // Dust Property // + /////////////////////////////////// + + public static int harvestLevel(Material m) { + DustProperty prop = m.getProperty(PropertyKey.DUST); + if (prop != null) { + return prop.getHarvestLevel(); + } else logError(m, "get the harvest level", "Dust"); + return 0; + } + + public static int burnTime(Material m) { + DustProperty prop = m.getProperty(PropertyKey.DUST); + if (prop != null) { + return prop.getBurnTime(); + } else logError(m, "get the burn time", "Dust"); + return 0; + } + + public static void setHarvestLevel(Material m, int harvestLevel) { + if (checkFrozen("set harvest level")) return; + DustProperty prop = m.getProperty(PropertyKey.DUST); + if (prop != null) { + prop.setHarvestLevel(harvestLevel); + } else logError(m, "set the harvest level", "Dust"); + } + + public static void setBurnTime(Material m, int burnTime) { + if (checkFrozen("set burn time")) return; + DustProperty prop = m.getProperty(PropertyKey.DUST); + if (prop != null) { + prop.setBurnTime(burnTime); + } else logError(m, "set the burn time", "Dust"); + } + + /////////////////////////////////// + // Tool Property // + /////////////////////////////////// + public static float toolSpeed(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolSpeed(); + } else logError(m, "get the tool speed", "Tool"); + return 0; + } + + public static float attackDamage(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolAttackDamage(); + } else logError(m, "get the tool attack damage", "Tool"); + return 0; + } + + public static int toolDurability(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolDurability(); + } else logError(m, "get the tool durability", "Tool"); + return 0; + } + + public static int toolHarvestLevel(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolHarvestLevel(); + } else logError(m, "get the tool harvest level", "Tool"); + return 0; + } + + public static int toolEnchantability(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolEnchantability(); + } else logError(m, "get the tool enchantability", "Tool"); + return 0; + } + + public static void addToolEnchantment(Material m, Enchantment enchantment, int level) { + addScaledToolEnchantment(m, enchantment, level, 0); + } + + public static void addScaledToolEnchantment(Material m, Enchantment enchantment, int level, double levelGrowth) { + if (checkFrozen("add tool enchantment")) return; + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + prop.addEnchantmentForTools(enchantment, level, levelGrowth); + } else logError(m, "change tool enchantments", "Tool"); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + boolean shouldIngoreCraftingTools) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, 0, 0, shouldIngoreCraftingTools); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + int enchantability, boolean shouldIngoreCraftingTools) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, enchantability, 0, shouldIngoreCraftingTools); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, 0, 0, false); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + int enchantability) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, enchantability, 0, false); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + int enchantability, int toolHarvestLevel) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, enchantability, toolHarvestLevel, false); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + int enchantability, int toolHarvestLevel, + boolean shouldIngoreCraftingTools) { + if (checkFrozen("set tool stats")) return; + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + prop.setToolSpeed(toolSpeed); + prop.setToolAttackDamage(toolAttackDamage); + prop.setToolDurability(toolDurability); + prop.setToolHarvestLevel(toolHarvestLevel == 0 ? 2 : toolHarvestLevel); + prop.setToolEnchantability(enchantability == 0 ? 10 : enchantability); + prop.setShouldIgnoreCraftingTools(shouldIngoreCraftingTools); + } else logError(m, "change tool stats", "Tool"); + } + + // Wire/Item Pipe/Fluid Pipe stuff? + + //////////////////////////////////// + // Blast Property // + //////////////////////////////////// + + public static void setBlastTemp(Material m, int blastTemp) { + if (checkFrozen("set blast temperature")) return; + if (blastTemp <= 0) { + GroovyLog.get().error("Blast Temperature must be greater than zero! Material: " + m.getUnlocalizedName()); + return; + } + BlastProperty prop = m.getProperty(PropertyKey.BLAST); + if (prop != null) prop.setBlastTemperature(blastTemp); + else m.setProperty(PropertyKey.BLAST, new BlastProperty(blastTemp)); + } + + public static int blastTemp(Material m) { + BlastProperty prop = m.getProperty(PropertyKey.BLAST); + if (prop != null) { + return prop.getBlastTemperature(); + } else logError(m, "get blast temperature", "Blast"); + return 0; + } + + //////////////////////////////////// + // Ore Property // + //////////////////////////////////// + + public static int oreMultiplier(Material m) { + OreProperty prop = m.getProperty(PropertyKey.ORE); + if (prop != null) { + return prop.getOreMultiplier(); + } else logError(m, "get ore multiplier", "Ore"); + return 0; + } +} diff --git a/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java b/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java new file mode 100644 index 00000000000..83ceb1b27a7 --- /dev/null +++ b/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java @@ -0,0 +1,355 @@ +package gregtech.integration.groovy; + +import gregtech.api.fluids.FluidBuilder; +import gregtech.api.fluids.FluidState; +import gregtech.api.fluids.attribute.FluidAttributes; +import gregtech.api.fluids.store.FluidStorageKey; +import gregtech.api.fluids.store.FluidStorageKeys; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.properties.BlastProperty; +import gregtech.api.unification.material.properties.DustProperty; +import gregtech.api.unification.material.properties.FluidPipeProperties; +import gregtech.api.unification.material.properties.FluidProperty; +import gregtech.api.unification.material.properties.GemProperty; +import gregtech.api.unification.material.properties.IngotProperty; +import gregtech.api.unification.material.properties.ItemPipeProperties; +import gregtech.api.unification.material.properties.OreProperty; +import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.api.unification.material.properties.ToolProperty; +import gregtech.api.unification.material.properties.WireProperties; +import gregtech.api.unification.material.properties.WoodProperty; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; + +import static gregtech.integration.groovy.GroovyScriptModule.checkFrozen; + +@SuppressWarnings("unused") +public class MaterialPropertyExpansion { + + ///////////////////////////////////// + // Property Checkers // + ///////////////////////////////////// + + public static boolean hasBlastTemp(Material m) { + return m.hasProperty(PropertyKey.BLAST); + } + + public static boolean hasDust(Material m) { + return m.hasProperty(PropertyKey.DUST); + } + + public static boolean hasFluidPipes(Material m) { + return m.hasProperty(PropertyKey.FLUID_PIPE); + } + + public static boolean hasFluid(Material m) { + return m.hasProperty(PropertyKey.FLUID); + } + + public static boolean hasGem(Material m) { + return m.hasProperty(PropertyKey.GEM); + } + + public static boolean hasIngot(Material m) { + return m.hasProperty(PropertyKey.INGOT); + } + + public static boolean hasItemPipes(Material m) { + return m.hasProperty(PropertyKey.ITEM_PIPE); + } + + public static boolean hasOre(Material m) { + return m.hasProperty(PropertyKey.ORE); + } + + public static boolean hasTools(Material m) { + return m.hasProperty(PropertyKey.TOOL); + } + + public static boolean hasWires(Material m) { + return m.hasProperty(PropertyKey.WIRE); + } + + //////////////////////////////////// + // Property Setters // + //////////////////////////////////// + + public static void addBlastTemp(Material m, int blastTemp) { + if (checkFrozen("add blast temperature")) return; + if (m.hasProperty(PropertyKey.BLAST)) m.getProperty(PropertyKey.BLAST).setBlastTemperature(blastTemp); + else m.setProperty(PropertyKey.BLAST, new BlastProperty(blastTemp)); + } + + public static void addBlastProperty(Material m, int blastTemp) { + addBlastProperty(m, blastTemp, null, 0, 0, 0, 0); + } + + public static void addBlastProperty(Material m, int blastTemp, String gasTier) { + addBlastProperty(m, blastTemp, gasTier, 0, 0, 0, 0); + } + + public static void addBlastProperty(Material m, int blastTemp, String gasTier, + int durationOverride) { + addBlastProperty(m, blastTemp, gasTier, durationOverride, 0, 0, 0); + } + + public static void addBlastProperty(Material m, int blastTemp, String gasTier, + int durationOverride, int eutOverride) { + addBlastProperty(m, blastTemp, gasTier, durationOverride, eutOverride, 0, 0); + } + + public static void addBlastProperty(Material m, int blastTemp, String gasTier, + int durationOverride, int eutOverride, + int vacuumDurationOverride, int vacuumEUtOverride) { + if (checkFrozen("add blast property")) return; + if (m.hasProperty(PropertyKey.BLAST)) { + BlastProperty property = m.getProperty(PropertyKey.BLAST); + property.setBlastTemperature(blastTemp); + if (gasTier != null) property.setGasTier(BlastProperty.validateGasTier(gasTier)); + if (durationOverride != 0) property.setDurationOverride(durationOverride); + if (eutOverride != 0) property.setEutOverride(eutOverride); + if (vacuumDurationOverride != 0) property.setVacuumDurationOverride(vacuumDurationOverride); + if (vacuumEUtOverride != 0) property.setVacuumEutOverride(vacuumEUtOverride); + } else { + BlastProperty.Builder builder = new BlastProperty.Builder(); + builder.temp(blastTemp, + gasTier == null ? BlastProperty.GasTier.LOW : BlastProperty.validateGasTier(gasTier)); + builder.blastStats(durationOverride == 0 ? -1 : durationOverride, eutOverride == 0 ? -1 : eutOverride); + builder.vacuumStats(vacuumEUtOverride == 0 ? -1 : vacuumEUtOverride, + vacuumDurationOverride == 0 ? -1 : vacuumDurationOverride); + m.setProperty(PropertyKey.BLAST, builder.build()); + } + } + + public static void addDust(Material m) { + addDust(m, 0, 0); + } + + public static void addDust(Material m, int harvestLevel) { + addDust(m, harvestLevel, 0); + } + + public static void addDust(Material m, int harvestLevel, int burnTime) { + if (checkFrozen("add a dust to a material")) return; + if (harvestLevel == 0) harvestLevel = 2; + if (m.hasProperty(PropertyKey.DUST)) { + m.getProperty(PropertyKey.DUST).setHarvestLevel(harvestLevel); + m.getProperty(PropertyKey.DUST).setBurnTime(burnTime); + } else m.setProperty(PropertyKey.DUST, new DustProperty(harvestLevel, burnTime)); + } + + public static void addWood(Material m) { + if (checkFrozen("add a wood to a material")) return; + if (!m.hasProperty(PropertyKey.WOOD)) { + m.setProperty(PropertyKey.WOOD, new WoodProperty()); + } + } + + public static void addFluidPipes(Material m, int maxFluidTemperature, int throughput, boolean gasProof) { + addFluidPipes(m, maxFluidTemperature, throughput, gasProof, false, false, false); + } + + public static void addFluidPipes(Material m, int maxFluidTemperature, int throughput, boolean gasProof, + boolean acidProof, boolean cryoProof, boolean plasmaProof) { + if (checkFrozen("add fluid pipes to a material")) return; + if (m.hasProperty(PropertyKey.FLUID_PIPE)) { + m.getProperty(PropertyKey.FLUID_PIPE).setMaxFluidTemperature(maxFluidTemperature); + m.getProperty(PropertyKey.FLUID_PIPE).setThroughput(throughput); + m.getProperty(PropertyKey.FLUID_PIPE).setGasProof(gasProof); + m.getProperty(PropertyKey.FLUID_PIPE).setCanContain(FluidAttributes.ACID, acidProof); + m.getProperty(PropertyKey.FLUID_PIPE).setCryoProof(cryoProof); + m.getProperty(PropertyKey.FLUID_PIPE).setPlasmaProof(plasmaProof); + } else { + m.setProperty(PropertyKey.FLUID_PIPE, new FluidPipeProperties(maxFluidTemperature, throughput, gasProof, + acidProof, cryoProof, plasmaProof)); + } + } + + @GroovyBlacklist + private static void addFluidInternal(Material m, FluidStorageKey key, FluidBuilder builder) { + if (checkFrozen("add a Fluid to a material")) return; + FluidProperty property = m.getProperty(PropertyKey.FLUID); + if (property == null) { + property = new FluidProperty(); + m.setProperty(PropertyKey.FLUID, property); + } + property.getStorage().enqueueRegistration(key, builder); + } + + public static void addLiquid(Material m, FluidBuilder builder) { + addFluidInternal(m, FluidStorageKeys.LIQUID, builder.state(FluidState.LIQUID)); + } + + public static void addLiquid(Material m) { + addLiquid(m, new FluidBuilder()); + } + + public static void addFluid(Material m) { + addLiquid(m); + } + + @Deprecated + public static void addFluid(Material m, String fluidTypeName) { + addFluid(m, fluidTypeName, false); + } + + @Deprecated + public static void addFluid(Material m, String fluidTypeName, boolean hasBlock) { + GroovyLog.get().error("The usage of `material.addFluid(String, boolean)` is strongly discouraged. " + + "Please use `addLiquid()`, `addGas()` or `addPlasma()` with or without `FluidBuilder`."); + if (checkFrozen("add a Fluid to a material")) return; + FluidState type = GroovyScriptModule.parseAndValidateEnumValue(FluidState.class, fluidTypeName, "fluid type", + true); + FluidStorageKey storageKey = switch (type) { + case LIQUID -> FluidStorageKeys.LIQUID; + case GAS -> FluidStorageKeys.GAS; + case PLASMA -> FluidStorageKeys.PLASMA; + }; + FluidBuilder builder = new FluidBuilder(); + builder.state(type); + if (hasBlock) builder.block(); + addFluidInternal(m, storageKey, builder); + } + + public static void addGas(Material m, FluidBuilder builder) { + addFluidInternal(m, FluidStorageKeys.GAS, builder.state(FluidState.GAS)); + } + + public static void addGas(Material m) { + addGas(m, new FluidBuilder()); + } + + public static void addPlasma(Material m, FluidBuilder builder) { + addFluidInternal(m, FluidStorageKeys.PLASMA, builder.state(FluidState.PLASMA)); + } + + public static void addPlasma(Material m) { + addPlasma(m, new FluidBuilder()); + } + + public static void addGem(Material m) { + if (checkFrozen("add a Gem to a material")) return; + if (!m.hasProperty(PropertyKey.GEM)) m.setProperty(PropertyKey.GEM, new GemProperty()); + } + + public static void addIngot(Material m) { + if (checkFrozen("add an Ingot to a material")) return; + if (!m.hasProperty(PropertyKey.INGOT)) m.setProperty(PropertyKey.INGOT, new IngotProperty()); + } + + public static void addOre(Material m) { + addOre(m, false); + } + + public static void addOre(Material m, boolean emissive) { + addOre(m, 0, 0, emissive); + } + + public static void addOre(Material m, int oreMultiplier, int byproductMultiplier) { + addOre(m, oreMultiplier, byproductMultiplier, false); + } + + public static void addOre(Material m, int oreMultiplier, int byproductMultiplier, boolean emissive) { + if (checkFrozen("add an Ore to a material")) return; + oreMultiplier = oreMultiplier == 0 ? 1 : oreMultiplier; + byproductMultiplier = byproductMultiplier == 0 ? 1 : byproductMultiplier; + if (m.hasProperty(PropertyKey.ORE)) { + m.getProperty(PropertyKey.ORE).setOreMultiplier(oreMultiplier); + m.getProperty(PropertyKey.ORE).setByProductMultiplier(byproductMultiplier); + m.getProperty(PropertyKey.ORE).setEmissive(emissive); + } else m.setProperty(PropertyKey.ORE, new OreProperty(oreMultiplier, byproductMultiplier, emissive)); + } + + public static void addItemPipes(Material m, int priority, float transferRate) { + if (checkFrozen("add Item Pipes to a material")) return; + if (m.hasProperty(PropertyKey.ITEM_PIPE)) { + m.getProperty(PropertyKey.ITEM_PIPE).setPriority(priority); + m.getProperty(PropertyKey.ITEM_PIPE).setTransferRate(transferRate); + } else m.setProperty(PropertyKey.ITEM_PIPE, new ItemPipeProperties(priority, transferRate)); + } + + public static void addTools(Material m, ToolProperty.Builder builder) { + addTools(m, builder.build()); + } + + public static void addTools(Material m, ToolProperty prop) { + if (checkFrozen("add Tools to a material")) return; + ToolProperty property = m.getProperty(PropertyKey.TOOL); + if (property != null) { + property.setToolSpeed(prop.getToolSpeed()); + property.setToolAttackDamage(prop.getToolAttackDamage()); + property.setToolDurability(prop.getToolDurability()); + property.setToolHarvestLevel(prop.getToolHarvestLevel()); + property.setToolAttackSpeed(prop.getToolAttackSpeed()); + property.setToolEnchantability(prop.getToolEnchantability()); + property.setMagnetic(prop.isMagnetic()); + property.setUnbreakable(prop.getUnbreakable()); + property.setShouldIgnoreCraftingTools(prop.getShouldIgnoreCraftingTools()); + property.setDurabilityMultiplier(prop.getDurabilityMultiplier()); + } else { + m.setProperty(PropertyKey.TOOL, prop); + } + } + + public static void addTools(Material m, float toolSpeed, float toolAttackDamage, float toolAttackSpeed, + int toolDurability) { + addTools(m, toolSpeed, toolAttackDamage, toolAttackSpeed, toolDurability, 0, 10, 1); + } + + public static void addTools(Material m, float toolSpeed, float toolAttackDamage, float toolAttackSpeed, + int toolDurability, int toolHarvestLevel) { + addTools(m, toolSpeed, toolAttackDamage, toolAttackSpeed, toolDurability, toolHarvestLevel, 10, 1); + } + + public static void addTools(Material m, float toolSpeed, float toolAttackDamage, float toolAttackSpeed, + int toolDurability, int toolHarvestLevel, int toolEnchantability) { + addTools(m, toolSpeed, toolAttackDamage, toolAttackSpeed, toolDurability, toolHarvestLevel, toolEnchantability, + 1); + } + + public static void addTools(Material m, float toolSpeed, float toolAttackDamage, float toolAttackSpeed, + int toolDurability, int toolHarvestLevel, int toolEnchantability, + int durabilityMultiplier) { + if (toolEnchantability == 0) toolEnchantability = 10; + if (durabilityMultiplier <= 0) durabilityMultiplier = 1; + addTools(m, ToolProperty.Builder.of(toolSpeed, toolAttackDamage, toolDurability, toolHarvestLevel) + .attackSpeed(toolAttackSpeed) + .enchantability(toolEnchantability) + .durabilityMultiplier(durabilityMultiplier)); + } + + public static void addWires(Material m, int voltage, int baseAmperage, int lossPerBlock) { + addWires(m, voltage, baseAmperage, lossPerBlock, false, 0); + } + + public static void addWires(Material m, int voltage, int baseAmperage, int lossPerBlock, boolean isSuperCon) { + addWires(m, voltage, baseAmperage, lossPerBlock, isSuperCon, 0); + } + + public static void addWires(Material m, int voltage, int baseAmperage, int lossPerBlock, boolean isSuperCon, + int criticalTemp) { + if (checkFrozen("add Wires to a material")) return; + if (m.hasProperty(PropertyKey.WIRE)) { + m.getProperty(PropertyKey.WIRE).setVoltage(voltage); + m.getProperty(PropertyKey.WIRE).setAmperage(baseAmperage); + m.getProperty(PropertyKey.WIRE).setLossPerBlock(lossPerBlock); + m.getProperty(PropertyKey.WIRE).setSuperconductor(isSuperCon); + m.getProperty(PropertyKey.WIRE).setSuperconductorCriticalTemperature(criticalTemp); + } else m.setProperty(PropertyKey.WIRE, + new WireProperties(voltage, baseAmperage, lossPerBlock, isSuperCon, criticalTemp)); + } + + public static void addCables(Material m, int voltage, int baseAmperage, int lossPerBlock) { + addWires(m, voltage, baseAmperage, lossPerBlock, false, 0); + } + + public static void addCables(Material m, int voltage, int baseAmperage, int lossPerBlock, boolean isSuperCon) { + addWires(m, voltage, baseAmperage, lossPerBlock, isSuperCon, 0); + } + + public static void addCables(Material m, int voltage, int baseAmperage, int lossPerBlock, boolean isSuperCon, + int criticalTemp) { + addWires(m, voltage, baseAmperage, lossPerBlock, isSuperCon, criticalTemp); + } +} diff --git a/src/main/java/gregtech/integration/groovy/PropertyContainer.java b/src/main/java/gregtech/integration/groovy/PropertyContainer.java new file mode 100644 index 00000000000..35da8ce4905 --- /dev/null +++ b/src/main/java/gregtech/integration/groovy/PropertyContainer.java @@ -0,0 +1,47 @@ +package gregtech.integration.groovy; + +import gregtech.api.unification.material.event.MaterialEvent; +import gregtech.api.unification.material.event.PostMaterialEvent; + +import net.minecraftforge.fml.common.eventhandler.EventPriority; + +import com.cleanroommc.groovyscript.GroovyScript; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.compat.mods.ModPropertyContainer; +import com.cleanroommc.groovyscript.event.EventBusType; +import com.cleanroommc.groovyscript.event.GroovyEventManager; +import com.cleanroommc.groovyscript.sandbox.ClosureHelper; +import com.cleanroommc.groovyscript.sandbox.LoadStage; +import groovy.lang.Closure; +import groovy.lang.DelegatesTo; + +public class PropertyContainer extends ModPropertyContainer { + + public void materialEvent(EventPriority priority, @DelegatesTo(MaterialEvent.class) Closure eventListener) { + if (GroovyScriptModule.isCurrentlyRunning() && + GroovyScript.getSandbox().getCurrentLoader() != LoadStage.PRE_INIT) { + GroovyLog.get().error("GregTech's material event can only be used in pre init!"); + return; + } + ClosureHelper.withEnvironment(eventListener, new MaterialEvent(), true); + GroovyEventManager.INSTANCE.listen(priority, EventBusType.MAIN, MaterialEvent.class, eventListener); + } + + public void materialEvent(Closure eventListener) { + materialEvent(EventPriority.NORMAL, eventListener); + } + + public void lateMaterialEvent(EventPriority priority, Closure eventListener) { + if (GroovyScriptModule.isCurrentlyRunning() && + GroovyScript.getSandbox().getCurrentLoader() != LoadStage.PRE_INIT) { + GroovyLog.get().error("GregTech's material event can only be used in pre init!"); + return; + } + GroovyEventManager.INSTANCE.listen(priority, EventBusType.MAIN, PostMaterialEvent.class, + eventListener); + } + + public void lateMaterialEvent(Closure eventListener) { + materialEvent(EventPriority.NORMAL, eventListener); + } +} diff --git a/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java b/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java index a2dbf7a3d55..6bd80f4db05 100644 --- a/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java +++ b/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java @@ -23,7 +23,7 @@ public class VirtualizedRecipeMap extends VirtualizedRegistry { public VirtualizedRecipeMap(RecipeMap recipeMap) { super(Alias.generateOf(recipeMap.unlocalizedName, CaseFormat.LOWER_UNDERSCORE)); this.recipeMap = recipeMap; - GroovyScriptModule.getInstance().getVirtualizedRegistrar().addRegistry(this); + GroovyScriptModule.getInstance().getRegistrar().addRegistry(this); } @Override diff --git a/src/main/java/gregtech/integration/hwyla/HWYLAModule.java b/src/main/java/gregtech/integration/hwyla/HWYLAModule.java index bce36365fc0..d26defcbde3 100644 --- a/src/main/java/gregtech/integration/hwyla/HWYLAModule.java +++ b/src/main/java/gregtech/integration/hwyla/HWYLAModule.java @@ -2,6 +2,7 @@ import gregtech.api.GTValues; import gregtech.api.modules.GregTechModule; +import gregtech.api.util.Mods; import gregtech.integration.IntegrationSubmodule; import gregtech.integration.hwyla.provider.*; import gregtech.modules.GregTechModules; @@ -17,7 +18,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_HWYLA, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_HWYLA, + modDependencies = Mods.Names.HWYLA, name = "GregTech HWYLA Integration", description = "HWYLA (WAILA) Integration Module") public class HWYLAModule extends IntegrationSubmodule implements IWailaPlugin { diff --git a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java index be7c1bd50ca..491db7fb1f1 100644 --- a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java +++ b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java @@ -20,6 +20,7 @@ import gregtech.api.recipes.machines.RecipeMapFurnace; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.api.util.Mods; import gregtech.api.worldgen.config.BedrockFluidDepositDefinition; import gregtech.api.worldgen.config.OreDepositDefinition; import gregtech.api.worldgen.config.WorldGenRegistry; @@ -74,10 +75,10 @@ import org.jetbrains.annotations.NotNull; import java.lang.reflect.Field; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -85,7 +86,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_JEI, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_JEI, + modDependencies = Mods.Names.JUST_ENOUGH_ITEMS, name = "GregTech JEI Integration", description = "JustEnoughItems Integration Module") public class JustEnoughItemsModule extends IntegrationSubmodule implements IModPlugin { @@ -214,7 +215,7 @@ public void register(IModRegistry registry) { registry.addRecipeCatalyst(MetaTileEntities.LARGE_TITANIUM_BOILER.getStackForm(), semiFluidMapId); registry.addRecipeCatalyst(MetaTileEntities.LARGE_TUNGSTENSTEEL_BOILER.getStackForm(), semiFluidMapId); - List oreByproductList = new CopyOnWriteArrayList<>(); + List oreByproductList = new ArrayList<>(); for (Material material : GregTechAPI.materialManager.getRegisteredMaterials()) { if (material.hasProperty(PropertyKey.ORE)) { oreByproductList.add(new OreByProduct(material)); @@ -222,7 +223,7 @@ public void register(IModRegistry registry) { } String oreByProductId = GTValues.MODID + ":" + "ore_by_product"; registry.addRecipes(oreByproductList, oreByProductId); - MetaTileEntity[][] machineLists = new MetaTileEntity[][] { + MetaTileEntity[][] machineLists = { MetaTileEntities.MACERATOR, MetaTileEntities.ORE_WASHER, MetaTileEntities.CENTRIFUGE, @@ -237,7 +238,7 @@ public void register(IModRegistry registry) { } // Material Tree - List materialTreeList = new CopyOnWriteArrayList<>(); + List materialTreeList = new ArrayList<>(); for (Material material : GregTechAPI.materialManager.getRegisteredMaterials()) { if (material.hasProperty(PropertyKey.DUST)) { materialTreeList.add(new MaterialTree(material)); @@ -247,7 +248,7 @@ public void register(IModRegistry registry) { // Ore Veins List oreVeins = WorldGenRegistry.getOreDeposits(); - List oreInfoList = new CopyOnWriteArrayList<>(); + List oreInfoList = new ArrayList<>(); for (OreDepositDefinition vein : oreVeins) { oreInfoList.add(new GTOreInfo(vein)); } @@ -261,7 +262,7 @@ public void register(IModRegistry registry) { // Fluid Veins List fluidVeins = WorldGenRegistry.getBedrockVeinDeposits(); - List fluidVeinInfos = new CopyOnWriteArrayList<>(); + List fluidVeinInfos = new ArrayList<>(); for (BedrockFluidDepositDefinition fluidVein : fluidVeins) { fluidVeinInfos.add(new GTFluidVeinInfo(fluidVein)); } @@ -307,7 +308,7 @@ private void setupInputHandler() { showsRecipeFocuses.add(new MultiblockInfoRecipeFocusShower()); - } catch (Exception e) { + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException | SecurityException e) { getLogger().error("Could not reflect JEI Internal inputHandler", e); } } diff --git a/src/main/java/gregtech/integration/jei/basic/GTOreInfo.java b/src/main/java/gregtech/integration/jei/basic/GTOreInfo.java index 0f5bd90bf9f..75d8c11f81a 100644 --- a/src/main/java/gregtech/integration/jei/basic/GTOreInfo.java +++ b/src/main/java/gregtech/integration/jei/basic/GTOreInfo.java @@ -4,6 +4,7 @@ import gregtech.api.unification.material.Material; import gregtech.api.util.FileUtility; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.api.worldgen.config.FillerConfigUtils; import gregtech.api.worldgen.config.OreDepositDefinition; import gregtech.api.worldgen.filler.BlockFiller; @@ -26,7 +27,6 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.IFluidBlock; -import net.minecraftforge.fml.common.Loader; import com.google.common.collect.ImmutableList; import mezz.jei.api.ingredients.IIngredients; @@ -41,7 +41,6 @@ import java.util.function.Function; import static gregtech.api.GTValues.M; -import static gregtech.api.GTValues.MODID_CC; public class GTOreInfo implements IRecipeWrapper { @@ -64,7 +63,7 @@ public GTOreInfo(OreDepositDefinition definition) { // Don't default to vanilla Maximums and minimums if the values are not defined and Cubic Chunks is loaded // This could be improved to use the actual minimum and maximum heights, at the cost of including the CC Api - if (Loader.isModLoaded(MODID_CC)) { + if (Mods.CubicChunks.isModLoaded()) { this.maxHeight = definition.getMaximumHeight() == Integer.MAX_VALUE ? Integer.MAX_VALUE : definition.getMaximumHeight(); this.minHeight = definition.getMinimumHeight() == Integer.MIN_VALUE ? Integer.MIN_VALUE : diff --git a/src/main/java/gregtech/integration/jei/basic/MaterialTree.java b/src/main/java/gregtech/integration/jei/basic/MaterialTree.java index 3babd634779..82cc58d5dab 100644 --- a/src/main/java/gregtech/integration/jei/basic/MaterialTree.java +++ b/src/main/java/gregtech/integration/jei/basic/MaterialTree.java @@ -6,6 +6,7 @@ import gregtech.api.unification.ore.OrePrefix; import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import com.google.common.collect.ImmutableList; @@ -74,7 +75,10 @@ public MaterialTree(Material material) { List matFluidsStack = new ArrayList<>(); if (material.hasProperty(PropertyKey.FLUID)) { - matFluidsStack.add(material.getFluid(1000)); + Fluid fluid = material.getFluid(); + if (fluid != null) { + matFluidsStack.add(new FluidStack(fluid, 1000)); + } } this.fluidInputs.add(matFluidsStack); diff --git a/src/main/java/gregtech/integration/jei/recipe/GTRecipeWrapper.java b/src/main/java/gregtech/integration/jei/recipe/GTRecipeWrapper.java index 9c1382a453d..bf837cf38da 100644 --- a/src/main/java/gregtech/integration/jei/recipe/GTRecipeWrapper.java +++ b/src/main/java/gregtech/integration/jei/recipe/GTRecipeWrapper.java @@ -202,11 +202,21 @@ public void addIngredientTooltips(@NotNull Collection tooltip, boolean n double chance = entry.getChance() / 100.0; double boost = entry.getChanceBoost() / 100.0; if (logic != ChancedOutputLogic.NONE && logic != ChancedOutputLogic.OR) { - tooltip.add(TooltipHelper.BLINKING_CYAN + I18n.format("gregtech.recipe.chance_logic", - chance, boost, I18n.format(logic.getTranslationKey()))); + if (boost > 0) { + tooltip.add(TooltipHelper.BLINKING_CYAN + I18n.format("gregtech.recipe.chance_logic", + chance, boost, I18n.format(logic.getTranslationKey()))); + } else { + tooltip.add(TooltipHelper.BLINKING_CYAN + I18n.format("gregtech.recipe.chance_logic_no_boost", + chance, I18n.format(logic.getTranslationKey()))); + } } else { - tooltip.add(TooltipHelper.BLINKING_CYAN + I18n.format("gregtech.recipe.chance", - chance, boost)); + if (boost > 0) { + tooltip.add(TooltipHelper.BLINKING_CYAN + I18n.format("gregtech.recipe.chance", + chance, boost)); + } else { + tooltip.add(TooltipHelper.BLINKING_CYAN + I18n.format("gregtech.recipe.chance_no_boost", + chance)); + } } } } else if (notConsumed) { diff --git a/src/main/java/gregtech/integration/jei/utils/JEIResourceDepositCategoryUtils.java b/src/main/java/gregtech/integration/jei/utils/JEIResourceDepositCategoryUtils.java index 77ee3c8bcb7..bc5042b0d64 100644 --- a/src/main/java/gregtech/integration/jei/utils/JEIResourceDepositCategoryUtils.java +++ b/src/main/java/gregtech/integration/jei/utils/JEIResourceDepositCategoryUtils.java @@ -1,6 +1,7 @@ package gregtech.integration.jei.utils; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.api.worldgen.config.OreDepositDefinition; import net.minecraft.client.Minecraft; @@ -10,7 +11,6 @@ import net.minecraft.world.WorldProvider; import net.minecraft.world.biome.Biome; import net.minecraftforge.common.DimensionManager; -import net.minecraftforge.fml.common.Loader; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.IntArrayList; @@ -27,8 +27,6 @@ import java.util.function.Function; import java.util.function.Predicate; -import static gregtech.api.GTValues.MODID_AR; - /** * Common util methods shared between {@link gregtech.integration.jei.basic.GTOreCategory} * and {@link gregtech.integration.jei.basic.GTFluidVeinCategory} @@ -139,7 +137,7 @@ public static int[] getAllRegisteredDimensions(@Nullable Predicate= 100 || chanceBase == 0) { + s = (this.chanceBase / 100) + "%"; + } else { + s = "." + this.chanceBase + "%"; + } if (this.chanceLogic != null && this.chanceLogic != ChancedOutputLogic.NONE && this.chanceLogic != ChancedOutputLogic.OR) { s += "*"; diff --git a/src/main/java/gregtech/integration/opencomputers/OpenComputersModule.java b/src/main/java/gregtech/integration/opencomputers/OpenComputersModule.java index 344dee2667e..c64c1e164e7 100644 --- a/src/main/java/gregtech/integration/opencomputers/OpenComputersModule.java +++ b/src/main/java/gregtech/integration/opencomputers/OpenComputersModule.java @@ -3,8 +3,8 @@ import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.modules.GregTechModule; +import gregtech.api.util.Mods; import gregtech.integration.IntegrationSubmodule; -import gregtech.integration.IntegrationUtil; import gregtech.integration.opencomputers.drivers.*; import gregtech.integration.opencomputers.drivers.specific.DriverConverter; import gregtech.integration.opencomputers.drivers.specific.DriverFusionReactor; @@ -21,17 +21,14 @@ @GregTechModule( moduleID = GregTechModules.MODULE_OC, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_OC, + modDependencies = Mods.Names.OPEN_COMPUTERS, name = "GregTech OpenComputers Integration", description = "OpenComputers Integration Module") public class OpenComputersModule extends IntegrationSubmodule { - private static final String MODID_GTCE2OC = "gtce2oc"; - @Override public void preInit(FMLPreInitializationEvent event) { - IntegrationUtil.throwIncompatibilityIfLoaded(MODID_GTCE2OC, - "All functionality from this mod has been implemented in GregTech CE Unofficial."); + Mods.GTCE2OC.throwIncompatibilityIfLoaded("All functionality from this mod has been implemented here."); } @Override diff --git a/src/main/java/gregtech/integration/opencomputers/drivers/DriverRecipeMapMultiblockController.java b/src/main/java/gregtech/integration/opencomputers/drivers/DriverRecipeMapMultiblockController.java index 344b1d6b806..7db4e9bd232 100644 --- a/src/main/java/gregtech/integration/opencomputers/drivers/DriverRecipeMapMultiblockController.java +++ b/src/main/java/gregtech/integration/opencomputers/drivers/DriverRecipeMapMultiblockController.java @@ -152,5 +152,10 @@ public Object[] getInputTank(final Context context, final Arguments args) { public Object[] getOutputTank(final Context context, final Arguments args) { return getTank(tileEntity.getOutputFluidInventory()); } + + @Callback(doc = "function():number -- Gets the number of maintenance problems.") + public Object[] getMaintenanceProblems(final Context context, final Arguments args) { + return new Object[] { tileEntity.getNumMaintenanceProblems() }; + } } } diff --git a/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java b/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java index 509de932b1b..956ec6a760c 100644 --- a/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java +++ b/src/main/java/gregtech/integration/opencomputers/drivers/specific/DriverPowerSubstation.java @@ -63,9 +63,19 @@ public Object[] getPassiveDrain(final Context context, final Arguments args) { return new Object[] { tileEntity.getPassiveDrain() }; } - @Callback(doc = "function():number -- Returns the average net EU/t in or out over the last second.") - public Object[] getAverageIOLastSec(final Context context, final Arguments args) { - return new Object[] { tileEntity.getAverageIOLastSec() }; + @Callback(doc = "function():number -- Returns the average EU/t in over the last second.") + public Object[] getAverageInLastSec(final Context context, final Arguments args) { + return new Object[] { tileEntity.getAverageInLastSec() }; + } + + @Callback(doc = "function():number -- Returns the average EU/t out over the last second.") + public Object[] getAverageOutLastSec(final Context context, final Arguments args) { + return new Object[] { tileEntity.getAverageOutLastSec() }; + } + + @Callback(doc = "function():number -- Gets the number of maintenance problems.") + public Object[] getMaintenanceProblems(final Context context, final Arguments args) { + return new Object[] { tileEntity.getNumMaintenanceProblems() }; } } } diff --git a/src/main/java/gregtech/integration/theoneprobe/TheOneProbeModule.java b/src/main/java/gregtech/integration/theoneprobe/TheOneProbeModule.java index 943448ce2ce..8b64c066cc9 100644 --- a/src/main/java/gregtech/integration/theoneprobe/TheOneProbeModule.java +++ b/src/main/java/gregtech/integration/theoneprobe/TheOneProbeModule.java @@ -2,6 +2,7 @@ import gregtech.api.GTValues; import gregtech.api.modules.GregTechModule; +import gregtech.api.util.Mods; import gregtech.integration.IntegrationSubmodule; import gregtech.integration.theoneprobe.provider.*; import gregtech.integration.theoneprobe.provider.debug.DebugPipeNetInfoProvider; @@ -16,7 +17,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_TOP, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_TOP, + modDependencies = Mods.Names.THE_ONE_PROBE, name = "GregTech TheOneProbe Integration", description = "TheOneProbe Integration Module") public class TheOneProbeModule extends IntegrationSubmodule { diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/CoverInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/CoverInfoProvider.java index 6656fcc9d7e..0aebf88036a 100644 --- a/src/main/java/gregtech/integration/theoneprobe/provider/CoverInfoProvider.java +++ b/src/main/java/gregtech/integration/theoneprobe/provider/CoverInfoProvider.java @@ -10,6 +10,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IStringSerializable; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.common.capabilities.Capability; @@ -57,22 +58,25 @@ protected void addProbeInfo(@NotNull CoverHolder capability, @NotNull IProbeInfo * @param conveyor the conveyor to get data from */ private static void conveyorInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverConveyor conveyor) { - String rateUnit = " {*cover.conveyor.transfer_rate*}"; + String rateUnit = lang("cover.conveyor.transfer_rate"); if (conveyor instanceof CoverItemVoiding) { itemVoidingInfo(probeInfo, (CoverItemVoiding) conveyor); - } else if (!(conveyor instanceof CoverRoboticArm) || - ((CoverRoboticArm) conveyor).getTransferMode() == TransferMode.TRANSFER_ANY) { + } else if (!(conveyor instanceof CoverRoboticArm arm) || + arm.getTransferMode() == TransferMode.TRANSFER_ANY) { // only display the regular rate if the cover does not have a specialized rate - transferRateText(probeInfo, conveyor.getConveyorMode(), rateUnit, conveyor.getTransferRate()); + transferRateText(probeInfo, conveyor.getConveyorMode(), " " + rateUnit, conveyor.getTransferRate()); } ItemFilterContainer filter = conveyor.getItemFilterContainer(); if (conveyor instanceof CoverRoboticArm roboticArm) { - transferModeText(probeInfo, roboticArm.getTransferMode(), rateUnit, filter.getTransferStackSize(), - filter.getFilterWrapper().getItemFilter() != null); + if (roboticArm.getTransferMode() != TransferMode.TRANSFER_ANY) + rateUnit = lang("cover.robotic_arm.exact"); + + transferModeText(probeInfo, roboticArm.getTransferMode(), rateUnit, + filter.getTransferSize(), filter.hasFilter()); } - itemFilterText(probeInfo, filter.getFilterWrapper().getItemFilter()); + itemFilterText(probeInfo, filter.getFilter()); } /** @@ -82,13 +86,13 @@ private static void conveyorInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverCo * @param voiding the voiding cover to get data from */ private static void itemVoidingInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverItemVoiding voiding) { - String unit = " {*gregtech.top.unit.items*}"; + String unit = lang("gregtech.top.unit.items"); ItemFilterContainer container = voiding.getItemFilterContainer(); if (voiding instanceof CoverItemVoidingAdvanced advanced) { VoidingMode mode = advanced.getVoidingMode(); - voidingText(probeInfo, mode, unit, container.getTransferStackSize(), - container.getFilterWrapper().getItemFilter() != null); + voidingText(probeInfo, mode, unit, container.getTransferSize(), + container.hasFilter() && !container.isBlacklistFilter()); } } @@ -99,12 +103,14 @@ private static void itemVoidingInfo(@NotNull IProbeInfo probeInfo, @NotNull Cove * @param pump the pump to get data from */ private static void pumpInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverPump pump) { - String rateUnit = IProbeInfo.STARTLOC + pump.getBucketMode().getName() + IProbeInfo.ENDLOC; + String rateUnit = lang(pump.getBucketMode() == CoverPump.BucketMode.BUCKET ? + "cover.bucket.mode.bucket_rate" : + "cover.bucket.mode.milli_bucket_rate"); if (pump instanceof CoverFluidVoiding) { fluidVoidingInfo(probeInfo, (CoverFluidVoiding) pump); - } else if (!(pump instanceof CoverFluidRegulator) || - ((CoverFluidRegulator) pump).getTransferMode() == TransferMode.TRANSFER_ANY) { + } else if (!(pump instanceof CoverFluidRegulator regulator) || + regulator.getTransferMode() == TransferMode.TRANSFER_ANY) { // do not display the regular rate if the cover has a specialized rate transferRateText(probeInfo, pump.getPumpMode(), " " + rateUnit, pump.getBucketMode() == CoverPump.BucketMode.BUCKET ? pump.getTransferRate() / 1000 : @@ -113,10 +119,15 @@ private static void pumpInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverPump p FluidFilterContainer filter = pump.getFluidFilterContainer(); if (pump instanceof CoverFluidRegulator regulator) { - transferModeText(probeInfo, regulator.getTransferMode(), rateUnit, regulator.getTransferAmount(), - filter.getFilterWrapper().getFluidFilter() != null); + if (regulator.getTransferMode() != TransferMode.TRANSFER_ANY) + rateUnit = lang(regulator.getBucketMode() == CoverPump.BucketMode.BUCKET ? + "gregtech.top.unit.fluid_buckets" : + "gregtech.top.unit.fluid_milibuckets"); + + transferModeText(probeInfo, regulator.getTransferMode(), rateUnit, regulator + .getFluidFilterContainer().getTransferSize(), filter.hasFilter() && !filter.isBlacklistFilter()); } - fluidFilterText(probeInfo, filter.getFilterWrapper().getFluidFilter()); + fluidFilterText(probeInfo, filter.getFilter()); } /** @@ -126,8 +137,10 @@ private static void pumpInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverPump p * @param voiding the voiding cover to get data from */ private static void fluidVoidingInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverFluidVoiding voiding) { - String unit = voiding.getBucketMode() == CoverPump.BucketMode.BUCKET ? " {*gregtech.top.unit.fluid_buckets*}" : - " {*gregtech.top.unit.fluid_milibuckets*}"; + String unit = lang(voiding.getBucketMode() == CoverPump.BucketMode.BUCKET ? + "gregtech.top.unit.fluid_buckets" : + "gregtech.top.unit.fluid_milibuckets"); + var container = voiding.getFluidFilterContainer(); if (voiding instanceof CoverFluidVoidingAdvanced advanced) { VoidingMode mode = advanced.getVoidingMode(); @@ -135,7 +148,7 @@ private static void fluidVoidingInfo(@NotNull IProbeInfo probeInfo, @NotNull Cov voidingText(probeInfo, mode, unit, voiding.getBucketMode() == CoverPump.BucketMode.BUCKET ? advanced.getTransferAmount() / 1000 : advanced.getTransferAmount(), - voiding.getFluidFilterContainer().getFilterWrapper().getFluidFilter() != null); + container.hasFilter() && !container.isBlacklistFilter()); } } @@ -147,7 +160,7 @@ private static void fluidVoidingInfo(@NotNull IProbeInfo probeInfo, @NotNull Cov */ private static void itemFilterInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverItemFilter itemFilter) { filterModeText(probeInfo, itemFilter.getFilterMode()); - itemFilterText(probeInfo, itemFilter.getItemFilter().getItemFilter()); + itemFilterText(probeInfo, itemFilter.getFilter()); } /** @@ -158,7 +171,7 @@ private static void itemFilterInfo(@NotNull IProbeInfo probeInfo, @NotNull Cover */ private static void fluidFilterInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverFluidFilter fluidFilter) { filterModeText(probeInfo, fluidFilter.getFilterMode()); - fluidFilterText(probeInfo, fluidFilter.getFluidFilter().getFluidFilter()); + fluidFilterText(probeInfo, fluidFilter.getFilter()); } /** @@ -168,12 +181,13 @@ private static void fluidFilterInfo(@NotNull IProbeInfo probeInfo, @NotNull Cove * @param enderFluidLink the ender fluid link cover to get data from */ private static void enderFluidLinkInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverEnderFluidLink enderFluidLink) { - transferRateText(probeInfo, enderFluidLink.getPumpMode(), " {*cover.bucket.mode.milli_bucket*}", + transferRateText(probeInfo, enderFluidLink.getPumpMode(), " " + lang("cover.bucket.mode.milli_bucket_rate"), enderFluidLink.isIOEnabled() ? CoverEnderFluidLink.TRANSFER_RATE : 0); - fluidFilterText(probeInfo, enderFluidLink.getFluidFilterContainer().getFilterWrapper().getFluidFilter()); + fluidFilterText(probeInfo, enderFluidLink.getFluidFilterContainer().getFilter()); if (!enderFluidLink.getColorStr().isEmpty()) { - probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.link_cover.color*} " + enderFluidLink.getColorStr()); + probeInfo.text( + TextStyleClass.INFO + lang("gregtech.top.link_cover.color") + " " + enderFluidLink.getColorStr()); } } @@ -187,7 +201,8 @@ private static void enderFluidLinkInfo(@NotNull IProbeInfo probeInfo, @NotNull C */ private static void transferRateText(@NotNull IProbeInfo probeInfo, @NotNull IIOMode mode, @NotNull String rateUnit, int rate) { - String modeText = mode.isImport() ? "{*gregtech.top.mode.import*} " : "{*gregtech.top.mode.export*} "; + String modeText = mode.isImport() ? lang("gregtech.top.mode.import") : lang("gregtech.top.mode.export"); + modeText += " "; probeInfo.text(TextStyleClass.OK + modeText + TextStyleClass.LABEL + TextFormattingUtil.formatNumbers(rate) + rateUnit); } @@ -197,15 +212,15 @@ private static void transferRateText(@NotNull IProbeInfo probeInfo, @NotNull IIO * * @param probeInfo the info to add the text to * @param mode the transfer mode of the cover - * @param rateUnit the unit of what is transferred * @param rate the transfer rate of the mode * @param hasFilter whether the cover has a filter installed */ private static void transferModeText(@NotNull IProbeInfo probeInfo, @NotNull TransferMode mode, @NotNull String rateUnit, int rate, boolean hasFilter) { - String text = TextStyleClass.OK + IProbeInfo.STARTLOC + mode.getName() + IProbeInfo.ENDLOC; + String text = TextStyleClass.OK + lang(mode.getName()); if (!hasFilter && mode != TransferMode.TRANSFER_ANY) - text += TextStyleClass.LABEL + " " + TextFormattingUtil.formatNumbers(rate) + rateUnit; + text += TextStyleClass.LABEL + " " + TextFormattingUtil.formatNumbers(rate) + " " + rateUnit; + probeInfo.text(text); } @@ -220,45 +235,49 @@ private static void transferModeText(@NotNull IProbeInfo probeInfo, @NotNull Tra */ private static void voidingText(@NotNull IProbeInfo probeInfo, @NotNull VoidingMode mode, @NotNull String unit, int amount, boolean hasFilter) { - String text = TextFormatting.RED + IProbeInfo.STARTLOC + mode.getName() + IProbeInfo.ENDLOC; - if (mode != VoidingMode.VOID_ANY && !hasFilter) text += " " + TextFormattingUtil.formatNumbers(amount) + unit; + String text = TextFormatting.RED + lang(mode.getName()); + if (mode != VoidingMode.VOID_ANY && !hasFilter) + text += " " + TextFormattingUtil.formatNumbers(amount) + " " + unit; probeInfo.text(text); } /** - * Displays text for {@link IFilterMode} covers + * Displays text for {@link net.minecraft.util.IStringSerializable} covers * * @param probeInfo the info to add the text to * @param mode the filter mode of the cover */ - private static void filterModeText(@NotNull IProbeInfo probeInfo, @NotNull IFilterMode mode) { - probeInfo.text(TextStyleClass.WARNING + IProbeInfo.STARTLOC + mode.getName() + IProbeInfo.ENDLOC); + private static void filterModeText(@NotNull IProbeInfo probeInfo, @NotNull IStringSerializable mode) { + probeInfo.text(TextStyleClass.WARNING + lang(mode.getName())); } /** - * Displays text for {@link ItemFilter} covers + * Displays text for {@link BaseFilter} item covers * * @param probeInfo the info to add the text to * @param filter the filter to display info from */ - private static void itemFilterText(@NotNull IProbeInfo probeInfo, @Nullable ItemFilter filter) { - String label = TextStyleClass.INFO + "{*gregtech.top.filter.label*} "; + private static void itemFilterText(@NotNull IProbeInfo probeInfo, @Nullable BaseFilter filter) { + String label = TextStyleClass.INFO + lang("gregtech.top.filter.label"); if (filter instanceof OreDictionaryItemFilter) { String expression = ((OreDictionaryItemFilter) filter).getExpression(); if (!expression.isEmpty()) probeInfo.text(label + expression); - } else if (filter instanceof SmartItemFilter) { - probeInfo.text(label + IProbeInfo.STARTLOC + ((SmartItemFilter) filter).getFilteringMode().getName() + - IProbeInfo.ENDLOC); + } else if (filter instanceof SmartItemFilter smartItemFilter) { + probeInfo.text(label + lang(smartItemFilter.getFilteringMode().getName())); } } /** - * Displays text for {@link FluidFilter} covers + * Displays text for {@link BaseFilter} fluid covers * * @param probeInfo the info to add the text to * @param filter the filter to display info from */ - private static void fluidFilterText(@NotNull IProbeInfo probeInfo, @Nullable FluidFilter filter) { + private static void fluidFilterText(@NotNull IProbeInfo probeInfo, @Nullable BaseFilter filter) { // TODO If more unique fluid filtration is added, providers for it go here } + + private static String lang(String lang) { + return IProbeInfo.STARTLOC + lang + IProbeInfo.ENDLOC; + } } diff --git a/src/main/java/gregtech/loaders/MaterialInfoLoader.java b/src/main/java/gregtech/loaders/MaterialInfoLoader.java index 7808074a400..09123d09b4f 100644 --- a/src/main/java/gregtech/loaders/MaterialInfoLoader.java +++ b/src/main/java/gregtech/loaders/MaterialInfoLoader.java @@ -232,6 +232,10 @@ public static void init() { new ItemMaterialInfo(new MaterialStack(Bronze, M * 6 * 2 / 64), // 2 large pipe / 64 new MaterialStack(Steel, M * 8 / 64))); // 8 steel plate / 64 + OreDictUnifier.registerOre(new ItemStack(MetaBlocks.PANELLING), new ItemMaterialInfo( + new MaterialStack(Materials.Steel, M / 4) // 4 plates per 16 blocks + )); + if (ConfigHolder.recipes.hardAdvancedIronRecipes) { OreDictUnifier.registerOre(new ItemStack(Items.IRON_DOOR, 1), new ItemMaterialInfo( new MaterialStack(Materials.Iron, M * 4 + (M * 3 / 16)), // 4 iron plates + 1 iron bars diff --git a/src/main/java/gregtech/loaders/WoodTypeEntry.java b/src/main/java/gregtech/loaders/WoodTypeEntry.java index 7a086b1b55e..dd75a07cdb7 100644 --- a/src/main/java/gregtech/loaders/WoodTypeEntry.java +++ b/src/main/java/gregtech/loaders/WoodTypeEntry.java @@ -52,6 +52,8 @@ public final class WoodTypeEntry { public final String fenceGateRecipeName; @NotNull public final ItemStack stairs; + @Nullable + public final String stairsRecipeName; public final boolean addStairsCraftingRecipe; @NotNull public final ItemStack boat; @@ -83,13 +85,14 @@ private WoodTypeEntry(@NotNull String modid, @NotNull String woodName, @NotNull @NotNull ItemStack slab, @Nullable String slabRecipeName, boolean addSlabCraftingRecipe, @NotNull ItemStack fence, @Nullable String fenceRecipeName, @NotNull ItemStack fenceGate, @Nullable String fenceGateRecipeName, @NotNull ItemStack stairs, - boolean addStairsCraftingRecipe, @NotNull ItemStack boat, @Nullable String boatRecipeName, - @Nullable Material material, boolean addLogOreDict, boolean addPlanksOreDict, - boolean addDoorsOreDict, boolean addSlabsOreDict, boolean addFencesOreDict, - boolean addFenceGatesOreDict, boolean addStairsOreDict, boolean addPlanksUnificationInfo, - boolean addDoorsUnificationInfo, boolean addSlabsUnificationInfo, - boolean addFencesUnificationInfo, boolean addFenceGatesUnificationInfo, - boolean addStairsUnificationInfo, boolean addBoatsUnificationInfo) { + @Nullable String stairsRecipeName, boolean addStairsCraftingRecipe, @NotNull ItemStack boat, + @Nullable String boatRecipeName, @Nullable Material material, boolean addLogOreDict, + boolean addPlanksOreDict, boolean addDoorsOreDict, boolean addSlabsOreDict, + boolean addFencesOreDict, boolean addFenceGatesOreDict, boolean addStairsOreDict, + boolean addPlanksUnificationInfo, boolean addDoorsUnificationInfo, + boolean addSlabsUnificationInfo, boolean addFencesUnificationInfo, + boolean addFenceGatesUnificationInfo, boolean addStairsUnificationInfo, + boolean addBoatsUnificationInfo) { this.modid = modid; this.woodName = woodName; this.log = log; @@ -107,6 +110,7 @@ private WoodTypeEntry(@NotNull String modid, @NotNull String woodName, @NotNull this.fenceGate = fenceGate; this.fenceGateRecipeName = fenceGateRecipeName; this.stairs = stairs; + this.stairsRecipeName = stairsRecipeName; this.addStairsCraftingRecipe = addStairsCraftingRecipe; this.boat = boat; this.boatRecipeName = boatRecipeName; @@ -153,6 +157,7 @@ public static class Builder { private ItemStack fenceGate = ItemStack.EMPTY; private String fenceGateRecipeName; private ItemStack stairs = ItemStack.EMPTY; + private String stairsRecipeName; private boolean addStairsCraftingRecipe; private ItemStack boat = ItemStack.EMPTY; private String boatRecipeName; @@ -294,11 +299,13 @@ public Builder fenceGate(@NotNull ItemStack fenceGate, @Nullable String fenceGat /** * Add an entry for stairs * - * @param stairs the stairs to add + * @param stairs the stairs to add + * @param stairsRecipeName the recipe name for crafting the stairs * @return this */ - public Builder stairs(@NotNull ItemStack stairs) { + public Builder stairs(@NotNull ItemStack stairs, @Nullable String stairsRecipeName) { this.stairs = stairs; + this.stairsRecipeName = stairsRecipeName; return this; } @@ -410,12 +417,11 @@ public WoodTypeEntry build() { Preconditions.checkArgument(!planks.isEmpty(), "Planks cannot be empty."); return new WoodTypeEntry(modid, woodName, log, removeCharcoalRecipe, addCharcoalRecipe, planks, planksRecipeName, door, doorRecipeName, slab, slabRecipeName, addSlabsCraftingRecipe, fence, - fenceRecipeName, - fenceGate, fenceGateRecipeName, stairs, addStairsCraftingRecipe, boat, boatRecipeName, material, - addLogOreDict, addPlanksOreDict, addDoorsOreDict, addSlabsOreDict, addFencesOreDict, - addFenceGatesOreDict, addStairsOreDict, addPlanksUnificationInfo, addDoorsUnificationInfo, - addSlabsUnificationInfo, addFencesUnificationInfo, addFenceGatesUnificationInfo, - addStairsUnificationInfo, addBoatsUnificationInfo); + fenceRecipeName, fenceGate, fenceGateRecipeName, stairs, stairsRecipeName, addStairsCraftingRecipe, + boat, boatRecipeName, material, addLogOreDict, addPlanksOreDict, addDoorsOreDict, addSlabsOreDict, + addFencesOreDict, addFenceGatesOreDict, addStairsOreDict, addPlanksUnificationInfo, + addDoorsUnificationInfo, addSlabsUnificationInfo, addFencesUnificationInfo, + addFenceGatesUnificationInfo, addStairsUnificationInfo, addBoatsUnificationInfo); } } } diff --git a/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java index 0b0d513a7f7..8b18ba7a811 100644 --- a/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java @@ -336,6 +336,11 @@ private static void loadCraftingRecipes() { new UnificationEntry(OrePrefix.wireGtQuadruple, Osmium), 'P', new UnificationEntry(OrePrefix.plateDouble, Iridium), 'O', MetaItems.ENERGY_LAPOTRONIC_ORB.getStackForm()); + + ModHandler.addShapedRecipe("powderbarrel", new ItemStack(MetaBlocks.POWDERBARREL), "PSP", "GGG", "PGP", + 'P', new UnificationEntry(OrePrefix.plate, Wood), + 'S', new ItemStack(Items.STRING), + 'G', new UnificationEntry(OrePrefix.dust, Gunpowder)); } private static void registerFacadeRecipe(Material material, int facadeAmount) { diff --git a/src/main/java/gregtech/loaders/recipe/DecorationRecipes.java b/src/main/java/gregtech/loaders/recipe/DecorationRecipes.java index 75c0e216964..442b88f2d6f 100644 --- a/src/main/java/gregtech/loaders/recipe/DecorationRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/DecorationRecipes.java @@ -2,11 +2,14 @@ import gregtech.api.unification.material.Materials; import gregtech.api.unification.ore.OrePrefix; +import gregtech.common.blocks.BlockPanelling; import gregtech.common.blocks.MetaBlocks; import net.minecraft.item.EnumDyeColor; import static gregtech.api.recipes.RecipeMaps.*; +import static gregtech.api.unification.material.Materials.Steel; +import static gregtech.api.unification.ore.OrePrefix.plate; public class DecorationRecipes { @@ -41,6 +44,13 @@ private static void assemblerRecipes() { .outputs(MetaBlocks.STUDS.getItemVariant(EnumDyeColor.BLACK, 32)) .EUt(4).duration(20) .buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder().EUt(16).duration(120) + .input(plate, Steel, 4) + .circuitMeta(16) + .outputs(MetaBlocks.PANELLING.getItemVariant( + BlockPanelling.PanellingType.GRAY)) + .buildAndRegister(); } private static void dyeRecipes() { @@ -65,6 +75,13 @@ private static void dyeRecipes() { .outputs(MetaBlocks.STUDS.getItemVariant(EnumDyeColor.values()[i])) .EUt(2).duration(10) .buildAndRegister(); + + CHEMICAL_BATH_RECIPES.recipeBuilder() + .inputs(MetaBlocks.PANELLING.getItemVariant(BlockPanelling.PanellingType.GRAY)) + .fluidInputs(Materials.CHEMICAL_DYES[i].getFluid(9)) + .outputs(MetaBlocks.PANELLING.getItemVariant(BlockPanelling.PanellingType.values()[i])) + .EUt(2).duration(10) + .buildAndRegister(); } } } diff --git a/src/main/java/gregtech/loaders/recipe/GTRecipeManager.java b/src/main/java/gregtech/loaders/recipe/GTRecipeManager.java index e91a9bd2c7a..2d2b7bd30f4 100644 --- a/src/main/java/gregtech/loaders/recipe/GTRecipeManager.java +++ b/src/main/java/gregtech/loaders/recipe/GTRecipeManager.java @@ -2,6 +2,7 @@ import gregtech.api.event.MaterialInfoEvent; import gregtech.loaders.recipe.handlers.DecompositionRecipeHandler; +import gregtech.loaders.recipe.handlers.FluidRecipeHandler; import gregtech.loaders.recipe.handlers.RecipeHandlerList; import gregtech.loaders.recipe.handlers.ToolRecipeHandler; @@ -26,6 +27,7 @@ public static void load() { public static void loadLatest() { MinecraftForge.EVENT_BUS.post(new MaterialInfoEvent()); DecompositionRecipeHandler.runRecipeGeneration(); + FluidRecipeHandler.runRecipeGeneration(); RecyclingRecipes.init(); } } diff --git a/src/main/java/gregtech/loaders/recipe/MachineRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/MachineRecipeLoader.java index 61b30c19423..5726dc8e419 100644 --- a/src/main/java/gregtech/loaders/recipe/MachineRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/MachineRecipeLoader.java @@ -15,6 +15,7 @@ import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.MaterialStack; import gregtech.api.unification.stack.UnificationEntry; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import gregtech.common.blocks.*; import gregtech.common.blocks.BlockMachineCasing.MachineCasingType; @@ -34,7 +35,6 @@ import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.oredict.OreDictionary; import java.util.Arrays; @@ -830,6 +830,52 @@ private static void registerAssemblerRecipes() { ConfigHolder.recipes.casingsPerCraft)) .duration(200).buildAndRegister(); + ASSEMBLER_RECIPES.recipeBuilder().EUt(48).duration(280) + .input(plateDouble, Inconel) + .input(plate, Steel, 5) + .input(frameGt, Steel) + .outputs(MetaBlocks.FISSION_CASING.getItemVariant( + BlockFissionCasing.FissionCasingType.REACTOR_VESSEL, ConfigHolder.recipes.casingsPerCraft)) + .buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder().EUt(48).duration(280) + .input(pipeLargeFluid, Inconel) + .input(frameGt, Steel) + .outputs(MetaBlocks.FISSION_CASING.getItemVariant( + BlockFissionCasing.FissionCasingType.COOLANT_CHANNEL)) + .buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder().EUt(48).duration(280) + .input(stick, Zircaloy, 6) + .input(ring, Zircaloy, 1) + .circuitMeta(1) + .outputs(MetaBlocks.FISSION_CASING.getItemVariant( + BlockFissionCasing.FissionCasingType.FUEL_CHANNEL)) + .buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder().EUt(48).duration(280) + .input(stick, Zircaloy, 3) + .input(ring, Zircaloy, 1) + .circuitMeta(2) + .outputs(MetaBlocks.FISSION_CASING.getItemVariant( + BlockFissionCasing.FissionCasingType.CONTROL_ROD_CHANNEL)) + .buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder().EUt(48).duration(200) + .inputs(MetaBlocks.BOILER_CASING.getItemVariant( + BlockBoilerCasing.BoilerCasingType.POLYTETRAFLUOROETHYLENE_PIPE)) + .input(wireGtSingle, Nichrome, 4) + .outputs(MetaBlocks.NUCLEAR_CASING.getItemVariant( + BlockNuclearCasing.NuclearCasingType.GAS_CENTRIFUGE_HEATER)) + .buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder().EUt(64).duration(200) + .input(stick, BoronCarbide, 8) + .outputs( + MetaBlocks.NUCLEAR_CASING.getItemVariant(BlockNuclearCasing.NuclearCasingType.SPENT_FUEL_CASING, + ConfigHolder.recipes.casingsPerCraft)) + .buildAndRegister(); + // If these recipes are changed, change the values in MaterialInfoLoader.java RecipeMaps.ASSEMBLER_RECIPES.recipeBuilder().duration(25).EUt(16) @@ -1405,6 +1451,16 @@ private static void registerNBTRemoval() { ModHandler.addShapelessNBTClearingRecipe("data_module_nbt", TOOL_DATA_MODULE.getStackForm(), TOOL_DATA_MODULE.getStackForm()); + // Filters + ModHandler.addShapelessNBTClearingRecipe("clear_item_filter", + ITEM_FILTER.getStackForm(), ITEM_FILTER); + ModHandler.addShapelessNBTClearingRecipe("clear_fluid_filter", + FLUID_FILTER.getStackForm(), FLUID_FILTER); + ModHandler.addShapelessNBTClearingRecipe("clear_smart_filter", + SMART_FILTER.getStackForm(), SMART_FILTER); + ModHandler.addShapelessNBTClearingRecipe("clear_oredict_filter", + ORE_DICTIONARY_FILTER.getStackForm(), ORE_DICTIONARY_FILTER); + // Jetpacks ModHandler.addShapelessRecipe("fluid_jetpack_clear", SEMIFLUID_JETPACK.getStackForm(), SEMIFLUID_JETPACK.getStackForm()); @@ -1461,7 +1517,7 @@ private static void ConvertHatchToHatch() { } } - if (Loader.isModLoaded(MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { ModHandler.addShapedRecipe("me_fluid_hatch_output_to_input", FLUID_IMPORT_HATCH_ME.getStackForm(), "d", "B", 'B', FLUID_EXPORT_HATCH_ME.getStackForm()); ModHandler.addShapedRecipe("me_fluid_hatch_input_to_output", FLUID_EXPORT_HATCH_ME.getStackForm(), "d", "B", diff --git a/src/main/java/gregtech/loaders/recipe/MetaTileEntityLoader.java b/src/main/java/gregtech/loaders/recipe/MetaTileEntityLoader.java index 9cb0e321a0e..437c257fdcd 100644 --- a/src/main/java/gregtech/loaders/recipe/MetaTileEntityLoader.java +++ b/src/main/java/gregtech/loaders/recipe/MetaTileEntityLoader.java @@ -12,6 +12,7 @@ import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.UnificationEntry; import gregtech.common.ConfigHolder; +import gregtech.common.blocks.BlockFissionCasing; import gregtech.common.blocks.BlockGlassCasing; import gregtech.common.blocks.BlockMetalCasing.MetalCasingType; import gregtech.common.blocks.BlockMultiblockCasing; @@ -898,7 +899,8 @@ public static void init() { ROTOR); registerMachineRecipe(ArrayUtils.subarray(MetaTileEntities.DIODES, GTValues.ULV, GTValues.HV), "CDC", "DHD", - "PDP", 'H', HULL, 'D', MetaItems.DIODE, 'P', PLATE, 'C', CABLE_QUAD); + "PDP", 'H', HULL, 'D', new UnificationEntry(OrePrefix.component, MarkerMaterials.Component.Diode), 'P', + PLATE, 'C', CABLE_QUAD); registerMachineRecipe(ArrayUtils.subarray(MetaTileEntities.DIODES, GTValues.HV, GTValues.LuV), "CDC", "DHD", "PDP", 'H', HULL, 'D', MetaItems.SMD_DIODE, 'P', PLATE, 'C', CABLE_QUAD); registerMachineRecipe( @@ -1139,6 +1141,34 @@ public static void init() { registerMachineRecipe(MetaTileEntities.ENERGY_CONVERTER[3], " WW", "RMC", " WW", 'C', CIRCUIT, 'M', HULL, 'W', CABLE_HEX, 'R', new UnificationEntry(OrePrefix.cableGtHex, Materials.RedAlloy)); } + + ModHandler.addShapedRecipe(true, "fission_reactor", MetaTileEntities.FISSION_REACTOR.getStackForm(), "CSC", + "RHR", "CWC", + 'C', new UnificationEntry(OrePrefix.circuit, MarkerMaterials.Tier.EV), 'H', + MetaBlocks.FISSION_CASING.getItemVariant( + BlockFissionCasing.FissionCasingType.REACTOR_VESSEL), + 'S', SENSOR.getIngredient(GTValues.EV), + 'R', new UnificationEntry(OrePrefix.rotor, Materials.Steel), 'W', + CABLE_QUAD.getIngredient(GTValues.EV)); + + ModHandler.addShapedRecipe(true, "heat_exchanger", MetaTileEntities.HEAT_EXCHANGER.getStackForm(), "FFF", + "PCP", "FFF", + 'C', new UnificationEntry(OrePrefix.circuit, MarkerMaterials.Tier.HV), + 'P', new UnificationEntry(OrePrefix.pipeLargeFluid, Materials.Inconel), + 'F', MetaBlocks.METAL_CASING.getItemVariant(STEEL_SOLID)); + + ModHandler.addShapedRecipe(true, "gas_centrifuge", MetaTileEntities.GAS_CENTRIFUGE.getStackForm(), "FFF", + "WRW", "CCC", + 'C', new UnificationEntry(OrePrefix.circuit, MarkerMaterials.Tier.EV), + 'R', new UnificationEntry(OrePrefix.rotor, Materials.Titanium), + 'F', MetaBlocks.METAL_CASING.getItemVariant(PTFE_INERT_CASING), + 'W', CABLE_QUAD.getIngredient(GTValues.EV)); + + ModHandler.addShapedRecipe(true, "spent_fuel_pool", MetaTileEntities.SPENT_FUEL_POOL.getStackForm(), "PFP", + "PCP", "PFP", + 'C', new UnificationEntry(OrePrefix.circuit, MarkerMaterials.Tier.LV), + 'F', MetaBlocks.METAL_CASING.getItemVariant(STAINLESS_CLEAN), + 'P', new UnificationEntry(OrePrefix.plate, Materials.StainlessSteel)); } // Can only accept a subset of "Item" types: diff --git a/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java index cc01014c03a..0122ad4f62c 100644 --- a/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java @@ -1,14 +1,19 @@ package gregtech.loaders.recipe; import gregtech.api.GTValues; +import gregtech.api.items.OreDictNames; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.recipes.ModHandler; +import gregtech.api.recipes.ingredients.GTRecipeInput; +import gregtech.api.recipes.ingredients.GTRecipeItemInput; +import gregtech.api.recipes.ingredients.GTRecipeOreInput; +import gregtech.api.unification.material.MarkerMaterials; import gregtech.api.unification.stack.UnificationEntry; +import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.common.registry.GameRegistry; import static gregtech.api.GTValues.*; import static gregtech.api.recipes.RecipeMaps.ASSEMBLER_RECIPES; @@ -19,7 +24,6 @@ import static gregtech.common.blocks.MetaBlocks.LD_FLUID_PIPE; import static gregtech.common.blocks.MetaBlocks.LD_ITEM_PIPE; import static gregtech.common.items.MetaItems.*; -import static gregtech.common.items.MetaItems.SENSOR_UV; import static gregtech.common.metatileentities.MetaTileEntities.*; public class MetaTileEntityMachineRecipeLoader { @@ -243,8 +247,8 @@ public static void init() { .duration(300).EUt(VA[EV]).buildAndRegister(); // Item Buses - registerHatchBusRecipe(ULV, ITEM_IMPORT_BUS[ULV], ITEM_EXPORT_BUS[ULV], new ItemStack(Blocks.CHEST)); - registerHatchBusRecipe(LV, ITEM_IMPORT_BUS[LV], ITEM_EXPORT_BUS[LV], new ItemStack(Blocks.CHEST)); + registerHatchBusRecipe(ULV, ITEM_IMPORT_BUS[ULV], ITEM_EXPORT_BUS[ULV], OreDictNames.chestWood.toString()); + registerHatchBusRecipe(LV, ITEM_IMPORT_BUS[LV], ITEM_EXPORT_BUS[LV], OreDictNames.chestWood.toString()); registerHatchBusRecipe(MV, ITEM_IMPORT_BUS[MV], ITEM_EXPORT_BUS[MV], BRONZE_CRATE.getStackForm()); registerHatchBusRecipe(HV, ITEM_IMPORT_BUS[HV], ITEM_EXPORT_BUS[HV], STEEL_CRATE.getStackForm()); registerHatchBusRecipe(EV, ITEM_IMPORT_BUS[EV], ITEM_EXPORT_BUS[EV], ALUMINIUM_CRATE.getStackForm()); @@ -989,11 +993,11 @@ public static void init() { // ME Parts - if (Loader.isModLoaded(MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { - ItemStack fluidInterface = GameRegistry.makeItemStack(MODID_APPENG + ":fluid_interface", 0, 1, null); - ItemStack normalInterface = GameRegistry.makeItemStack(MODID_APPENG + ":interface", 0, 1, null); - ItemStack accelerationCard = GameRegistry.makeItemStack(MODID_APPENG + ":material", 30, 2, null); + ItemStack fluidInterface = Mods.AppliedEnergistics2.getItem("fluid_interface"); + ItemStack normalInterface = Mods.AppliedEnergistics2.getItem("interface"); + ItemStack accelerationCard = Mods.AppliedEnergistics2.getItem("material", 30, 2); ASSEMBLER_RECIPES.recipeBuilder() .input(FLUID_EXPORT_HATCH[EV]) @@ -1022,11 +1026,38 @@ public static void init() { .inputs(accelerationCard.copy()) .output(ITEM_IMPORT_BUS_ME) .duration(300).EUt(VA[HV]).buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder() + .input(ITEM_IMPORT_BUS[IV]) + .inputs(normalInterface.copy()) + .input(CONVEYOR_MODULE_IV) + .input(SENSOR_IV) + .inputs(GTUtility.copy(4, accelerationCard)) + .output(STOCKING_BUS_ME) + .duration(300).EUt(VA[IV]).buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder() + .input(FLUID_IMPORT_HATCH[IV]) + .inputs(fluidInterface.copy()) + .input(ELECTRIC_PUMP_IV) + .input(SENSOR_IV) + .inputs(GTUtility.copy(4, accelerationCard)) + .output(STOCKING_HATCH_ME) + .duration(300).EUt(VA[IV]).buildAndRegister(); } } private static void registerHatchBusRecipe(int tier, MetaTileEntity inputBus, MetaTileEntity outputBus, - ItemStack extra) { + Object extraInput) { + GTRecipeInput extra; + if (extraInput instanceof ItemStack stack) { + extra = new GTRecipeItemInput(stack); + } else if (extraInput instanceof String oreName) { + extra = new GTRecipeOreInput(oreName); + } else { + throw new IllegalArgumentException("extraInput must be ItemStack or GTRecipeInput"); + } + // Glue recipe for ULV and LV // 250L for ULV, 500L for LV if (tier <= GTValues.LV) { @@ -1115,29 +1146,18 @@ private static void registerHatchBusRecipe(int tier, MetaTileEntity inputBus, Me } private static int getFluidAmount(int offsetTier) { - switch (offsetTier) { - case 0: - return 4; - case 1: - return 9; - case 2: - return 18; - case 3: - return 36; - case 4: - return 72; - case 5: - return 144; - case 6: - return 288; - case 7: - return 432; - case 8: - return 576; - case 9: - default: - return 720; - } + return switch (offsetTier) { + case 0 -> 4; + case 1 -> 9; + case 2 -> 18; + case 3 -> 36; + case 4 -> 72; + case 5 -> 144; + case 6 -> 288; + case 7 -> 432; + case 8 -> 576; + default -> 720; + }; } // TODO clean this up with a CraftingComponent rework @@ -1387,5 +1407,58 @@ private static void registerLaserRecipes() { .circuitMeta(3) .output(LASER_OUTPUT_HATCH_4096[3]) .duration(1200).EUt(VA[UV]).buildAndRegister(); + + // Nuclear Technology + + ASSEMBLER_RECIPES.recipeBuilder() + .input(pipeLargeFluid, Inconel) + .input(HULL[EV]) + .fluidInputs(Polyethylene.getFluid(144)) + .circuitMeta(1) + .outputs(COOLANT_INPUT.getStackForm()) + .duration(300).EUt(VA[EV]).buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder() + .input(pipeLargeFluid, Inconel) + .input(HULL[EV]) + .fluidInputs(Polyethylene.getFluid(144)) + .circuitMeta(2) + .outputs(COOLANT_OUTPUT.getStackForm()) + .duration(300).EUt(VA[EV]).buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder() + .input(stick, Zircaloy, 6) + .input(HULL[EV]) + .fluidInputs(Polyethylene.getFluid(144)) + .circuitMeta(1) + .outputs(FUEL_ROD_INPUT.getStackForm()) + .duration(300).EUt(VA[EV]).buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder() + .input(stick, Zircaloy, 6) + .input(HULL[EV]) + .fluidInputs(Polyethylene.getFluid(144)) + .circuitMeta(2) + .outputs(FUEL_ROD_OUTPUT.getStackForm()) + .duration(300).EUt(VA[EV]).buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder() + .input(stickLong, Hafnium) + .input(circuit, MarkerMaterials.Tier.EV) + .input(HULL[EV]) + .circuitMeta(1) + .fluidInputs(Polyethylene.getFluid(144)) + .outputs(CONTROL_ROD.getStackForm()) + .duration(300).EUt(VA[EV]).buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder() + .input(stickLong, Hafnium) + .input(dust, Graphite) + .input(circuit, MarkerMaterials.Tier.EV) + .input(HULL[EV]) + .circuitMeta(2) + .fluidInputs(Polyethylene.getFluid(144)) + .outputs(CONTROL_ROD_MODERATED.getStackForm()) + .duration(300).EUt(VA[EV]).buildAndRegister(); } } diff --git a/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java index fb06348d385..953649972d8 100644 --- a/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java @@ -49,7 +49,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(Blocks.WOODEN_SLAB), "oak_wooden_slab") .fence(new ItemStack(Blocks.OAK_FENCE), "fence") .fenceGate(new ItemStack(Blocks.OAK_FENCE_GATE), "fence_gate") - .stairs(new ItemStack(Blocks.OAK_STAIRS)) + .stairs(new ItemStack(Blocks.OAK_STAIRS), "oak_stairs") .boat(new ItemStack(Items.BOAT), "boat") .registerAllUnificationInfo() .build(), @@ -60,7 +60,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(Blocks.WOODEN_SLAB, 1, 1), "spruce_wooden_slab") .fence(new ItemStack(Blocks.SPRUCE_FENCE), "spruce_fence") .fenceGate(new ItemStack(Blocks.SPRUCE_FENCE_GATE), "spruce_fence_gate") - .stairs(new ItemStack(Blocks.SPRUCE_STAIRS)) + .stairs(new ItemStack(Blocks.SPRUCE_STAIRS), "spruce_stairs") .boat(new ItemStack(Items.SPRUCE_BOAT), "spruce_boat") .registerAllUnificationInfo() .build(), @@ -71,7 +71,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(Blocks.WOODEN_SLAB, 1, 2), "birch_wooden_slab") .fence(new ItemStack(Blocks.BIRCH_FENCE), "birch_fence") .fenceGate(new ItemStack(Blocks.BIRCH_FENCE_GATE), "birch_fence_gate") - .stairs(new ItemStack(Blocks.BIRCH_STAIRS)) + .stairs(new ItemStack(Blocks.BIRCH_STAIRS), "birch_stairs") .boat(new ItemStack(Items.BIRCH_BOAT), "birch_boat") .registerAllUnificationInfo() .build(), @@ -82,7 +82,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(Blocks.WOODEN_SLAB, 1, 3), "jungle_wooden_slab") .fence(new ItemStack(Blocks.JUNGLE_FENCE), "jungle_fence") .fenceGate(new ItemStack(Blocks.JUNGLE_FENCE_GATE), "jungle_fence_gate") - .stairs(new ItemStack(Blocks.JUNGLE_STAIRS)) + .stairs(new ItemStack(Blocks.JUNGLE_STAIRS), "jungle_stairs") .boat(new ItemStack(Items.JUNGLE_BOAT), "jungle_boat") .registerAllUnificationInfo() .build(), @@ -93,7 +93,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(Blocks.WOODEN_SLAB, 1, 4), "acacia_wooden_slab") .fence(new ItemStack(Blocks.ACACIA_FENCE), "acacia_fence") .fenceGate(new ItemStack(Blocks.ACACIA_FENCE_GATE), "acacia_fence_gate") - .stairs(new ItemStack(Blocks.ACACIA_STAIRS)) + .stairs(new ItemStack(Blocks.ACACIA_STAIRS), "acacia_stairs") .boat(new ItemStack(Items.ACACIA_BOAT), "acacia_boat") .registerAllUnificationInfo() .build(), @@ -104,7 +104,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(Blocks.WOODEN_SLAB, 1, 5), "dark_oak_wooden_slab") .fence(new ItemStack(Blocks.DARK_OAK_FENCE), "dark_oak_fence") .fenceGate(new ItemStack(Blocks.DARK_OAK_FENCE_GATE), "dark_oak_fence_gate") - .stairs(new ItemStack(Blocks.DARK_OAK_STAIRS)) + .stairs(new ItemStack(Blocks.DARK_OAK_STAIRS), "dark_oak_stairs") .boat(new ItemStack(Items.DARK_OAK_BOAT), "dark_oak_boat") .registerAllUnificationInfo() .build(), @@ -115,7 +115,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(MetaBlocks.WOOD_SLAB), null).addSlabRecipe() .fence(new ItemStack(MetaBlocks.RUBBER_WOOD_FENCE), null) .fenceGate(new ItemStack(MetaBlocks.RUBBER_WOOD_FENCE_GATE), null) - .stairs(new ItemStack(MetaBlocks.RUBBER_WOOD_STAIRS)).addStairsRecipe() + .stairs(new ItemStack(MetaBlocks.RUBBER_WOOD_STAIRS), null).addStairsRecipe() .boat(MetaItems.RUBBER_WOOD_BOAT.getStackForm(), null) .registerAllOres() .registerAllUnificationInfo() @@ -126,7 +126,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(MetaBlocks.WOOD_SLAB, 1, 1), null).addSlabRecipe() .fence(new ItemStack(MetaBlocks.TREATED_WOOD_FENCE), null) .fenceGate(new ItemStack(MetaBlocks.TREATED_WOOD_FENCE_GATE), null) - .stairs(new ItemStack(MetaBlocks.TREATED_WOOD_STAIRS)).addStairsRecipe() + .stairs(new ItemStack(MetaBlocks.TREATED_WOOD_STAIRS), null).addStairsRecipe() .boat(MetaItems.TREATED_WOOD_BOAT.getStackForm(), null) .material(TreatedWood) .registerAllOres() @@ -326,8 +326,10 @@ public static void registerWoodTypeRecipe(@NotNull WoodTypeEntry entry) { // stairs if (!entry.stairs.isEmpty()) { + final boolean hasStairRecipe = entry.stairsRecipeName != null; if (entry.addStairsCraftingRecipe) { - ModHandler.addShapedRecipe(name + "_stairs", GTUtility.copy(4, entry.stairs), + ModHandler.addShapedRecipe(hasStairRecipe ? entry.stairsRecipeName : name + "_stairs", + GTUtility.copy(4, entry.stairs), "P ", "PP ", "PPP", 'P', entry.planks.copy()); } @@ -482,7 +484,7 @@ private static void registerGTWoodRecipes() { 'L', MetaBlocks.PLANKS.getItemVariant(BlockGregPlanks.BlockType.TREATED_PLANK)); if (ConfigHolder.recipes.nerfWoodCrafting) { ModHandler.addShapedRecipe("treated_wood_stick_saw", OreDictUnifier.get(OrePrefix.stick, TreatedWood, 4), - "s", "L", + "s", "L", "L", 'L', MetaBlocks.PLANKS.getItemVariant(BlockGregPlanks.BlockType.TREATED_PLANK)); } } diff --git a/src/main/java/gregtech/loaders/recipe/chemistry/NuclearRecipes.java b/src/main/java/gregtech/loaders/recipe/chemistry/NuclearRecipes.java index 5c5adc80dac..b082ba98b53 100644 --- a/src/main/java/gregtech/loaders/recipe/chemistry/NuclearRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/chemistry/NuclearRecipes.java @@ -1,13 +1,60 @@ package gregtech.loaders.recipe.chemistry; +import gregtech.common.items.MetaItems; + import static gregtech.api.GTValues.*; import static gregtech.api.recipes.RecipeMaps.*; import static gregtech.api.unification.material.Materials.*; -import static gregtech.api.unification.ore.OrePrefix.dust; +import static gregtech.api.unification.ore.OrePrefix.*; public class NuclearRecipes { public static void init() { + // Thorium Fuel + /* + * CHEMICAL_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + * .input(dust, Thorium, 1) + * .fluidInputs(Fluorine.getFluid(4000)) + * .output(dust, ThoriumTetrafluoride, 5) + * .buildAndRegister(); + * + * CHEMICAL_RECIPES.recipeBuilder().duration(100).EUt(VA[LV]) + * .input(dust, Lithium, 1) + * .fluidInputs(Fluorine.getFluid(1000)) + * .output(dust, LithiumFluoride, 2) + * .buildAndRegister(); + * + * CHEMICAL_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + * .input(dust, Beryllium, 1) + * .fluidInputs(Fluorine.getFluid(2000)) + * .output(dust, BerylliumFluoride, 3) + * .buildAndRegister(); + * + * BLAST_RECIPES.recipeBuilder().duration(200).EUt(VA[EV]).blastFurnaceTemp(1000) + * .input(dust, ThoriumTetrafluoride, 5) + * .input(dust, LithiumFluoride, 4) + * .input(dust, BerylliumFluoride, 3) + * .fluidOutputs(ThoriumFLiBe.getFluid(4000)) + * .buildAndRegister(); + */ + + // Boron carbide for spent fuel racks + + CHEMICAL_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + .input(dust, Boron, 2) + .fluidInputs(Oxygen.getFluid(3000)) + .output(dust, BoronTrioxide, 5) + .buildAndRegister(); + + CHEMICAL_RECIPES.recipeBuilder().duration(400).EUt(VA[MV]) + .input(dust, BoronTrioxide, 2) + .input(dust, Carbon, 7) + .output(dust, BoronCarbide, 5) + .fluidOutputs(CarbonMonoxide.getFluid(6000)) + .buildAndRegister(); + + // Uranium enrichment + CHEMICAL_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) .input(dust, Uraninite, 3) .fluidInputs(HydrofluoricAcid.getFluid(4000)) @@ -16,22 +63,277 @@ public static void init() { .fluidOutputs(Water.getFluid(2000)) .buildAndRegister(); - CENTRIFUGE_RECIPES.recipeBuilder().duration(160).EUt(VA[HV]) + GAS_CENTRIFUGE_RECIPES.recipeBuilder().duration(160).EUt(VA[HV]) .fluidInputs(UraniumHexafluoride.getFluid(1000)) - .fluidOutputs(EnrichedUraniumHexafluoride.getFluid(100)) + .fluidOutputs(LowEnrichedUraniumHexafluoride.getFluid(100)) + .fluidOutputs(DepletedUraniumHexafluoride.getFluid(900)) + .buildAndRegister(); + + GAS_CENTRIFUGE_RECIPES.recipeBuilder().duration(160).EUt(VA[HV]) + .fluidInputs(LowEnrichedUraniumHexafluoride.getFluid(1000)) + .fluidOutputs(HighEnrichedUraniumHexafluoride.getFluid(100)) .fluidOutputs(DepletedUraniumHexafluoride.getFluid(900)) .buildAndRegister(); - ELECTROLYZER_RECIPES.recipeBuilder().duration(160).EUt(VA[MV]) - .fluidInputs(EnrichedUraniumHexafluoride.getFluid(1000)) - .output(dust, Uranium235) - .fluidOutputs(Fluorine.getFluid(6000)) + MIXER_RECIPES.recipeBuilder().duration(400).EUt(VA[HV]) + .input(dust, FissilePlutoniumDioxide, 1) + .input(dust, Uraninite, 20) + .circuitMeta(1) + .output(dust, LowGradeMOX, 1) .buildAndRegister(); - ELECTROLYZER_RECIPES.recipeBuilder().duration(160).EUt(VA[MV]) + MIXER_RECIPES.recipeBuilder().duration(400).EUt(VA[HV]) + .input(dust, FissilePlutoniumDioxide, 1) + .input(dust, Uraninite, 5) + .circuitMeta(2) + .output(dust, HighGradeMOX, 1) + .buildAndRegister(); + + // Zircaloy + BLAST_RECIPES.recipeBuilder().duration(200).EUt(VA[EV]).blastFurnaceTemp(2100) + .input(dust, Zircon, 1) + .output(dust, SiliconDioxide, 3) + .chancedOutput(dust, ZirconiumDioxide, 3, 9000, 0) + .chancedOutput(dust, HafniumDioxide, 3, 1000, 0) + .buildAndRegister(); + + BLAST_RECIPES.recipeBuilder().duration(200).EUt(VA[EV]).blastFurnaceTemp(1400) + .input(dust, ZirconiumDioxide, 1) + .input(dust, Carbon, 1) + .fluidInputs(Chlorine.getFluid(4000)) + .fluidOutputs(CarbonDioxide.getFluid(1000)) + .output(dust, ZirconiumTetrachloride, 5) + .buildAndRegister(); + + BLAST_RECIPES.recipeBuilder().duration(200).EUt(VA[EV]).blastFurnaceTemp(1250) + .input(dust, HafniumDioxide, 1) + .input(dust, Carbon, 1) + .fluidInputs(Chlorine.getFluid(4000)) + .fluidOutputs(CarbonDioxide.getFluid(1000)) + .output(dust, HafniumTetrachloride, 5) + .buildAndRegister(); + + BLAST_RECIPES.recipeBuilder().duration(200).EUt(VA[EV]).blastFurnaceTemp(1150) + .input(dust, ZirconiumTetrachloride, 5) + .input(dust, Magnesium, 2) + .output(dust, Zirconium, 1) + .output(dust, MagnesiumChloride, 6) + .buildAndRegister(); + + BLAST_RECIPES.recipeBuilder().duration(200).EUt(VA[EV]).blastFurnaceTemp(1150) + .input(dust, HafniumTetrachloride, 5) + .input(dust, Magnesium, 2) + .output(dust, Hafnium, 1) + .output(dust, MagnesiumChloride, 6) + .buildAndRegister(); + + MIXER_RECIPES.recipeBuilder().duration(200).EUt(VA[EV]) + .input(dust, Zirconium, 16) + .fluidInputs(Tin.getFluid(32)) + .fluidInputs(Chrome.getFluid(2)) + .output(dust, Zircaloy, 16) + .buildAndRegister(); + + // Inconel 718 + MIXER_RECIPES.recipeBuilder().duration(200).EUt(VA[EV]) + .input(dust, Nickel, 5) + .input(dust, Chrome, 2) + .input(dust, Iron, 2) + .fluidInputs(Niobium.getFluid(72)) + .fluidInputs(Molybdenum.getFluid(48)) + .output(dust, Inconel, 10) + .buildAndRegister(); + + // LEU-235 Dioxide + CHEMICAL_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + .fluidInputs(HighEnrichedUraniumHexafluoride.getFluid(1000)) + .fluidInputs(Water.getFluid(2000)) + .fluidInputs(Hydrogen.getFluid(2000)) + .output(dust, HighEnrichedUraniumDioxide, 1) + .fluidOutputs(HydrofluoricAcid.getFluid(6000)) + .buildAndRegister(); + + CHEMICAL_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + .fluidInputs(LowEnrichedUraniumHexafluoride.getFluid(1000)) + .fluidInputs(Water.getFluid(2000)) + .fluidInputs(Hydrogen.getFluid(2000)) + .output(dust, LowEnrichedUraniumDioxide, 1) + .fluidOutputs(HydrofluoricAcid.getFluid(6000)) + .buildAndRegister(); + + CHEMICAL_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) .fluidInputs(DepletedUraniumHexafluoride.getFluid(1000)) - .output(dust, Uranium) - .fluidOutputs(Fluorine.getFluid(6000)) + .fluidInputs(Water.getFluid(2000)) + .fluidInputs(Hydrogen.getFluid(2000)) + .output(dust, DepletedUraniumDioxide, 3) + .fluidOutputs(HydrofluoricAcid.getFluid(6000)) + .buildAndRegister(); + + MIXER_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + .input(dust, HighEnrichedUraniumDioxide, 1) + .input(dust, DepletedUraniumDioxide, 5) + .output(dust, HEU235, 6) + .buildAndRegister(); + + MIXER_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + .input(dust, HighEnrichedUraniumDioxide, 1) + .input(dust, DepletedUraniumDioxide, 20) + .output(dust, LEU235, 21) + .buildAndRegister(); + + CHEMICAL_RECIPES.recipeBuilder().duration(40).EUt(VA[ULV]) + .input(dust, Plutonium239) + .fluidInputs(Oxygen.getFluid(2000)) + .output(dust, FissilePlutoniumDioxide, 3) + .buildAndRegister(); + + CHEMICAL_RECIPES.recipeBuilder().duration(40).EUt(VA[ULV]) + .input(dust, Plutonium241) + .fluidInputs(Oxygen.getFluid(2000)) + .output(dust, FissilePlutoniumDioxide, 3) + .buildAndRegister(); + + // U/Pu extraction + + ASSEMBLER_RECIPES.recipeBuilder().duration(400).EUt(VA[LV]) + .input(ring, Titanium, 2) + .input(stick, Titanium, 16) + .output(MetaItems.ANODE_BASKET) + .buildAndRegister(); + + ELECTROLYZER_RECIPES.recipeBuilder().duration(800).EUt(VA[EV]) + .notConsumable(MetaItems.ANODE_BASKET) + .notConsumable(Salt.getFluid(1000)) + .input(fuelPelletDepleted, LEU235) + .output(dustSpentFuel, LEU235) + .output(dustBredFuel, LEU235) + .chancedOutput(dustFissionByproduct, LEU235, 266, 0) + .buildAndRegister(); + + ELECTROLYZER_RECIPES.recipeBuilder().duration(800).EUt(VA[EV]) + .notConsumable(MetaItems.ANODE_BASKET) + .notConsumable(Salt.getFluid(1000)) + .input(fuelPelletDepleted, HEU235) + .output(dustSpentFuel, HEU235) + .output(dustBredFuel, HEU235) + .chancedOutput(dustFissionByproduct, HEU235, 301, 0) + .buildAndRegister(); + + ELECTROLYZER_RECIPES.recipeBuilder().duration(800).EUt(VA[EV]) + .notConsumable(MetaItems.ANODE_BASKET) + .notConsumable(Salt.getFluid(1000)) + .input(fuelPelletDepleted, LowGradeMOX) + .output(dustSpentFuel, LowGradeMOX) + .output(dustBredFuel, LowGradeMOX) + .chancedOutput(dustFissionByproduct, LowGradeMOX, 229, 0) + .buildAndRegister(); + + ELECTROLYZER_RECIPES.recipeBuilder().duration(800).EUt(VA[EV]) + .notConsumable(MetaItems.ANODE_BASKET) + .notConsumable(Salt.getFluid(1000)) + .input(fuelPelletDepleted, HighGradeMOX) + .output(dustSpentFuel, HighGradeMOX) + .output(dustBredFuel, HighGradeMOX) + .chancedOutput(dustFissionByproduct, HighGradeMOX, 443, 0) + .buildAndRegister(); + + CHEMICAL_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + .input(dustSpentFuel, LEU235, 1) + .fluidInputs(HydrofluoricAcid.getFluid(4000)) + .fluidInputs(Fluorine.getFluid(2000)) + .fluidOutputs(UraniumHexafluoride.getFluid(1000)) + .fluidOutputs(Water.getFluid(2000)) + .buildAndRegister(); + + CHEMICAL_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + .input(dustSpentFuel, HEU235, 1) + .fluidInputs(HydrofluoricAcid.getFluid(4000)) + .fluidInputs(Fluorine.getFluid(2000)) + .fluidOutputs(LowEnrichedUraniumHexafluoride.getFluid(1000)) + .fluidOutputs(Water.getFluid(2000)) + .buildAndRegister(); + + CHEMICAL_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + .input(dustSpentFuel, LowGradeMOX, 1) + .fluidInputs(HydrofluoricAcid.getFluid(4000)) + .fluidInputs(Fluorine.getFluid(2000)) + .fluidOutputs(DepletedUraniumHexafluoride.getFluid(1000)) + .fluidOutputs(Water.getFluid(2000)) + .buildAndRegister(); + + CENTRIFUGE_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + .input(dustBredFuel, LEU235) + .chancedOutput(dust, Plutonium239, 47, 0) + .chancedOutput(dust, Plutonium240, 22, 0) + .chancedOutput(dust, Plutonium241, 14, 0) + .chancedOutput(dust, Neptunium239, 3, 0) + .buildAndRegister(); + + CENTRIFUGE_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + .input(dustBredFuel, HEU235) + .chancedOutput(dust, Plutonium239, 47, 0) + .chancedOutput(dust, Plutonium240, 22, 0) + .chancedOutput(dust, Plutonium241, 14, 0) + .chancedOutput(dust, Neptunium239, 3, 0) + .buildAndRegister(); + + CENTRIFUGE_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + .input(dustBredFuel, LowGradeMOX) + .chancedOutput(dust, Plutonium240, 33, 0) + .chancedOutput(dust, Plutonium241, 1, 0) + .chancedOutput(dust, Neptunium239, 3, 0) + .buildAndRegister(); + + CENTRIFUGE_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + .input(dustBredFuel, HighGradeMOX) + .chancedOutput(dust, Plutonium240, 724, 0) + .chancedOutput(dust, Plutonium241, 192, 0) + .chancedOutput(dust, Plutonium242, 59, 0) + .chancedOutput(dust, Neptunium239, 3, 0) + .buildAndRegister(); + + CENTRIFUGE_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + .input(dustFissionByproduct, LEU235) + .chancedOutput(dust, Molybdenum, 800, 0) + .chancedOutput(dust, Technetium, 755, 0) + .chancedOutput(dust, Caesium, 2390, 0) + .chancedOutput(dust, Barium, 1751, 0) + .chancedOutput(dust, Cerium, 778, 0) + .chancedOutput(dust, Praseodymium, 722, 0) + .chancedFluidOutput(Xenon.getFluid(1000), 881, 0) + .buildAndRegister(); + + CENTRIFUGE_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + .input(dustFissionByproduct, HEU235) + .chancedOutput(dust, Strontium, 706, 0) + .chancedOutput(dust, Technetium, 755, 0) + .chancedOutput(dust, Caesium, 2390, 0) + .chancedOutput(dust, Barium, 1751, 0) + .chancedOutput(dust, Cerium, 777, 0) + .chancedOutput(dust, Praseodymium, 721, 0) + .chancedFluidOutput(Xenon.getFluid(1000), 881, 0) + .buildAndRegister(); + + CENTRIFUGE_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + .input(dustFissionByproduct, LowGradeMOX) + .chancedOutput(dust, Technetium, 750, 0) + .chancedOutput(dust, Caesium, 2490, 0) + .chancedOutput(dust, Neodymium, 519, 0) + .chancedOutput(dust, Praseodymium, 654, 0) + .chancedOutput(dust, Barium, 1874, 0) + .chancedOutput(dust, Palladium, 463, 0) + .chancedFluidOutput(Xenon.getFluid(1000), 1019, 0) + .buildAndRegister(); + + CENTRIFUGE_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + .input(dustFissionByproduct, HighGradeMOX) + .chancedOutput(dust, Technetium, 744, 0) + .chancedOutput(dust, Caesium, 2497, 0) + .chancedOutput(dust, Barium, 1893, 0) + .chancedOutput(dust, Cerium, 693, 0) + .chancedOutput(dust, Praseodymium, 654, 0) + .chancedOutput(dust, Promethium, 265, 0) + .chancedFluidOutput(Xenon.getFluid(1000), 1025, 0) .buildAndRegister(); } } diff --git a/src/main/java/gregtech/loaders/recipe/chemistry/ReactorRecipes.java b/src/main/java/gregtech/loaders/recipe/chemistry/ReactorRecipes.java index 8a07b6dba0a..ab73d214064 100644 --- a/src/main/java/gregtech/loaders/recipe/chemistry/ReactorRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/chemistry/ReactorRecipes.java @@ -3,6 +3,7 @@ import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.MarkerMaterials; import gregtech.api.unification.material.Materials; +import gregtech.common.blocks.MetaBlocks; import gregtech.common.items.MetaItems; import net.minecraft.init.Blocks; @@ -570,6 +571,13 @@ public static void init() { .outputs(new ItemStack(Blocks.TNT)) .duration(200).EUt(24).buildAndRegister(); + CHEMICAL_RECIPES.recipeBuilder() + .inputs(MetaItems.GELLED_TOLUENE.getStackForm(4)) + .fluidInputs(NitrationMixture.getFluid(200)) + .outputs(new ItemStack(MetaBlocks.ITNT)) + .fluidOutputs(DilutedSulfuricAcid.getFluid(150)) + .duration(80).EUt(VA[HV]).buildAndRegister(); + CHEMICAL_RECIPES.recipeBuilder() .input(dust, SodiumHydroxide, 6) .fluidInputs(Dichlorobenzene.getFluid(1000)) diff --git a/src/main/java/gregtech/loaders/recipe/handlers/FluidRecipeHandler.java b/src/main/java/gregtech/loaders/recipe/handlers/FluidRecipeHandler.java new file mode 100644 index 00000000000..e341cf7df0c --- /dev/null +++ b/src/main/java/gregtech/loaders/recipe/handlers/FluidRecipeHandler.java @@ -0,0 +1,46 @@ +package gregtech.loaders.recipe.handlers; + +import gregtech.api.GregTechAPI; +import gregtech.api.recipes.RecipeMaps; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.Materials; +import gregtech.api.unification.material.properties.CoolantProperty; +import gregtech.api.unification.material.properties.PropertyKey; + +public class FluidRecipeHandler { + + public static void runRecipeGeneration() { + for (Material material : GregTechAPI.materialManager.getRegisteredMaterials()) { + if (material.hasProperty(PropertyKey.COOLANT)) + processCoolant(material, material.getProperty(PropertyKey.COOLANT)); + } + } + + public static void processCoolant(Material mat, CoolantProperty coolant) { + RecipeMaps.HEAT_EXCHANGER_RECIPES.recipeBuilder().duration(1).circuitMeta(1) + .fluidInputs(coolant.getHotHPCoolant().getFluid(6), Materials.Water.getFluid(6)) + .fluidOutputs(mat.getFluid(6), Materials.Steam.getFluid(960)) + .buildAndRegister(); + + RecipeMaps.HEAT_EXCHANGER_RECIPES.recipeBuilder().duration(1).circuitMeta(1) + .fluidInputs(coolant.getHotHPCoolant().getFluid(6), Materials.DistilledWater.getFluid(6)) + .fluidOutputs(mat.getFluid(6), Materials.Steam.getFluid(960)) + .buildAndRegister(); + + RecipeMaps.HEAT_EXCHANGER_RECIPES.recipeBuilder().duration(1).circuitMeta(2) + .fluidInputs(coolant.getHotHPCoolant().getFluid(600), Materials.Water.getFluid(600)) + .fluidOutputs(mat.getFluid(600), Materials.Steam.getFluid(96000)) + .buildAndRegister(); + + RecipeMaps.HEAT_EXCHANGER_RECIPES.recipeBuilder().duration(1).circuitMeta(2) + .fluidInputs(coolant.getHotHPCoolant().getFluid(600), Materials.DistilledWater.getFluid(600)) + .fluidOutputs(mat.getFluid(600), Materials.Steam.getFluid(96000)) + .buildAndRegister(); + + // Radiator + RecipeMaps.HEAT_EXCHANGER_RECIPES.recipeBuilder().duration(10).circuitMeta(3) + .fluidInputs(coolant.getHotHPCoolant().getFluid(8000)) + .fluidOutputs(mat.getFluid(8000)) + .buildAndRegister(); + } +} diff --git a/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java b/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java index ac915b45dc7..cbdf94add16 100644 --- a/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java +++ b/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java @@ -13,6 +13,7 @@ import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.GTUtility; import gregtech.common.ConfigHolder; +import gregtech.common.blocks.MetaBlocks; import gregtech.common.items.MetaItems; import gregtech.loaders.recipe.CraftingComponent; @@ -90,14 +91,28 @@ public static void processDust(OrePrefix dustPrefix, Material mat, DustProperty .inputs(GTUtility.copy(4, dustStack)) .outputs(GTUtility.copy(3, gemStack)) .chancedOutput(dust, Materials.DarkAsh, 2500, 0) - .explosivesAmount(2) + .explosivesType(new ItemStack(MetaBlocks.POWDERBARREL, 8)) .buildAndRegister(); RecipeMaps.IMPLOSION_RECIPES.recipeBuilder() .inputs(GTUtility.copy(4, dustStack)) .outputs(GTUtility.copy(3, gemStack)) .chancedOutput(dust, Materials.DarkAsh, 2500, 0) - .explosivesType(MetaItems.DYNAMITE.getStackForm()) + .explosivesAmount(4) + .buildAndRegister(); + + RecipeMaps.IMPLOSION_RECIPES.recipeBuilder() + .inputs(GTUtility.copy(4, dustStack)) + .outputs(GTUtility.copy(3, gemStack)) + .chancedOutput(dust, Materials.DarkAsh, 2500, 0) + .explosivesType(MetaItems.DYNAMITE.getStackForm(2)) + .buildAndRegister(); + + RecipeMaps.IMPLOSION_RECIPES.recipeBuilder() + .inputs(GTUtility.copy(4, dustStack)) + .outputs(GTUtility.copy(3, gemStack)) + .chancedOutput(dust, Materials.DarkAsh, 2500, 0) + .explosivesType(new ItemStack(MetaBlocks.ITNT)) .buildAndRegister(); } @@ -286,10 +301,10 @@ public static void processIngot(OrePrefix ingotPrefix, Material material, IngotP } } - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_INGOT) - .fluidInputs(material.getFluid(L)) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom(L)) .outputs(OreDictUnifier.get(ingotPrefix, material)) .duration(20).EUt(VA[ULV]) .buildAndRegister(); @@ -424,10 +439,10 @@ public static void processNugget(OrePrefix orePrefix, Material material, DustPro .output(ingot, material) .buildAndRegister(); - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_NUGGET) - .fluidInputs(material.getFluid(L)) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom(L)) .outputs(OreDictUnifier.get(orePrefix, material, 9)) .duration((int) material.getMass()) .EUt(VA[ULV]) @@ -465,10 +480,11 @@ public static void processFrame(OrePrefix framePrefix, Material material, DustPr public static void processBlock(OrePrefix blockPrefix, Material material, DustProperty property) { ItemStack blockStack = OreDictUnifier.get(blockPrefix, material); long materialAmount = blockPrefix.getMaterialAmount(material); - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_BLOCK) - .fluidInputs(material.getFluid((int) (materialAmount * L / M))) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom( + ((int) (materialAmount * L / M)))) .outputs(blockStack) .duration((int) material.getMass()).EUt(VA[ULV]) .buildAndRegister(); diff --git a/src/main/java/gregtech/loaders/recipe/handlers/NuclearRecipeHandler.java b/src/main/java/gregtech/loaders/recipe/handlers/NuclearRecipeHandler.java new file mode 100644 index 00000000000..22f3f4cd0f8 --- /dev/null +++ b/src/main/java/gregtech/loaders/recipe/handlers/NuclearRecipeHandler.java @@ -0,0 +1,56 @@ +package gregtech.loaders.recipe.handlers; + +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.properties.OreProperty; +import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.api.unification.ore.OrePrefix; +import gregtech.common.items.MetaItems; + +import static gregtech.api.GTValues.*; +import static gregtech.api.recipes.RecipeMaps.*; +import static gregtech.api.unification.material.Materials.*; +import static gregtech.api.unification.ore.OrePrefix.*; + +public class NuclearRecipeHandler { + + public static void register() { + OrePrefix.fuelRod.addProcessingHandler(PropertyKey.ORE, NuclearRecipeHandler::processFuelRod); + } + + private static void processFuelRod(OrePrefix orePrefix, Material material, OreProperty oreProperty) { + SPENT_FUEL_POOL_RECIPES.recipeBuilder().duration(24000) + .input(fuelRod, material) + .output(fuelRodDepleted, material) + .buildAndRegister(); + + MACERATOR_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) + .input(fuelRodDepleted, material) + .output(dust, Zircaloy, 4) + .buildAndRegister(); + + SPENT_FUEL_POOL_RECIPES.recipeBuilder().duration(400) + .input(fuelRodHotDepleted, material) + .output(fuelRodDepleted, material) + .buildAndRegister(); + + CUTTER_RECIPES.recipeBuilder().duration(200).EUt(VA[EV]) + .input(fuelRodDepleted, material) + .output(plate, Zircaloy, 4) + .output(fuelPelletDepleted, material, 16) + .buildAndRegister(); + + FORMING_PRESS_RECIPES.recipeBuilder().duration(25).EUt(VA[EV]) + .input(dust, material, 1) + .notConsumable(MetaItems.SHAPE_MOLD_CYLINDER) + .output(fuelPellet, material) + .buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder().duration(800).EUt(VA[EV]) + .input(plate, Zircaloy, 4) + .input(spring, Inconel, 1) + .input(round, StainlessSteel, 2) + .input(fuelPellet, material, 16) + .output(fuelRod, material) + .buildAndRegister(); + } +} diff --git a/src/main/java/gregtech/loaders/recipe/handlers/PartsRecipeHandler.java b/src/main/java/gregtech/loaders/recipe/handlers/PartsRecipeHandler.java index 24ec5349133..ddff63fd34a 100644 --- a/src/main/java/gregtech/loaders/recipe/handlers/PartsRecipeHandler.java +++ b/src/main/java/gregtech/loaders/recipe/handlers/PartsRecipeHandler.java @@ -200,11 +200,12 @@ public static void processGear(OrePrefix gearPrefix, Material material, DustProp } } - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { boolean isSmall = gearPrefix == OrePrefix.gearSmall; RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(isSmall ? MetaItems.SHAPE_MOLD_GEAR_SMALL : MetaItems.SHAPE_MOLD_GEAR) - .fluidInputs(material.getFluid(L * (isSmall ? 1 : 4))) + .fluidInputs( + material.getProperty(PropertyKey.FLUID).solidifiesFrom(L * (isSmall ? 1 : 4))) .outputs(stack) .duration(isSmall ? 20 : 100) .EUt(VA[ULV]) @@ -285,10 +286,10 @@ public static void processLens(OrePrefix lensPrefix, Material material, GemPrope } public static void processPlate(OrePrefix platePrefix, Material material, DustProperty property) { - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_PLATE) - .fluidInputs(material.getFluid(L)) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom(L)) .outputs(OreDictUnifier.get(platePrefix, material)) .duration(40) .EUt(VA[ULV]) @@ -399,10 +400,10 @@ public static void processRotor(OrePrefix rotorPrefix, Material material, IngotP 'S', new UnificationEntry(screw, material), 'R', new UnificationEntry(ring, material)); - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_ROTOR) - .fluidInputs(material.getFluid(L * 4)) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom(L * 4)) .outputs(GTUtility.copy(stack)) .duration(120) .EUt(20) diff --git a/src/main/java/gregtech/loaders/recipe/handlers/RecipeHandlerList.java b/src/main/java/gregtech/loaders/recipe/handlers/RecipeHandlerList.java index 3ee805f8185..a1d413bfcce 100644 --- a/src/main/java/gregtech/loaders/recipe/handlers/RecipeHandlerList.java +++ b/src/main/java/gregtech/loaders/recipe/handlers/RecipeHandlerList.java @@ -12,5 +12,6 @@ public static void register() { ToolRecipeHandler.register(); PolarizingRecipeHandler.register(); RecyclingRecipeHandler.register(); + NuclearRecipeHandler.register(); } } diff --git a/src/main/java/gregtech/loaders/recipe/handlers/ToolRecipeHandler.java b/src/main/java/gregtech/loaders/recipe/handlers/ToolRecipeHandler.java index 4b6ec9210b2..1997631a38c 100644 --- a/src/main/java/gregtech/loaders/recipe/handlers/ToolRecipeHandler.java +++ b/src/main/java/gregtech/loaders/recipe/handlers/ToolRecipeHandler.java @@ -287,6 +287,10 @@ private static void processElectricTool(OrePrefix prefix, Material material, Too .EUt(8 * voltageMultiplier) .buildAndRegister(); } + + // wirecutter + addElectricWirecutterRecipe(material, + new IGTTool[] { ToolItems.WIRECUTTER_LV, ToolItems.WIRECUTTER_HV, ToolItems.WIRECUTTER_IV }); } // screwdriver @@ -316,6 +320,21 @@ public static void addElectricToolRecipe(OrePrefix toolHead, Material material, } } + public static void addElectricWirecutterRecipe(Material material, IGTTool[] toolItems) { + for (IGTTool toolItem : toolItems) { + int tier = toolItem.getElectricTier(); + ItemStack powerUnitStack = powerUnitItems.get(tier).getStackForm(); + IElectricItem powerUnit = powerUnitStack.getCapability(GregtechCapabilities.CAPABILITY_ELECTRIC_ITEM, null); + ItemStack tool = toolItem.get(material, 0, powerUnit.getMaxCharge()); + ModHandler.addShapedEnergyTransferRecipe(String.format("%s_%s", toolItem.getToolId(), material), tool, + Ingredient.fromStacks(powerUnitStack), true, true, + "PfP", "hPd", "RUR", + 'P', new UnificationEntry(OrePrefix.plate, material), + 'U', powerUnitStack, + 'R', new UnificationEntry(OrePrefix.stick, material)); + } + } + public static void addToolRecipe(@NotNull Material material, @NotNull IGTTool tool, boolean mirrored, Object... recipe) { if (mirrored) { diff --git a/src/main/resources/assets/gregtech/blockstates/itnt.json b/src/main/resources/assets/gregtech/blockstates/itnt.json new file mode 100644 index 00000000000..79c7d216ccb --- /dev/null +++ b/src/main/resources/assets/gregtech/blockstates/itnt.json @@ -0,0 +1,16 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:cube_bottom_top", + "textures": { + "bottom": "minecraft:blocks/tnt_bottom", + "top": "minecraft:blocks/tnt_top", + "side": "gregtech:blocks/misc/itnt" + } + }, + "variants": { + "normal": [ + {} + ] + } +} diff --git a/src/main/resources/assets/gregtech/blockstates/powderbarrel.json b/src/main/resources/assets/gregtech/blockstates/powderbarrel.json new file mode 100644 index 00000000000..60d676619f5 --- /dev/null +++ b/src/main/resources/assets/gregtech/blockstates/powderbarrel.json @@ -0,0 +1,14 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:cube_all", + "textures": { + "all": "gregtech:blocks/misc/powderbarrel" + } + }, + "variants": { + "normal": [ + {} + ] + } +} diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index cf8bfa8749c..a374099c26c 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -43,12 +43,20 @@ tile.fission_casing.reactor_vessel.name=Reactor Vessel tile.fission_casing.fuel_channel.name=Fuel Channel tile.fission_casing.control_rod_channel.name=Control Rod Channel tile.fission_casing.coolant_channel.name=Coolant Channel -gregtech.machine.fission_reactor.name=Fission Reactor Controller gregtech.machine.fuel_rod_input.name=Fuel Rod Input Port +gregtech.machine.fuel_rod_input.tooltip=Requires §fFuel Channels§7 below itself to function and form. gregtech.machine.fuel_rod_output.name=Fuel Rod Output Port +gregtech.machine.fuel_rod_output.tooltip=Requires §fFuel Channels§7 above itself to function and form. gregtech.machine.coolant_input.name=Coolant Input Port +gregtech.machine.coolant_input.tooltip=Requires §fCoolant Channels§7 below itself to function and form. gregtech.machine.coolant_output.name=Coolant Output Port +gregtech.machine.coolant_output.tooltip=Requires §fCoolant Channels§7 above itself to function and form. gregtech.machine.control_rod.name=Control Rod Port +gregtech.machine.control_rod.tooltip=Requires §fControl Rod Channels§7 below itself to function and form. +gregtech.machine.control_rod.tooltip.1=Lowers neutron multiplication as it is inserted when placed between fuel rods! +gregtech.machine.control_rod_moderated.name=Graphite-Tipped Control Rod Port +gregtech.machine.control_rod_moderated.tooltip=Requires §fControl Rod Channels§7 below itself to function and form. +gregtech.machine.control_rod_moderated.tooltip.1=Increases neutron multiplication when placed between fuel rods when inserted slightly! gregtech.machine.steam_grinder.name=Steam Grinder gregtech.multiblock.steam_grinder.description=A Multiblock Macerator at the Steam Age. Requires at least 14 Bronze Casings to form. Cannot use normal Input/Output busses, nor Fluid Hatches other than the Steam Hatch. @@ -146,6 +154,8 @@ gregtech.multiblock.primitive_water_pump.extra1=Biome Coefficient:/n Ocean, Riv gregtech.multiblock.primitive_water_pump.extra2=Hatch Multipliers:/n Pump Hatch: 1x/n ULV Output Hatch: 2x/n LV Output Hatch: 4x/n/nWhile raining in the Pump's Biome, the total water production will be increased by 50%%. gregtech.multiblock.processing_array.description=The Processing Array combines up to 16 single block machine(s) in a single multiblock, effectively easing automation. gregtech.multiblock.advanced_processing_array.description=The Processing Array combines up to 64 single block machine(s) in a single multiblock, effectively easing automation. +gregtech.multiblock.fission_reactor.description=Fission Reactors use fuel rods placed together to create a sustained chain of fission reactions. These reactions generate heat that may be soaked up by coolants, which can then be used inside turbines. The reactor can take on a variety of shapes. Its cross sections can be seen in JEI, and the reactor may extend 7 blocks up and down from the controller. Reactors can import and exports fuel rods/coolants through special pairs of hatches on the top and bottom layers, respectively. Control rod hatches may also be placed on the top layer, and they give users more control over the reactor. Inserting them more decreases the neutron multiplication rate k_eff, a factor by which the power is continually multiplied by. In fact, the reactor automatically shifts this over time, attempting to reach a stable equilibrium. This may be overridden manually. Control rods, fuel hatches, and coolant hatches all require special tubing beneath them to form correctly; check their tooltips to see which blocks to use. Once a reactor's hatches are filled, the reactor can be locked to begin operation, meaning that the types of items/fluids in the hatches can not be changed while the reactor operates. + item.invalid.name=Invalid item fluid.empty=Empty @@ -833,6 +843,7 @@ metaitem.fluid_filter.name=Fluid Filter metaitem.fluid_filter.tooltip=Filters §fFluid§7 I/O as §fCover§7./nCan be used as an §fElectric Pump§7 and §fFluid Regulator§7 upgrade. metaitem.smart_item_filter.name=Smart Item Filter metaitem.smart_item_filter.tooltip=Filters §fItem§7 I/O with §fMachine Recipes§7 as §fCover§7./nCan be used as a §fConveyor Module§7 and §fRobotic Arm§7 upgrade. +behaviour.filter_ui_manager=§fRight-Click§7 to configure, §fShift Right-Click§7 to clear configuration metaitem.cover.controller.name=Machine Controller metaitem.cover.controller.tooltip=Turns Machines §fON/OFF§7 as §fCover§7. @@ -1019,6 +1030,9 @@ item.gt.tool.screwdriver_lv.name=%s Screwdriver (LV) item.gt.tool.screwdriver_lv.tooltip=§8Adjusts Covers and Machines item.gt.tool.plunger.name=%s Plunger item.gt.tool.plunger.tooltip=§8Removes Fluids from Machines +item.gt.tool.wire_cutter_lv.name=%s Wire Cutter (LV) +item.gt.tool.wire_cutter_hv.name=%s Wire Cutter (HV) +item.gt.tool.wire_cutter_iv.name=%s Wire Cutter (IV) item.gt.tool.tooltip.crafting_uses=§a%s Crafting Uses @@ -1186,7 +1200,9 @@ cover.filter.blacklist.disabled=Whitelist cover.filter.blacklist.enabled=Blacklist cover.ore_dictionary_filter.title=Ore Dictionary Filter -cover.ore_dictionary_filter.info=§bAccepts complex expressions/n§6a & b§r = AND/n§6a | b§r = OR/n§6a ^ b§r = XOR/n§6! abc§r = NOT/n§6( abc )§r for grouping/n§6*§r for wildcard (i.e. 0 or more characters)/n§6?§r for any 1 character/n§6()§r for matching empty entry (including items with no ore dictionary)/n§bExample:/n§6dust*Gold | (plate* & !*Double*)/nWill match all gold dusts of all sizes or all plates, but not double plates +cover.ore_dictionary_filter.info=§bAccepts complex expressions\n§6a & b§r = AND\n§6a | b§r = OR\n§6a ^ b§r = XOR\n§6! abc§r = NOT\n§6( abc )§r for grouping\n§6*§r for wildcard (i.e. 0 or more characters)\n§6?§r for any 1 character\n§6()§r for matching empty entry (including items with no ore dictionary)\n§bExample:\n§6dust*Gold | (plate* & !*Double*)\nWill match all gold dusts of all sizes or all plates, but not double plates +cover.ore_dictionary_filter.match_all=Match All: %s +cover.ore_dictionary_filter.case_sensitive=Case Sensitive: %s cover.ore_dictionary_filter.test_slot.info=Insert a item to test if it matches the filter expression cover.ore_dictionary_filter.test_slot.matches=§a* %s cover.ore_dictionary_filter.test_slot.matches_not=§c* %s @@ -1251,6 +1267,7 @@ cover.fluid_filter.mode.filter_drain=Filter Drain cover.fluid_filter.mode.filter_both=Filter Fill & Drain cover.item_filter.title=Item Filter +cover.filter.mode.title=Filter Mode cover.filter.mode.filter_insert=Filter Insert cover.filter.mode.filter_extract=Filter Extract cover.filter.mode.filter_both=Filter Insert/Extract @@ -1258,9 +1275,11 @@ cover.item_filter.ignore_damage.enabled=Ignore Damage cover.item_filter.ignore_damage.disabled=Respect Damage cover.item_filter.ignore_nbt.enabled=Ignore NBT cover.item_filter.ignore_nbt.disabled=Respect NBT +cover.item_filter.config_amount=Scroll wheel up increases amount, down decreases.\nShift[§6x4§r], Ctrl[§ex16§r], Alt[§ax64§r]\nRight click increases amount, left click decreases.\nShift Left-Click to clear cover.voiding.voiding_mode.void_any=Void Matching cover.voiding.voiding_mode.void_overflow=Void Overflow +cover.voiding.voiding_mode=Voiding Mode cover.voiding.voiding_mode.description=§eVoid Matching§r will void anything matching the filter. /n§eVoid Overflow§r will void anything matching the filter, up to the specified amount. cover.fluid.voiding.title=Fluid Voiding Settings cover.fluid.voiding.advanced.title=Advanced Fluid Voiding Settings @@ -1281,13 +1300,18 @@ cover.smart_item_filter.filtering_mode.centrifuge=Centrifuge cover.smart_item_filter.filtering_mode.sifter=Sifter cover.smart_item_filter.filtering_mode.description=Select Machine this Smart Filter will use for filtering./nIt will automatically pick right portions of items for robotic arm. +cover.generic.transfer_mode=Transfer Mode +cover.generic.manual_io=Manual IO Mode +cover.generic.io=IO Mode +cover.pump.mode=Pump Mode cover.conveyor.title=Conveyor Cover Settings (%s) cover.conveyor.transfer_rate=§7items/sec cover.conveyor.mode.export=Mode: Export cover.conveyor.mode.import=Mode: Import -cover.conveyor.distribution.round_robin_enhanced=Distribution Mode/n§bEnhanced Round Robin§r/n§7Splits items equally to all inventories -cover.conveyor.distribution.round_robin=Distribution Mode/n§bRound Robin§r with Priority/n§7Tries to split items equally to inventories -cover.conveyor.distribution.first_insert=Distribution Mode/n§bFirst Insert§r/n§7Will insert into the first inventory it finds +cover.conveyor.distribution.name=Distribution Mode +cover.conveyor.distribution.round_robin_enhanced=§bEnhanced Round Robin§r\n§7Splits items equally to all inventories +cover.conveyor.distribution.round_robin=§bRound Robin§r with Priority\n§7Tries to split items equally to inventories +cover.conveyor.distribution.first_insert=§bFirst Insert§r\n§7Will insert into the first inventory it finds cover.conveyor.blocks_input.enabled=If enabled, items will not be inserted when cover is set to pull items from the inventory into pipe./n§aEnabled cover.conveyor.blocks_input.disabled=If enabled, items will not be inserted when cover is set to pull items from the inventory into pipe./n§cDisabled cover.universal.manual_import_export.mode.disabled=Manual I/O: Disabled @@ -1298,6 +1322,7 @@ cover.conveyor.item_filter.title=Item Filter cover.conveyor.ore_dictionary.title=Ore Dictionary Name cover.conveyor.ore_dictionary.title2=(use * for wildcard) cover.robotic_arm.title=Robotic Arm Settings (%s) +cover.robotic_arm.exact=§7items cover.robotic_arm.transfer_mode.transfer_any=Transfer Any cover.robotic_arm.transfer_mode.transfer_exact=Supply Exact cover.robotic_arm.transfer_mode.keep_exact=Keep Exact @@ -1308,8 +1333,12 @@ cover.pump.transfer_rate=%s cover.pump.mode.export=Mode: Export cover.pump.mode.import=Mode: Import cover.pump.fluid_filter.title=Fluid Filter -cover.bucket.mode.bucket=kL/s -cover.bucket.mode.milli_bucket=L/s +cover.bucket.mode.bucket=Bucket Mode: kL +cover.bucket.mode.milli_bucket=Bucket Mode: L +cover.bucket.mode.bucket_rate=kL/s +cover.bucket.mode.bucket_exact=kL +cover.bucket.mode.milli_bucket_rate=L/s +cover.bucket.mode.milli_bucket_exact=L cover.fluid_regulator.title=Fluid Regulator Settings (%s) cover.fluid_regulator.transfer_mode.description=§eTransfer Any§r - in this mode, cover will transfer as many fluids matching its filter as possible./n§eSupply Exact§r - in this mode, cover will supply fluids in portions specified in the window underneath this button. If amount of fluids is less than portion size, fluids won't be moved./n§eKeep Exact§r - in this mode, cover will keep specified amount of fluids in the destination inventory, supplying additional amount of fluids if required./n§7Tip: shift click will multiply increase/decrease amounts by 10 and ctrl click will multiply by 100. cover.fluid_regulator.supply_exact=Supply Exact: %s @@ -1332,7 +1361,7 @@ cover.machine_controller.disable_with_redstone=Disable with Redstone cover.ender_fluid_link.title=Ender Fluid Link cover.ender_fluid_link.iomode.enabled=I/O Enabled cover.ender_fluid_link.iomode.disabled=I/O Disabled -cover.ender_fluid_link.private.tooltip.disabled=Switch to private tank mode/nPrivate mode uses the player who originally placed the cover +cover.ender_fluid_link.private.tooltip.disabled=Switch to private tank mode\nPrivate mode uses the player who originally placed the cover cover.ender_fluid_link.private.tooltip.enabled=Switch to public tank mode cover.ender_fluid_link.incomplete_hex=Inputted color is incomplete!/nIt will be applied once complete (all 8 hex digits)/nClosing the gui will lose edits! @@ -1467,9 +1496,13 @@ item.material.oreprefix.polymer.dustSmall=Small Pile of %s Pulp item.material.oreprefix.polymer.dust=%s Pulp item.material.oreprefix.polymer.ingot=%s Bar item.material.oreprefix.fuelRod=%s Fuel Rod -item.material.oreprefix.fuelRodDepleted=%s Exhausted Fuel Rod -item.material.oreprefix.fuelRodHotDepleted=%s Hot Exhausted Fuel Rod - +item.material.oreprefix.fuelRodDepleted=%s Depleted Fuel Rod +item.material.oreprefix.fuelRodHotDepleted=%s Hot Depleted Fuel Rod +item.material.oreprefix.fuelPellet=%s Fuel Pellet +item.material.oreprefix.fuelPelletDepleted=%s Depleted Fuel Pellet +item.material.oreprefix.dustSpentFuel=%s Spent Fuel Dust +item.material.oreprefix.dustBredFuel=%s Bred Fuel Dust +item.material.oreprefix.dustFissionByproduct=%s Fission Byproduct Dust # Direct Element Materials gregtech.material.actinium=Actinium @@ -1540,6 +1573,9 @@ gregtech.material.moscovium=Moscovium gregtech.material.neodymium=Neodymium gregtech.material.neon=Neon gregtech.material.neptunium=Neptunium +gregtech.material.neptunium_235=Neptunium 235 +gregtech.material.neptunium_236=Neptunium 236 +gregtech.material.neptunium_237=Neptunium 237 gregtech.material.nickel=Nickel gregtech.material.nihonium=Nihonium gregtech.material.niobium=Niobium @@ -1552,8 +1588,12 @@ gregtech.material.palladium=Palladium gregtech.material.phosphorus=Phosphorus gregtech.material.polonium=Polonium gregtech.material.platinum=Platinum +gregtech.material.plutonium_238=Plutonium 238 gregtech.material.plutonium=Plutonium 239 +gregtech.material.plutonium_240=Plutonium 240 gregtech.material.plutonium_241=Plutonium 241 +gregtech.material.plutonium_242=Plutonium 242 +gregtech.material.plutonium_244=Plutonium 244 gregtech.material.potassium=Potassium gregtech.material.praseodymium=Praseodymium gregtech.material.promethium=Promethium @@ -1587,7 +1627,9 @@ gregtech.material.tin=Tin gregtech.material.titanium=Titanium gregtech.material.tritium=Tritium gregtech.material.tungsten=Tungsten -gregtech.material.uranium=Uranium 238 +gregtech.material.uranium=Uranium +gregtech.material.uranium_239=Uranium 239 +gregtech.material.uranium_238=Uranium 238 gregtech.material.uranium_235=Uranium 235 gregtech.material.vanadium=Vanadium gregtech.material.xenon=Xenon @@ -1769,7 +1811,7 @@ gregtech.material.hydrofluoric_acid=Hydrofluoric Acid gregtech.material.nitric_oxide=Nitric Oxide gregtech.material.iron_iii_chloride=Iron III Chloride gregtech.material.uranium_hexafluoride=Uranium Hexafluoride -gregtech.material.enriched_uranium_hexafluoride=Enriched Uranium Hexafluoride +gregtech.material.enriched_uranium_hexafluoride=Low Enriched Uranium Hexafluoride gregtech.material.depleted_uranium_hexafluoride=Depleted Uranium Hexafluoride gregtech.material.nitrous_oxide=Nitrous Oxide gregtech.material.ender_pearl=Enderpearl @@ -1777,6 +1819,7 @@ gregtech.material.potassium_feldspar=Potassium Feldspar gregtech.material.neodymium_magnetic=Magnetic Neodymium gregtech.material.hydrochloric_acid=Hydrochloric Acid gregtech.material.steam=Steam +gregtech.material.high_pressure_steam=High Pressure Steam gregtech.material.distilled_water=Distilled Water gregtech.material.sodium_potassium=Sodium Potassium gregtech.material.samarium_magnetic=Magnetic Samarium @@ -1808,15 +1851,22 @@ gregtech.material.enriched_naquadah_sulfate=Enriched Naquadah Sulfate gregtech.material.naquadria_sulfate=Naquadria Sulfate gregtech.material.pyrochlore=Pyrochlore gregtech.material.rtm_alloy=RTM Alloy -gregtech.material.enriched_uranium_dioxide=Enriched Uranium Dioxide +gregtech.material.high_enriched_uranium_hexafluoride=Highly Enriched Uranium Hexafluoride +gregtech.material.high_enriched_uranium_dioxide=Highly Enriched Uranium Dioxide +gregtech.material.low_enriched_uranium_dioxide=Low Enriched Uranium Dioxide gregtech.material.depleted_uranium_dioxide=Depleted Uranium Dioxide -gregtech.material.plutonium_239_dioxide=Plutonium 239 Dioxide -gregtech.material.neptunium_235=Neptunium 235 -gregtech.material.neptunium_236=Neptunium 236 -gregtech.material.neptunium_237=Neptunium 237 -gregtech.material.plutonium_240=Plutonium 240 -gregtech.material.plutonium_242=Plutonium 242 -gregtech.material.plutonium_244=Plutonium 244 +gregtech.material.fissile_plutonium_dioxide=Fissile Plutonium Dioxide +gregtech.material.inconel=Inconel +gregtech.material.corium=Corium +gregtech.material.zircon=Zircon +gregtech.material.zircaloy=Zircaloy +gregtech.material.zirconium_dioxide=Zirconium Dioxide +gregtech.material.zirconium_tetrachloride=Zirconium Tetrachloride +gregtech.material.hafnium_dioxide=Hafnium Dioxide +gregtech.material.hafnium_tetrachloride=Hafnium Tetrachloride +gregtech.material.boron_trioxide=Boron Trioxide +gregtech.material.boron_carbide=Boron Carbide + # Organic Chemistry Materials gregtech.material.silicone_rubber=Silicone Rubber @@ -2334,6 +2384,9 @@ recipemap.rock_breaker.name=Rock Breaker recipemap.primitive_blast_furnace.name=Primitive Blast Furnace recipemap.coke_oven.name=Coke Oven recipemap.research_station.name=Research Station +recipemap.heat_exchanger.name=Heat Exchanger +recipemap.gas_centrifuge.name=Gas Centrifuge + gregtech.recipe.category.arc_furnace_recycling=Arc Furnace Recycling gregtech.recipe.category.macerator_recycling=Macerator Recycling @@ -2373,6 +2426,17 @@ tile.treated_wood_fence.name=Treated Wood Fence tile.rubber_wood_fence_gate.name=Rubber Wood Fence Gate tile.treated_wood_fence_gate.name=Treated Wood Fence Gate +tile.gt_explosive.breaking_tooltip=Primes explosion when mined, sneak mine to pick back up +tile.gt_explosive.lighting_tooltip=Cannot be lit with Redstone + +tile.powderbarrel.name=Powderbarrel +tile.powderbarrel.drops_tooltip=Slightly larger than TNT, drops all destroyed Blocks as Items +entity.Powderbarrel.name=Powderbarrel + +tile.itnt.name=Industrial TNT +tile.itnt.drops_tooltip=Much larger than TNT, drops all destroyed Blocks as Items +entity.ITNT.name=Industrial TNT + tile.brittle_charcoal.name=Brittle Charcoal tile.brittle_charcoal.tooltip.1=Produced by the Charcoal Pile Igniter. tile.brittle_charcoal.tooltip.2=Mine this to get Charcoal. @@ -2467,6 +2531,8 @@ metaitem.cover.digital.wireless.name=Wireless Digital Interface metaitem.coloured.leds.name=Coloured LEDs metaitem.display.name=Display +metaitem.basket.anode.name=Anode Basket + tile.casing.ulv=ULV Machine Casing tile.casing.lv=LV Machine Casing tile.casing.mv=MV Machine Casing @@ -2573,6 +2639,23 @@ tile.studs.green.name=Green Studs tile.studs.red.name=Red Studs tile.studs.black.name=Black Studs +tile.panelling.white.name=White Panelling +tile.panelling.orange.name=Orange Panelling +tile.panelling.magenta.name=Magenta Panelling +tile.panelling.light_blue.name=Light Blue Panelling +tile.panelling.yellow.name=Yellow Panelling +tile.panelling.lime.name=Lime Panelling +tile.panelling.pink.name=Pink Panelling +tile.panelling.gray.name=Gray Panelling +tile.panelling.light_gray.name=Light Gray Panelling +tile.panelling.cyan.name=Cyan Panelling +tile.panelling.purple.name=Purple Panelling +tile.panelling.blue.name=Blue Panelling +tile.panelling.brown.name=Brown Panelling +tile.panelling.green.name=Green Panelling +tile.panelling.red.name=Red Panelling +tile.panelling.black.name=Black Panelling + # Lamps(ON) tile.gregtech_lamp.white.name=White Lamp tile.gregtech_lamp.orange.name=Orange Lamp @@ -2715,6 +2798,11 @@ tile.battery_block.tooltip_empty=For filling space in your Power Substation tile.long_distance_item_pipeline.name=Long Distance Item Pipe tile.long_distance_fluid_pipeline.name=Long Distance Fluid Pipe +# Nuclear Blocks +tile.nuclear_casing.spent_fuel_casing.name=Spent Fuel Casing +tile.nuclear_casing.gas_centrifuge_heater.name=Gas Centrifuge Heater +tile.gas_centrifuge_casing.gas_centrifuge_column.name=Gas Centrifuge Column + # Creative tabs itemGroup.gregtech.main=GregTech itemGroup.gregtech.machines=Machines (GT) @@ -4892,6 +4980,16 @@ metaitem.cover.digital.mode.fluid.enabled=Fluid Mode enabled gregtech.machine.monitor_screen.name=Monitor Screen +gregtech.machine.fission_reactor.name=Fission Reactor +gregtech.machine.fission_reactor.tooltip.1=Check preview for allowed shapes. +gregtech.machine.fission_reactor.tooltip.2=§cMay meltdown/explode if the temperature/pressure gets too high! +gregtech.machine.fission_reactor.tooltip.3=Please read the JEI info page! + + +gregtech.machine.heat_exchanger.name=Heat Exchanger +gregtech.machine.spent_fuel_pool.name=Spent Fuel Pool +gregtech.machine.gas_centrifuge.name=Gas Centrifuge + # Multiblock Tooltips gregtech.machine.primitive_water_pump.tooltip=Endervoir at Home @@ -4931,6 +5029,8 @@ gregtech.machine.fluid_drilling_rig.hv.tooltip=Does not perform Fracking gregtech.machine.fluid_drilling_rig.ev.tooltip=Well Drainer gregtech.machine.cleanroom.tooltip=Keeping those pesky particles out gregtech.machine.charcoal_pile.tooltip=Underground fuel bakery +gregtech.machine.fission_reactor.tooltip=Blowy-uppy yumyum generator +gregtech.machine.heat_exchanger.tooltip=Molecular hot potato player # Multiblock machine parts gregtech.machine.item_bus.import.tooltip=Item Input for Multiblocks @@ -5268,15 +5368,32 @@ gregtech.machine.laser_hatch.tooltip2=§cLaser Cables must be in a straight line gregtech.machine.fluid_tank.max_multiblock=Max Multiblock Size: %,dx%,dx%,d gregtech.machine.fluid_tank.fluid=Contains %s L of %s -gregtech.machine.me_export_fluid_hatch.name=ME Output Hatch +# ME Parts +gregtech.machine.me_import_item_bus.name=ME Input Bus +gregtech.machine.me.item_import.tooltip=Extracts specified items from the ME network +gregtech.machine.me_stocking_item_bus.name=ME Stocking Input Bus +gregtech.machine.me.stocking_item.tooltip=Retrieves items directly from the ME network +gregtech.machine.me.stocking_item.tooltip.2=Auto-Pull from ME mode will automatically stock the first 16 items in the ME system, updated every 5 seconds. +gregtech.machine.me_import_item_hatch.configs.tooltip=Keeps 16 item types in stock +gregtech.machine.me_import_fluid_hatch.name=ME Input Hatch +gregtech.machine.me.fluid_import.tooltip=Extracts specified fluids from ME network +gregtech.machine.me_stocking_fluid_hatch.name=ME Stocking Input Hatch +gregtech.machine.me.stocking_fluid.tooltip=Retrieves fluids directly from the ME network +gregtech.machine.me.stocking_fluid.tooltip.2=Auto-Pull from ME mode will automatically stock the first 16 fluids in the ME system, updated every 5 seconds. +gregtech.machine.me_import_fluid_hatch.configs.tooltip=Keeps 16 fluid types in stock gregtech.machine.me_export_item_bus.name=ME Output Bus -gregtech.machine.me_import_fluid_hatch.name=ME Stocking Input Hatch -gregtech.machine.me_import_item_bus.name=ME Stocking Input Bus -gregtech.machine.me.fluid_export.tooltip=Stores fluid directly into ME network. -gregtech.machine.me.item_export.tooltip=Stores item directly into ME network. -gregtech.machine.me.fluid_import.tooltip=Fetch fluids from ME network automatically. -gregtech.machine.me.item_import.tooltip=Fetch items from ME network automatically. -gregtech.machine.me.export.tooltip=It has infinite capacity before connecting to ME network. +gregtech.machine.me.item_export.tooltip=Stores items directly into the ME network +gregtech.machine.me.item_export.tooltip.2=Can cache an infinite amount of items +gregtech.machine.me_export_fluid_hatch.name=ME Output Hatch +gregtech.machine.me.fluid_export.tooltip=Stores fluids directly into the ME network +gregtech.machine.me.fluid_export.tooltip.2=Can cache an infinite amount of fluid +gregtech.machine.me.stocking_auto_pull_enabled=Auto-Pull Enabled +gregtech.machine.me.stocking_auto_pull_disabled=Auto-Pull Disabled +gregtech.machine.me.copy_paste.tooltip=Left-click with Data Stick to copy settings, right-click to apply +gregtech.machine.me.import_copy_settings=Saved settings to Data Stick +gregtech.machine.me.import_paste_settings=Applied settings from Data Stick +gregtech.machine.me.item_import.data_stick.name=§oME Input Bus Configuration Data +gregtech.machine.me.fluid_import.data_stick.name=§oME Input Hatch Configuration Data # Universal tooltips gregtech.universal.tooltip.voltage_in=§aVoltage IN: §f%,d EU/t (%s§f) @@ -5327,7 +5444,9 @@ gregtech.recipe.duration=Duration: %s secs gregtech.recipe.amperage=Amperage: %,d gregtech.recipe.not_consumed=Does not get consumed in the process gregtech.recipe.chance=Chance: %s%% +%s%%/tier +gregtech.recipe.chance_no_boost=Chance: %s%% gregtech.recipe.chance_logic=Chance: %s%% +%s%%/tier (%s) +gregtech.recipe.chance_logic_no_boost=Chance: %s%% (%s) gregtech.chance_logic.or=OR gregtech.chance_logic.and=AND gregtech.chance_logic.xor=XOR @@ -5336,6 +5455,7 @@ gregtech.recipe.temperature=Temperature: %,dK (%s) gregtech.recipe.explosive=Explosive: %s gregtech.recipe.eu_to_start=Energy To Start: %sEU gregtech.recipe.dimensions=Dimensions: %s +gregtech.recipe.dimensions_blocked=Blocked Dimensions: %s gregtech.recipe.cleanroom=Requires %s gregtech.recipe.cleanroom.display_name=Cleanroom gregtech.recipe.cleanroom_sterile.display_name=Sterile Cleanroom @@ -5417,10 +5537,27 @@ gregtech.gui.me_network.offline=Network Status: §4Offline§r gregtech.gui.waiting_list=Sending Queue: gregtech.gui.config_slot=§fConfig Slot§r gregtech.gui.config_slot.set=§7Click to §bset/select§7 config slot.§r +gregtech.gui.config_slot.set_only=§7Click to §bset§7 config slot.§r gregtech.gui.config_slot.scroll=§7Scroll wheel to §achange§7 config amount.§r gregtech.gui.config_slot.remove=§7Right click to §4clear§7 config slot.§r +gregtech.gui.config_slot.auto_pull_managed=§4Disabled:§7 Managed by Auto-Pull +gregtech.gui.me_bus.extra_slot=Extra Slot/n§7Put extra items for recipes here, like Molds or Lenses +gregtech.gui.me_bus.auto_pull_button=Click to toggle automatic item pulling from ME gregtech.gui.alarm.radius=Radius: +gregtech.gui.fission.control_rod_insertion=Control rod insertion: %d +gregtech.gui.fission.coolant_flow=Coolant flow rate: %d L +gregtech.gui.fission.temperature=Temperature: %.3f K +gregtech.gui.fission.pressure=Pressure: %.3f Pa +gregtech.gui.fission.power=Power: %.3f MW / %.3f MW +gregtech.gui.fission.k_eff=K eff: %f + +gregtech.gui.fission.lock.locked=Reactor locked & active! +gregtech.gui.fission.lock.unlocked=Reactor not active +gregtech.gui.fission.lock.should_lock=Activating... +gregtech.gui.fission.lock.missing_inputs=A hatch is blocked/empty! +gregtech.gui.fission.lock.missing_fuel=There is no fuel! +gregtech.gui.fission.lock.invalid_component=Erm, what the flip? Check your log file ore.spawnlocation.name=Ore Spawn Information gregtech.jei.ore.surface_rock_1=Surface Rocks with this material denote vein spawn locations. @@ -5675,8 +5812,10 @@ gregtech.multiblock.computation.not_enough_computation=Machine needs more comput gregtech.multiblock.power_substation.stored=Stored: %s gregtech.multiblock.power_substation.capacity=Capacity: %s gregtech.multiblock.power_substation.passive_drain=Passive Drain: %s -gregtech.multiblock.power_substation.average_io=Avg. I/O: %s -gregtech.multiblock.power_substation.average_io_hover=The average change in energy of the Power Substation's internal energy bank +gregtech.multiblock.power_substation.average_in=Avg. EU IN: %s +gregtech.multiblock.power_substation.average_out=Avg. EU OUT: %s +gregtech.multiblock.power_substation.average_in_hover=The average EU/t input into the Power Substation's internal energy bank +gregtech.multiblock.power_substation.average_out_hover=The average EU/t output from the Power Substation's internal energy bank, both passive loss and outputs gregtech.multiblock.power_substation.time_to_fill=Time to fill: %s gregtech.multiblock.power_substation.time_to_drain=Time to drain: %s gregtech.multiblock.power_substation.time_seconds=%s Seconds diff --git a/src/main/resources/assets/gregtech/lang/zh_cn.lang b/src/main/resources/assets/gregtech/lang/zh_cn.lang index 88906474bcf..67437657210 100644 --- a/src/main/resources/assets/gregtech/lang/zh_cn.lang +++ b/src/main/resources/assets/gregtech/lang/zh_cn.lang @@ -112,7 +112,7 @@ gregtech.waila.progress_computation=计算进度:%s / %s gregtech.multiblock.title=多方块结构 gregtech.multiblock.primitive_blast_furnace.bronze.description=土高炉是(PBF)是个多方块结构。尽管它不是很快,却能在游戏前期为你的发展提供钢材。 -gregtech.multiblock.coke_oven.description=焦炉是个多方块结构,用于在早期生产焦炭和杂酚油。无需燃料即可工作,内部至多可容纳32桶杂酚油。其存储可通过焦炉仓进行访问。 +gregtech.multiblock.coke_oven.description=焦炉是一种多方块结构,用于在早期生产焦煤和杂酚油,无需燃料即可工作,内部至多可容纳 32 桶杂酚油。其存储可通过焦炉仓进行访问。 gregtech.multiblock.vacuum_freezer.description=真空冷冻机是个多方块结构,主要用于热锭冷却。此外,它还可以冻结水等其他物质。 gregtech.multiblock.implosion_compressor.description=聚爆压缩机是个多方块结构,能够借助炸药将宝石粉转化为相应的宝石。 gregtech.multiblock.pyrolyse_oven.description=热解炉是种用于将原木处理为木炭、杂酚油、灰烬或重油的多方块结构。 @@ -531,7 +531,7 @@ metaitem.tool.datamodule.name=数据模块 metaitem.tool.datamodule.tooltip=超复杂数据存储/n§c只能用数据库读取 metaitem.circuit.integrated.name=编程电路 metaitem.circuit.integrated.tooltip=右击以打开配置界面/n/n手持并潜行右击带有编程电路槽位的机器可应用相应配置。/n -metaitem.circuit.integrated.gui=编程电路配置 +metaitem.circuit.integrated.gui=电路配置 metaitem.circuit.integrated.jei_description=JEI将仅显示匹配当前编程电路配置的配方。\n\n在编程电路配置界面中调整配置以查看对应配方。 item.glass.lens=玻璃透镜(白色) @@ -852,7 +852,7 @@ metaitem.cover.item.voiding.advanced.tooltip=作§f覆盖板§7时允许按数 metaitem.cover.storage.name=存储覆盖板 metaitem.cover.storage.tooltip=给零碎的小玩意准备的小型存储空间 metaitem.cover.maintenance.detector.name=维护需求覆盖板 -metaitem.cover.maintenance.detector.tooltip=作§f覆盖板§7时在机器§f需要维护§7输出红石信号。 +metaitem.cover.maintenance.detector.tooltip=作§f覆盖板§7时在机器§f需要维护§7时发出红石信号。 metaitem.cover.facade.name=%s伪装板 metaitem.cover.facade.tooltip=可作为§f覆盖板§7加装装饰性套壳。 @@ -924,7 +924,7 @@ metaitem.wooden_form.brick.name=木制砖模具 item.gt.tool.replace_tool_head=在合成栏用新的工具头替换 item.gt.tool.usable_as=可用作:§f%s -item.gt.tool.behavior.silk_ice=§b切冰利刃:§f精准采集冰 +item.gt.tool.behavior.silk_ice=§b切冰利刃:§f精准采集冰块 item.gt.tool.behavior.torch_place=§e洞窟探客:§f右击可放置火把 item.gt.tool.behavior.tree_felling=§4伐木好手:§f一次性砍下整棵树木 item.gt.tool.behavior.shield_disable=§c野兽蛮攻:§f破除盾牌 @@ -1008,6 +1008,9 @@ item.gt.tool.screwdriver_lv.name=%s螺丝刀(LV) item.gt.tool.screwdriver_lv.tooltip=§8调整覆盖板和机器 item.gt.tool.plunger.name=%s搋子 item.gt.tool.plunger.tooltip=§8从机器中抽除流体 +item.gt.tool.wire_cutter_lv.name=%s剪线钳(LV) +item.gt.tool.wire_cutter_hv.name=%s剪线钳(HV) +item.gt.tool.wire_cutter_iv.name=%s剪线钳(IV) item.gt.tool.tooltip.crafting_uses=§a合成耐久度:%s @@ -1175,7 +1178,7 @@ cover.filter.blacklist.disabled=白名单 cover.filter.blacklist.enabled=黑名单 cover.ore_dictionary_filter.title=矿物词典过滤 -cover.ore_dictionary_filter.info=§b接受复杂表达式/n§6a & b§r = 且/n§6a | b§r = 或/n§6a ^ b§r = 异或/n§6! abc§r = 非/n§6( abc )§r 表示组别/n§6*§r 表示通配(也即零或多个字符)/n§6?§r 表示任意一个字符/n§6()§r 匹配空条目(包括不带矿物词典的物品)/n在表达式开头添加 §6$c§r 可严格区分大小写/n§b使用范例:/n§6dust*Gold | (plate* & !*Double*)/n匹配双层板以外的板与包括小撮、小堆在内的所有金粉 +cover.ore_dictionary_filter.info=§b接受复杂表达式/n§6a & b§r = 且/n§6a | b§r = 或/n§6a ^ b§r = 异或/n§6! abc§r = 非/n§6( abc )§r 表示组别/n§6*§r 表示通配(也即零或多个字符)/n§6?§r 表示任意一个字符/n§6()§r 匹配空条目(包括不带矿物词典的物品)/n在表达式开头添加 §b使用范例:/n§6dust*Gold | (plate* & !*Double*)/n匹配双层板以外的板与包括小撮、小堆在内的所有金粉 cover.ore_dictionary_filter.test_slot.info=放入一件物品以测试是否匹配过滤表达式 cover.ore_dictionary_filter.test_slot.matches=§a* %s cover.ore_dictionary_filter.test_slot.matches_not=§c* %s @@ -1186,6 +1189,10 @@ cover.ore_dictionary_filter.status.err_warn=§c%s个错误、%s个警告 cover.ore_dictionary_filter.status.warn=§7%s个警告 cover.ore_dictionary_filter.status.no_issues=§a无问题 cover.ore_dictionary_filter.status.explain=矿物过滤说明: +cover.ore_dictionary_filter.button.case_sensitive.disabled=匹配大小写 +cover.ore_dictionary_filter.button.case_sensitive.enabled=忽略大小写 +cover.ore_dictionary_filter.button.match_all.disabled=匹配物品的任一矿词条目 +cover.ore_dictionary_filter.button.match_all.enabled=匹配物品的所有矿词条目 cover.ore_dictionary_filter.preview.next=...接着是 cover.ore_dictionary_filter.preview.match='%s' @@ -1300,11 +1307,6 @@ cover.fluid_regulator.transfer_mode.description=§e任意传输§r - 在此模 cover.fluid_regulator.supply_exact=精确补给:%s cover.fluid_regulator.keep_exact=保持补给:%s -cover.machine_controller.title=机器控制设定 -cover.machine_controller.normal=普通 -cover.machine_controller.inverted=反相 -cover.machine_controller.inverted.description=§e普通§r - 该模式下的覆盖板需要比设定强度小的红石信号来触发/n§e反相§r - 该模式下的覆盖板需要比设定强度大的红石信号来触发 -cover.machine_controller.redstone=最小红石信号强度:%,d cover.machine_controller.mode.machine=控制目标:机器 cover.machine_controller.mode.cover_up=控制目标:覆盖板(顶面) cover.machine_controller.mode.cover_down=控制目标:覆盖板(底面) @@ -1312,6 +1314,12 @@ cover.machine_controller.mode.cover_south=控制目标:覆盖板(南面) cover.machine_controller.mode.cover_north=控制目标:覆盖板(北面) cover.machine_controller.mode.cover_east=控制目标:覆盖板(东面) cover.machine_controller.mode.cover_west=控制目标:覆盖板(西面) +cover.machine_controller.this_cover=§c此覆盖板 +cover.machine_controller.cover_not_controllable=§c不可控制的覆盖板 +cover.machine_controller.machine_not_controllable=§c不可控制的机器 +cover.machine_controller.control=控制: +cover.machine_controller.enable_with_redstone=接收红石信号时开启 +cover.machine_controller.disable_with_redstone=接收红石信号时关闭 cover.ender_fluid_link.title=末影流体连接 cover.ender_fluid_link.iomode.enabled=已启用I/O @@ -1356,9 +1364,9 @@ item.material.oreprefix.oreBasalt=玄武岩%s矿石 item.material.oreprefix.oreSand=沙子%s矿石 item.material.oreprefix.oreRedSand=红沙%s矿石 item.material.oreprefix.oreNetherrack=地狱岩%s矿石 -item.material.oreprefix.oreNether=下界%s矿石 +item.material.oreprefix.oreNether=地狱岩%s矿石 item.material.oreprefix.oreEndstone=末地石%s矿石 -item.material.oreprefix.oreEnd=末地%s矿石 +item.material.oreprefix.oreEnd=末地石%s矿石 item.material.oreprefix.ore=%s矿石 item.material.oreprefix.oreGranite=花岗岩%s矿石 item.material.oreprefix.oreDiorite=闪长岩%s矿石 @@ -1645,7 +1653,7 @@ gregtech.material.rose_gold=玫瑰金 gregtech.material.black_bronze=黑青铜 gregtech.material.bismuth_bronze=铋青铜 gregtech.material.biotite=黑云母 -gregtech.material.powellite=钼钨钙矿 +gregtech.material.powellite=钼钙矿 gregtech.material.pyrite=黄铁矿 gregtech.material.pyrolusite=软锰矿 gregtech.material.pyrope=镁铝榴石 @@ -2343,6 +2351,17 @@ tile.treated_wood_fence.name=防腐木栅栏 tile.rubber_wood_fence_gate.name=橡胶木栅栏门 tile.treated_wood_fence_gate.name=防腐木栅栏门 +tile.gt_explosive.breaking_tooltip=破坏它会引爆火药,潜行挖掘以重新拾取 +tile.gt_explosive.lighting_tooltip=无法用红石信号引爆 + +tile.powderbarrel.name=火药桶 +tile.powderbarrel.drops_tooltip=爆炸范围略大于TNT,所有被摧毁的方块都会掉落 +entity.Powderbarrel.name=火药桶 + +tile.itnt.name=工业TNT +tile.itnt.drops_tooltip=爆炸范围比TNT大得多,所有被摧毁的方块都会掉落 +entity.ITNT.name=工业TNT + tile.brittle_charcoal.name=脆木炭块 tile.brittle_charcoal.tooltip.1=产自木炭堆点火器。 tile.brittle_charcoal.tooltip.2=采掘可掉落木炭。 @@ -2908,9 +2927,9 @@ gregtech.machine.steam_hammer_bronze.tooltip=锤锻机器 gregtech.machine.steam_hammer_steel.name=高压蒸汽锻造锤 gregtech.machine.steam_hammer_steel.tooltip=锤锻机器 gregtech.machine.steam_furnace_bronze.name=蒸汽熔炉 -gregtech.machine.steam_furnace_bronze.tooltip=利用蒸汽来熔炼物品 +gregtech.machine.steam_furnace_bronze.tooltip=利用蒸汽冶炼物品 gregtech.machine.steam_furnace_steel.name=高压蒸汽熔炉 -gregtech.machine.steam_furnace_steel.tooltip=利用蒸汽来熔炼物品 +gregtech.machine.steam_furnace_steel.tooltip=利用蒸汽冶炼物品 gregtech.machine.steam_alloy_smelter_bronze.name=蒸汽合金炉 gregtech.machine.steam_alloy_smelter_bronze.tooltip=熔合冶炼炉 gregtech.machine.steam_alloy_smelter_steel.name=高压合金炉 @@ -2989,9 +3008,9 @@ gregtech.machine.macerator.lv.tooltip=粉碎矿石 gregtech.machine.macerator.mv.name=进阶研磨机 gregtech.machine.macerator.mv.tooltip=粉碎矿石 gregtech.machine.macerator.hv.name=进阶研磨机 II -gregtech.machine.macerator.hv.tooltip=粉碎矿石,且能产出副产物 +gregtech.machine.macerator.hv.tooltip=粉碎矿石并获得副产物 gregtech.machine.macerator.ev.name=进阶研磨机 III -gregtech.machine.macerator.ev.tooltip=粉碎矿石,且能产出副产物 +gregtech.machine.macerator.ev.tooltip=粉碎矿石并获得副产物 gregtech.machine.macerator.iv.name=精英研磨机 gregtech.machine.macerator.iv.tooltip=全自动破壁机 9001 gregtech.machine.macerator.luv.name=精英研磨机 II @@ -3049,11 +3068,11 @@ gregtech.machine.arc_furnace.hv.tooltip=谁还要高炉啊? gregtech.machine.arc_furnace.ev.name=进阶电弧炉 III gregtech.machine.arc_furnace.ev.tooltip=谁还要高炉啊? gregtech.machine.arc_furnace.iv.name=精英电弧炉 -gregtech.machine.arc_furnace.iv.tooltip=解体加热器 +gregtech.machine.arc_furnace.iv.tooltip=放电加热器 gregtech.machine.arc_furnace.luv.name=精英电弧炉 II -gregtech.machine.arc_furnace.luv.tooltip=解体加热器 +gregtech.machine.arc_furnace.luv.tooltip=放电加热器 gregtech.machine.arc_furnace.zpm.name=精英电弧炉 III -gregtech.machine.arc_furnace.zpm.tooltip=解体加热器 +gregtech.machine.arc_furnace.zpm.tooltip=放电加热器 gregtech.machine.arc_furnace.uv.name=终极电弧炉 gregtech.machine.arc_furnace.uv.tooltip=短路加热器 gregtech.machine.arc_furnace.uhv.name=史诗电弧炉 @@ -3275,23 +3294,23 @@ gregtech.machine.chemical_reactor.hv.tooltip=使化学品相互反应 gregtech.machine.chemical_reactor.ev.name=进阶化学反应釜 III gregtech.machine.chemical_reactor.ev.tooltip=使化学品相互反应 gregtech.machine.chemical_reactor.iv.name=精英化学反应釜 -gregtech.machine.chemical_reactor.iv.tooltip=化学反应操作仪 +gregtech.machine.chemical_reactor.iv.tooltip=化学表演艺术家 gregtech.machine.chemical_reactor.luv.name=精英化学反应釜 II -gregtech.machine.chemical_reactor.luv.tooltip=化学反应操作仪 +gregtech.machine.chemical_reactor.luv.tooltip=化学表演艺术家 gregtech.machine.chemical_reactor.zpm.name=精英化学反应釜 III -gregtech.machine.chemical_reactor.zpm.tooltip=化学反应操作仪 +gregtech.machine.chemical_reactor.zpm.tooltip=化学表演艺术家 gregtech.machine.chemical_reactor.uv.name=终极化学反应釜 -gregtech.machine.chemical_reactor.uv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uv.tooltip=反应催化器 gregtech.machine.chemical_reactor.uhv.name=史诗化学反应釜 -gregtech.machine.chemical_reactor.uhv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uhv.tooltip=反应催化器 gregtech.machine.chemical_reactor.uev.name=史诗化学反应釜 II -gregtech.machine.chemical_reactor.uev.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uev.tooltip=反应催化器 gregtech.machine.chemical_reactor.uiv.name=史诗化学反应釜 III -gregtech.machine.chemical_reactor.uiv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uiv.tooltip=反应催化器 gregtech.machine.chemical_reactor.uxv.name=史诗化学反应釜 IV -gregtech.machine.chemical_reactor.uxv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uxv.tooltip=反应催化器 gregtech.machine.chemical_reactor.opv.name=传奇化学反应釜 -gregtech.machine.chemical_reactor.opv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.opv.tooltip=反应催化器 # Compressor gregtech.machine.compressor.lv.name=基础压缩机 @@ -3337,17 +3356,17 @@ gregtech.machine.cutter.luv.tooltip=物质切削器 gregtech.machine.cutter.zpm.name=精英切割机 III gregtech.machine.cutter.zpm.tooltip=物质切削器 gregtech.machine.cutter.uv.name=终极切割机 -gregtech.machine.cutter.uv.tooltip=物品对象分割者 +gregtech.machine.cutter.uv.tooltip=对象分割者 gregtech.machine.cutter.uhv.name=史诗切割机 -gregtech.machine.cutter.uhv.tooltip=物品对象分割者 +gregtech.machine.cutter.uhv.tooltip=对象分割者 gregtech.machine.cutter.uev.name=史诗切割机 II -gregtech.machine.cutter.uev.tooltip=物品对象分割者 +gregtech.machine.cutter.uev.tooltip=对象分割者 gregtech.machine.cutter.uiv.name=史诗切割机 III -gregtech.machine.cutter.uiv.tooltip=物品对象分割者 +gregtech.machine.cutter.uiv.tooltip=对象分割者 gregtech.machine.cutter.uxv.name=史诗切割机 IV -gregtech.machine.cutter.uxv.tooltip=物品对象分割者 +gregtech.machine.cutter.uxv.tooltip=对象分割者 gregtech.machine.cutter.opv.name=传奇切割机 -gregtech.machine.cutter.opv.tooltip=物品对象分割者 +gregtech.machine.cutter.opv.tooltip=对象分割者 # Distillery gregtech.machine.distillery.lv.name=基础蒸馏室 @@ -3365,17 +3384,17 @@ gregtech.machine.distillery.luv.tooltip=凝结物质分离器 gregtech.machine.distillery.zpm.name=精英蒸馏室 III gregtech.machine.distillery.zpm.tooltip=凝结物质分离器 gregtech.machine.distillery.uv.name=终极蒸馏室 -gregtech.machine.distillery.uv.tooltip=少数分流者 +gregtech.machine.distillery.uv.tooltip=馏分分离器 gregtech.machine.distillery.uhv.name=史诗蒸馏室 -gregtech.machine.distillery.uhv.tooltip=少数分流者 +gregtech.machine.distillery.uhv.tooltip=馏分分离器 gregtech.machine.distillery.uev.name=史诗蒸馏室 II -gregtech.machine.distillery.uev.tooltip=少数分流者 +gregtech.machine.distillery.uev.tooltip=馏分分离器 gregtech.machine.distillery.uiv.name=史诗蒸馏室 III -gregtech.machine.distillery.uiv.tooltip=少数分流者 +gregtech.machine.distillery.uiv.tooltip=馏分分离器 gregtech.machine.distillery.uxv.name=史诗蒸馏室 IV -gregtech.machine.distillery.uxv.tooltip=少数分流者 +gregtech.machine.distillery.uxv.tooltip=馏分分离器 gregtech.machine.distillery.opv.name=传奇蒸馏室 -gregtech.machine.distillery.opv.tooltip=少数分流者 +gregtech.machine.distillery.opv.tooltip=馏分分离器 # Electrolyzer gregtech.machine.electrolyzer.lv.name=基础电解机 @@ -3435,13 +3454,13 @@ gregtech.machine.electromagnetic_separator.opv.tooltip=电磁场驱离装置 # Extractor gregtech.machine.extractor.lv.name=基础提取机 -gregtech.machine.extractor.lv.tooltip=毁灭级榨干机 - D123 +gregtech.machine.extractor.lv.tooltip=毁灭级榨汁机 - D123 gregtech.machine.extractor.mv.name=进阶提取机 -gregtech.machine.extractor.mv.tooltip=毁灭级榨干机 - D123 +gregtech.machine.extractor.mv.tooltip=毁灭级榨汁机 - D123 gregtech.machine.extractor.hv.name=进阶提取机 II -gregtech.machine.extractor.hv.tooltip=毁灭级榨干机 - D123 +gregtech.machine.extractor.hv.tooltip=毁灭级榨汁机 - D123 gregtech.machine.extractor.ev.name=进阶提取机 III -gregtech.machine.extractor.ev.tooltip=毁灭级榨干机 - D123 +gregtech.machine.extractor.ev.tooltip=毁灭级榨汁机 - D123 gregtech.machine.extractor.iv.name=精英提取机 gregtech.machine.extractor.iv.tooltip=真空提炼机 gregtech.machine.extractor.luv.name=精英提取机 II @@ -3463,13 +3482,13 @@ gregtech.machine.extractor.opv.tooltip=液化吸取者 # Extruder gregtech.machine.extruder.lv.name=基础压模器 -gregtech.machine.extruder.lv.tooltip=通用的金属处理机器 +gregtech.machine.extruder.lv.tooltip=通用型金属加工器 gregtech.machine.extruder.mv.name=进阶压模器 -gregtech.machine.extruder.mv.tooltip=通用的金属处理机器 +gregtech.machine.extruder.mv.tooltip=通用型金属加工器 gregtech.machine.extruder.hv.name=进阶压模器 II -gregtech.machine.extruder.hv.tooltip=通用的金属处理机器 +gregtech.machine.extruder.hv.tooltip=通用型金属加工器 gregtech.machine.extruder.ev.name=进阶压模器 III -gregtech.machine.extruder.ev.tooltip=通用的金属处理机器 +gregtech.machine.extruder.ev.tooltip=通用型金属加工器 gregtech.machine.extruder.iv.name=精英压模器 gregtech.machine.extruder.iv.tooltip=材料压出器 gregtech.machine.extruder.luv.name=精英压模器 II @@ -3498,11 +3517,11 @@ gregtech.machine.fermenter.hv.tooltip=发酵流体 gregtech.machine.fermenter.ev.name=进阶发酵槽 III gregtech.machine.fermenter.ev.tooltip=发酵流体 gregtech.machine.fermenter.iv.name=精英发酵槽 -gregtech.machine.fermenter.iv.tooltip=发酵催促器 +gregtech.machine.fermenter.iv.tooltip=发酵加速器 gregtech.machine.fermenter.luv.name=精英发酵槽 II -gregtech.machine.fermenter.luv.tooltip=发酵催促器 +gregtech.machine.fermenter.luv.tooltip=发酵加速器 gregtech.machine.fermenter.zpm.name=精英发酵槽 III -gregtech.machine.fermenter.zpm.tooltip=发酵催促器 +gregtech.machine.fermenter.zpm.tooltip=发酵加速器 gregtech.machine.fermenter.uv.name=终极发酵槽 gregtech.machine.fermenter.uv.tooltip=呼吸控制器 gregtech.machine.fermenter.uhv.name=史诗发酵槽 @@ -3518,41 +3537,41 @@ gregtech.machine.fermenter.opv.tooltip=呼吸控制器 # Fluid Heater gregtech.machine.fluid_heater.lv.name=基础流体加热器 -gregtech.machine.fluid_heater.lv.tooltip=加热流体 +gregtech.machine.fluid_heater.lv.tooltip=加热你的流体 gregtech.machine.fluid_heater.mv.name=进阶流体加热器 -gregtech.machine.fluid_heater.mv.tooltip=加热流体 +gregtech.machine.fluid_heater.mv.tooltip=加热你的流体 gregtech.machine.fluid_heater.hv.name=进阶流体加热器 II -gregtech.machine.fluid_heater.hv.tooltip=加热流体 +gregtech.machine.fluid_heater.hv.tooltip=加热你的流体 gregtech.machine.fluid_heater.ev.name=进阶流体加热器 III -gregtech.machine.fluid_heater.ev.tooltip=加热流体 +gregtech.machine.fluid_heater.ev.tooltip=加热你的流体 gregtech.machine.fluid_heater.iv.name=精英流体加热器 -gregtech.machine.fluid_heater.iv.tooltip=热量注入器 +gregtech.machine.fluid_heater.iv.tooltip=热量灌注器 gregtech.machine.fluid_heater.luv.name=精英流体加热器 II -gregtech.machine.fluid_heater.luv.tooltip=热量注入器 +gregtech.machine.fluid_heater.luv.tooltip=热量灌注器 gregtech.machine.fluid_heater.zpm.name=精英流体加热器 III -gregtech.machine.fluid_heater.zpm.tooltip=热量注入器 +gregtech.machine.fluid_heater.zpm.tooltip=热量灌注器 gregtech.machine.fluid_heater.uv.name=终极流体加热器 -gregtech.machine.fluid_heater.uv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uv.tooltip=热量灌输器 gregtech.machine.fluid_heater.uhv.name=史诗流体加热器 -gregtech.machine.fluid_heater.uhv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uhv.tooltip=热量灌输器 gregtech.machine.fluid_heater.uev.name=史诗流体加热器 II -gregtech.machine.fluid_heater.uev.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uev.tooltip=热量灌输器 gregtech.machine.fluid_heater.uiv.name=史诗流体加热器 III -gregtech.machine.fluid_heater.uiv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uiv.tooltip=热量灌输器 gregtech.machine.fluid_heater.uxv.name=史诗流体加热器 IV -gregtech.machine.fluid_heater.uxv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uxv.tooltip=热量灌输器 gregtech.machine.fluid_heater.opv.name=传奇流体加热器 -gregtech.machine.fluid_heater.opv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.opv.tooltip=热量灌输器 # Fluid Solidifier gregtech.machine.fluid_solidifier.lv.name=基础流体固化器 -gregtech.machine.fluid_solidifier.lv.tooltip=冷却液体并定型为固体 +gregtech.machine.fluid_solidifier.lv.tooltip=冷却液体形成固体 gregtech.machine.fluid_solidifier.mv.name=进阶流体固化器 -gregtech.machine.fluid_solidifier.mv.tooltip=冷却液体并定型为固体 +gregtech.machine.fluid_solidifier.mv.tooltip=冷却液体形成固体 gregtech.machine.fluid_solidifier.hv.name=进阶流体固化器 II -gregtech.machine.fluid_solidifier.hv.tooltip=冷却液体并定型为固体 +gregtech.machine.fluid_solidifier.hv.tooltip=冷却液体形成固体 gregtech.machine.fluid_solidifier.ev.name=进阶流体固化器 III -gregtech.machine.fluid_solidifier.ev.tooltip=冷却液体并定型为固体 +gregtech.machine.fluid_solidifier.ev.tooltip=冷却液体形成固体 gregtech.machine.fluid_solidifier.iv.name=精英流体固化器 gregtech.machine.fluid_solidifier.iv.tooltip=并不是制冰机 gregtech.machine.fluid_solidifier.luv.name=精英流体固化器 II @@ -3582,11 +3601,11 @@ gregtech.machine.forge_hammer.hv.tooltip=停,抡锤时间到! gregtech.machine.forge_hammer.ev.name=进阶锻造锤 III gregtech.machine.forge_hammer.ev.tooltip=停,抡锤时间到! gregtech.machine.forge_hammer.iv.name=精英锻造锤 -gregtech.machine.forge_hammer.iv.tooltip=板材锻造机 +gregtech.machine.forge_hammer.iv.tooltip=锻板机 gregtech.machine.forge_hammer.luv.name=精英锻造锤 II -gregtech.machine.forge_hammer.luv.tooltip=板材锻造机 +gregtech.machine.forge_hammer.luv.tooltip=锻板机 gregtech.machine.forge_hammer.zpm.name=精英锻造锤 III -gregtech.machine.forge_hammer.zpm.tooltip=板材锻造机 +gregtech.machine.forge_hammer.zpm.tooltip=锻板机 gregtech.machine.forge_hammer.uv.name=终极锻造锤 gregtech.machine.forge_hammer.uv.tooltip=冲击调制器 gregtech.machine.forge_hammer.uhv.name=史诗锻造锤 @@ -3602,13 +3621,13 @@ gregtech.machine.forge_hammer.opv.tooltip=冲击调制器 # Forming Press gregtech.machine.forming_press.lv.name=基础冲压机床 -gregtech.machine.forming_press.lv.tooltip=将印象压印为实际的存在 +gregtech.machine.forming_press.lv.tooltip=图像拓印者 gregtech.machine.forming_press.mv.name=进阶冲压机床 -gregtech.machine.forming_press.mv.tooltip=印象具现者 +gregtech.machine.forming_press.mv.tooltip=图像拓印者 gregtech.machine.forming_press.hv.name=进阶冲压机床 II -gregtech.machine.forming_press.hv.tooltip=印象具现者 +gregtech.machine.forming_press.hv.tooltip=图像拓印者 gregtech.machine.forming_press.ev.name=进阶冲压机床 III -gregtech.machine.forming_press.ev.tooltip=印象具现者 +gregtech.machine.forming_press.ev.tooltip=图像拓印者 gregtech.machine.forming_press.iv.name=精英冲压机床 gregtech.machine.forming_press.iv.tooltip=对象层化机 gregtech.machine.forming_press.luv.name=精英冲压机床 II @@ -3742,13 +3761,13 @@ gregtech.machine.packer.opv.tooltip=亚马逊仓库 # Polarizer gregtech.machine.polarizer.lv.name=基础两极磁化机 -gregtech.machine.polarizer.lv.tooltip=使磁体两极化 +gregtech.machine.polarizer.lv.tooltip=将你的磁体极化 gregtech.machine.polarizer.mv.name=进阶两极磁化机 -gregtech.machine.polarizer.mv.tooltip=使磁体两极化 +gregtech.machine.polarizer.mv.tooltip=将你的磁体极化 gregtech.machine.polarizer.hv.name=进阶两极磁化机 II -gregtech.machine.polarizer.hv.tooltip=使磁体两极化 +gregtech.machine.polarizer.hv.tooltip=将你的磁体极化 gregtech.machine.polarizer.ev.name=进阶两极磁化机 III -gregtech.machine.polarizer.ev.tooltip=使磁体两极化 +gregtech.machine.polarizer.ev.tooltip=将你的磁体极化 gregtech.machine.polarizer.iv.name=精英两极磁化机 gregtech.machine.polarizer.iv.tooltip=磁性引入机 gregtech.machine.polarizer.luv.name=精英两极磁化机 II @@ -3778,11 +3797,11 @@ gregtech.machine.laser_engraver.hv.tooltip=请勿直视激光 gregtech.machine.laser_engraver.ev.name=进阶精密激光蚀刻机 III gregtech.machine.laser_engraver.ev.tooltip=请勿直视激光 gregtech.machine.laser_engraver.iv.name=精英精密激光蚀刻机 -gregtech.machine.laser_engraver.iv.tooltip=蕴含着两百零四万瓦的能量 +gregtech.machine.laser_engraver.iv.tooltip=功率高达两百零四万瓦 gregtech.machine.laser_engraver.luv.name=精英精密激光蚀刻机 II -gregtech.machine.laser_engraver.luv.tooltip=蕴含着两百零四万瓦的能量 +gregtech.machine.laser_engraver.luv.tooltip=功率高达八百一十六万瓦 gregtech.machine.laser_engraver.zpm.name=精英精密激光蚀刻机 III -gregtech.machine.laser_engraver.zpm.tooltip=蕴含着两百零四万瓦的能量 +gregtech.machine.laser_engraver.zpm.tooltip=功率高达三千两百六十四万瓦 gregtech.machine.laser_engraver.uv.name=终极精密激光蚀刻机 gregtech.machine.laser_engraver.uv.tooltip=高精度光子加农炮 gregtech.machine.laser_engraver.uhv.name=史诗激光蚀刻机 @@ -3882,13 +3901,13 @@ gregtech.machine.wiremill.opv.tooltip=导线易形者 # Circuit Assembler gregtech.machine.circuit_assembler.lv.name=基础电路组装机 -gregtech.machine.circuit_assembler.lv.tooltip=一拿一放,东拣西装。 +gregtech.machine.circuit_assembler.lv.tooltip=一拿一放,东拣西装 gregtech.machine.circuit_assembler.mv.name=进阶电路组装机 -gregtech.machine.circuit_assembler.mv.tooltip=一拿一放,东拣西装。 +gregtech.machine.circuit_assembler.mv.tooltip=一拿一放,东拣西装 gregtech.machine.circuit_assembler.hv.name=进阶电路组装机 II -gregtech.machine.circuit_assembler.hv.tooltip=一拿一放,东拣西装。 +gregtech.machine.circuit_assembler.hv.tooltip=一拿一放,东拣西装 gregtech.machine.circuit_assembler.ev.name=进阶电路组装机 III -gregtech.machine.circuit_assembler.ev.tooltip=一拿一放,东拣西装。 +gregtech.machine.circuit_assembler.ev.tooltip=一拿一放,东拣西装 gregtech.machine.circuit_assembler.iv.name=精英电路组装机 gregtech.machine.circuit_assembler.iv.tooltip=电子厂 gregtech.machine.circuit_assembler.luv.name=精英电路组装机 II @@ -3896,17 +3915,17 @@ gregtech.machine.circuit_assembler.luv.tooltip=电子厂 gregtech.machine.circuit_assembler.zpm.name=精英电路组装机 III gregtech.machine.circuit_assembler.zpm.tooltip=电子厂 gregtech.machine.circuit_assembler.uv.name=终极电路组装机 -gregtech.machine.circuit_assembler.uv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uv.tooltip=计算机工厂 gregtech.machine.circuit_assembler.uhv.name=史诗电路组装机 -gregtech.machine.circuit_assembler.uhv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uhv.tooltip=计算机工厂 gregtech.machine.circuit_assembler.uev.name=史诗电路组装机 II -gregtech.machine.circuit_assembler.uev.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uev.tooltip=计算机工厂 gregtech.machine.circuit_assembler.uiv.name=史诗电路组装机 III -gregtech.machine.circuit_assembler.uiv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uiv.tooltip=计算机工厂 gregtech.machine.circuit_assembler.uxv.name=史诗电路组装机 IV -gregtech.machine.circuit_assembler.uxv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uxv.tooltip=计算机工厂 gregtech.machine.circuit_assembler.opv.name=传奇电路组装机 -gregtech.machine.circuit_assembler.opv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.opv.tooltip=计算机工厂 # Mass Fabricator gregtech.machine.mass_fabricator.lv.name=基础质量发生器 @@ -3918,11 +3937,11 @@ gregtech.machine.mass_fabricator.hv.tooltip=UU物质 = “质量” * “发生 gregtech.machine.mass_fabricator.ev.name=进阶质量发生器 III gregtech.machine.mass_fabricator.ev.tooltip=UU物质 = “质量” * “发生”的平方 gregtech.machine.mass_fabricator.iv.name=精英质量发生器 -gregtech.machine.mass_fabricator.iv.tooltip=创世工坊 +gregtech.machine.mass_fabricator.iv.tooltip=创世纪工厂 gregtech.machine.mass_fabricator.luv.name=精英质量发生器 II -gregtech.machine.mass_fabricator.luv.tooltip=创世工坊 +gregtech.machine.mass_fabricator.luv.tooltip=创世纪工厂 gregtech.machine.mass_fabricator.zpm.name=精英质量发生器 III -gregtech.machine.mass_fabricator.zpm.tooltip=创世工坊 +gregtech.machine.mass_fabricator.zpm.tooltip=创世纪工厂 gregtech.machine.mass_fabricator.uv.name=终极质量发生器 gregtech.machine.mass_fabricator.uv.tooltip=存在之源 gregtech.machine.mass_fabricator.uhv.name=史诗质量发生器 @@ -3938,13 +3957,13 @@ gregtech.machine.mass_fabricator.opv.tooltip=存在之源 # Replicator gregtech.machine.replicator.lv.name=基础复制机 -gregtech.machine.replicator.lv.tooltip=生产出至纯的元素 +gregtech.machine.replicator.lv.tooltip=生产最纯净的元素 gregtech.machine.replicator.mv.name=进阶复制机 -gregtech.machine.replicator.mv.tooltip=生产出至纯的元素 +gregtech.machine.replicator.mv.tooltip=生产最纯净的元素 gregtech.machine.replicator.hv.name=进阶复制机 II -gregtech.machine.replicator.hv.tooltip=生产出至纯的元素 +gregtech.machine.replicator.hv.tooltip=生产最纯净的元素 gregtech.machine.replicator.ev.name=进阶复制机 III -gregtech.machine.replicator.ev.tooltip=生产出至纯的元素 +gregtech.machine.replicator.ev.tooltip=生产最纯净的元素 gregtech.machine.replicator.iv.name=精英复制机 gregtech.machine.replicator.iv.tooltip=物质粘贴机 gregtech.machine.replicator.luv.name=精英复制机 II @@ -4146,7 +4165,7 @@ gregtech.machine.transformer.adjustable.opv.name=过载压高能变压器(§9O gregtech.machine.diode.message=电流吞吐上限:%s gregtech.machine.diode.tooltip_tool_usage=手持软锤右击以调节电流。 gregtech.machine.diode.tooltip_general=使能量作单向传输并限制电流 -gregtech.machine.diode.tooltip_starts_at=默认为§f1A§7,使用软锤来轮换电流设定 +gregtech.machine.diode.tooltip_starts_at=默认允许§f1A§r电流通行,使用软锤切换。 gregtech.machine.diode.ulv.name=超低压二极管(§8ULV§r) gregtech.machine.diode.lv.name=低压二极管(§7LV§r) @@ -4302,7 +4321,7 @@ gregtech.machine.quantum_tank.uv.name=量子缸 IV gregtech.machine.quantum_tank.uhv.name=量子缸 V #Buffers -gregtech.machine.buffer.tooltip=能够存储物品与流体的小型缓存器 +gregtech.machine.buffer.tooltip=用于存储物品和流体的小小缓冲器 gregtech.machine.buffer.lv.name=基础缓存器 gregtech.machine.buffer.mv.name=进阶缓存器 gregtech.machine.buffer.hv.name=进阶缓存器 II @@ -4320,31 +4339,31 @@ tile.hermetic_casing.hermetic_casing_uhv.name=密封机械方块 IX #Gas Collectors gregtech.machine.gas_collector.lv.name=基础集气室 -gregtech.machine.gas_collector.lv.tooltip=收集不同维度的空气中种类各异的气体 +gregtech.machine.gas_collector.lv.tooltip=依照维度从空气中收集种类各异的气体 gregtech.machine.gas_collector.mv.name=进阶集气室 -gregtech.machine.gas_collector.mv.tooltip=收集不同维度的空气中种类各异的气体 +gregtech.machine.gas_collector.mv.tooltip=依照维度从空气中收集种类各异的气体 gregtech.machine.gas_collector.hv.name=进阶集气室 II -gregtech.machine.gas_collector.hv.tooltip=收集不同维度的空气中种类各异的气体 +gregtech.machine.gas_collector.hv.tooltip=依照维度从空气中收集种类各异的气体 gregtech.machine.gas_collector.ev.name=进阶集气室 III -gregtech.machine.gas_collector.ev.tooltip=收集不同维度的空气中种类各异的气体 +gregtech.machine.gas_collector.ev.tooltip=依照维度从空气中收集种类各异的气体 gregtech.machine.gas_collector.iv.name=精英集气室 -gregtech.machine.gas_collector.iv.tooltip=收集不同维度的大气中种类各异的气体 +gregtech.machine.gas_collector.iv.tooltip=依照维度从大气层中收集种类各异的气体 gregtech.machine.gas_collector.luv.name=精英集气室 II -gregtech.machine.gas_collector.luv.tooltip=收集不同维度的大气中种类各异的气体 +gregtech.machine.gas_collector.luv.tooltip=依照维度从大气层中收集种类各异的气体 gregtech.machine.gas_collector.zpm.name=精英集气室 III -gregtech.machine.gas_collector.zpm.tooltip=收集不同维度的大气中种类各异的气体 +gregtech.machine.gas_collector.zpm.tooltip=依照维度从大气层中收集种类各异的气体 gregtech.machine.gas_collector.uv.name=终极集气室 -gregtech.machine.gas_collector.uv.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uv.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.uhv.name=史诗集气室 -gregtech.machine.gas_collector.uhv.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uhv.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.uev.name=史诗集气室 II -gregtech.machine.gas_collector.uev.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uev.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.uiv.name=史诗集气室 III -gregtech.machine.gas_collector.uiv.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uiv.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.uxv.name=史诗集气室 IV -gregtech.machine.gas_collector.uxv.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uxv.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.opv.name=传说集气室 -gregtech.machine.gas_collector.opv.tooltip=从宇宙中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.opv.tooltip=依照维度从宇宙中收集种类各异的气体 #Rock Breakers gregtech.machine.rock_breaker.lv.name=基础碎岩机 @@ -4362,17 +4381,17 @@ gregtech.machine.rock_breaker.luv.tooltip=岩浆冷却固化器 R-9200 gregtech.machine.rock_breaker.zpm.name=精英碎岩机 III gregtech.machine.rock_breaker.zpm.tooltip=岩浆冷却固化器 R-10200 gregtech.machine.rock_breaker.uv.name=终极碎岩机 -gregtech.machine.rock_breaker.uv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uv.tooltip=火山成型室 gregtech.machine.rock_breaker.uhv.name=史诗碎岩机 -gregtech.machine.rock_breaker.uhv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uhv.tooltip=火山成型室 gregtech.machine.rock_breaker.uev.name=史诗碎岩机 II -gregtech.machine.rock_breaker.uev.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uev.tooltip=火山成型室 gregtech.machine.rock_breaker.uiv.name=史诗碎岩机 III -gregtech.machine.rock_breaker.uiv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uiv.tooltip=火山成型室 gregtech.machine.rock_breaker.uxv.name=史诗碎岩机 IV -gregtech.machine.rock_breaker.uxv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uxv.tooltip=火山成型室 gregtech.machine.rock_breaker.opv.name=传奇碎岩机 -gregtech.machine.rock_breaker.opv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.opv.tooltip=火山成型室 #Fisher gregtech.machine.fisher.lv.name=基础捕鱼机 @@ -4709,7 +4728,7 @@ gregtech.machine.large_chemical_reactor.name=大型化学反应釜 gregtech.machine.large_combustion_engine.name=大型内燃引擎 gregtech.machine.extreme_combustion_engine.name=极限内燃引擎 gregtech.machine.large_combustion_engine.tooltip.boost_regular=提供§f20 L/s§7的氧气,并消耗§f双倍§7燃料以产生高达§f%s§7 EU/t的功率。 -gregtech.machine.large_combustion_engine.tooltip.boost_extreme=提供§f80 L/s§7的液氧,并消耗§f双倍§7燃料以产生高达§f%s§7 EU/t的功率。 +gregtech.machine.large_combustion_engine.tooltip.boost_extreme=提供§f80L/s§7的液态氧,并消耗§f双倍§7燃料以产生高达§f%s§7EU/t的功率。 gregtech.machine.large_turbine.steam.name=大型蒸汽涡轮 gregtech.machine.large_turbine.gas.name=大型燃气涡轮 @@ -4740,7 +4759,7 @@ gregtech.machine.large_miner.ev.name=基础采矿场 gregtech.machine.large_miner.iv.name=进阶采矿场 gregtech.machine.large_miner.luv.name=进阶采矿场 II gregtech.machine.miner.multi.modes=具有精准采集模式与区块对齐模式。 -gregtech.machine.miner.multi.production=粉碎矿石的产出量为§f研磨机§7的§f3倍§7。 +gregtech.machine.miner.multi.production=产出§f研磨机§7§f3x§7倍的粉碎矿石。 gregtech.machine.miner.fluid_usage=每tick消耗§f%,d L§7的§f%s§7,超频时翻倍。 gregtech.machine.miner.multi.description=一台工作范围极广的多方块采矿机,能够提供巨量矿石。 gregtech.machine.miner.multi.needsfluid=钻井液不足! @@ -4804,7 +4823,7 @@ gregtech.machine.power_substation.tooltip3=最多容许§f%d层电容§7。 gregtech.machine.power_substation.tooltip4=每§f24小时§7损失相当于总容量的§f1%%§7的能量。 gregtech.machine.power_substation.tooltip5=每个电容的损失上限为§f%,d EU/t§7。 gregtech.machine.power_substation.tooltip6=可以使用 -gregtech.machine.power_substation.tooltip6.5= 激光仓§7。 +gregtech.machine.power_substation.tooltip6.5=激光仓§7。 gregtech.multiblock.power_substation.description=蓄能变电站是一个用于储存大量能量的多方块结构,它最多可以容纳18层电容,每层都必须填充完整,这意味着你可以用空电容来填充空间。 gregtech.machine.active_transformer.name=有源变压器 @@ -4933,7 +4952,6 @@ gregtech.machine.item_bus.export.uhv.name=§4UHV§r输出总线 gregtech.bus.collapse_true=已启用物品堆叠自动合并 gregtech.bus.collapse_false=已禁用物品堆叠自动合并 -gregtech.bus.collapse.error=总线位于已成型的多方块结构后方可进行该操作 gregtech.machine.fluid_hatch.import.tooltip=为多方块结构输入流体 @@ -5239,15 +5257,27 @@ gregtech.machine.laser_hatch.tooltip2=§c激光传导线缆必须直线摆放! gregtech.machine.fluid_tank.max_multiblock=多方块结构最大尺寸:%,dx%,dx%,d gregtech.machine.fluid_tank.fluid=含有%s mB%s -gregtech.machine.me_export_fluid_hatch.name=ME输出仓 +# ME Parts +gregtech.machine.me_import_item_bus.name=ME输入总线 +gregtech.machine.me.item_import.tooltip=从ME网络提取指定物品 +gregtech.machine.me_stocking_item_bus.name=ME库存输入总线 +gregtech.machine.me.stocking_item.tooltip=直接从ME网络抽取物品 +gregtech.machine.me.stocking_item.tooltip.2=ME自动拉取模式将自动标记ME网络中的前16种物品,每5秒更新一次。 +gregtech.machine.me_import_item_hatch.configs.tooltip=可标记16种物品 +gregtech.machine.me_import_fluid_hatch.name=ME输入仓 +gregtech.machine.me.fluid_import.tooltip=从ME网络提取指定流体 +gregtech.machine.me_stocking_fluid_hatch.name=ME库存输入仓 +gregtech.machine.me.stocking_fluid.tooltip=直接从ME网络抽取流体 +gregtech.machine.me.stocking_fluid.tooltip.2=ME自动拉取模式将自动标记ME网络中的前16种流体,每5秒更新一次。 +gregtech.machine.me_import_fluid_hatch.configs.tooltip=可标记16种流体 gregtech.machine.me_export_item_bus.name=ME输出总线 -gregtech.machine.me_import_fluid_hatch.name=ME库存输入仓 -gregtech.machine.me_import_item_bus.name=ME库存输入总线 -gregtech.machine.me.fluid_export.tooltip=将流体直接存储到ME网络中。 -gregtech.machine.me.item_export.tooltip=将物品直接存储到ME网络中。 -gregtech.machine.me.fluid_import.tooltip=自动从ME网络获取流体。 -gregtech.machine.me.item_import.tooltip=自动从ME网络获取物品。 -gregtech.machine.me.export.tooltip=在连接到ME网络之前,它具有无限容量。 +gregtech.machine.me.item_export.tooltip=将物品直接存储到ME网络中 +gregtech.machine.me.item_export.tooltip.2=可以缓存无限数量的物品 +gregtech.machine.me_export_fluid_hatch.name=ME输出仓 +gregtech.machine.me.fluid_export.tooltip=将流体直接存储到ME网络中 +gregtech.machine.me.fluid_export.tooltip.2=可以缓存无限数量的流体 +gregtech.machine.me.stocking_auto_pull_enabled=ME自动拉取已启用 +gregtech.machine.me.stocking_auto_pull_disabled=ME自动拉取已禁用 # Universal tooltips gregtech.universal.tooltip.voltage_in=§a输入电压:§f%,d EU/t(%s§f) @@ -5270,7 +5300,7 @@ gregtech.universal.tooltip.item_stored=§d内含物品:§f%2$,d + %3$,d 个%1$ gregtech.universal.tooltip.item_transfer_rate=§b传输速率:§f%,d件物品/s gregtech.universal.tooltip.item_transfer_rate_stacks=§b传输速率:§f%,d组物品/s gregtech.universal.tooltip.fluid_storage_capacity=§9流体容量:§f%,d L -gregtech.universal.tooltip.fluid_storage_capacity_mult=§9流体容量:共§f%d§7个流体槽,每个§f%dL§7 +gregtech.universal.tooltip.fluid_storage_capacity_mult=§9流体容量:§7共§f%d§7个流体槽,每个§f%dL§7 gregtech.universal.tooltip.fluid_stored=§d内含流体:§f%2$,d L %1$s gregtech.universal.tooltip.fluid_transfer_rate=§b传输速率:§f%,d L/t gregtech.universal.tooltip.parallel=§d最大并行:§f%d @@ -5366,9 +5396,12 @@ gregtech.gui.fluid_auto_output.tooltip.enabled=流体自动输出已启用 gregtech.gui.fluid_auto_output.tooltip.disabled=流体自动输出已禁用 gregtech.gui.item_auto_output.tooltip.enabled=物品自动输出已启用 gregtech.gui.item_auto_output.tooltip.disabled=物品自动输出已禁用 +gregtech.gui.item_auto_collapse.tooltip.enabled=物品堆叠自动合并已启用 +gregtech.gui.item_auto_collapse.tooltip.disabled=物品堆叠自动合并已禁用 gregtech.gui.charger_slot.tooltip=§f充电槽§r/n§7从%s电池中取电§7/n§7也可为%s工具或电池充电 -gregtech.gui.configurator_slot.tooltip=§f编程电路槽§r/n§a配置值:§f%d§7/n/n§7左击/右击/滚轮可浏览循环列表/n§7Shift+右键单击以清除 +gregtech.gui.configurator_slot.tooltip=§f编程电路槽§r\n§a配置值:§f%d§7\n\n§7左击/右击/滚轮可循环浏览列表\n§7Shift+左键单击以打开选择GUI\n§7Shift+右键单击以清除 gregtech.gui.configurator_slot.no_value=空 +gregtech.gui.configurator_slot.unavailable.tooltip=编程电路槽位无法使用 gregtech.gui.fluid_lock.tooltip.enabled=流体锁定已启用 gregtech.gui.fluid_lock.tooltip.disabled=流体锁定已禁用 gregtech.gui.fluid_voiding.tooltip.enabled=过量流体销毁已启用 @@ -5385,8 +5418,12 @@ gregtech.gui.me_network.offline=网络状态:§4离线§r gregtech.gui.waiting_list=发送队列: gregtech.gui.config_slot=§f配置槽位§r gregtech.gui.config_slot.set=§7点击§b设置/选择§7配置槽位。§r +gregtech.gui.config_slot.set_only=§7点击§b设置§7配置槽位。§r gregtech.gui.config_slot.scroll=§7使用滚轮§a切换§7配置数。§r gregtech.gui.config_slot.remove=§7右击§4清除§7配置槽位。§r +gregtech.gui.config_slot.auto_pull_managed=§4禁用:§7由ME自动拉取管理 +gregtech.gui.me_bus.extra_slot=额外槽位/n§7在这里放置配方的额外物品,例如模具或透镜 +gregtech.gui.me_bus.auto_pull_button=单击以切换ME自动拉取模式 gregtech.gui.alarm.radius=半径: @@ -5555,7 +5592,7 @@ gregtech.multiblock.pattern.error.batteries=§c必须至少有一个不是空电 gregtech.multiblock.pattern.error.filters=§c必须使用同种过滤器§r gregtech.multiblock.pattern.clear_amount_1=§6前方必须有1x1x1大小的空间§r gregtech.multiblock.pattern.clear_amount_3=§6前方必须有3x3x1大小的空间§r -gregtech.multiblock.pattern.single=§6仅可使用该种方块§r +gregtech.multiblock.pattern.single=§6仅可使用该种方块类型§r gregtech.multiblock.pattern.location_end=§c最末端§r gregtech.multiblock.pattern.replaceable_air=可为空气 @@ -5640,8 +5677,10 @@ gregtech.multiblock.computation.not_enough_computation=机器需要更多算力 gregtech.multiblock.power_substation.stored=存储:%s gregtech.multiblock.power_substation.capacity=容量:%s gregtech.multiblock.power_substation.passive_drain=被动损失:%s -gregtech.multiblock.power_substation.average_io=平均输入/输出:%s -gregtech.multiblock.power_substation.average_io_hover=蓄能变电站内部的平均能量变化 +gregtech.multiblock.power_substation.average_in=平均EU输入:%s +gregtech.multiblock.power_substation.average_out=平均EU输出:%s +gregtech.multiblock.power_substation.average_in_hover=蓄能变电站内部的平均功率输入 +gregtech.multiblock.power_substation.average_out_hover=蓄能变电站内部的平均功率输出 gregtech.multiblock.power_substation.time_to_fill=预计充满时间:%s gregtech.multiblock.power_substation.time_to_drain=预计耗空时间:%s gregtech.multiblock.power_substation.time_seconds=%s秒 diff --git a/src/main/resources/assets/gregtech/models/item/material_sets/dull/dust_bred_fuel.json b/src/main/resources/assets/gregtech/models/item/material_sets/dull/dust_bred_fuel.json new file mode 100644 index 00000000000..bddd046838d --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/material_sets/dull/dust_bred_fuel.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/material_sets/dull/dust_bred_fuel" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/material_sets/dull/dust_fission_byproduct.json b/src/main/resources/assets/gregtech/models/item/material_sets/dull/dust_fission_byproduct.json new file mode 100644 index 00000000000..795e4ca2509 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/material_sets/dull/dust_fission_byproduct.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/material_sets/dull/dust_fission_byproduct" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/material_sets/dull/dust_spent_fuel.json b/src/main/resources/assets/gregtech/models/item/material_sets/dull/dust_spent_fuel.json new file mode 100644 index 00000000000..ad6dfae00fa --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/material_sets/dull/dust_spent_fuel.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/material_sets/dull/dust_spent_fuel" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_pellet.json b/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_pellet.json new file mode 100644 index 00000000000..671278d8837 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_pellet.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/material_sets/dull/fuel_pellet" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_pellet_depleted.json b/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_pellet_depleted.json new file mode 100644 index 00000000000..b0443d9a1bc --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/material_sets/dull/fuel_pellet_depleted.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/material_sets/dull/fuel_pellet_depleted" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/material_sets/dull/tool_head_wirecutter.json b/src/main/resources/assets/gregtech/models/item/material_sets/dull/tool_head_wirecutter.json new file mode 100644 index 00000000000..92690c87e45 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/material_sets/dull/tool_head_wirecutter.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/material_sets/dull/tool_head_wire_cutter" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/metaitems/basket.anode.json b/src/main/resources/assets/gregtech/models/item/metaitems/basket.anode.json new file mode 100644 index 00000000000..e62090d36b7 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/metaitems/basket.anode.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/metaitems/basket.anode" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_hv.json b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_hv.json new file mode 100644 index 00000000000..60a5a9255c1 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_hv.json @@ -0,0 +1,7 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "gregtech:items/tools/handle_electric_wire_cutter_hv", + "layer1": "gregtech:items/tools/wire_cutter_electric" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_iv.json b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_iv.json new file mode 100644 index 00000000000..6a7f378d8a9 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_iv.json @@ -0,0 +1,7 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "gregtech:items/tools/handle_electric_wire_cutter_iv", + "layer1": "gregtech:items/tools/wire_cutter_electric" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_lv.json b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_lv.json new file mode 100644 index 00000000000..406df61785c --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_lv.json @@ -0,0 +1,7 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "gregtech:items/tools/handle_electric_wire_cutter_lv", + "layer1": "gregtech:items/tools/wire_cutter_electric" + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/misc/itnt.png b/src/main/resources/assets/gregtech/textures/blocks/misc/itnt.png new file mode 100644 index 00000000000..a167e1676b7 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/misc/itnt.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/misc/powderbarrel.png b/src/main/resources/assets/gregtech/textures/blocks/misc/powderbarrel.png new file mode 100644 index 00000000000..b5624295e93 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/misc/powderbarrel.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front.png new file mode 100644 index 00000000000..72bbef85af9 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_active.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_active.png new file mode 100644 index 00000000000..94a4416b1f5 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_active_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_active_emissive.png new file mode 100644 index 00000000000..822fa52e130 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_active_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_emissive.png new file mode 100644 index 00000000000..00bcc3b5185 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_paused.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_paused.png new file mode 100644 index 00000000000..8f139ba6ab3 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_paused.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_paused_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_paused_emissive.png new file mode 100644 index 00000000000..577f0815c1d Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/fission_reactor/overlay_front_paused_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus.png index 76486f57cdd..dd3d1f12037 100644 Binary files a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus.png and b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus_active.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus_active.png new file mode 100644 index 00000000000..c9bb59b3b46 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch.png index f19def26e30..a2644c44b46 100644 Binary files a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch.png and b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch_active.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch_active.png new file mode 100644 index 00000000000..fd4570e0f9f Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_bus.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_bus.png index 96ac2920c71..8914379ca05 100644 Binary files a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_bus.png and b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_bus.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_bus_active.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_bus_active.png new file mode 100644 index 00000000000..39de0bb51bf Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_bus_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch.png index 313e4fdbeb6..e13a7f0fb7c 100644 Binary files a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch.png and b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch_active.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch_active.png new file mode 100644 index 00000000000..de4b2100518 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/base/slot_dark.png b/src/main/resources/assets/gregtech/textures/gui/base/slot_dark.png new file mode 100644 index 00000000000..90a91082dc3 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/base/slot_dark.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/overlay/conveyor_mode_overlay.png b/src/main/resources/assets/gregtech/textures/gui/overlay/conveyor_mode_overlay.png new file mode 100644 index 00000000000..0c2a1ac6212 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/overlay/conveyor_mode_overlay.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/overlay/filter_mode_overlay.png b/src/main/resources/assets/gregtech/textures/gui/overlay/filter_mode_overlay.png new file mode 100644 index 00000000000..0f9c95e8b68 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/overlay/filter_mode_overlay.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/overlay/filter_settings_overlay.png b/src/main/resources/assets/gregtech/textures/gui/overlay/filter_settings_overlay.png new file mode 100644 index 00000000000..31b8cdb6ce8 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/overlay/filter_settings_overlay.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/overlay/fluid_transfer_mode_overlay.png b/src/main/resources/assets/gregtech/textures/gui/overlay/fluid_transfer_mode_overlay.png new file mode 100644 index 00000000000..6fe690f9fbb Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/overlay/fluid_transfer_mode_overlay.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/overlay/manual_io_overlay.png b/src/main/resources/assets/gregtech/textures/gui/overlay/manual_io_overlay.png new file mode 100644 index 00000000000..a8f8bef7a54 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/overlay/manual_io_overlay.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/overlay/transfer_mode_overlay.png b/src/main/resources/assets/gregtech/textures/gui/overlay/transfer_mode_overlay.png new file mode 100644 index 00000000000..9364d84544d Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/overlay/transfer_mode_overlay.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/overlay/voiding_mode_overlay.png b/src/main/resources/assets/gregtech/textures/gui/overlay/voiding_mode_overlay.png new file mode 100644 index 00000000000..d948e2c551c Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/overlay/voiding_mode_overlay.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/arrow_double.png b/src/main/resources/assets/gregtech/textures/gui/widget/arrow_double.png new file mode 100644 index 00000000000..5613c4a3785 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/widget/arrow_double.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/button_distribution_mode.png b/src/main/resources/assets/gregtech/textures/gui/widget/button_distribution_mode.png index 86f6a27bd53..9dbdac4862f 100644 Binary files a/src/main/resources/assets/gregtech/textures/gui/widget/button_distribution_mode.png and b/src/main/resources/assets/gregtech/textures/gui/widget/button_distribution_mode.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/button_me_auto_pull.png b/src/main/resources/assets/gregtech/textures/gui/widget/button_me_auto_pull.png new file mode 100644 index 00000000000..16ada2daad4 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/widget/button_me_auto_pull.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_bred_fuel.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_bred_fuel.png new file mode 100644 index 00000000000..be707322226 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_bred_fuel.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_fission_byproduct.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_fission_byproduct.png new file mode 100644 index 00000000000..be707322226 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_fission_byproduct.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_spent_fuel.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_spent_fuel.png new file mode 100644 index 00000000000..be0cd30a253 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/dust_spent_fuel.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_pellet.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_pellet.png new file mode 100644 index 00000000000..4873ba60124 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_pellet.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_pellet_depleted.png b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_pellet_depleted.png new file mode 100644 index 00000000000..0caa5988662 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/dull/fuel_pellet_depleted.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_bred_fuel.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_bred_fuel.png new file mode 100644 index 00000000000..8f597c61e0e Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_bred_fuel.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_fission_byproduct.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_fission_byproduct.png new file mode 100644 index 00000000000..8f597c61e0e Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_fission_byproduct.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_spent_fuel.png b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_spent_fuel.png new file mode 100644 index 00000000000..4c8e6485ec3 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/material_sets/metallic/dust_spent_fuel.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/fuel_cladding.png b/src/main/resources/assets/gregtech/textures/items/metaitems/fuel_cladding.png new file mode 100644 index 00000000000..44525dbbd77 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/metaitems/fuel_cladding.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_hv.png b/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_hv.png new file mode 100644 index 00000000000..b54d8d136c2 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_hv.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_iv.png b/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_iv.png new file mode 100644 index 00000000000..303fea217f6 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_iv.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_lv.png b/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_lv.png new file mode 100644 index 00000000000..c45bffa4360 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_lv.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/tools/wire_cutter_electric.png b/src/main/resources/assets/gregtech/textures/items/tools/wire_cutter_electric.png new file mode 100644 index 00000000000..602eea83d49 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/tools/wire_cutter_electric.png differ diff --git a/src/main/resources/gregtech_at.cfg b/src/main/resources/gregtech_at.cfg index 343dd1b65f5..76892c9fc05 100644 --- a/src/main/resources/gregtech_at.cfg +++ b/src/main/resources/gregtech_at.cfg @@ -81,3 +81,6 @@ protected net.minecraft.entity.item.EntityBoat field_184473_aH # lastYd # EntityItem public net.minecraft.entity.item.EntityItem field_145804_b # pickupDelay + +# Explosion +public net.minecraft.world.Explosion field_77283_e # exploder