diff --git a/.github/actions/build_setup/action.yml b/.github/actions/build_setup/action.yml index 7409143dc18..7d53a2dbea2 100644 --- a/.github/actions/build_setup/action.yml +++ b/.github/actions/build_setup/action.yml @@ -18,7 +18,7 @@ runs: java-version: 17 - name: Setup Gradle - uses: gradle/gradle-build-action@v2 + uses: gradle/actions/setup-gradle@v3 with: cache-write-only: ${{ inputs.update-cache }} generate-job-summary: false diff --git a/.github/workflows/publish_project.yml b/.github/workflows/publish_project.yml index a6bb305d5bb..28aa35e34ac 100644 --- a/.github/workflows/publish_project.yml +++ b/.github/workflows/publish_project.yml @@ -35,7 +35,7 @@ jobs: run: ./gradlew build --warning-mode all --build-cache - name: Publish to GitHub - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: files: "build/libs/*.jar" generate_release_notes: true diff --git a/.github/workflows/test_java.yml b/.github/workflows/test_java.yml index 11bc42e8067..0faabb0cf0c 100644 --- a/.github/workflows/test_java.yml +++ b/.github/workflows/test_java.yml @@ -5,11 +5,9 @@ on: push: branches: - master - paths: ['src/main/java/**', 'src/test/**', 'src/api/java/**', 'gradle/**', '**.gradle', 'gradle.properties', - 'gradlew**', 'src/main/resources/*_at.cfg'] pull_request: - paths: ['src/main/java/**', 'src/test/**', 'src/api/java/**', 'gradle/**', '**.gradle', 'gradle.properties', - 'gradlew**', 'src/main/resources/*_at.cfg'] + branches: + - '*' concurrency: group: tests-${{ github.head_ref || github.ref }} diff --git a/.github/workflows/update_buildscript.yml b/.github/workflows/update_buildscript.yml index 45fa46819d2..f9c923fe09c 100644 --- a/.github/workflows/update_buildscript.yml +++ b/.github/workflows/update_buildscript.yml @@ -35,13 +35,11 @@ jobs: - name: Create Pull Request id: create-pull-request - uses: peter-evans/create-pull-request@v5 + uses: peter-evans/create-pull-request@v6 env: GITHUB_TOKEN: ${{ secrets.BUILDSCRIPT_UPDATER_TOKEN }} with: token: ${{ secrets.BUILDSCRIPT_UPDATER_TOKEN }} - committer: GitHub - author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com> commit-message: 'update build script version to ${{ steps.version-check.outputs.NEW_VERSION }}' branch: gha-update-buildscript title: Update build script version to ${{ steps.version-check.outputs.NEW_VERSION }} diff --git a/.github/workflows/validate_gradle_wrapper.yml b/.github/workflows/validate_gradle_wrapper.yml index 591e487d7d5..8824259410d 100644 --- a/.github/workflows/validate_gradle_wrapper.yml +++ b/.github/workflows/validate_gradle_wrapper.yml @@ -26,4 +26,4 @@ jobs: uses: actions/checkout@v4 - name: Validate Gradle Wrapper - uses: gradle/wrapper-validation-action@v1 + uses: gradle/actions/wrapper-validation diff --git a/.gitignore b/.gitignore index 0b58556f5f1..1756bc23f1e 100644 --- a/.gitignore +++ b/.gitignore @@ -81,3 +81,5 @@ local.properties run/ logs/ + +libs/ diff --git a/addon.gradle b/addon.gradle new file mode 100644 index 00000000000..51789b691e1 --- /dev/null +++ b/addon.gradle @@ -0,0 +1,19 @@ + +minecraft { + injectedTags.put('DEP_VERSION_STRING', "required-after:gregtech@[${modVersion},);") +} + +configurations { + 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 + exclude group: "com.google.code.findbugs", module: "jsr305" + // exclude scala as we don't use it for anything and causes import confusion + exclude group: "org.scala-lang" + exclude group: "org.scala-lang.modules" + exclude group: "org.scala-lang.plugins" + } +} + + diff --git a/build.gradle b/build.gradle index babe6d51d90..76a3672e84b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -//version: 1707682661 +//version: 1720106721 /* * DO NOT CHANGE THIS FILE! * Also, you may replace this file at any time if there is an update available. @@ -7,14 +7,24 @@ */ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import com.gtnewhorizons.retrofuturagradle.MinecraftExtension +import com.gtnewhorizons.retrofuturagradle.mcp.MCPTasks +import com.gtnewhorizons.retrofuturagradle.minecraft.MinecraftTasks import com.gtnewhorizons.retrofuturagradle.mcp.ReobfuscatedJar +import com.gtnewhorizons.retrofuturagradle.minecraft.RunMinecraftTask +import com.gtnewhorizons.retrofuturagradle.util.Distribution import com.modrinth.minotaur.dependencies.ModDependency import com.modrinth.minotaur.dependencies.VersionDependency +import de.undercouch.gradle.tasks.download.DownloadExtension +import org.apache.commons.io.FileUtils +import org.gradle.api.internal.artifacts.configurations.DefaultUnlockedConfiguration import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent import org.gradle.internal.logging.text.StyledTextOutputFactory import org.jetbrains.gradle.ext.Gradle +import javax.inject.Inject + import static org.gradle.internal.logging.text.StyledTextOutput.Style plugins { @@ -23,9 +33,9 @@ plugins { id 'base' id 'eclipse' id 'maven-publish' - id 'org.jetbrains.gradle.plugin.idea-ext' version '1.1.7' - id 'com.gtnewhorizons.retrofuturagradle' version '1.3.33' - id 'net.darkhax.curseforgegradle' version '1.1.18' apply false + id 'org.jetbrains.gradle.plugin.idea-ext' version '1.1.8' + id 'com.gtnewhorizons.retrofuturagradle' version '1.4.0' + id 'net.darkhax.curseforgegradle' version '1.1.24' 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 @@ -33,6 +43,7 @@ plugins { id 'org.jetbrains.kotlin.jvm' version '1.8.0' apply false id 'org.jetbrains.kotlin.kapt' version '1.8.0' apply false id 'com.google.devtools.ksp' version '1.8.0-1.0.9' apply false + id 'de.undercouch.download' version '5.6.0' apply false } def out = services.get(StyledTextOutputFactory).create('an-output') @@ -58,6 +69,8 @@ propertyDefaultIfUnset("includeMCVersionJar", false) propertyDefaultIfUnset("autoUpdateBuildScript", false) propertyDefaultIfUnset("modArchivesBaseName", project.modId) propertyDefaultIfUnsetWithEnvVar("developmentEnvironmentUserName", "Developer", "DEV_USERNAME") +propertyDefaultIfUnset("additionalJavaArguments", "") +propertyDefaultIfUnset("enableJava17RunTasks", false) propertyDefaultIfUnset("generateGradleTokenClass", "") propertyDefaultIfUnset("gradleTokenModId", "") propertyDefaultIfUnset("gradleTokenModName", "") @@ -65,8 +78,10 @@ propertyDefaultIfUnset("gradleTokenVersion", "") propertyDefaultIfUnset("useSrcApiPath", false) propertyDefaultIfUnset("includeWellKnownRepositories", true) propertyDefaultIfUnset("includeCommonDevEnvMods", true) +propertyDefaultIfUnset("stripForgeRequirements", false) propertyDefaultIfUnset("noPublishedSources", false) propertyDefaultIfUnset("forceEnableMixins", false) +propertyDefaultIfUnset("mixinConfigRefmap", "mixins.${project.modId}.refmap.json") propertyDefaultIfUnsetWithEnvVar("enableCoreModDebug", false, "CORE_MOD_DEBUG") propertyDefaultIfUnset("generateMixinConfig", true) propertyDefaultIfUnset("usesShadowedDependencies", false) @@ -107,7 +122,7 @@ if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists( if (apiPackage) { final String endApiPath = modGroupPath + '/' + apiPackagePath - if (useSrcApiPath) { + if (useSrcApiPath.toBoolean()) { targetPackageJava = 'src/api/java/' + endApiPath targetPackageScala = 'src/api/scala/' + endApiPath targetPackageKotlin = 'src/api/kotlin/' + endApiPath @@ -369,6 +384,14 @@ minecraft { '-Dlegacy.debugClassLoadingSave=true' ]) } + + if (additionalJavaArguments.size() != 0) { + extraRunJvmArguments.addAll(additionalJavaArguments.split(';')) + } + + if (enableJava17RunTasks.toBoolean()) { + lwjgl3Version = "3.3.2" + } } if (coreModClass) { @@ -504,7 +527,7 @@ dependencies { // should use 2.8.6 but 2.8.9+ has a vulnerability fix annotationProcessor 'com.google.code.gson:gson:2.8.9' - mixinProviderSpec = modUtils.enableMixins(mixinProviderSpec, "mixins.${modId}.refmap.json") + mixinProviderSpec = modUtils.enableMixins(mixinProviderSpec, mixinConfigRefmap) api (mixinProviderSpec) { transitive = false } @@ -546,6 +569,10 @@ dependencies { transitive = false } + if ((usesMixins.toBoolean() || forceEnableMixins.toBoolean()) && stripForgeRequirements.toBoolean()) { + runtimeOnlyNonPublishable 'com.cleanroommc:strip-latest-forge-requirements:1.0' + } + if (includeCommonDevEnvMods.toBoolean()) { if (!(modId.equals('jei'))) { implementation 'mezz.jei:jei_1.12.2:4.16.1.302' @@ -679,7 +706,6 @@ tasks.register('generateAssets') { if (usesMixins.toBoolean() && generateMixinConfig.toBoolean()) { def mixinConfigFile = getFile("src/main/resources/mixins.${modId}.json") if (!mixinConfigFile.exists()) { - def mixinConfigRefmap = "mixins.${modId}.refmap.json" mixinConfigFile.text = """{ "package": "${modGroup}.${mixinsPackage}", @@ -820,6 +846,218 @@ def getManifestAttributes() { } +// LWJGL3ify setup +if (enableJava17RunTasks.toBoolean()) { + + apply plugin: 'de.undercouch.download' + + ext.java17Toolchain = (JavaToolchainSpec spec) -> { + spec.languageVersion.set(JavaLanguageVersion.of(17)) + spec.vendor.set(JvmVendorSpec.matching("jetbrains")) + } + ext.java21Toolchain = (JavaToolchainSpec spec) -> { + spec.languageVersion.set(JavaLanguageVersion.of(21)) + spec.vendor.set(JvmVendorSpec.matching("jetbrains")) + } + + ext.java17DependenciesCfg = (DefaultUnlockedConfiguration) configurations.create("java17Dependencies") { + extendsFrom(configurations.getByName("runtimeClasspath")) // Ensure consistent transitive dependency resolution + canBeConsumed = false + } + ext.java17PatchDependenciesCfg = (DefaultUnlockedConfiguration) configurations.create("java17PatchDependencies") { + canBeConsumed = false + } + + dependencies { + if (modId != 'lwjgl3ify') { + java17Dependencies("io.github.twilightflower:lwjgl3ify:1.0.0") + } + java17PatchDependencies("io.github.twilightflower:lwjgl3ify:1.0.0:forgePatches") { + transitive = false + } + } + + ext.java17JvmArgs = [ + "-Dfile.encoding=UTF-8", + "-Djava.system.class.loader=com.gtnewhorizons.retrofuturabootstrap.RfbSystemClassLoader", + "-Djava.security.manager=allow", + "--add-opens", "java.base/jdk.internal.loader=ALL-UNNAMED", + "--add-opens", "java.base/java.net=ALL-UNNAMED", + "--add-opens", "java.base/java.nio=ALL-UNNAMED", + "--add-opens", "java.base/java.io=ALL-UNNAMED", + "--add-opens", "java.base/java.lang=ALL-UNNAMED", + "--add-opens", "java.base/java.lang.reflect=ALL-UNNAMED", + "--add-opens", "java.base/java.text=ALL-UNNAMED", + "--add-opens", "java.base/java.util=ALL-UNNAMED", + "--add-opens", "java.base/jdk.internal.reflect=ALL-UNNAMED", + "--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED", + "--add-opens", "jdk.naming.dns/com.sun.jndi.dns=ALL-UNNAMED,java.naming", + "--add-opens", "java.desktop/sun.awt=ALL-UNNAMED", + "--add-opens", "java.desktop/sun.awt.image=ALL-UNNAMED", + "--add-opens", "java.desktop/com.sun.imageio.plugins.png=ALL-UNNAMED", + "--add-opens", "jdk.dynalink/jdk.dynalink.beans=ALL-UNNAMED", + "--add-opens", "java.sql.rowset/javax.sql.rowset.serial=ALL-UNNAMED" + ] + + ext.hotswapJvmArgs = [ + // DCEVM advanced hot reload + "-XX:+AllowEnhancedClassRedefinition", + "-XX:HotswapAgent=fatjar" + ] + + ext.setupHotswapAgent17 = tasks.register("setupHotswapAgent17", SetupHotswapAgentTask, t -> { + t.setTargetForToolchain(java17Toolchain) + }) + + ext.setupHotswapAgent21 = tasks.register("setupHotswapAgent21", SetupHotswapAgentTask, t -> { + t.setTargetForToolchain(java21Toolchain) + }) + + def runClient17Task = tasks.register("runClient17", RunHotswappableMinecraftTask, Distribution.CLIENT, "runClient") + runClient17Task.configure { + dependsOn(setupHotswapAgent17) + setup(project) + javaLauncher = project.javaToolchains.launcherFor(project.java17Toolchain) + } + + def runServer17Task = tasks.register("runServer17", RunHotswappableMinecraftTask, Distribution.DEDICATED_SERVER, "runServer") + runServer17Task.configure { + dependsOn(setupHotswapAgent17) + setup(project) + javaLauncher = project.javaToolchains.launcherFor(project.java17Toolchain) + } + + def runClient21Task = tasks.register("runClient21", RunHotswappableMinecraftTask, Distribution.CLIENT, "runClient") + runClient21Task.configure { + dependsOn(setupHotswapAgent21) + setup(project) + javaLauncher = project.javaToolchains.launcherFor(project.java21Toolchain) + } + + def runServer21Task = tasks.register("runServer21", RunHotswappableMinecraftTask, Distribution.DEDICATED_SERVER, "runServer") + runServer21Task.configure { + dependsOn(setupHotswapAgent21) + setup(project) + javaLauncher = project.javaToolchains.launcherFor(project.java21Toolchain) + } +} + +abstract class RunHotswappableMinecraftTask extends RunMinecraftTask { + + // IntelliJ doesn't seem to allow pre-set commandline arguments, so we also support an env variable + private boolean enableHotswap = Boolean.valueOf(System.getenv("HOTSWAP")) + + public final Distribution side + public final String superTask + + @Input + boolean getEnableHotswap() { + return enableHotswap + } + + @Option(option = "hotswap", description = "Enables HotSwapAgent for enhanced class reloading under a debugger") + boolean setEnableHotswap(boolean enable) { + enableHotswap = enable + } + + @Inject + RunHotswappableMinecraftTask(Distribution side, String superTask, org.gradle.api.invocation.Gradle gradle) { + super(side, gradle) + + this.side = side + this.superTask = superTask + setGroup("Modded Minecraft") + setDescription("Runs the modded " + side.name().toLowerCase(Locale.ROOT) + " using modern Java and lwjgl3ify") + this.getLwjglVersion().set(3) + } + + void setup(Project project) { + final MinecraftExtension minecraft = project.getExtensions().getByType(MinecraftExtension.class) + final MCPTasks mcpTasks = project.getExtensions().getByType(MCPTasks.class) + final MinecraftTasks mcTasks = project.getExtensions().getByType(MinecraftTasks.class) + + this.getExtraJvmArgs().addAll((List) project.property("java17JvmArgs")) + if (getEnableHotswap()) { + this.getExtraJvmArgs().addAll((List) project.property("hotswapJvmArgs")) + } + + this.classpath(project.property("java17PatchDependenciesCfg")) + this.classpath(mcpTasks.getTaskPackageMcLauncher()) + this.classpath(mcpTasks.getTaskPackagePatchedMc()) + this.classpath(mcpTasks.getPatchedConfiguration()) + this.classpath(project.getTasks().named("jar")) + this.classpath(project.property("java17DependenciesCfg")) + + super.setup(project) + + dependsOn( + mcpTasks.getLauncherSources().getClassesTaskName(), + mcTasks.getTaskDownloadVanillaAssets(), + mcpTasks.getTaskPackagePatchedMc(), + "jar" + ) + + getMainClass().set((side == Distribution.CLIENT) ? "GradleStart" : "GradleStartServer") + getUsername().set(minecraft.getUsername()) + getUserUUID().set(minecraft.getUserUUID()) + if (side == Distribution.DEDICATED_SERVER) { + getExtraArgs().add("nogui") + } + + systemProperty("gradlestart.bouncerClient", "com.gtnewhorizons.retrofuturabootstrap.Main") + systemProperty("gradlestart.bouncerServer", "com.gtnewhorizons.retrofuturabootstrap.Main") + + if (project.usesMixins.toBoolean()) { + this.extraJvmArgs.addAll(project.provider(() -> { + def mixinCfg = project.configurations.detachedConfiguration(project.dependencies.create(project.mixinProviderSpec)) + mixinCfg.canBeConsumed = false + mixinCfg.canBeResolved = true + mixinCfg.transitive = false + enableHotswap ? ["-javaagent:" + mixinCfg.singleFile.absolutePath] : [] + })) + } + } +} + +abstract class SetupHotswapAgentTask extends DefaultTask { + + @OutputFile + abstract RegularFileProperty getTargetFile() + + void setTargetForToolchain(Action spec) { + getTargetFile().set(project.javaToolchains.launcherFor(spec).map { + it.metadata.installationPath.file("lib/hotswap/hotswap-agent.jar") + }) + } + + @Inject + SetupHotswapAgentTask() { + setGroup("GT Buildscript") + setDescription("Installs a recent version of HotSwapAgent into the Java runtime directory") + onlyIf("Run only if not already installed", t -> !((SetupHotswapAgentTask) t).getTargetFile().getAsFile().get().exists()) + } + + @TaskAction + void installHSA() { + final String url = 'https://github.com/HotswapProjects/HotswapAgent/releases/download/1.4.2-SNAPSHOT/hotswap-agent-1.4.2-SNAPSHOT.jar' + final File target = getTargetFile().getAsFile().get() + final File parent = target.getParentFile() + FileUtils.forceMkdir(parent) + final DownloadExtension download = getProject().getExtensions().findByType(DownloadExtension.class) + download.run(ds -> { + try { + ds.src(url) + } catch (MalformedURLException e) { + throw new RuntimeException(e) + } + ds.dest(target) + ds.overwrite(false) + ds.tempAndMove(true) + }) + } +} + + // IDE Configuration eclipse { @@ -844,9 +1082,25 @@ idea { '2. Run Client'(Gradle) { taskNames = ['runClient'] } + if (enableJava17RunTasks.toBoolean()) { + '2a. Run Client (Java 17)'(Gradle) { + taskNames = ['runClient17'] + } + '2b. Run Client (Java 21)'(Gradle) { + taskNames = ['runClient21'] + } + } '3. Run Server'(Gradle) { taskNames = ['runServer'] } + if (enableJava17RunTasks.toBoolean()) { + '3a. Run Server (Java 17)'(Gradle) { + taskNames = ['runServer17'] + } + '3b. Run Server (Java 21)'(Gradle) { + taskNames = ['runServer21'] + } + } '4. Run Obfuscated Client'(Gradle) { taskNames = ['runObfClient'] } diff --git a/dependencies.gradle b/dependencies.gradle index 4ab81db91bd..9011b72660f 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -41,21 +41,23 @@ dependencies { // 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("com.cleanroommc:groovyscript:1.1.0") { transitive = false } + api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.698") + api("appeng:ae2-uel:v0.56.4") { transitive = false } api rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31 // 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:journeymap-32274:5172461") // Journeymap 5.7.1p3 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("curse.maven:xaeros-263420:5394758") // Xaero's Minimap 24.2.0 + compileOnly rfg.deobf("curse.maven:opencomputers-223008:5274236") // OpenComputers 1.8.5+179e1c3 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 + compileOnly rfg.deobf("curse.maven:littletiles-257818:4750222") // LittleTiles 1.5.82-1.12.2 + compileOnly rfg.deobf("curse.maven:creativecore-257814:4722163") // Creative Core 1.10.71 // 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. @@ -67,20 +69,3 @@ dependencies { // 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 { - injectedTags.put('DEP_VERSION_STRING', "required-after:gregtech@[${modVersion},);") -} - -configurations { - 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 - exclude group: "com.google.code.findbugs", module: "jsr305" - // exclude scala as we don't use it for anything and causes import confusion - exclude group: "org.scala-lang" - exclude group: "org.scala-lang.modules" - exclude group: "org.scala-lang.plugins" - } -} diff --git a/gradle.properties b/gradle.properties index 05f1703bf1b..53c417ab907 100644 --- a/gradle.properties +++ b/gradle.properties @@ -51,29 +51,25 @@ useSrcApiPath=false accessTransformersFile = gregtech_at.cfg # Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled! -usesMixins = false +usesMixins = true # Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail! -mixinsPackage = +mixinsPackage = mixins # Automatically generates a mixin config json if enabled, with the name mixins.modid.json -generateMixinConfig=false +generateMixinConfig = false # Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin! # Example value: coreModClass = asm.FMLPlugin + modGroup = com.myname.mymodid -> com.myname.mymodid.asm.FMLPlugin coreModClass = asm.GregTechLoadingPlugin # If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod (meaning that # there is no class annotated with @Mod) you want this to be true. When in doubt: leave it on false! -containsMixinsAndOrCoreModOnly = false - +containsMixinsAndOrCoreModOnly=false # Enables Mixins even if this mod doesn't use them, useful if one of the dependencies uses mixins. -forceEnableMixins = true - +forceEnableMixins=false # Outputs pre-transformed and post-transformed loaded classes to run/CLASSLOADER_TEMP. Can be used in combination with # diff to see exactly what your ASM or Mixins are changing in the target file. # Optionally can be specified with the 'CORE_MOD_DEBUG' env var. Will output a lot of files! -enableCoreModDebug = false - +enableCoreModDebug=false # Adds CurseMaven, Modrinth Maven, BlameJared maven, and some more well-known 1.12.2 repositories -includeWellKnownRepositories = true - +includeWellKnownRepositories=true # Adds JEI and TheOneProbe to your development environment. Adds them as 'implementation', meaning they will # be available at compiletime and runtime for your mod (in-game and in-code). # Overrides the above setting to be always true, as these repositories are needed to fetch the mods diff --git a/src/api/java/com/creativemd/littletiles/client/render/cache/LayeredRenderBoxCache.java b/src/api/java/com/creativemd/littletiles/client/render/cache/LayeredRenderBoxCache.java deleted file mode 100644 index 5bba9443bfb..00000000000 --- a/src/api/java/com/creativemd/littletiles/client/render/cache/LayeredRenderBoxCache.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.creativemd.littletiles.client.render.cache; - -public class LayeredRenderBoxCache { -} diff --git a/src/api/java/com/creativemd/littletiles/client/render/tile/LittleRenderBox.java b/src/api/java/com/creativemd/littletiles/client/render/tile/LittleRenderBox.java deleted file mode 100644 index 10987d58d48..00000000000 --- a/src/api/java/com/creativemd/littletiles/client/render/tile/LittleRenderBox.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.creativemd.littletiles.client.render.tile; - -public class LittleRenderBox { - public boolean needsResorting; -} diff --git a/src/api/java/me/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPass.java b/src/api/java/me/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPass.java new file mode 100644 index 00000000000..7ac97f9d095 --- /dev/null +++ b/src/api/java/me/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPass.java @@ -0,0 +1,11 @@ +package me.jellysquid.mods.sodium.client.render.chunk.passes; + +/** + * Adapted and minimized from BlockRenderPass.java + */ +public enum BlockRenderPass { + ; + + public static BlockRenderPass[] VALUES; + public static int COUNT; +} diff --git a/src/api/java/me/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPassManager.java b/src/api/java/me/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPassManager.java new file mode 100644 index 00000000000..0eb76a2deb3 --- /dev/null +++ b/src/api/java/me/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPassManager.java @@ -0,0 +1,19 @@ +package me.jellysquid.mods.sodium.client.render.chunk.passes; + +import net.minecraft.util.BlockRenderLayer; + +/** + * Adapted and minimized from BlockRenderPassManager.java + */ +public class BlockRenderPassManager { + + private void addMapping(BlockRenderLayer layer, BlockRenderPass type) {} + + /** + * Creates a set of render pass mappings to vanilla render layers which closely mirrors the rendering + * behavior of vanilla. + */ + public static BlockRenderPassManager createDefaultMappings() { + return new BlockRenderPassManager(); + } +} diff --git a/src/api/java/me/jellysquid/mods/sodium/client/util/BufferSizeUtil.java b/src/api/java/me/jellysquid/mods/sodium/client/util/BufferSizeUtil.java new file mode 100644 index 00000000000..dee60c5a9d9 --- /dev/null +++ b/src/api/java/me/jellysquid/mods/sodium/client/util/BufferSizeUtil.java @@ -0,0 +1,14 @@ +package me.jellysquid.mods.sodium.client.util; + +import net.minecraft.util.BlockRenderLayer; + +import java.util.HashMap; +import java.util.Map; + +/** + * Adapted and minimized from BufferSizeUtil.java + */ +public class BufferSizeUtil { + + public static final Map BUFFER_SIZES = new HashMap<>(); +} diff --git a/src/api/java/me/jellysquid/mods/sodium/client/util/EnumUtil.java b/src/api/java/me/jellysquid/mods/sodium/client/util/EnumUtil.java new file mode 100644 index 00000000000..da58e286b15 --- /dev/null +++ b/src/api/java/me/jellysquid/mods/sodium/client/util/EnumUtil.java @@ -0,0 +1,12 @@ +package me.jellysquid.mods.sodium.client.util; + +import net.minecraft.util.BlockRenderLayer; + +/** + * Adapted and minimized from EnumUtil.java + */ +public class EnumUtil { + + public static BlockRenderLayer[] LAYERS = BlockRenderLayer.values(); + +} diff --git a/src/main/java/gregtech/GregTechMod.java b/src/main/java/gregtech/GregTechMod.java index b0afab8f2d6..59a72f3db03 100644 --- a/src/main/java/gregtech/GregTechMod.java +++ b/src/main/java/gregtech/GregTechMod.java @@ -33,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@[1.0.1,);" + + "after:jei@[4.15.0,);" + "after:crafttweaker@[4.1.20,);" + "after:groovyscript@[1.1.0,);" + "after:theoneprobe;" + "after:hwyla;") public class GregTechMod { diff --git a/src/main/java/gregtech/api/GTValues.java b/src/main/java/gregtech/api/GTValues.java index 006f9444117..2048c61affe 100644 --- a/src/main/java/gregtech/api/GTValues.java +++ b/src/main/java/gregtech/api/GTValues.java @@ -170,7 +170,8 @@ public class GTValues { MODID_PROJRED_CORE = "projectred-core", MODID_RC = "railcraft", MODID_CHISEL = "chisel", - MODID_RS = "refinedstorage"; + MODID_RS = "refinedstorage", + MODID_LITTLETILES = "littletiles"; private static Boolean isClient; diff --git a/src/main/java/gregtech/api/GregTechAPI.java b/src/main/java/gregtech/api/GregTechAPI.java index c4506dfbfc0..01845f8b047 100644 --- a/src/main/java/gregtech/api/GregTechAPI.java +++ b/src/main/java/gregtech/api/GregTechAPI.java @@ -1,14 +1,14 @@ package gregtech.api; import gregtech.api.advancement.IAdvancementManager; +import gregtech.api.block.ICleanroomFilter; import gregtech.api.block.IHeatingCoilBlockStats; -import gregtech.api.block.machines.BlockMachine; import gregtech.api.command.ICommandManager; import gregtech.api.cover.CoverDefinition; import gregtech.api.event.HighTierEvent; import gregtech.api.gui.UIFactory; -import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.multiblock.IBatteryData; +import gregtech.api.metatileentity.registry.MTEManager; import gregtech.api.modules.IModuleManager; import gregtech.api.network.INetworkHandler; import gregtech.api.sound.ISoundManager; @@ -20,6 +20,7 @@ import gregtech.api.util.GTLog; import gregtech.api.util.IBlockOre; import gregtech.common.ConfigHolder; +import gregtech.datafix.migration.lib.MigrationAPI; import net.minecraft.block.state.IBlockState; import net.minecraft.util.ResourceLocation; @@ -51,23 +52,25 @@ public class GregTechAPI { public static IMaterialRegistryManager materialManager; /** Will be available at the Pre-Initialization stage */ public static MarkerMaterialRegistry markerMaterialRegistry; + /** Will be available at the Pre-Initialization stage */ + public static MTEManager mteManager; + /** GT's data migrations API */ + public static final MigrationAPI MIGRATIONS = new MigrationAPI(); /** Will be available at the Pre-Initialization stage */ private static boolean highTier; private static boolean highTierInitialized; - public static final GTControlledRegistry MTE_REGISTRY = new GTControlledRegistry<>( - Short.MAX_VALUE); @Deprecated public static final GTControlledRegistry UI_FACTORY_REGISTRY = new GTControlledRegistry<>( Short.MAX_VALUE); public static final GTControlledRegistry COVER_REGISTRY = new GTControlledRegistry<>( Integer.MAX_VALUE); - public static BlockMachine MACHINE; public static final Map> oreBlockTable = new HashMap<>(); public static final Object2ObjectMap HEATING_COILS = new Object2ObjectOpenHashMap<>(); public static final Object2ObjectMap PSS_BATTERIES = new Object2ObjectOpenHashMap<>(); + public static final Object2ObjectMap CLEANROOM_FILTERS = new Object2ObjectOpenHashMap<>(); /** Will be available at the Pre-Initialization stage */ public static boolean isHighTier() { diff --git a/src/main/java/gregtech/api/block/ICleanroomFilter.java b/src/main/java/gregtech/api/block/ICleanroomFilter.java new file mode 100644 index 00000000000..8889bcbf0fe --- /dev/null +++ b/src/main/java/gregtech/api/block/ICleanroomFilter.java @@ -0,0 +1,28 @@ +package gregtech.api.block; + +import gregtech.api.GTValues; +import gregtech.api.metatileentity.multiblock.CleanroomType; + +import org.jetbrains.annotations.Nullable; + +public interface ICleanroomFilter { + + /** + * @return The {@link CleanroomType} this filter should provide, + * can be null if the block isn't a filter + */ + @Nullable + CleanroomType getCleanroomType(); + + /** + * @return The "tier" of the filter, for use in JEI previews + */ + int getTier(); + + /** + * @return The minimum voltage tier a cleanroom with this filter will accept + */ + default int getMinTier() { + return GTValues.LV; + } +} diff --git a/src/main/java/gregtech/api/block/machines/BlockMachine.java b/src/main/java/gregtech/api/block/machines/BlockMachine.java index 181c670d540..ad352e97186 100644 --- a/src/main/java/gregtech/api/block/machines/BlockMachine.java +++ b/src/main/java/gregtech/api/block/machines/BlockMachine.java @@ -4,6 +4,7 @@ import gregtech.api.block.BlockCustomParticle; import gregtech.api.block.UnlistedIntegerProperty; import gregtech.api.block.UnlistedStringProperty; +import gregtech.api.capability.GregtechDataCodes; import gregtech.api.cover.Cover; import gregtech.api.cover.IFacadeCover; import gregtech.api.items.toolitem.ToolClasses; @@ -12,6 +13,7 @@ import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.api.metatileentity.registry.MTERegistry; import gregtech.api.pipenet.IBlockAppearance; import gregtech.api.util.GTUtility; import gregtech.api.util.Mods; @@ -71,6 +73,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.Random; import java.util.Set; @@ -255,16 +258,37 @@ public boolean recolorBlock(@NotNull World world, @NotNull BlockPos pos, @NotNul public void onBlockPlacedBy(World worldIn, @NotNull BlockPos pos, @NotNull IBlockState state, @NotNull EntityLivingBase placer, ItemStack stack) { IGregTechTileEntity holder = (IGregTechTileEntity) worldIn.getTileEntity(pos); - MetaTileEntity sampleMetaTileEntity = GregTechAPI.MTE_REGISTRY.getObjectById(stack.getItemDamage()); + MTERegistry registry = GregTechAPI.mteManager.getRegistry( + Objects.requireNonNull(stack.getItem().getRegistryName()).getNamespace()); + + MetaTileEntity sampleMetaTileEntity = registry.getObjectById(stack.getItemDamage()); if (holder != null && sampleMetaTileEntity != null) { // TODO Fix this if (stack.hasDisplayName() && holder instanceof MetaTileEntityHolder) { ((MetaTileEntityHolder) holder).setCustomName(stack.getDisplayName()); } MetaTileEntity metaTileEntity = holder.setMetaTileEntity(sampleMetaTileEntity); - if (stack.hasTagCompound()) { - // noinspection ConstantConditions - metaTileEntity.initFromItemStackData(stack.getTagCompound()); + var stackTag = stack.getTagCompound(); + if (stackTag != null && !stackTag.isEmpty()) { + if (stackTag.hasKey(GregtechDataCodes.BLOCK_ENTITY_TAG)) { + var blockTag = stackTag.getCompoundTag(GregtechDataCodes.BLOCK_ENTITY_TAG); + String customName = blockTag.getString(GregtechDataCodes.CUSTOM_NAME); + if (!customName.isEmpty()) + ((MetaTileEntityHolder) holder).setCustomName(customName); + + var mteTag = blockTag.getCompoundTag(GregtechDataCodes.TAG_KEY_MTE); + List removed = new ArrayList<>(); + for (var key : mteTag.getKeySet()) { + var trait = metaTileEntity.getMTETrait(key); + if (trait == null) continue; + + removed.add(key); + } + removed.forEach(mteTag::removeTag); + metaTileEntity.readFromNBT(mteTag); + } else { + metaTileEntity.initFromItemStackData(stackTag); + } } if (metaTileEntity.isValidFrontFacing(EnumFacing.UP)) { metaTileEntity.setFrontFacing(EnumFacing.getDirectionFromEntityLiving(pos, placer)); @@ -487,7 +511,10 @@ public int getLightOpacity(@NotNull IBlockState state, @NotNull IBlockAccess wor @Override public void getSubBlocks(@NotNull CreativeTabs tab, @NotNull NonNullList items) { - for (MetaTileEntity metaTileEntity : GregTechAPI.MTE_REGISTRY) { + MTERegistry registry = GregTechAPI.mteManager + .getRegistry(Objects.requireNonNull(getRegistryName()).getNamespace()); + + for (MetaTileEntity metaTileEntity : registry) { if (metaTileEntity.isInCreativeTab(tab)) { metaTileEntity.getSubItems(tab, items); } diff --git a/src/main/java/gregtech/api/block/machines/MachineItemBlock.java b/src/main/java/gregtech/api/block/machines/MachineItemBlock.java index d8fb09dcc19..d226978fb5d 100644 --- a/src/main/java/gregtech/api/block/machines/MachineItemBlock.java +++ b/src/main/java/gregtech/api/block/machines/MachineItemBlock.java @@ -1,7 +1,6 @@ package gregtech.api.block.machines; import gregtech.api.GTValues; -import gregtech.api.GregTechAPI; import gregtech.api.metatileentity.ITieredMetaTileEntity; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.pipenet.block.BlockPipe; @@ -48,7 +47,7 @@ public class MachineItemBlock extends ItemBlock { /** * Adds another creative tab for the machine item. Additional tabs added by this method are checked along with - * default tabs ({@link GregTechAPI#MACHINE} and {@link CreativeTabs#SEARCH}) during + * default tabs ({@link GTCreativeTabs#TAB_GREGTECH_MACHINES} and {@link CreativeTabs#SEARCH}) during * {@link net.minecraft.item.Item#getSubItems(CreativeTabs, NonNullList) Item#getSubItems()} operation.
* Note that, for machines to be properly registered on the creative tab, a matching implementation of * {@link MetaTileEntity#isInCreativeTab(CreativeTabs)} should be provided as well. @@ -203,4 +202,9 @@ public int getItemStackLimit(@NotNull ItemStack stack) { MetaTileEntity metaTileEntity = GTUtility.getMetaTileEntity(stack); return metaTileEntity != null ? metaTileEntity.getItemStackLimit(stack) : super.getItemStackLimit(stack); } + + @Override + public @NotNull BlockMachine getBlock() { + return (BlockMachine) super.getBlock(); + } } diff --git a/src/main/java/gregtech/api/capability/GregtechDataCodes.java b/src/main/java/gregtech/api/capability/GregtechDataCodes.java index 225e12e4f74..56078a8e64f 100644 --- a/src/main/java/gregtech/api/capability/GregtechDataCodes.java +++ b/src/main/java/gregtech/api/capability/GregtechDataCodes.java @@ -152,6 +152,8 @@ public static int assignId() { // From MetaTileEntityHolder public static final String CUSTOM_NAME = "CustomName"; + public static final String BLOCK_ENTITY_TAG = "BlockEntityTag"; + public static final String TAG_KEY_MTE = "MetaTileEntity"; // From MetaTileEntity public static final String TAG_KEY_PAINTING_COLOR = "PaintingColor"; diff --git a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java index 6d8877ff1dc..4ff7875d7bb 100644 --- a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java @@ -13,11 +13,13 @@ import gregtech.api.metatileentity.multiblock.ICleanroomReceiver; import gregtech.api.metatileentity.multiblock.ParallelLogicType; import gregtech.api.recipes.Recipe; +import gregtech.api.recipes.RecipeBuilder; 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.GTLog; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; import gregtech.common.ConfigHolder; @@ -50,6 +52,9 @@ public abstract class AbstractRecipeLogic extends MTETrait implements IWorkable, private final RecipeMap recipeMap; + private double euDiscount = -1; + private double speedBonus = -1; + protected Recipe previousRecipe; private boolean allowOverclocking = true; protected int parallelRecipesPerformed; @@ -457,6 +462,23 @@ public boolean prepareRecipe(Recipe recipe, IItemHandlerModifiable inputInventor recipe = Recipe.trimRecipeOutputs(recipe, getRecipeMap(), metaTileEntity.getItemOutputLimit(), metaTileEntity.getFluidOutputLimit()); + // apply EU/speed discount (if any) before parallel + if (euDiscount > 0 || speedBonus > 0) { // if-statement to avoid unnecessarily creating RecipeBuilder object + RecipeBuilder builder = new RecipeBuilder<>(recipe, recipeMap); + if (euDiscount > 0) { + int newEUt = (int) Math.round(recipe.getEUt() * euDiscount); + if (newEUt <= 0) newEUt = 1; + builder.EUt(newEUt); + } + if (speedBonus > 0) { + int duration = recipe.getDuration(); + int newDuration = (int) Math.round(duration * speedBonus); + if (newDuration <= 0) newDuration = 1; + builder.duration(newDuration); + } + recipe = builder.build().getResult(); + } + // Pass in the trimmed recipe to the parallel logic recipe = findParallelRecipe( recipe, @@ -508,6 +530,55 @@ public void setParallelLimit(int amount) { parallelLimit = amount; } + /** + * Sets an EU/t discount to apply to a machine when running recipes.
+ * This does NOT affect recipe lookup voltage, even if the discount drops it to a lower voltage tier.
+ * This discount is applied pre-parallel/pre-overclock. + * + * @param discount The discount, must be greater than 0 and less than 1. + * If discount == 0.75, then the recipe will only require 75% of the listed power to run. + * If discount is > 1, then the recipe will require more than the listed power to run. + * Be careful as this may not always be possible within the EU/t maximums of the machine! + * + */ + public void setEUDiscount(double discount) { + if (discount <= 0) { + GTLog.logger.warn("Cannot set EU discount for recipe logic to {}, discount must be > 0", discount); + return; + } + euDiscount = discount; + } + + /** + * @return the EU/t discount, or -1 if no discount. + */ + public double getEUtDiscount() { + return euDiscount; + } + + /** + * Sets a speed multiplier to apply to a machine when running recipes.
+ * This discount is applied pre-parallel/pre-overclock. + * + * @param bonus The bonus, must be greater than 0. + * If bonus == 0.2, then the recipe will be 20% of the normal duration. + * If bonus is > 1, then the recipe will be slower than the normal duration. + */ + public void setSpeedBonus(double bonus) { + if (bonus <= 0) { + GTLog.logger.warn("Cannot set speed bonus for recipe logic to {}, bonus must be > 0", bonus); + return; + } + speedBonus = bonus; + } + + /** + * @return the speed bonus, or -1 if no bonus. + */ + public double getSpeedBonus() { + return speedBonus; + } + /** * @return the parallel logic type to use for recipes */ diff --git a/src/main/java/gregtech/api/capability/impl/BoilerRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/BoilerRecipeLogic.java index 292437e8921..d8510d363aa 100644 --- a/src/main/java/gregtech/api/capability/impl/BoilerRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/BoilerRecipeLogic.java @@ -4,7 +4,9 @@ import gregtech.api.capability.IMultiblockController; import gregtech.api.capability.IMultipleTankHandler; import gregtech.api.recipes.Recipe; +import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.RecipeMaps; +import gregtech.api.recipes.category.ICategoryOverride; import gregtech.api.unification.material.Materials; import gregtech.api.util.GTLog; import gregtech.common.ConfigHolder; @@ -28,7 +30,7 @@ import static gregtech.api.capability.GregtechDataCodes.BOILER_HEAT; import static gregtech.api.capability.GregtechDataCodes.BOILER_LAST_TICK_STEAM; -public class BoilerRecipeLogic extends AbstractRecipeLogic { +public class BoilerRecipeLogic extends AbstractRecipeLogic implements ICategoryOverride { private static final long STEAM_PER_WATER = 160; @@ -347,4 +349,14 @@ private static FluidStack getBoilerFluidFromContainer(@NotNull IFluidHandler flu } return drainedWater; } + + @Override + public @NotNull RecipeMap @NotNull [] getJEIRecipeMapCategoryOverrides() { + return new RecipeMap[] { RecipeMaps.COMBUSTION_GENERATOR_FUELS, RecipeMaps.SEMI_FLUID_GENERATOR_FUELS }; + } + + @Override + public @NotNull String @NotNull [] getJEICategoryOverrides() { + return new String[] { "minecraft.fuel" }; + } } diff --git a/src/main/java/gregtech/api/capability/impl/CleanroomLogic.java b/src/main/java/gregtech/api/capability/impl/CleanroomLogic.java index 24390dc9545..24dd0434e8f 100644 --- a/src/main/java/gregtech/api/capability/impl/CleanroomLogic.java +++ b/src/main/java/gregtech/api/capability/impl/CleanroomLogic.java @@ -19,7 +19,7 @@ public class CleanroomLogic { private int maxProgress = 0; private int progressTime = 0; - private final int minEnergyTier; + private int minEnergyTier; private final MetaTileEntity metaTileEntity; private final boolean hasMaintenance; @@ -48,6 +48,9 @@ public void updateLogic() { // all maintenance problems not fixed means the machine does not run if (hasMaintenance && ((IMaintenance) metaTileEntity).getNumMaintenanceProblems() > 5) return; + // if the energy tier is below min tier then do nothing + if (!isVoltageHighEnough()) return; + // drain the energy if (consumeEnergy(true)) { consumeEnergy(false); @@ -128,6 +131,10 @@ public void setWorkingEnabled(boolean workingEnabled) { } } + public boolean isVoltageHighEnough() { + return minEnergyTier <= ((ICleanroomProvider) metaTileEntity).getEnergyTier(); + } + /** * @return whether working is enabled for the logic */ @@ -165,6 +172,10 @@ protected int getTierDifference() { return ((ICleanroomProvider) metaTileEntity).getEnergyTier() - minEnergyTier; } + public void setMinEnergyTier(int energyTier) { + this.minEnergyTier = energyTier; + } + /** * writes all needed values to NBT * This MUST be called and returned in the MetaTileEntity's {@link MetaTileEntity#writeToNBT(NBTTagCompound)} method diff --git a/src/main/java/gregtech/api/damagesources/DamageSources.java b/src/main/java/gregtech/api/damagesources/DamageSources.java index 2283c396139..423b0417b63 100644 --- a/src/main/java/gregtech/api/damagesources/DamageSources.java +++ b/src/main/java/gregtech/api/damagesources/DamageSources.java @@ -49,23 +49,17 @@ public static DamageSource getTurbineDamage() { return TURBINE; } - // accessed via ASM - @SuppressWarnings("unused") public static DamageSource getPlayerDamage(@Nullable EntityPlayer source) { ItemStack stack = source != null ? source.getHeldItemMainhand() : ItemStack.EMPTY; - if (!stack.isEmpty() && stack.getItem() instanceof IGTTool) { - IGTTool tool = (IGTTool) stack.getItem(); + if (!stack.isEmpty() && stack.getItem() instanceof IGTTool tool) { return new DamageSourceTool("player", source, String.format("death.attack.%s", tool.getToolId())); } return new EntityDamageSource("player", source); } - // accessed via ASM - @SuppressWarnings("unused") public static DamageSource getMobDamage(@Nullable EntityLivingBase source) { ItemStack stack = source != null ? source.getItemStackFromSlot(EntityEquipmentSlot.MAINHAND) : ItemStack.EMPTY; - if (!stack.isEmpty() && stack.getItem() instanceof IGTTool) { - IGTTool tool = (IGTTool) stack.getItem(); + if (!stack.isEmpty() && stack.getItem() instanceof IGTTool tool) { return new DamageSourceTool("mob", source, String.format("death.attack.%s", tool.getToolId())); } return new EntityDamageSource("mob", source); diff --git a/src/main/java/gregtech/api/fluids/FluidBuilder.java b/src/main/java/gregtech/api/fluids/FluidBuilder.java index a7c9d6528ef..31c9caad896 100644 --- a/src/main/java/gregtech/api/fluids/FluidBuilder.java +++ b/src/main/java/gregtech/api/fluids/FluidBuilder.java @@ -390,7 +390,7 @@ private static int convertViscosity(double viscosity) { private void determineName(@Nullable Material material, @Nullable FluidStorageKey key) { if (name != null) return; if (material == null || key == null) throw new IllegalArgumentException("Fluid must have a name"); - name = key.getRegistryNameFor(material.getName()); + name = key.getRegistryNameFor(material); } private void determineTextures(@Nullable Material material, @Nullable FluidStorageKey key, @NotNull String modid) { diff --git a/src/main/java/gregtech/api/fluids/GTFluidRegistration.java b/src/main/java/gregtech/api/fluids/GTFluidRegistration.java index 52409e9f871..8f690c15c4c 100644 --- a/src/main/java/gregtech/api/fluids/GTFluidRegistration.java +++ b/src/main/java/gregtech/api/fluids/GTFluidRegistration.java @@ -82,7 +82,7 @@ public void register() { for (Material material : GregTechAPI.materialManager.getRegisteredMaterials()) { FluidProperty property = material.getProperty(PropertyKey.FLUID); if (property != null) { - property.getStorage().registerFluids(material); + property.registerFluids(material); } } } diff --git a/src/main/java/gregtech/api/fluids/store/FluidStorage.java b/src/main/java/gregtech/api/fluids/store/FluidStorage.java index fe7505423d0..f939e3b76e2 100644 --- a/src/main/java/gregtech/api/fluids/store/FluidStorage.java +++ b/src/main/java/gregtech/api/fluids/store/FluidStorage.java @@ -1,27 +1,13 @@ package gregtech.api.fluids.store; import gregtech.api.fluids.FluidBuilder; -import gregtech.api.unification.material.Material; -import gregtech.api.util.GTLog; import net.minecraftforge.fluids.Fluid; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Comparator; -import java.util.Map; - -public final class FluidStorage { - - private final Map map = new Object2ObjectOpenHashMap<>(); - private Map toRegister = new Object2ObjectOpenHashMap<>(); - - private boolean registered = false; - - public FluidStorage() {} +public interface FluidStorage { /** * Enqueue a fluid for registration @@ -29,81 +15,21 @@ public FluidStorage() {} * @param key the key corresponding with the fluid * @param builder the FluidBuilder to build */ - public void enqueueRegistration(@NotNull FluidStorageKey key, @NotNull FluidBuilder builder) { - if (registered) { - throw new IllegalStateException("Cannot enqueue a builder after registration"); - } - - if (toRegister.containsKey(key)) { - throw new IllegalArgumentException("FluidStorageKey " + key + " is already queued"); - } - toRegister.put(key, builder); - } + void enqueueRegistration(@NotNull FluidStorageKey key, @NotNull FluidBuilder builder); /** * @param key the key corresponding with the FluidBuilder * @return the fluid builder queued to be registered */ - public @Nullable FluidBuilder getQueuedBuilder(@NotNull FluidStorageKey key) { - if (registered) { - throw new IllegalArgumentException("FluidStorage has already been registered"); - } - return toRegister.get(key); - } - - /** - * Register the enqueued fluids - * - * @param material the material the fluid is based off of - */ - @ApiStatus.Internal - public void registerFluids(@NotNull Material material) { - if (registered) { - throw new IllegalStateException("FluidStorage has already been registered"); - } - - // If nothing is queued for registration and nothing is manually stored, - // we need something for the registry to handle this will prevent cases - // of a material having a fluid property but no fluids actually created - // for the material. - if (toRegister.isEmpty() && map.isEmpty()) { - enqueueRegistration(FluidStorageKeys.LIQUID, new FluidBuilder()); - } - - toRegister.entrySet().stream() - .sorted(Comparator.comparingInt(e -> -e.getKey().getRegistrationPriority())) - .forEach(entry -> { - Fluid fluid = entry.getValue().build(material.getModid(), material, entry.getKey()); - if (!storeNoOverwrites(entry.getKey(), fluid)) { - GTLog.logger.error("{} already has an associated fluid for material {}", material); - } - }); - toRegister = null; - registered = true; - } + @Nullable + FluidBuilder getQueuedBuilder(@NotNull FluidStorageKey key); /** * @param key the key corresponding with the fluid * @return the fluid associated with the key */ - public @Nullable Fluid get(@NotNull FluidStorageKey key) { - return map.get(key); - } - - /** - * Will do nothing if an existing fluid association would be overwritten. - * - * @param key the key to associate with the fluid - * @param fluid the fluid to associate with the key - * @return if the associations were successfully updated - */ - public boolean storeNoOverwrites(@NotNull FluidStorageKey key, @NotNull Fluid fluid) { - if (map.containsKey(key)) { - return false; - } - store(key, fluid); - return true; - } + @Nullable + Fluid get(@NotNull FluidStorageKey key); /** * Will overwrite existing fluid associations. @@ -111,7 +37,5 @@ public boolean storeNoOverwrites(@NotNull FluidStorageKey key, @NotNull Fluid fl * @param key the key to associate with the fluid * @param fluid the fluid to associate with the key */ - public void store(@NotNull FluidStorageKey key, @NotNull Fluid fluid) { - map.put(key, fluid); - } + void store(@NotNull FluidStorageKey key, @NotNull Fluid fluid); } diff --git a/src/main/java/gregtech/api/fluids/store/FluidStorageImpl.java b/src/main/java/gregtech/api/fluids/store/FluidStorageImpl.java new file mode 100644 index 00000000000..06911df8deb --- /dev/null +++ b/src/main/java/gregtech/api/fluids/store/FluidStorageImpl.java @@ -0,0 +1,101 @@ +package gregtech.api.fluids.store; + +import gregtech.api.fluids.FluidBuilder; +import gregtech.api.unification.material.Material; +import gregtech.api.util.GTLog; + +import net.minecraftforge.fluids.Fluid; + +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Comparator; +import java.util.Map; + +public final class FluidStorageImpl implements FluidStorage { + + private final Map map = new Object2ObjectOpenHashMap<>(); + private Map toRegister = new Object2ObjectOpenHashMap<>(); + + private boolean registered = false; + + public FluidStorageImpl() {} + + @Override + public void enqueueRegistration(@NotNull FluidStorageKey key, @NotNull FluidBuilder builder) { + if (registered) { + throw new IllegalStateException("Cannot enqueue a builder after registration"); + } + + if (toRegister.containsKey(key)) { + throw new IllegalArgumentException("FluidStorageKey " + key + " is already queued"); + } + toRegister.put(key, builder); + } + + @Override + public @Nullable FluidBuilder getQueuedBuilder(@NotNull FluidStorageKey key) { + if (registered) { + throw new IllegalArgumentException("FluidStorageImpl has already been registered"); + } + return toRegister.get(key); + } + + /** + * Register the enqueued fluids + * + * @param material the material the fluid is based off of + */ + @ApiStatus.Internal + public void registerFluids(@NotNull Material material) { + if (registered) { + throw new IllegalStateException("FluidStorageImpl has already been registered"); + } + + // If nothing is queued for registration and nothing is manually stored, + // we need something for the registry to handle this will prevent cases + // of a material having a fluid property but no fluids actually created + // for the material. + if (toRegister.isEmpty() && map.isEmpty()) { + enqueueRegistration(FluidStorageKeys.LIQUID, new FluidBuilder()); + } + + toRegister.entrySet().stream() + .sorted(Comparator.comparingInt(e -> -e.getKey().getRegistrationPriority())) + .forEach(entry -> { + Fluid fluid = entry.getValue().build(material.getModid(), material, entry.getKey()); + if (!storeNoOverwrites(entry.getKey(), fluid)) { + GTLog.logger.error("{} already has an associated fluid for material {}", material); + } + }); + toRegister = null; + registered = true; + } + + @Override + public @Nullable Fluid get(@NotNull FluidStorageKey key) { + return map.get(key); + } + + /** + * Will do nothing if an existing fluid association would be overwritten. + * + * @param key the key to associate with the fluid + * @param fluid the fluid to associate with the key + * @return if the associations were successfully updated + */ + private boolean storeNoOverwrites(@NotNull FluidStorageKey key, @NotNull Fluid fluid) { + if (map.containsKey(key)) { + return false; + } + store(key, fluid); + return true; + } + + @Override + public void store(@NotNull FluidStorageKey key, @NotNull Fluid fluid) { + map.put(key, fluid); + } +} diff --git a/src/main/java/gregtech/api/fluids/store/FluidStorageKey.java b/src/main/java/gregtech/api/fluids/store/FluidStorageKey.java index 7b58514aa35..4000c1d5ef9 100644 --- a/src/main/java/gregtech/api/fluids/store/FluidStorageKey.java +++ b/src/main/java/gregtech/api/fluids/store/FluidStorageKey.java @@ -12,7 +12,6 @@ import java.util.Map; import java.util.function.Function; -import java.util.function.UnaryOperator; public final class FluidStorageKey { @@ -20,32 +19,32 @@ public final class FluidStorageKey { private final ResourceLocation resourceLocation; private final MaterialIconType iconType; - private final UnaryOperator registryNameOperator; + private final Function registryNameFunction; private final Function translationKeyFunction; private final int hashCode; private final FluidState defaultFluidState; private final int registrationPriority; public FluidStorageKey(@NotNull ResourceLocation resourceLocation, @NotNull MaterialIconType iconType, - @NotNull UnaryOperator<@NotNull String> registryNameOperator, + @NotNull Function<@NotNull Material, @NotNull String> registryNameFunction, @NotNull Function<@NotNull Material, @NotNull String> translationKeyFunction) { - this(resourceLocation, iconType, registryNameOperator, translationKeyFunction, null); + this(resourceLocation, iconType, registryNameFunction, translationKeyFunction, null); } public FluidStorageKey(@NotNull ResourceLocation resourceLocation, @NotNull MaterialIconType iconType, - @NotNull UnaryOperator<@NotNull String> registryNameOperator, + @NotNull Function<@NotNull Material, @NotNull String> registryNameFunction, @NotNull Function<@NotNull Material, @NotNull String> translationKeyFunction, @Nullable FluidState defaultFluidState) { - this(resourceLocation, iconType, registryNameOperator, translationKeyFunction, defaultFluidState, 0); + this(resourceLocation, iconType, registryNameFunction, translationKeyFunction, defaultFluidState, 0); } public FluidStorageKey(@NotNull ResourceLocation resourceLocation, @NotNull MaterialIconType iconType, - @NotNull UnaryOperator<@NotNull String> registryNameOperator, + @NotNull Function<@NotNull Material, @NotNull String> registryNameFunction, @NotNull Function<@NotNull Material, @NotNull String> translationKeyFunction, @Nullable FluidState defaultFluidState, int registrationPriority) { this.resourceLocation = resourceLocation; this.iconType = iconType; - this.registryNameOperator = registryNameOperator; + this.registryNameFunction = registryNameFunction; this.translationKeyFunction = translationKeyFunction; this.hashCode = resourceLocation.hashCode(); this.defaultFluidState = defaultFluidState; @@ -72,8 +71,8 @@ public FluidStorageKey(@NotNull ResourceLocation resourceLocation, @NotNull Mate * @param baseName the base name of the fluid * @return the registry name to use */ - public @NotNull String getRegistryNameFor(@NotNull String baseName) { - return registryNameOperator.apply(baseName); + public @NotNull String getRegistryNameFor(@NotNull Material baseName) { + return registryNameFunction.apply(baseName); } /** diff --git a/src/main/java/gregtech/api/fluids/store/FluidStorageKeys.java b/src/main/java/gregtech/api/fluids/store/FluidStorageKeys.java index 3b9a6be51e8..515fb605270 100644 --- a/src/main/java/gregtech/api/fluids/store/FluidStorageKeys.java +++ b/src/main/java/gregtech/api/fluids/store/FluidStorageKeys.java @@ -1,10 +1,12 @@ package gregtech.api.fluids.store; import gregtech.api.fluids.FluidState; +import gregtech.api.unification.material.Material; import gregtech.api.unification.material.info.MaterialIconType; +import gregtech.api.unification.material.properties.FluidProperty; import gregtech.api.unification.material.properties.PropertyKey; -import java.util.function.UnaryOperator; +import org.jetbrains.annotations.NotNull; import static gregtech.api.util.GTUtility.gregtechId; @@ -12,18 +14,20 @@ public final class FluidStorageKeys { public static final FluidStorageKey LIQUID = new FluidStorageKey(gregtechId("liquid"), MaterialIconType.liquid, - UnaryOperator.identity(), + m -> prefixedRegistryName("liquid.", FluidStorageKeys.LIQUID, m), m -> m.hasProperty(PropertyKey.DUST) ? "gregtech.fluid.liquid_generic" : "gregtech.fluid.generic", FluidState.LIQUID); public static final FluidStorageKey GAS = new FluidStorageKey(gregtechId("gas"), MaterialIconType.gas, - UnaryOperator.identity(), + m -> prefixedRegistryName("gas.", FluidStorageKeys.GAS, m), m -> { if (m.hasProperty(PropertyKey.DUST)) { return "gregtech.fluid.gas_vapor"; } - if (m.isElement()) { + + FluidProperty property = m.getProperty(PropertyKey.FLUID); + if (m.isElement() || (property != null && property.getPrimaryKey() != FluidStorageKeys.LIQUID)) { return "gregtech.fluid.gas_generic"; } return "gregtech.fluid.generic"; @@ -32,8 +36,24 @@ public final class FluidStorageKeys { public static final FluidStorageKey PLASMA = new FluidStorageKey(gregtechId("plasma"), MaterialIconType.plasma, - s -> "plasma." + s, m -> "gregtech.fluid.plasma", + m -> "plasma." + m.getName(), + m -> "gregtech.fluid.plasma", FluidState.PLASMA, -1); private FluidStorageKeys() {} + + /** + * @param prefix the prefix string for the registry name + * @param key the key which does not require the prefix + * @param material the material to create a registry name for + * @return the registry name + */ + private static @NotNull String prefixedRegistryName(@NotNull String prefix, @NotNull FluidStorageKey key, + @NotNull Material material) { + FluidProperty property = material.getProperty(PropertyKey.FLUID); + if (property != null && property.getPrimaryKey() != key) { + return prefix + material.getName(); + } + return material.getName(); + } } diff --git a/src/main/java/gregtech/api/items/metaitem/MusicDiscStats.java b/src/main/java/gregtech/api/items/metaitem/MusicDiscStats.java index a505896cb24..b90f1ce5f88 100644 --- a/src/main/java/gregtech/api/items/metaitem/MusicDiscStats.java +++ b/src/main/java/gregtech/api/items/metaitem/MusicDiscStats.java @@ -31,6 +31,10 @@ public SoundEvent getSound() { return sound; } + public String getName() { + return sound.getSoundName().getPath(); + } + @Override public ActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index fd0f404e2dc..c5c183e6113 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -24,6 +24,7 @@ import gregtech.api.items.toolitem.ToolHelper; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.interfaces.ISyncedTileEntity; +import gregtech.api.metatileentity.registry.MTERegistry; import gregtech.api.mui.GTGuiTheme; import gregtech.api.mui.GregTechGuiScreen; import gregtech.api.mui.factory.MetaTileEntityGuiFactory; @@ -120,6 +121,8 @@ public abstract class MetaTileEntity implements ISyncedTileEntity, CoverHolder, public static final String TAG_KEY_PAINTING_COLOR = "PaintingColor"; public static final String TAG_KEY_MUFFLED = "Muffled"; + private final MTERegistry registry; + public final ResourceLocation metaTileEntityId; IGregTechTileEntity holder; @@ -157,8 +160,9 @@ public abstract class MetaTileEntity implements ISyncedTileEntity, CoverHolder, private int playSoundCooldown = 0; private int lastTick = 0; - public MetaTileEntity(ResourceLocation metaTileEntityId) { + protected MetaTileEntity(@NotNull ResourceLocation metaTileEntityId) { this.metaTileEntityId = metaTileEntityId; + this.registry = GregTechAPI.mteManager.getRegistry(metaTileEntityId.getNamespace()); initializeInventory(); } @@ -884,9 +888,9 @@ private void updateSound() { } } - public final ItemStack getStackForm(int amount) { - int metaTileEntityIntId = GregTechAPI.MTE_REGISTRY.getIdByObjectName(metaTileEntityId); - return new ItemStack(GregTechAPI.MACHINE, amount, metaTileEntityIntId); + public final @NotNull ItemStack getStackForm(int amount) { + int metaTileEntityIntId = registry.getIdByObjectName(metaTileEntityId); + return new ItemStack(registry.getBlock(), amount, metaTileEntityIntId); } @Override @@ -894,6 +898,14 @@ public final ItemStack getStackForm(int amount) { return getStackForm(1); } + public final @NotNull MTERegistry getRegistry() { + return registry; + } + + public final @NotNull BlockMachine getBlock() { + return registry.getBlock(); + } + /** * Add special drops which this meta tile entity contains here * Meta tile entity item is ALREADY added into this list diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java index 5c6487e6180..b0bd546db51 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java @@ -6,6 +6,7 @@ import gregtech.api.cover.Cover; import gregtech.api.gui.IUIHolder; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.registry.MTERegistry; import gregtech.api.util.GTLog; import gregtech.api.util.Mods; import gregtech.api.util.TextFormattingUtil; @@ -24,7 +25,11 @@ import net.minecraft.util.Rotation; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.text.*; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.Style; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.text.TextFormatting; import net.minecraft.world.IWorldNameable; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; @@ -90,7 +95,9 @@ public MetaTileEntity setMetaTileEntity(MetaTileEntity sampleMetaTileEntity) { if (hasWorld() && !getWorld().isRemote) { updateBlockOpacity(); writeCustomData(INITIALIZE_MTE, buffer -> { - buffer.writeVarInt(GregTechAPI.MTE_REGISTRY.getIdByObjectName(getMetaTileEntity().metaTileEntityId)); + buffer.writeVarInt(sampleMetaTileEntity.getRegistry().getNetworkId()); + buffer.writeVarInt( + sampleMetaTileEntity.getRegistry().getIdByObjectName(getMetaTileEntity().metaTileEntityId)); getMetaTileEntity().writeInitialSyncData(buffer); }); // just to update neighbours so cables and other things will work properly @@ -126,7 +133,8 @@ public void readFromNBT(@NotNull NBTTagCompound compound) { if (compound.hasKey("MetaId", NBT.TAG_STRING)) { String metaTileEntityIdRaw = compound.getString("MetaId"); ResourceLocation metaTileEntityId = new ResourceLocation(metaTileEntityIdRaw); - MetaTileEntity sampleMetaTileEntity = GregTechAPI.MTE_REGISTRY.getObject(metaTileEntityId); + MTERegistry registry = GregTechAPI.mteManager.getRegistry(metaTileEntityId.getNamespace()); + MetaTileEntity sampleMetaTileEntity = registry.getObject(metaTileEntityId); NBTTagCompound metaTileEntityData = compound.getCompoundTag("MetaTileEntity"); if (sampleMetaTileEntity != null) { setRawMetaTileEntity(sampleMetaTileEntity.createMetaTileEntity(this)); @@ -136,7 +144,7 @@ public void readFromNBT(@NotNull NBTTagCompound compound) { */ this.metaTileEntity.readFromNBT(metaTileEntityData); } else { - GTLog.logger.error("Failed to load MetaTileEntity with invalid ID " + metaTileEntityIdRaw); + GTLog.logger.error("Failed to load MetaTileEntity with invalid ID {}", metaTileEntityIdRaw); } if (Mods.AppliedEnergistics2.isModLoaded()) { readFromNBT_AENetwork(compound); @@ -297,7 +305,8 @@ public void writeInitialSyncData(@NotNull PacketBuffer buf) { buf.writeString(getName()); if (metaTileEntity != null) { buf.writeBoolean(true); - buf.writeVarInt(GregTechAPI.MTE_REGISTRY.getIdByObjectName(metaTileEntity.metaTileEntityId)); + buf.writeVarInt(metaTileEntity.getRegistry().getNetworkId()); + buf.writeVarInt(metaTileEntity.getRegistry().getIdByObjectName(metaTileEntity.metaTileEntityId)); metaTileEntity.writeInitialSyncData(buf); } else buf.writeBoolean(false); } @@ -325,8 +334,10 @@ public void receiveCustomData(int discriminator, @NotNull PacketBuffer buffer) { * @param buf the buffer to read data from */ private void receiveMTEInitializationData(@NotNull PacketBuffer buf) { + int networkId = buf.readVarInt(); int metaTileEntityId = buf.readVarInt(); - setMetaTileEntity(GregTechAPI.MTE_REGISTRY.getObjectById(metaTileEntityId)); + MTERegistry registry = GregTechAPI.mteManager.getRegistry(networkId); + setMetaTileEntity(registry.getObjectById(metaTileEntityId)); this.metaTileEntity.onPlacement(); this.metaTileEntity.receiveInitialSyncData(buf); scheduleRenderUpdate(); diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java index 54b5bd45b5c..7f8ff37dba1 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java @@ -8,7 +8,11 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.pattern.*; +import gregtech.api.pattern.BlockPattern; +import gregtech.api.pattern.BlockWorldState; +import gregtech.api.pattern.MultiblockShapeInfo; +import gregtech.api.pattern.PatternMatchContext; +import gregtech.api.pattern.TraceabilityPredicate; import gregtech.api.pipenet.tile.IPipeTile; import gregtech.api.unification.material.Material; import gregtech.api.util.BlockInfo; @@ -52,7 +56,18 @@ 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.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.Stack; import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; @@ -206,7 +221,7 @@ private static Supplier getCandidates(MetaTileEntity... metaTileEnt holder.setMetaTileEntity(tile); holder.getMetaTileEntity().onPlacement(); holder.getMetaTileEntity().setFrontFacing(EnumFacing.SOUTH); - return new BlockInfo(MetaBlocks.MACHINE.getDefaultState(), holder); + return new BlockInfo(tile.getBlock().getDefaultState(), holder); }).toArray(BlockInfo[]::new); } diff --git a/src/main/java/gregtech/api/metatileentity/registry/MTEManager.java b/src/main/java/gregtech/api/metatileentity/registry/MTEManager.java new file mode 100644 index 00000000000..601fc941a26 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/registry/MTEManager.java @@ -0,0 +1,91 @@ +package gregtech.api.metatileentity.registry; + +import gregtech.api.GTValues; + +import net.minecraftforge.fml.common.eventhandler.Event; + +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.UnmodifiableView; + +import java.util.Collection; +import java.util.Map; + +public final class MTEManager { + + private static MTEManager instance; + + private static int networkId; + private static MTERegistry internalRegistry; + + private final Map registryMap = new Object2ObjectOpenHashMap<>(); + private final Int2ObjectMap networkMap = new Int2ObjectOpenHashMap<>(); + + /** + * @return the global MTE Manager instance + */ + @ApiStatus.Internal + public static @NotNull MTEManager getInstance() { + if (instance == null) { + instance = new MTEManager(); + internalRegistry = instance.createRegistry(GTValues.MODID); + } + return instance; + } + + private MTEManager() {} + + /** + * @param modid the modid of the registry + * @return the registry associated with the modid, otherwise the default registry + */ + public @NotNull MTERegistry getRegistry(@NotNull String modid) { + MTERegistry registry = registryMap.get(modid); + if (registry == null) { + throw new IllegalArgumentException("No MTE registry exists for modid " + modid); + } + return registry; + } + + /** + * Create an MTE Registry + * + * @param modid the modid for the registry + * @return the created registry + */ + public @NotNull MTERegistry createRegistry(@NotNull String modid) { + if (registryMap.containsKey(modid)) { + throw new IllegalArgumentException("MTE Registry for modid " + modid + " is already registered"); + } + MTERegistry registry = new MTERegistry(modid, ++networkId); + registryMap.put(modid, registry); + networkMap.put(networkId, registry); + return registry; + } + + /** + * @param networkId the network id of the registry + * @return the registry associated with the network id, otherwise the default registry + */ + public @NotNull MTERegistry getRegistry(int networkId) { + MTERegistry registry = networkMap.get(networkId); + return registry == null ? internalRegistry : registry; + } + + /** + * @return all the available MTE registries + */ + public @NotNull @UnmodifiableView Collection<@NotNull MTERegistry> getRegistries() { + return registryMap.values(); + } + + /** + * Event during which MTE Registries should be added by mods. + *

+ * Use {@link #createRegistry(String)} to create a new MTE registry. + */ + public static class MTERegistryEvent extends Event {} +} diff --git a/src/main/java/gregtech/api/metatileentity/registry/MTERegistry.java b/src/main/java/gregtech/api/metatileentity/registry/MTERegistry.java new file mode 100644 index 00000000000..13155a63d9a --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/registry/MTERegistry.java @@ -0,0 +1,80 @@ +package gregtech.api.metatileentity.registry; + +import gregtech.api.block.machines.BlockMachine; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.util.GTControlledRegistry; + +import net.minecraft.util.ResourceLocation; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +public final class MTERegistry extends GTControlledRegistry { + + private final String modid; + private final int networkId; + + private BlockMachine block; + + public MTERegistry(@NotNull String modid, int networkId) { + super(Short.MAX_VALUE); + this.modid = modid; + this.networkId = networkId; + } + + @Override + public void register(int id, @NotNull ResourceLocation key, @NotNull MetaTileEntity value) { + if (!canRegister(key.getNamespace())) { + throw new IllegalArgumentException("Cannot register MTE to another mod's registry"); + } + super.register(id, key, value); + } + + /** + * @param modid the modid to test + * @return if the mod is allowed to be registered to this registry + */ + private boolean canRegister(@NotNull String modid) { + return this.modid.equals(modid); + } + + /** + * @return the modid of this registry + */ + public @NotNull String getModid() { + return this.modid; + } + + /** + * @return the id used to represent this MTE Registry over the network + */ + public int getNetworkId() { + return this.networkId; + } + + /** + * @return the Block associated with this registry + */ + public @NotNull BlockMachine getBlock() { + return this.block; + } + + /** + * Initialize the registry's Block + * + * @param block the block to set + */ + @ApiStatus.Internal + public void setBlock(@NotNull BlockMachine block) { + this.block = block; + } + + @Override + public String toString() { + return "MTERegistry{" + + "modid='" + modid + '\'' + + ", networkId=" + networkId + + ", block=" + block + + '}'; + } +} diff --git a/src/main/java/gregtech/api/mui/GTGuiTextures.java b/src/main/java/gregtech/api/mui/GTGuiTextures.java index d585285efc2..f17affee609 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTextures.java +++ b/src/main/java/gregtech/api/mui/GTGuiTextures.java @@ -176,7 +176,9 @@ public static class IDs { 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", + public static final UITexture[] MANUAL_IO_OVERLAY_IN = slice("textures/gui/overlay/manual_io_overlay_in.png", + 18, 18 * 3, 18, 18, true); + public static final UITexture[] MANUAL_IO_OVERLAY_OUT = slice("textures/gui/overlay/manual_io_overlay_out.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); diff --git a/src/main/java/gregtech/api/pattern/BlockPattern.java b/src/main/java/gregtech/api/pattern/BlockPattern.java index 667202c7404..f392ba1b26e 100644 --- a/src/main/java/gregtech/api/pattern/BlockPattern.java +++ b/src/main/java/gregtech/api/pattern/BlockPattern.java @@ -5,9 +5,9 @@ import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.api.metatileentity.registry.MTERegistry; import gregtech.api.util.BlockInfo; import gregtech.api.util.RelativeDirection; -import gregtech.common.blocks.MetaBlocks; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; @@ -382,12 +382,12 @@ public void autoBuild(EntityPlayer player, MultiblockControllerBase controllerBa blocks.put(pos, state); world.setBlockState(pos, state); TileEntity holder = world.getTileEntity(pos); - if (holder instanceof IGregTechTileEntity) { - MetaTileEntity sampleMetaTileEntity = GregTechAPI.MTE_REGISTRY - .getObjectById(found.getItemDamage()); + if (holder instanceof IGregTechTileEntity igtte) { + MTERegistry registry = GregTechAPI.mteManager + .getRegistry(found.getItem().getRegistryName().getNamespace()); + MetaTileEntity sampleMetaTileEntity = registry.getObjectById(found.getItemDamage()); if (sampleMetaTileEntity != null) { - MetaTileEntity metaTileEntity = ((IGregTechTileEntity) holder) - .setMetaTileEntity(sampleMetaTileEntity); + MetaTileEntity metaTileEntity = igtte.setMetaTileEntity(sampleMetaTileEntity); metaTileEntity.onPlacement(); blocks.put(pos, metaTileEntity); if (found.getTagCompound() != null) { @@ -577,7 +577,7 @@ public BlockInfo[][][] getPreview(int[] repetition) { MetaTileEntityHolder holder = new MetaTileEntityHolder(); holder.setMetaTileEntity(((MetaTileEntityHolder) info.getTileEntity()).getMetaTileEntity()); holder.getMetaTileEntity().onPlacement(); - info = new BlockInfo(MetaBlocks.MACHINE.getDefaultState(), holder); + info = new BlockInfo(holder.getMetaTileEntity().getBlock().getDefaultState(), holder); } blocks.put(pos, info); minX = Math.min(pos.getX(), minX); diff --git a/src/main/java/gregtech/api/pattern/MultiblockShapeInfo.java b/src/main/java/gregtech/api/pattern/MultiblockShapeInfo.java index a768aae5c68..f8cd3a5cbaf 100644 --- a/src/main/java/gregtech/api/pattern/MultiblockShapeInfo.java +++ b/src/main/java/gregtech/api/pattern/MultiblockShapeInfo.java @@ -3,7 +3,6 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.util.BlockInfo; -import gregtech.common.blocks.MetaBlocks; import net.minecraft.block.state.IBlockState; import net.minecraft.tileentity.TileEntity; @@ -65,7 +64,7 @@ public Builder where(char symbol, MetaTileEntity tileEntity, EnumFacing frontSid holder.setMetaTileEntity(tileEntity); holder.getMetaTileEntity().onPlacement(); holder.getMetaTileEntity().setFrontFacing(frontSide); - return where(symbol, new BlockInfo(MetaBlocks.MACHINE.getDefaultState(), holder)); + return where(symbol, new BlockInfo(tileEntity.getBlock().getDefaultState(), holder)); } /** diff --git a/src/main/java/gregtech/api/recipes/category/ICategoryOverride.java b/src/main/java/gregtech/api/recipes/category/ICategoryOverride.java new file mode 100644 index 00000000000..fbbc8acb68c --- /dev/null +++ b/src/main/java/gregtech/api/recipes/category/ICategoryOverride.java @@ -0,0 +1,51 @@ +package gregtech.api.recipes.category; + +import gregtech.api.recipes.RecipeMap; + +import org.jetbrains.annotations.NotNull; + +/** + * When a registered mte's class or recipe logic implements this interface, the mte is associated with the override's + * recipe maps in JEI. + */ +public interface ICategoryOverride { + + /** + * Controls whether the override should be performed or not. + * Useful to disable overrides if a class's parent implements this interface. + * + * @return whether the override should be performed or not + */ + default boolean shouldOverride() { + return true; + } + + /** + * Controls whether the normal logic for determining JEI category association should be completely replaced. + * + * @return whether to ignore normal logic or not + */ + default boolean shouldReplace() { + return true; + } + + /** + * The actual overrides for JEI recipe map category association. + * + * @return an array of recipe maps the mte should be associated with in JEI. Can be empty, but not null. + */ + default @NotNull RecipeMap @NotNull [] getJEIRecipeMapCategoryOverrides() { + return new RecipeMap[] {}; + } + + /** + * Allows JEI category association using JEI's underlying API. + * Use this to associate a multiblock with solid, burnable fuel recipes for example. + * + * @return an array of recipe category UUIDs that are valid for JEI's + * {@link mezz.jei.api.IModRegistry#addRecipeCatalyst(Object, String...)} method. + */ + default @NotNull String @NotNull [] getJEICategoryOverrides() { + return new String[] {}; + } +} diff --git a/src/main/java/gregtech/api/recipes/ingredients/GTRecipeOreInput.java b/src/main/java/gregtech/api/recipes/ingredients/GTRecipeOreInput.java index e36d9e39370..a742a23c819 100644 --- a/src/main/java/gregtech/api/recipes/ingredients/GTRecipeOreInput.java +++ b/src/main/java/gregtech/api/recipes/ingredients/GTRecipeOreInput.java @@ -7,12 +7,19 @@ import net.minecraft.item.ItemStack; import net.minecraftforge.oredict.OreDictionary; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.Objects; public class GTRecipeOreInput extends GTRecipeInput { + // Standard forces a refresh of the input stack cache + // Used in GroovyScript Reload, and to avoid race conditions with CraftTweaker. + // Short.MAX_VALUE should be enough for the amount of times this is loaded + // (1 without GroovyScript Reload, Amount of GroovyScript Reloads otherwise) + private static short STANDARD = 0; + private short currentStandard; private final int ore; private ItemStack[] inputStacks; @@ -88,12 +95,15 @@ public GTRecipeInput copyWithAmount(int amount) { return copy; } - // The items returned here are not updated after its first call, so they are not suitable for use while recipes are - // being processed and + // The items returned here are not updated after its first call, unless standard is changed, + // so they are not suitable for use while recipes are being processed and // the OreDicts being modified. @Override public ItemStack[] getInputStacks() { - if (this.inputStacks == null) { + // Standard forces a refresh of the input stack cache. + // Used in GroovyScript Reload, and upon Load Complete to fix unreliable behaviour with CT and GS scripts. + if (inputStacks == null || currentStandard != STANDARD) { + currentStandard = STANDARD; inputStacks = (OreDictionary.getOres(OreDictionary.getOreName(ore)).stream().map(is -> { is = is.copy(); is.setCount(this.amount); @@ -163,4 +173,12 @@ public String toString() { // noinspection StringConcatenationMissingWhitespace return amount + "x" + OreDictionary.getOreName(ore); } + + /** + * Forces a Refresh of every GTRecipeOreInput's Stack Cache. + */ + @ApiStatus.Internal + public static void refreshStackCache() { + STANDARD++; + } } diff --git a/src/main/java/gregtech/api/unification/material/Material.java b/src/main/java/gregtech/api/unification/material/Material.java index 8a80801af48..18770e5325c 100644 --- a/src/main/java/gregtech/api/unification/material/Material.java +++ b/src/main/java/gregtech/api/unification/material/Material.java @@ -209,10 +209,7 @@ public Fluid getFluid() { throw new IllegalArgumentException("Material " + getResourceLocation() + " does not have a Fluid!"); } - FluidStorageKey key = prop.getPrimaryKey(); - Fluid fluid = null; - - if (key != null) fluid = prop.getStorage().get(key); + Fluid fluid = prop.get(prop.getPrimaryKey()); if (fluid != null) return fluid; fluid = getFluid(FluidStorageKeys.LIQUID); @@ -231,7 +228,7 @@ public Fluid getFluid(@NotNull FluidStorageKey key) { throw new IllegalArgumentException("Material " + getResourceLocation() + " does not have a Fluid!"); } - return prop.getStorage().get(key); + return prop.get(key); } /** @@ -522,7 +519,8 @@ public Builder fluid(@NotNull FluidStorageKey key, @NotNull FluidState state) { public Builder fluid(@NotNull FluidStorageKey key, @NotNull FluidBuilder builder) { properties.ensureSet(PropertyKey.FLUID); FluidProperty property = properties.getProperty(PropertyKey.FLUID); - property.getStorage().enqueueRegistration(key, builder); + property.enqueueRegistration(key, builder); + return this; } @@ -535,7 +533,8 @@ public Builder fluid(@NotNull FluidStorageKey key, @NotNull FluidBuilder builder public Builder fluid(@NotNull Fluid fluid, @NotNull FluidStorageKey key, @NotNull FluidState state) { properties.ensureSet(PropertyKey.FLUID); FluidProperty property = properties.getProperty(PropertyKey.FLUID); - property.getStorage().store(key, fluid); + property.store(key, fluid); + postProcessors.add( m -> FluidTooltipUtil.registerTooltip(fluid, FluidTooltipUtil.createFluidTooltip(m, fluid, state))); return this; 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 c5136fc4a32..9f6c190d6f3 100644 --- a/src/main/java/gregtech/api/unification/material/materials/FirstDegreeMaterials.java +++ b/src/main/java/gregtech/api/unification/material/materials/FirstDegreeMaterials.java @@ -1204,7 +1204,7 @@ public static void register() { .build(); Iron3Chloride = new Material.Builder(411, gregtechId("iron_iii_chloride")) - .fluid() + .liquid() .color(0x060B0B) .flags(DECOMPOSITION_BY_ELECTROLYZING) .components(Iron, 1, Chlorine, 3) diff --git a/src/main/java/gregtech/api/unification/material/materials/OrganicChemistryMaterials.java b/src/main/java/gregtech/api/unification/material/materials/OrganicChemistryMaterials.java index de2bdf4a703..7bc82ca2805 100644 --- a/src/main/java/gregtech/api/unification/material/materials/OrganicChemistryMaterials.java +++ b/src/main/java/gregtech/api/unification/material/materials/OrganicChemistryMaterials.java @@ -97,7 +97,7 @@ public static void register() { .polymer() .liquid(new FluidBuilder().temperature(1450)) .color(0x2D2D2D) - .flags(EXCLUDE_BLOCK_CRAFTING_RECIPES, GENERATE_FOIL) + .flags(GENERATE_FOIL) .components(Carbon, 20, Hydrogen, 12, Nitrogen, 4) .fluidPipeProperties(1000, 350, true) .build(); 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 80c971fb4f1..d8662ec6bed 100644 --- a/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java +++ b/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java @@ -1,51 +1,114 @@ package gregtech.api.unification.material.properties; +import gregtech.api.fluids.FluidBuilder; import gregtech.api.fluids.store.FluidStorage; +import gregtech.api.fluids.store.FluidStorageImpl; import gregtech.api.fluids.store.FluidStorageKey; import gregtech.api.fluids.store.FluidStorageKeys; +import gregtech.api.unification.material.Material; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class FluidProperty implements IMaterialProperty { +public class FluidProperty implements IMaterialProperty, FluidStorage { - private final FluidStorage storage = new FluidStorage(); - private @Nullable FluidStorageKey primaryKey = null; + private final FluidStorageImpl storage = new FluidStorageImpl(); + private FluidStorageKey primaryKey = null; private @Nullable Fluid solidifyingFluid = null; public FluidProperty() {} + /** + * Helper constructor which automatically calls {@link #enqueueRegistration(FluidStorageKey, FluidBuilder)} for a + * builder. + *

+ * This is primarily useful for adding FluidProperties to materials after they are registered with a single fluid + * stored. + * + * @param key the fluid storage key to store the builder with + * @param builder the builder to enqueue + */ + public FluidProperty(@NotNull FluidStorageKey key, @NotNull FluidBuilder builder) { + enqueueRegistration(key, builder); + } + + /** + * Obsolete method, FluidProperty now contains this functionality. + * + * @deprecated {@link FluidStorage} + */ + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") + @Deprecated public @NotNull FluidStorage getStorage() { - return this.storage; + return this; } /** - * @return the FluidStorageKey fluid is stored as primarily + * @see FluidStorageImpl#registerFluids(Material) */ - public @Nullable FluidStorageKey getPrimaryKey() { + @ApiStatus.Internal + public void registerFluids(@NotNull Material material) { + this.storage.registerFluids(material); + } + + @Override + public void enqueueRegistration(@NotNull FluidStorageKey key, @NotNull FluidBuilder builder) { + storage.enqueueRegistration(key, builder); + if (primaryKey == null) { + primaryKey = key; + } + } + + @Override + public void store(@NotNull FluidStorageKey key, @NotNull Fluid fluid) { + storage.store(key, fluid); + if (primaryKey == null) { + primaryKey = key; + } + } + + @Override + public @Nullable Fluid get(@NotNull FluidStorageKey key) { + return storage.get(key); + } + + @Override + public @Nullable FluidBuilder getQueuedBuilder(@NotNull FluidStorageKey key) { + return storage.getQueuedBuilder(key); + } + + /** + * + * @return the key the fluid is stored with primarily + */ + public @NotNull FluidStorageKey getPrimaryKey() { return primaryKey; } /** * @param primaryKey the key to use primarily */ - public void setPrimaryKey(@Nullable FluidStorageKey primaryKey) { + public void setPrimaryKey(@NotNull FluidStorageKey primaryKey) { this.primaryKey = primaryKey; } @Override - public void verifyProperty(MaterialProperties properties) {} + public void verifyProperty(MaterialProperties properties) { + if (this.primaryKey == null) { + throw new IllegalStateException("FluidProperty cannot be empty"); + } + } /** * @return the Fluid which solidifies into the material. */ - - public Fluid solidifiesFrom() { + public @Nullable Fluid solidifiesFrom() { if (this.solidifyingFluid == null) { - return getStorage().get(FluidStorageKeys.LIQUID); + return storage.get(FluidStorageKeys.LIQUID); } return solidifyingFluid; } diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index 553279c72f4..b574780e6af 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -15,6 +15,7 @@ import gregtech.api.metatileentity.SimpleGeneratorMetaTileEntity; import gregtech.api.metatileentity.WorkableTieredMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.registry.MTERegistry; import gregtech.api.recipes.RecipeMap; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.ore.OrePrefix; @@ -66,6 +67,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.Random; import java.util.Set; import java.util.function.BooleanSupplier; @@ -704,7 +706,9 @@ public static MetaTileEntity getMetaTileEntity(IBlockAccess world, BlockPos pos) public static MetaTileEntity getMetaTileEntity(ItemStack stack) { if (!(stack.getItem() instanceof MachineItemBlock)) return null; - return GregTechAPI.MTE_REGISTRY.getObjectById(stack.getItemDamage()); + MTERegistry registry = GregTechAPI.mteManager.getRegistry( + Objects.requireNonNull(stack.getItem().getRegistryName()).getNamespace()); + return registry.getObjectById(stack.getItemDamage()); } /** diff --git a/src/main/java/gregtech/api/util/Mods.java b/src/main/java/gregtech/api/util/Mods.java index c022672f095..b62a262856d 100644 --- a/src/main/java/gregtech/api/util/Mods.java +++ b/src/main/java/gregtech/api/util/Mods.java @@ -54,6 +54,7 @@ public enum Mods { InventoryTweaks(Names.INVENTORY_TWEAKS), JourneyMap(Names.JOURNEY_MAP), JustEnoughItems(Names.JUST_ENOUGH_ITEMS), + LittleTiles(Names.LITTLE_TILES), MagicBees(Names.MAGIC_BEES), Nothirium(Names.NOTHIRIUM), NuclearCraft(Names.NUCLEAR_CRAFT, versionExcludes("2o")), @@ -68,6 +69,8 @@ public enum Mods { TOPAddons(Names.TOP_ADDONS), VoxelMap(Names.VOXEL_MAP), XaerosMinimap(Names.XAEROS_MINIMAP), + Vintagium(Names.VINTAGIUM), + Alfheim(Names.ALFHEIM), // Special Optifine handler, but consolidated here for simplicity Optifine(null) { @@ -122,6 +125,7 @@ public static class Names { 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 LITTLE_TILES = "littletiles"; public static final String MAGIC_BEES = "magicbees"; public static final String NOTHIRIUM = "nothirium"; public static final String NUCLEAR_CRAFT = "nuclearcraft"; @@ -135,6 +139,8 @@ public static class Names { public static final String TOP_ADDONS = "topaddons"; public static final String VOXEL_MAP = "voxelmap"; public static final String XAEROS_MINIMAP = "xaerominimap"; + public static final String VINTAGIUM = "vintagium"; + public static final String ALFHEIM = "alfheim"; } private final String ID; diff --git a/src/main/java/gregtech/api/util/world/DummyWorld.java b/src/main/java/gregtech/api/util/world/DummyWorld.java index 858a27138bb..451940347b9 100644 --- a/src/main/java/gregtech/api/util/world/DummyWorld.java +++ b/src/main/java/gregtech/api/util/world/DummyWorld.java @@ -1,5 +1,7 @@ package gregtech.api.util.world; +import gregtech.api.util.Mods; + import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.profiler.Profiler; @@ -10,6 +12,7 @@ import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.storage.WorldInfo; import net.minecraftforge.fml.common.ObfuscationReflectionHelper; +import net.minecraftforge.fml.common.Optional.Method; import net.minecraftforge.fml.relauncher.FMLLaunchHandler; import org.jetbrains.annotations.NotNull; @@ -37,6 +40,12 @@ public DummyWorld() { // De-allocate lightUpdateBlockList, checkLightFor uses this ObfuscationReflectionHelper.setPrivateValue(World.class, this, null, FMLLaunchHandler.isDeobfuscatedEnvironment() ? "lightUpdateBlockList" : "field_72994_J"); + + // De-allocate alfheim lighting engine + if (Mods.Alfheim.isModLoaded()) { + ObfuscationReflectionHelper.setPrivateValue(World.class, this, null, + "alfheim$lightingEngine"); + } } @Override @@ -90,4 +99,21 @@ protected boolean isChunkLoaded(int x, int z, boolean allowEmpty) { public boolean checkLightFor(@NotNull EnumSkyBlock lightType, @NotNull BlockPos pos) { return true; } + + @Override + @Method(modid = Mods.Names.ALFHEIM) + public World init() { + return this; + } + + @Override + @Method(modid = Mods.Names.ALFHEIM) + public int getLightFromNeighborsFor(EnumSkyBlock type, BlockPos pos) { + return 15; + } + + @Method(modid = Mods.Names.ALFHEIM) + public int alfheim$getLight(BlockPos pos, boolean checkNeighbors) { + return 15; + } } diff --git a/src/main/java/gregtech/asm/GregTechLoadingPlugin.java b/src/main/java/gregtech/asm/GregTechLoadingPlugin.java index b1e461c7954..ab48a079c83 100644 --- a/src/main/java/gregtech/asm/GregTechLoadingPlugin.java +++ b/src/main/java/gregtech/asm/GregTechLoadingPlugin.java @@ -8,14 +8,18 @@ import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin.TransformerExclusions; import org.jetbrains.annotations.Nullable; +import zone.rong.mixinbooter.IEarlyMixinLoader; +import java.util.ArrayList; +import java.util.List; import java.util.Map; @Name("GregTechLoadingPlugin") @MCVersion(ForgeVersion.mcVersion) @TransformerExclusions("gregtech.asm.") @SortingIndex(1001) -public class GregTechLoadingPlugin implements IFMLLoadingPlugin { +// TODO, move to mixin package +public class GregTechLoadingPlugin implements IFMLLoadingPlugin, IEarlyMixinLoader { @Override public String[] getASMTransformerClass() { @@ -40,4 +44,19 @@ public void injectData(Map data) {} public String getAccessTransformerClass() { return null; } + + @Override + public List getMixinConfigs() { + List configs = new ArrayList<>(); + + configs.add("mixins.gregtech.forge.json"); + configs.add("mixins.gregtech.minecraft.json"); + + return configs; + } + + @Override + public boolean shouldMixinConfigQueue(String mixinConfig) { + return IEarlyMixinLoader.super.shouldMixinConfigQueue(mixinConfig); + } } diff --git a/src/main/java/gregtech/asm/GregTechTransformer.java b/src/main/java/gregtech/asm/GregTechTransformer.java index 005ec295075..9a13badeaf5 100644 --- a/src/main/java/gregtech/asm/GregTechTransformer.java +++ b/src/main/java/gregtech/asm/GregTechTransformer.java @@ -1,21 +1,8 @@ package gregtech.asm; -import gregtech.api.util.Mods; -import gregtech.asm.util.ObfMapping; -import gregtech.asm.util.TargetClassVisitor; -import gregtech.asm.visitors.*; -import gregtech.common.ConfigHolder; - import net.minecraft.launchwrapper.IClassTransformer; -import net.minecraft.launchwrapper.Launch; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; -import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.MethodNode; - -import java.util.Iterator; public class GregTechTransformer implements IClassTransformer, Opcodes { @@ -23,186 +10,229 @@ public class GregTechTransformer implements IClassTransformer, Opcodes { public byte[] transform(String name, String transformedName, byte[] basicClass) { String internalName = transformedName.replace('.', '/'); switch (internalName) { - case JEIVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(0); - classReader.accept(new TargetClassVisitor(classWriter, JEIVisitor.TARGET_METHOD, JEIVisitor::new), 0); - return classWriter.toByteArray(); - } - case ConcretePowderVisitor.TARGET_CLASS_NAME: - if (ConfigHolder.recipes.disableConcreteInWorld) { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - classReader.accept(new TargetClassVisitor(classWriter, ConcretePowderVisitor.TARGET_METHOD, - ConcretePowderVisitor::new), 0); - return classWriter.toByteArray(); - } - break; - case LayerCustomHeadVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - classReader.accept(new TargetClassVisitor(classWriter, LayerCustomHeadVisitor.TARGET_METHOD, - LayerCustomHeadVisitor::new), 0); - return classWriter.toByteArray(); - } - case SpecialArmorApplyVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - classReader.accept(new SpecialArmorClassVisitor(classWriter, SpecialArmorApplyVisitor.TARGET_METHOD, - SpecialArmorApplyVisitor::new), 0); - return classWriter.toByteArray(); - } - case LayerArmorBaseVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - classReader.accept(new TargetClassVisitor(classWriter, LayerArmorBaseVisitor.TARGET_METHOD, - LayerArmorBaseVisitor::new), 0); - return classWriter.toByteArray(); - } - case RegionRenderCacheBuilderVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - classReader.accept(new TargetClassVisitor(classWriter, RegionRenderCacheBuilderVisitor.TARGET_METHOD, - RegionRenderCacheBuilderVisitor::new), 0); - return classWriter.toByteArray(); - } - case RenderChunkVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - classReader.accept( - new TargetClassVisitor(classWriter, RenderChunkVisitor.TARGET_METHOD, RenderChunkVisitor::new), - 0); - return classWriter.toByteArray(); - } - case EntityRendererVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - classReader.accept(new TargetClassVisitor(classWriter, EntityRendererVisitor.TARGET_METHOD, - EntityRendererVisitor::new), 0); - return classWriter.toByteArray(); - } - case BlockVisitor.TARGET_CLASS_NAME: { - try { - // must use Class#forName because CTM is client side only, and there is no other way to check - Class.forName("team.chisel.ctm.CTM", false, Launch.classLoader); - } catch (ClassNotFoundException ignored) { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - ClassNode classNode = new ClassNode(); - classReader.accept(classNode, 0); - BlockVisitor.handleClassNode(classNode).accept(classWriter); - return classWriter.toByteArray(); - } - break; - } - case WorldVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - classReader.accept(new TargetClassVisitor(classWriter, WorldVisitor.TARGET_METHOD, WorldVisitor::new), - 0); - return classWriter.toByteArray(); - } - case ModelCTMVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - classReader.accept( - new TargetClassVisitor(classWriter, ModelCTMVisitor.TARGET_METHOD, ModelCTMVisitor::new), 0); - return classWriter.toByteArray(); - } - case AbstractCTMBakedModelVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - classReader.accept(new TargetClassVisitor(classWriter, AbstractCTMBakedModelVisitor.TARGET_METHOD, - AbstractCTMBakedModelVisitor::new), 0); - return classWriter.toByteArray(); - } - case LittleTilesVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - classReader.accept( - new TargetClassVisitor(classWriter, LittleTilesVisitor.TARGET_METHOD, LittleTilesVisitor::new), - 0); - return classWriter.toByteArray(); - } - case CCLVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - classReader.accept(new TargetClassVisitor(classWriter, CCLVisitor.TARGET_METHOD, CCLVisitor::new), 0); - return classWriter.toByteArray(); - } - case NuclearCraftRecipeHelperVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(0); - - // 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 if (Mods.NuclearCraft.isModLoaded()) { - classReader.accept(new TargetClassVisitor(classWriter, - NuclearCraftRecipeHelperVisitor.TARGET_METHOD_NC, NuclearCraftRecipeHelperVisitor::new), 0); - } - return classWriter.toByteArray(); - } - case RenderItemVisitor.TARGET_CLASS_NAME: { - ClassNode classNode = new ClassNode(); - ClassReader classReader = new ClassReader(basicClass); - classReader.accept(classNode, 0); - Iterator methods = classNode.methods.iterator(); - RenderItemVisitor.transform(methods); - ClassWriter classWriter = new ClassWriter(0); - classNode.accept(classWriter); - return classWriter.toByteArray(); - } - case RecipeRepairItemVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - ClassNode classNode = new ClassNode(); - classReader.accept(classNode, 0); - RecipeRepairItemVisitor.handleClassNode(classNode).accept(classWriter); - return classWriter.toByteArray(); - } - case DamageSourceVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - ClassNode classNode = new ClassNode(); - classReader.accept(classNode, 0); - DamageSourceVisitor.handleClassNode(classNode).accept(classWriter); - return classWriter.toByteArray(); - } - case TheOneProbeVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(0); - classReader.accept( - new TargetClassVisitor(classWriter, TheOneProbeVisitor.TARGET_METHOD, TheOneProbeVisitor::new), - 0); - return classWriter.toByteArray(); - } - case MinecraftVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(0); - classReader.accept( - new TargetClassVisitor(classWriter, MinecraftVisitor.PROCESS_KEY_F3, MinecraftVisitor::new), - ClassReader.EXPAND_FRAMES); - return classWriter.toByteArray(); - } - case ModelLoaderRegistryVisitor.TARGET_CLASS_NAME: { - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(0); - classReader.accept(new TargetClassVisitor(classWriter, ModelLoaderRegistryVisitor.TARGET_METHOD, - ModelLoaderRegistryVisitor::new), ClassReader.EXPAND_FRAMES); - return classWriter.toByteArray(); - } - } - if (EnchantmentCanApplyVisitor.CLASS_TO_MAPPING_MAP.containsKey(internalName)) { - ObfMapping methodMapping = EnchantmentCanApplyVisitor.CLASS_TO_MAPPING_MAP.get(internalName); - ClassReader classReader = new ClassReader(basicClass); - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - classReader.accept(new TargetClassVisitor(classWriter, methodMapping, - mv -> new EnchantmentCanApplyVisitor(mv, methodMapping)), ClassReader.EXPAND_FRAMES); - return classWriter.toByteArray(); + /* + * case JEIVisitor.TARGET_CLASS_NAME: { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(0); + * classReader.accept(new TargetClassVisitor(classWriter, JEIVisitor.TARGET_METHOD, JEIVisitor::new), 0); + * return classWriter.toByteArray(); + * } + */ + /* + * case ConcretePowderVisitor.TARGET_CLASS_NAME: + * if (ConfigHolder.recipes.disableConcreteInWorld) { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + * classReader.accept(new TargetClassVisitor(classWriter, ConcretePowderVisitor.TARGET_METHOD, + * ConcretePowderVisitor::new), 0); + * return classWriter.toByteArray(); + * } + * break; + */ + /* + * case LayerCustomHeadVisitor.TARGET_CLASS_NAME: { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + * classReader.accept(new TargetClassVisitor(classWriter, LayerCustomHeadVisitor.TARGET_METHOD, + * LayerCustomHeadVisitor::new), 0); + * return classWriter.toByteArray(); + * } + */ + /* + * case SpecialArmorApplyVisitor.TARGET_CLASS_NAME: { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + * classReader.accept(new SpecialArmorClassVisitor(classWriter, SpecialArmorApplyVisitor.TARGET_METHOD, + * SpecialArmorApplyVisitor::new), 0); + * return classWriter.toByteArray(); + * } + */ + /* + * case LayerArmorBaseVisitor.TARGET_CLASS_NAME: { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + * classReader.accept(new TargetClassVisitor(classWriter, LayerArmorBaseVisitor.TARGET_METHOD, + * LayerArmorBaseVisitor::new), 0); + * return classWriter.toByteArray(); + * } + */ + /* + * case RegionRenderCacheBuilderVisitor.TARGET_CLASS_NAME: { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + * classReader.accept(new TargetClassVisitor(classWriter, RegionRenderCacheBuilderVisitor.TARGET_METHOD, + * RegionRenderCacheBuilderVisitor::new), 0); + * return classWriter.toByteArray(); + * } + */ + /* + * case RenderChunkVisitor.TARGET_CLASS_NAME: { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + * classReader.accept( + * new TargetClassVisitor(classWriter, RenderChunkVisitor.TARGET_METHOD, RenderChunkVisitor::new), + * 0); + * return classWriter.toByteArray(); + * } + */ + /* + * case EntityRendererVisitor.TARGET_CLASS_NAME: { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + * classReader.accept(new TargetClassVisitor(classWriter, EntityRendererVisitor.TARGET_METHOD, + * EntityRendererVisitor::new), 0); + * return classWriter.toByteArray(); + * } + */ + /* + * case BlockVisitor.TARGET_CLASS_NAME: { + * try { + * // must use Class#forName because CTM is client side only, and there is no other way to check + * Class.forName("team.chisel.ctm.CTM", false, Launch.classLoader); + * } catch (ClassNotFoundException ignored) { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + * ClassNode classNode = new ClassNode(); + * classReader.accept(classNode, 0); + * BlockVisitor.handleClassNode(classNode).accept(classWriter); + * return classWriter.toByteArray(); + * } + * break; + * } + */ + /* + * case WorldVisitor.TARGET_CLASS_NAME: { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + * classReader.accept(new TargetClassVisitor(classWriter, WorldVisitor.TARGET_METHOD, WorldVisitor::new), + * 0); + * return classWriter.toByteArray(); + * } + */ + /* + * case ModelCTMVisitor.TARGET_CLASS_NAME: { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + * classReader.accept( + * new TargetClassVisitor(classWriter, ModelCTMVisitor.TARGET_METHOD, ModelCTMVisitor::new), 0); + * return classWriter.toByteArray(); + * } + */ + /* + * case AbstractCTMBakedModelVisitor.TARGET_CLASS_NAME: { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + * classReader.accept(new TargetClassVisitor(classWriter, AbstractCTMBakedModelVisitor.TARGET_METHOD, + * AbstractCTMBakedModelVisitor::new), 0); + * return classWriter.toByteArray(); + * } + */ + /* + * case LittleTilesVisitor.TARGET_CLASS_NAME: { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + * classReader.accept( + * new TargetClassVisitor(classWriter, LittleTilesVisitor.TARGET_METHOD, LittleTilesVisitor::new), + * 0); + * return classWriter.toByteArray(); + * } + */ + /* + * case CCLVisitor.TARGET_CLASS_NAME: { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + * classReader.accept(new TargetClassVisitor(classWriter, CCLVisitor.TARGET_METHOD, CCLVisitor::new), 0); + * return classWriter.toByteArray(); + * } + * case RenderItemVisitor.TARGET_CLASS_NAME: { + * ClassNode classNode = new ClassNode(); + * ClassReader classReader = new ClassReader(basicClass); + * classReader.accept(classNode, 0); + * Iterator methods = classNode.methods.iterator(); + * RenderItemVisitor.transform(methods); + * ClassWriter classWriter = new ClassWriter(0); + * classNode.accept(classWriter); + * return classWriter.toByteArray(); + * } + */ + /* + * case RecipeRepairItemVisitor.TARGET_CLASS_NAME: { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + * ClassNode classNode = new ClassNode(); + * classReader.accept(classNode, 0); + * RecipeRepairItemVisitor.handleClassNode(classNode).accept(classWriter); + * return classWriter.toByteArray(); + * } + */ + /* + * case DamageSourceVisitor.TARGET_CLASS_NAME: { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + * ClassNode classNode = new ClassNode(); + * classReader.accept(classNode, 0); + * DamageSourceVisitor.handleClassNode(classNode).accept(classWriter); + * return classWriter.toByteArray(); + * } + */ + /* + * case TheOneProbeVisitor.TARGET_CLASS_NAME: { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(0); + * classReader.accept( + * new TargetClassVisitor(classWriter, TheOneProbeVisitor.TARGET_METHOD, TheOneProbeVisitor::new), + * 0); + * return classWriter.toByteArray(); + * } + */ + /* + * case MinecraftVisitor.TARGET_CLASS_NAME: { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(0); + * classReader.accept( + * new TargetClassVisitor(classWriter, MinecraftVisitor.PROCESS_KEY_F3, MinecraftVisitor::new), + * ClassReader.EXPAND_FRAMES); + * return classWriter.toByteArray(); + * } + */ + /* + * case ModelLoaderRegistryVisitor.TARGET_CLASS_NAME: { + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(0); + * classReader.accept(new TargetClassVisitor(classWriter, ModelLoaderRegistryVisitor.TARGET_METHOD, + * ModelLoaderRegistryVisitor::new), ClassReader.EXPAND_FRAMES); + * return classWriter.toByteArray(); + * } + */ + // TODO: Remove when vintagium has proper support for other rendering layers + // case VintagiumPassManagerVisitor.TARGET_CLASS_NAME: { + // ClassReader classReader = new ClassReader(basicClass); + // ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + // classReader.accept( + // new TargetClassVisitor(classWriter, VintagiumPassManagerVisitor.TARGET_METHOD, + // VintagiumPassManagerVisitor::new), + // ClassReader.EXPAND_FRAMES); + // return classWriter.toByteArray(); + // } + // case VintagiumManagerVistor.TARGET_CLASS_NAME: { + // ClassReader classReader = new ClassReader(basicClass); + // ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + // classReader.accept( + // new VintagiumManagerVistor(classWriter), + // 0); + // return classWriter.toByteArray(); + // } } + /* + * if (EnchantmentCanApplyVisitor.CLASS_TO_MAPPING_MAP.containsKey(internalName)) { + * ObfMapping methodMapping = EnchantmentCanApplyVisitor.CLASS_TO_MAPPING_MAP.get(internalName); + * ClassReader classReader = new ClassReader(basicClass); + * ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + * classReader.accept(new TargetClassVisitor(classWriter, methodMapping, + * mv -> new EnchantmentCanApplyVisitor(mv, methodMapping)), ClassReader.EXPAND_FRAMES); + * return classWriter.toByteArray(); + * } + */ return basicClass; } } diff --git a/src/main/java/gregtech/asm/visitors/NuclearCraftRecipeHelperVisitor.java b/src/main/java/gregtech/asm/visitors/NuclearCraftRecipeHelperVisitor.java deleted file mode 100644 index a70986c67fb..00000000000 --- a/src/main/java/gregtech/asm/visitors/NuclearCraftRecipeHelperVisitor.java +++ /dev/null @@ -1,29 +0,0 @@ -package gregtech.asm.visitors; - -import gregtech.asm.util.ObfMapping; - -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; - -public class NuclearCraftRecipeHelperVisitor extends MethodVisitor implements Opcodes { - - public static final String TARGET_CLASS_NAME = "nc/integration/gtce/GTCERecipeHelper"; - - public static final ObfMapping TARGET_METHOD_NC = new ObfMapping(TARGET_CLASS_NAME, "addGTCERecipe", - "(Ljava/lang/String;Lnc/recipe/ProcessorRecipe;)V"); - public static final ObfMapping TARGET_METHOD_NCO = new ObfMapping(TARGET_CLASS_NAME, "addGTCERecipe", - "(Ljava/lang/String;Lnc/recipe/BasicRecipe;)V"); - - public NuclearCraftRecipeHelperVisitor(MethodVisitor mv) { - super(ASM5, mv); - } - - @Override - public void visitFieldInsn(int opcode, String owner, String name, String desc) { - if (opcode == GETSTATIC && name.equals("FLUID_EXTRACTION_RECIPES")) { // FLUID_EXTRACTION_RECIPES -> - // EXTRACTOR_RECIPES - name = "EXTRACTOR_RECIPES"; - } - super.visitFieldInsn(opcode, owner, name, desc); - } -} diff --git a/src/main/java/gregtech/asm/visitors/VintagiumManagerVistor.java b/src/main/java/gregtech/asm/visitors/VintagiumManagerVistor.java new file mode 100644 index 00000000000..4d8d53edf47 --- /dev/null +++ b/src/main/java/gregtech/asm/visitors/VintagiumManagerVistor.java @@ -0,0 +1,24 @@ +package gregtech.asm.visitors; + +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.Opcodes; + +public class VintagiumManagerVistor extends ClassVisitor implements Opcodes { + + public static final String TARGET_CLASS_NAME = "me/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPass"; + + public VintagiumManagerVistor(ClassVisitor cv) { + super(ASM5, cv); + } + + @Override + public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { + // Make BlockRenderPass.VALUES and BlockRenderPass.COUNT not final + if (name.equals("VALUES") || name.equals("COUNT")) { + return super.visitField(access & ~ACC_FINAL, name, desc, signature, value); + } else { + return super.visitField(access, name, desc, signature, value); + } + } +} diff --git a/src/main/java/gregtech/asm/visitors/VintagiumPassManagerVisitor.java b/src/main/java/gregtech/asm/visitors/VintagiumPassManagerVisitor.java new file mode 100644 index 00000000000..eb103ffb651 --- /dev/null +++ b/src/main/java/gregtech/asm/visitors/VintagiumPassManagerVisitor.java @@ -0,0 +1,35 @@ +package gregtech.asm.visitors; + +import gregtech.asm.util.ObfMapping; + +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +public class VintagiumPassManagerVisitor extends MethodVisitor implements Opcodes { + + public static final String TARGET_CLASS_NAME = "me/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPassManager"; + public static final ObfMapping TARGET_METHOD = new ObfMapping(TARGET_CLASS_NAME, "createDefaultMappings", + "()Lme/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPassManager;"); + public static final ObfMapping GET_BLOOM_LAYER = new ObfMapping("gregtech/client/utils/BloomEffectUtil", + "getBloomLayer", "()Lnet/minecraft/util/BlockRenderLayer;"); + public static final ObfMapping GET_BLOOM_PASS = new ObfMapping("gregtech/client/utils/BloomEffectVintagiumUtil", + "getBloomPass", "()Lme/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPass;"); + public static final ObfMapping ADD_MAPPING = new ObfMapping(TARGET_CLASS_NAME, "addMapping", + "(Lnet/minecraft/util/BlockRenderLayer;Lme/jellysquid/mods/sodium/client/render/chunk/passes/BlockRenderPass;)V"); + + public VintagiumPassManagerVisitor(MethodVisitor mv) { + super(ASM5, mv); + } + + @Override + public void visitInsn(int opcode) { + // add mapper.addMapping(BloomEffectUtil.getBloomLayer(), BloomEffectVintagiumUtil.getBloomPass()); + if (opcode == ARETURN) { + GET_BLOOM_LAYER.visitMethodInsn(this, INVOKESTATIC); + GET_BLOOM_PASS.visitMethodInsn(this, INVOKESTATIC); + ADD_MAPPING.visitMethodInsn(this, INVOKESPECIAL); + super.visitVarInsn(ALOAD, 0); + } + super.visitInsn(opcode); + } +} diff --git a/src/main/java/gregtech/client/event/ClientEventHandler.java b/src/main/java/gregtech/client/event/ClientEventHandler.java index c83851d8e34..f4ac14d8bfd 100644 --- a/src/main/java/gregtech/client/event/ClientEventHandler.java +++ b/src/main/java/gregtech/client/event/ClientEventHandler.java @@ -11,6 +11,7 @@ import gregtech.client.renderer.handler.BlockPosHighlightRenderer; import gregtech.client.renderer.handler.MultiblockPreviewRenderer; import gregtech.client.renderer.handler.TerminalARRenderer; +import gregtech.client.utils.BloomEffectUtil; import gregtech.client.utils.DepthTextureUtil; import gregtech.client.utils.TooltipHelper; import gregtech.common.ConfigHolder; @@ -24,6 +25,7 @@ import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.event.*; +import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fml.client.event.ConfigChangedEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.EventPriority; @@ -157,4 +159,9 @@ private static void renderHUDMetaItem(@NotNull ItemStack stack) { } } } + + @SubscribeEvent + public static void onWorldUnload(WorldEvent.Unload event) { + BloomEffectUtil.invalidateWorldTickets(event.getWorld()); + } } diff --git a/src/main/java/gregtech/client/particle/GTLaserBeamParticle.java b/src/main/java/gregtech/client/particle/GTLaserBeamParticle.java index d57f40af1df..f269bef42c2 100644 --- a/src/main/java/gregtech/client/particle/GTLaserBeamParticle.java +++ b/src/main/java/gregtech/client/particle/GTLaserBeamParticle.java @@ -13,6 +13,7 @@ import net.minecraft.client.renderer.texture.SimpleTexture; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import codechicken.lib.vec.Vector3; @@ -34,11 +35,20 @@ public class GTLaserBeamParticle extends GTParticle { private float emit; private boolean doubleVertical; + private int activeTime; + private final int fadeInTime; + public GTLaserBeamParticle(@Nullable MetaTileEntity mte, @NotNull Vector3 startPos, @NotNull Vector3 endPos) { + this(mte, startPos, endPos, 0); + } + + public GTLaserBeamParticle(@Nullable MetaTileEntity mte, @NotNull Vector3 startPos, @NotNull Vector3 endPos, + int fadeInTime) { super(startPos.x, startPos.y, startPos.z); this.mte = mte; this.direction = endPos.copy().subtract(startPos); this.setRenderRange(64); + this.fadeInTime = fadeInTime; } @Override @@ -99,6 +109,15 @@ public float getAlpha() { return this.alpha; } + public float getAlpha(float partialTicks) { + if (this.fadeInTime > this.activeTime) { + return (float) (this.alpha * MathHelper.clampedLerp( + (double) this.activeTime / this.fadeInTime, + (double) (this.activeTime + 1) / this.fadeInTime, partialTicks)); + } + return this.alpha; + } + /** * Set emit speed. * @@ -131,9 +150,8 @@ public void onUpdate() { if (mte == null || mte.isValid() && mte.getWorld().isBlockLoaded(mte.getPos(), false) && mte.getWorld().getTileEntity(mte.getPos()) == mte.getHolder()) { - return; - } - setExpired(); + this.activeTime++; + } else setExpired(); } @Override @@ -169,7 +187,7 @@ public void renderParticle(@NotNull BufferBuilder buffer, @NotNull EffectRenderC bodyTexture.getGlTextureId(), headTexture == null ? -1 : headTexture.getGlTextureId(), - direction, cameraDirection, beamHeight, headWidth, alpha, offset); + direction, cameraDirection, beamHeight, headWidth, this.getAlpha(context.partialTicks()), offset); GlStateManager.translate(context.cameraX() - posX, context.cameraY() - posY, context.cameraZ() - posZ); } diff --git a/src/main/java/gregtech/client/particle/GTOverheatParticle.java b/src/main/java/gregtech/client/particle/GTOverheatParticle.java index d017af7b3a0..8736b628798 100644 --- a/src/main/java/gregtech/client/particle/GTOverheatParticle.java +++ b/src/main/java/gregtech/client/particle/GTOverheatParticle.java @@ -251,7 +251,15 @@ public void renderBloomEffect(@NotNull BufferBuilder buffer, @NotNull EffectRend @Override public boolean shouldRenderBloomEffect(@NotNull EffectRenderContext context) { - return !this.insulated; + if (this.insulated) return false; + for (Cuboid6 cuboid : pipeBoxes) { + if (!context.camera().isBoxInFrustum( + cuboid.min.x + posX, cuboid.min.y + posY, cuboid.min.z + posZ, + cuboid.max.x + posX, cuboid.max.y + posY, cuboid.max.z + posZ)) { + return false; + } + } + return true; } private static final IRenderSetup SETUP = new IRenderSetup() { diff --git a/src/main/java/gregtech/client/renderer/texture/Textures.java b/src/main/java/gregtech/client/renderer/texture/Textures.java index c007a6b13d6..8615691ba87 100644 --- a/src/main/java/gregtech/client/renderer/texture/Textures.java +++ b/src/main/java/gregtech/client/renderer/texture/Textures.java @@ -209,6 +209,8 @@ public class Textures { public static final OrientedOverlayRenderer ARC_FURNACE_OVERLAY = new OrientedOverlayRenderer( "machines/arc_furnace"); public static final OrientedOverlayRenderer ASSEMBLER_OVERLAY = new OrientedOverlayRenderer("machines/assembler"); + public static final OrientedOverlayRenderer CIRCUIT_ASSEMBLER_OVERLAY = new OrientedOverlayRenderer( + "machines/circuit_assembler"); public static final OrientedOverlayRenderer AUTOCLAVE_OVERLAY = new OrientedOverlayRenderer("machines/autoclave"); public static final OrientedOverlayRenderer BENDER_OVERLAY = new OrientedOverlayRenderer("machines/bender"); public static final OrientedOverlayRenderer BREWERY_OVERLAY = new OrientedOverlayRenderer("machines/brewery"); diff --git a/src/main/java/gregtech/client/utils/BloomEffectUtil.java b/src/main/java/gregtech/client/utils/BloomEffectUtil.java index 2dcc7d0be14..c4a4e0548ee 100644 --- a/src/main/java/gregtech/client/utils/BloomEffectUtil.java +++ b/src/main/java/gregtech/client/utils/BloomEffectUtil.java @@ -20,6 +20,7 @@ import net.minecraft.entity.Entity; import net.minecraft.launchwrapper.Launch; import net.minecraft.util.BlockRenderLayer; +import net.minecraft.world.World; import net.minecraftforge.common.util.EnumHelper; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -38,8 +39,10 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.concurrent.locks.ReentrantLock; import java.util.function.Consumer; import java.util.function.Predicate; +import java.util.function.Supplier; @SideOnly(Side.CLIENT) public class BloomEffectUtil { @@ -47,6 +50,8 @@ public class BloomEffectUtil { private static final Map> BLOOM_RENDERS = new Object2ObjectOpenHashMap<>(); private static final List SCHEDULED_BLOOM_RENDERS = new ArrayList<>(); + private static final ReentrantLock BLOOM_RENDER_LOCK = new ReentrantLock(); + /** * @deprecated use {@link #getBloomLayer()} */ @@ -147,12 +152,12 @@ public static Framebuffer getBloomFBO() { /** *

* Register a custom bloom render callback for subsequent world render. The render call persists until the - * {@code metaTileEntity} is invalidated, or the ticket is manually freed by calling - * {@link BloomRenderTicket#invalidate()}. + * {@code metaTileEntity} is invalidated, or the world associated with {@code metaTileEntity} or the ticket is + * manually freed by calling {@link BloomRenderTicket#invalidate()}. *

*

- * This method does not register bloom render ticket when Optifine is present, and {@code null} will be returned - * instead of a ticket instance. + * This method does not register bloom render ticket when Optifine is present, and an invalid ticket will be + * returned instead. *

* * @param setup Render setup, if exists @@ -162,13 +167,28 @@ public static Framebuffer getBloomFBO() { * @return Ticket for the registered bloom render callback * @throws NullPointerException if {@code bloomType == null || render == null || metaTileEntity == null} */ - @Nullable + @NotNull public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup, @NotNull BloomType bloomType, @NotNull IBloomEffect render, @NotNull MetaTileEntity metaTileEntity) { Objects.requireNonNull(metaTileEntity, "metaTileEntity == null"); - return registerBloomRender(setup, bloomType, render, t -> metaTileEntity.isValid()); + return registerBloomRender(setup, bloomType, + new IBloomEffect() { + + @Override + public void renderBloomEffect(@NotNull BufferBuilder buffer, @NotNull EffectRenderContext context) { + render.renderBloomEffect(buffer, context); + } + + @Override + public boolean shouldRenderBloomEffect(@NotNull EffectRenderContext context) { + return metaTileEntity.getWorld() == context.renderViewEntity().world && + render.shouldRenderBloomEffect(context); + } + }, + t -> metaTileEntity.isValid(), + metaTileEntity::getWorld); } /** @@ -178,8 +198,8 @@ public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup * {@link BloomRenderTicket#invalidate()}. *

*

- * This method does not register bloom render ticket when Optifine is present, and {@code null} will be returned - * instead of a ticket instance. + * This method does not register bloom render ticket when Optifine is present, and an invalid ticket will be + * returned instead. *

* * @param setup Render setup, if exists @@ -189,7 +209,7 @@ public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup * @return Ticket for the registered bloom render callback * @throws NullPointerException if {@code bloomType == null || render == null || metaTileEntity == null} */ - @Nullable + @NotNull public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup, @NotNull BloomType bloomType, @NotNull IBloomEffect render, @@ -204,8 +224,8 @@ public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup * manually freed by calling {@link BloomRenderTicket#invalidate()}, or invalidated by validity checker. *

*

- * This method does not register bloom render ticket when Optifine is present, and {@code null} will be returned - * instead of a ticket instance. + * This method does not register bloom render ticket when Optifine is present, and an invalid ticket will be + * returned instead. *

* * @param setup Render setup, if exists @@ -215,18 +235,85 @@ public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup * Checked on both pre/post render each frame. * @return Ticket for the registered bloom render callback * @throws NullPointerException if {@code bloomType == null || render == null} + * @see #registerBloomRender(IRenderSetup, BloomType, IBloomEffect, MetaTileEntity) + * @see #registerBloomRender(IRenderSetup, BloomType, IBloomEffect, GTParticle) + * @see #registerBloomRender(IRenderSetup, BloomType, IBloomEffect, Predicate, Supplier) */ - @Nullable + @NotNull public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup, @NotNull BloomType bloomType, @NotNull IBloomEffect render, @Nullable Predicate validityChecker) { - if (Mods.Optifine.isModLoaded()) return null; - BloomRenderTicket ticket = new BloomRenderTicket(setup, bloomType, render, validityChecker); - SCHEDULED_BLOOM_RENDERS.add(ticket); + return registerBloomRender(setup, bloomType, render, validityChecker, null); + } + + /** + *

+ * Register a custom bloom render callback for subsequent world render. The render call persists until it is + * manually freed by calling {@link BloomRenderTicket#invalidate()}, or invalidated by validity checker. + *

+ *

+ * This method does not register bloom render ticket when Optifine is present, and an invalid ticket will be + * returned instead. + *

+ * + * @param setup Render setup, if exists + * @param bloomType Type of the bloom + * @param render Rendering callback + * @param validityChecker Optional validity checker; returning {@code false} causes the ticket to be invalidated. + * Checked on both pre/post render each frame. + * @param worldContext Optional world bound to the ticket. If the world returned is not null, the bloom ticket + * will be automatically invalidated on world unload. If world context returns {@code null}, + * it will not be affected by aforementioned automatic invalidation. + * @return Ticket for the registered bloom render callback + * @throws NullPointerException if {@code bloomType == null || render == null} + * @see #registerBloomRender(IRenderSetup, BloomType, IBloomEffect, MetaTileEntity) + * @see #registerBloomRender(IRenderSetup, BloomType, IBloomEffect, GTParticle) + */ + @NotNull + public static BloomRenderTicket registerBloomRender(@Nullable IRenderSetup setup, + @NotNull BloomType bloomType, + @NotNull IBloomEffect render, + @Nullable Predicate validityChecker, + @Nullable Supplier worldContext) { + if (Mods.Optifine.isModLoaded()) return BloomRenderTicket.INVALID; + BloomRenderTicket ticket = new BloomRenderTicket(setup, bloomType, render, validityChecker, worldContext); + BLOOM_RENDER_LOCK.lock(); + try { + SCHEDULED_BLOOM_RENDERS.add(ticket); + } finally { + BLOOM_RENDER_LOCK.unlock(); + } return ticket; } + /** + * Invalidate tickets associated with given world. + * + * @param world World + */ + public static void invalidateWorldTickets(@NotNull World world) { + Objects.requireNonNull(world, "world == null"); + BLOOM_RENDER_LOCK.lock(); + try { + for (BloomRenderTicket ticket : SCHEDULED_BLOOM_RENDERS) { + if (ticket.isValid() && ticket.worldContext != null && ticket.worldContext.get() == world) { + ticket.invalidate(); + } + } + + for (Map.Entry> e : BLOOM_RENDERS.entrySet()) { + for (BloomRenderTicket ticket : e.getValue()) { + if (ticket.isValid() && ticket.worldContext != null && ticket.worldContext.get() == world) { + ticket.invalidate(); + } + } + } + } finally { + BLOOM_RENDER_LOCK.unlock(); + } + } + /** * @deprecated use ticket-based bloom render hooks */ @@ -281,14 +368,26 @@ public static int renderBloomBlockLayer(RenderGlobal renderGlobal, BlockRenderLayer blockRenderLayer, // 70% sure it's translucent uh yeah double partialTicks, int pass, - Entity entity) { - Minecraft mc = Minecraft.getMinecraft(); - mc.profiler.endStartSection("BTLayer"); + @NotNull Entity entity) { + Minecraft.getMinecraft().profiler.endStartSection("BTLayer"); if (Mods.Optifine.isModLoaded()) { return renderGlobal.renderBlockLayer(blockRenderLayer, partialTicks, pass, entity); } + BLOOM_RENDER_LOCK.lock(); + try { + return renderBloomInternal(renderGlobal, blockRenderLayer, partialTicks, pass, entity); + } finally { + BLOOM_RENDER_LOCK.unlock(); + } + } + + private static int renderBloomInternal(RenderGlobal renderGlobal, + BlockRenderLayer blockRenderLayer, + double partialTicks, + int pass, + @NotNull Entity entity) { preDraw(); EffectRenderContext context = EffectRenderContext.getInstance().update(entity, (float) partialTicks); @@ -309,7 +408,7 @@ public static int renderBloomBlockLayer(RenderGlobal renderGlobal, return renderGlobal.renderBlockLayer(blockRenderLayer, partialTicks, pass, entity); } - Framebuffer fbo = mc.getFramebuffer(); + Framebuffer fbo = Minecraft.getMinecraft().getFramebuffer(); if (bloomFBO == null || bloomFBO.framebufferWidth != fbo.framebufferWidth || @@ -360,12 +459,12 @@ public static int renderBloomBlockLayer(RenderGlobal renderGlobal, // reset transparent layer render state and render OpenGlHelper.glBindFramebuffer(OpenGlHelper.GL_FRAMEBUFFER, fbo.framebufferObject); GlStateManager.enableBlend(); - mc.getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); + Minecraft.getMinecraft().getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); GlStateManager.shadeModel(GL11.GL_SMOOTH); int result = renderGlobal.renderBlockLayer(blockRenderLayer, partialTicks, pass, entity); - mc.profiler.endStartSection("bloom"); + Minecraft.getMinecraft().profiler.endStartSection("bloom"); // blend bloom + transparent fbo.bindFramebufferTexture(); @@ -492,29 +591,44 @@ private record BloomRenderKey(@Nullable IRenderSetup renderSetup, @NotNull Bloom public static final class BloomRenderTicket { + public static final BloomRenderTicket INVALID = new BloomRenderTicket(); + @Nullable private final IRenderSetup renderSetup; private final BloomType bloomType; private final IBloomEffect render; @Nullable private final Predicate validityChecker; + @Nullable + private final Supplier worldContext; private boolean invalidated; + BloomRenderTicket() { + this(null, BloomType.DISABLED, (b, c) -> {}, null, null); + this.invalidated = true; + } + BloomRenderTicket(@Nullable IRenderSetup renderSetup, @NotNull BloomType bloomType, - @NotNull IBloomEffect render, @Nullable Predicate validityChecker) { + @NotNull IBloomEffect render, @Nullable Predicate validityChecker, + @Nullable Supplier worldContext) { this.renderSetup = renderSetup; this.bloomType = Objects.requireNonNull(bloomType, "bloomType == null"); this.render = Objects.requireNonNull(render, "render == null"); this.validityChecker = validityChecker; + this.worldContext = worldContext; } @Nullable + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public IRenderSetup getRenderSetup() { return this.renderSetup; } @NotNull + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public BloomType getBloomType() { return this.bloomType; } diff --git a/src/main/java/gregtech/client/utils/BloomEffectVintagiumUtil.java b/src/main/java/gregtech/client/utils/BloomEffectVintagiumUtil.java new file mode 100644 index 00000000000..0d63f22a2d4 --- /dev/null +++ b/src/main/java/gregtech/client/utils/BloomEffectVintagiumUtil.java @@ -0,0 +1,24 @@ +package gregtech.client.utils; + +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import me.jellysquid.mods.sodium.client.render.chunk.passes.BlockRenderPass; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; + +@SideOnly(Side.CLIENT) +public class BloomEffectVintagiumUtil { + + public static BlockRenderPass bloom; + + /** + * @return {@link BlockRenderPass} instance for the bloom render layer. + */ + @NotNull + @SuppressWarnings("unused") + public static BlockRenderPass getBloomPass() { + return Objects.requireNonNull(bloom, "Bloom effect is not initialized yet"); + } +} diff --git a/src/main/java/gregtech/client/utils/EffectRenderContext.java b/src/main/java/gregtech/client/utils/EffectRenderContext.java index e5b63b69feb..bee87a7a85a 100644 --- a/src/main/java/gregtech/client/utils/EffectRenderContext.java +++ b/src/main/java/gregtech/client/utils/EffectRenderContext.java @@ -1,6 +1,8 @@ package gregtech.client.utils; import net.minecraft.client.renderer.ActiveRenderInfo; +import net.minecraft.client.renderer.culling.ClippingHelperImpl; +import net.minecraft.client.renderer.culling.Frustum; import net.minecraft.entity.Entity; import net.minecraft.util.math.Vec3d; @@ -20,6 +22,9 @@ public static EffectRenderContext getInstance() { return instance; } + private final ClippingHelperImpl clippingHelper = new ClippingHelperImpl(); + private final Frustum camera = new Frustum(this.clippingHelper); + @Nullable private Entity renderViewEntity; private float partialTicks; @@ -53,6 +58,9 @@ public EffectRenderContext update(@NotNull Entity renderViewEntity, float partia this.rotationXY = ActiveRenderInfo.getRotationXY(); this.rotationXZ = ActiveRenderInfo.getRotationXZ(); + this.clippingHelper.init(); + this.camera.setPosition(this.cameraX, this.cameraY, this.cameraZ); + return this; } @@ -134,4 +142,12 @@ public float rotationXY() { public float rotationXZ() { return rotationXZ; } + + /** + * @return camera + */ + @NotNull + public Frustum camera() { + return camera; + } } diff --git a/src/main/java/gregtech/client/utils/IBloomEffect.java b/src/main/java/gregtech/client/utils/IBloomEffect.java index 2d3052ce09d..0e345794f3d 100644 --- a/src/main/java/gregtech/client/utils/IBloomEffect.java +++ b/src/main/java/gregtech/client/utils/IBloomEffect.java @@ -9,8 +9,11 @@ import org.jetbrains.annotations.NotNull; +import java.util.function.Predicate; + /** - * Render callback interface for {@link BloomEffectUtil#registerBloomRender(IRenderSetup, BloomType, IBloomEffect)}. + * Render callback interface for + * {@link BloomEffectUtil#registerBloomRender(IRenderSetup, BloomType, IBloomEffect, Predicate)}. */ @FunctionalInterface public interface IBloomEffect { @@ -26,8 +29,8 @@ public interface IBloomEffect { /** * @param context render context - * @return if this effect should be rendered; returning {@code false} skips {@link #renderBloomEffect(BufferBuilder, - * EffectRenderContext)} call. + * @return if this effect should be rendered; returning {@code false} skips + * {@link #renderBloomEffect(BufferBuilder, EffectRenderContext)} call. */ @SideOnly(Side.CLIENT) default boolean shouldRenderBloomEffect(@NotNull EffectRenderContext context) { diff --git a/src/main/java/gregtech/common/CommonProxy.java b/src/main/java/gregtech/common/CommonProxy.java index b9927847cd4..6817aaa7ce5 100644 --- a/src/main/java/gregtech/common/CommonProxy.java +++ b/src/main/java/gregtech/common/CommonProxy.java @@ -6,8 +6,10 @@ import gregtech.api.block.machines.MachineItemBlock; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.toolitem.IGTTool; +import gregtech.api.metatileentity.registry.MTERegistry; import gregtech.api.recipes.GTRecipeInputCache; import gregtech.api.recipes.ModHandler; +import gregtech.api.recipes.ingredients.GTRecipeOreInput; import gregtech.api.recipes.recipeproperties.FusionEUToStartProperty; import gregtech.api.terminal.TerminalRegistry; import gregtech.api.unification.material.Material; @@ -20,7 +22,16 @@ import gregtech.api.unification.stack.ItemMaterialInfo; import gregtech.api.util.AssemblyLineManager; import gregtech.api.util.GTLog; -import gregtech.common.blocks.*; +import gregtech.common.blocks.BlockCompressed; +import gregtech.common.blocks.BlockFrame; +import gregtech.common.blocks.BlockLamp; +import gregtech.common.blocks.BlockOre; +import gregtech.common.blocks.BlockSurfaceRock; +import gregtech.common.blocks.LampItemBlock; +import gregtech.common.blocks.MaterialItemBlock; +import gregtech.common.blocks.MetaBlocks; +import gregtech.common.blocks.OreItemBlock; +import gregtech.common.blocks.StoneVariantBlock; import gregtech.common.items.MetaItems; import gregtech.common.items.ToolItems; import gregtech.common.pipelike.cable.BlockCable; @@ -33,10 +44,13 @@ import gregtech.common.pipelike.laser.ItemBlockLaserPipe; import gregtech.common.pipelike.optical.BlockOpticalPipe; import gregtech.common.pipelike.optical.ItemBlockOpticalPipe; +import gregtech.datafix.GTDataFixers; +import gregtech.integration.groovy.GroovyScriptModule; import gregtech.loaders.MaterialInfoLoader; import gregtech.loaders.OreDictionaryLoader; import gregtech.loaders.recipe.CraftingComponent; import gregtech.loaders.recipe.GTRecipeManager; +import gregtech.modules.GregTechModules; import net.minecraft.block.Block; import net.minecraft.item.Item; @@ -74,7 +88,9 @@ public static void registerBlocks(RegistryEvent.Register event) { GTLog.logger.info("Registering Blocks..."); IForgeRegistry registry = event.getRegistry(); - registry.register(MACHINE); + for (MTERegistry r : GregTechAPI.mteManager.getRegistries()) { + registry.register(r.getBlock()); + } StoneType.init(); @@ -219,7 +235,9 @@ public static void registerItems(RegistryEvent.Register event) { GTRecipeManager.preLoad(); - registry.register(createItemBlock(MACHINE, MachineItemBlock::new)); + for (MTERegistry r : GregTechAPI.mteManager.getRegistries()) { + registry.register(createItemBlock(r.getBlock(), MachineItemBlock::new)); + } for (MaterialRegistry materialRegistry : GregTechAPI.materialManager.getRegistries()) { for (BlockCable cable : CABLES.get(materialRegistry.getModid())) @@ -387,7 +405,9 @@ private static ItemBlock createItemBlock(T block, Function CABLES = new Object2ObjectOpenHashMap<>(); public static final Map FLUID_PIPES = new Object2ObjectOpenHashMap<>(); public static final Map ITEM_PIPES = new Object2ObjectOpenHashMap<>(); @@ -187,8 +187,11 @@ private MetaBlocks() {} public static final List FLUID_BLOCKS = new ArrayList<>(); public static void init() { - GregTechAPI.MACHINE = MACHINE = new BlockMachine(); - MACHINE.setRegistryName("machine"); + for (MTERegistry registry : GregTechAPI.mteManager.getRegistries()) { + BlockMachine machine = new BlockMachine(); + machine.setRegistryName(registry.getModid(), "mte"); + registry.setBlock(machine); + } for (MaterialRegistry registry : GregTechAPI.materialManager.getRegistries()) { String modid = registry.getModid(); @@ -437,8 +440,11 @@ public static void registerTileEntity() { @SideOnly(Side.CLIENT) public static void registerItemModels() { - ModelLoader.setCustomMeshDefinition(Item.getItemFromBlock(MACHINE), - stack -> MetaTileEntityRenderer.MODEL_LOCATION); + for (MTERegistry registry : GregTechAPI.mteManager.getRegistries()) { + ModelLoader.setCustomMeshDefinition(Item.getItemFromBlock(registry.getBlock()), + stack -> MetaTileEntityRenderer.MODEL_LOCATION); + } + for (MaterialRegistry registry : GregTechAPI.materialManager.getRegistries()) { for (BlockCable cable : CABLES.get(registry.getModid())) cable.onModelRegister(); for (BlockFluidPipe pipe : FLUID_PIPES.get(registry.getModid())) pipe.onModelRegister(); @@ -536,7 +542,10 @@ private static void registerItemModelWithOverride(Block block, Map, @SideOnly(Side.CLIENT) public static void registerStateMappers() { - ModelLoader.setCustomStateMapper(MACHINE, new SimpleStateMapper(MetaTileEntityRenderer.MODEL_LOCATION)); + for (MTERegistry registry : GregTechAPI.mteManager.getRegistries()) { + ModelLoader.setCustomStateMapper(registry.getBlock(), + new SimpleStateMapper(MetaTileEntityRenderer.MODEL_LOCATION)); + } IStateMapper normalStateMapper; for (MaterialRegistry registry : GregTechAPI.materialManager.getRegistries()) { diff --git a/src/main/java/gregtech/common/covers/CoverConveyor.java b/src/main/java/gregtech/common/covers/CoverConveyor.java index 127c852fb83..d06bc4b3541 100644 --- a/src/main/java/gregtech/common/covers/CoverConveyor.java +++ b/src/main/java/gregtech/common/covers/CoverConveyor.java @@ -42,7 +42,9 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IDrawable; import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.drawable.DynamicDrawable; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Color; @@ -571,7 +573,14 @@ protected ParentWidget createUI(ModularPanel mainPanel, GuiSyncManager g column.child(new EnumRowBuilder<>(ManualImportExportMode.class) .value(manualIOmode) .lang("cover.generic.manual_io") - .overlay(GTGuiTextures.MANUAL_IO_OVERLAY) + .overlay(new IDrawable[] { + new DynamicDrawable(() -> conveyorMode.getValue().isImport() ? + GTGuiTextures.MANUAL_IO_OVERLAY_OUT[0] : GTGuiTextures.MANUAL_IO_OVERLAY_IN[0]), + new DynamicDrawable(() -> conveyorMode.getValue().isImport() ? + GTGuiTextures.MANUAL_IO_OVERLAY_OUT[1] : GTGuiTextures.MANUAL_IO_OVERLAY_IN[1]), + new DynamicDrawable(() -> conveyorMode.getValue().isImport() ? + GTGuiTextures.MANUAL_IO_OVERLAY_OUT[2] : GTGuiTextures.MANUAL_IO_OVERLAY_IN[2]) + }) .build()); if (createConveyorModeRow()) diff --git a/src/main/java/gregtech/common/covers/CoverPump.java b/src/main/java/gregtech/common/covers/CoverPump.java index e91a59118a6..a7fc92010d1 100644 --- a/src/main/java/gregtech/common/covers/CoverPump.java +++ b/src/main/java/gregtech/common/covers/CoverPump.java @@ -40,7 +40,9 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IDrawable; import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.drawable.DynamicDrawable; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Color; @@ -257,7 +259,14 @@ protected ParentWidget createUI(ModularPanel mainPanel, GuiSyncManager syncMa column.child(new EnumRowBuilder<>(ManualImportExportMode.class) .value(manualIOmode) .lang("cover.generic.manual_io") - .overlay(GTGuiTextures.MANUAL_IO_OVERLAY) + .overlay(new IDrawable[] { + new DynamicDrawable(() -> pumpMode.getValue().isImport() ? + GTGuiTextures.MANUAL_IO_OVERLAY_OUT[0] : GTGuiTextures.MANUAL_IO_OVERLAY_IN[0]), + new DynamicDrawable(() -> pumpMode.getValue().isImport() ? + GTGuiTextures.MANUAL_IO_OVERLAY_OUT[1] : GTGuiTextures.MANUAL_IO_OVERLAY_IN[1]), + new DynamicDrawable(() -> pumpMode.getValue().isImport() ? + GTGuiTextures.MANUAL_IO_OVERLAY_OUT[2] : GTGuiTextures.MANUAL_IO_OVERLAY_IN[2]) + }) .build()); if (createPumpModeRow()) diff --git a/src/main/java/gregtech/common/items/MetaItem1.java b/src/main/java/gregtech/common/items/MetaItem1.java index 23c6f54c761..a2ef67881d4 100644 --- a/src/main/java/gregtech/common/items/MetaItem1.java +++ b/src/main/java/gregtech/common/items/MetaItem1.java @@ -853,7 +853,8 @@ public void registerSubItems() { // Circuit Components: ID 516-565 VACUUM_TUBE = addItem(516, "circuit.vacuum_tube").setUnificationData(OrePrefix.circuit, Tier.ULV); - GLASS_TUBE = addItem(517, "component.glass.tube"); + GLASS_TUBE = addItem(517, "component.glass.tube") + .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Glass, M))); TRANSISTOR = addItem(518, "component.transistor").setUnificationData(OrePrefix.component, Component.Transistor); RESISTOR = addItem(519, "component.resistor").setUnificationData(OrePrefix.component, Component.Resistor); CAPACITOR = addItem(520, "component.capacitor").setUnificationData(OrePrefix.component, Component.Capacitor); diff --git a/src/main/java/gregtech/common/items/behaviors/ClipboardBehavior.java b/src/main/java/gregtech/common/items/behaviors/ClipboardBehavior.java index 3100a76249e..05923019334 100644 --- a/src/main/java/gregtech/common/items/behaviors/ClipboardBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/ClipboardBehavior.java @@ -1,5 +1,7 @@ package gregtech.common.items.behaviors; +import gregtech.api.GTValues; +import gregtech.api.GregTechAPI; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; import gregtech.api.gui.widgets.ClickButtonWidget; @@ -31,7 +33,6 @@ import java.util.ArrayList; import java.util.List; -import static gregtech.common.blocks.MetaBlocks.MACHINE; import static gregtech.common.metatileentities.MetaTileEntities.CLIPBOARD_TILE; public class ClipboardBehavior implements IItemBehaviour, ItemUIFactory { @@ -258,7 +259,7 @@ public ActionResult onItemUse(EntityPlayer player, World world, Block BlockPos shiftedPos = pos.offset(facing); Block shiftedBlock = world.getBlockState(shiftedPos).getBlock(); if (shiftedBlock.isAir(world.getBlockState(shiftedPos), world, shiftedPos)) { - IBlockState state = MACHINE.getDefaultState(); + IBlockState state = GregTechAPI.mteManager.getRegistry(GTValues.MODID).getBlock().getDefaultState(); world.setBlockState(shiftedPos, state); // Get new TE shiftedBlock.createTileEntity(world, state); diff --git a/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java b/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java index 82a2f46c854..8e86e967a7c 100644 --- a/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java @@ -1,8 +1,11 @@ package gregtech.common.items.behaviors; import gregtech.api.GTValues; -import gregtech.api.GregTechAPI; -import gregtech.api.capability.*; +import gregtech.api.capability.GregtechCapabilities; +import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IElectricItem; +import gregtech.api.capability.IEnergyContainer; +import gregtech.api.capability.IWorkable; import gregtech.api.capability.impl.FluidTankList; import gregtech.api.items.metaitem.stats.IItemBehaviour; import gregtech.api.metatileentity.IDataInfoProvider; @@ -141,8 +144,9 @@ public List getScannerInfo(EntityPlayer player, World world, Blo new TextComponentTranslation(LocalizationUtils.format(metaTileEntity.getMetaFullName())) .setStyle(new Style().setColor(TextFormatting.BLUE)), new TextComponentTranslation(TextFormattingUtil - .formatNumbers(GregTechAPI.MTE_REGISTRY.getIdByObjectName(metaTileEntity.metaTileEntityId))) - .setStyle(new Style().setColor(TextFormatting.BLUE)))); + .formatNumbers( + metaTileEntity.getRegistry().getIdByObjectName(metaTileEntity.metaTileEntityId))) + .setStyle(new Style().setColor(TextFormatting.BLUE)))); list.add(new TextComponentTranslation("behavior.tricorder.divider")); diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index 9f01ef182e5..e2e2624f8cd 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -132,6 +132,8 @@ import net.minecraft.util.ResourceLocation; +import org.jetbrains.annotations.NotNull; + import java.util.HashMap; import java.util.Map; import java.util.function.BiFunction; @@ -599,7 +601,7 @@ public static void init() { // Circuit Assembler, IDs 650-664 registerSimpleMetaTileEntity(CIRCUIT_ASSEMBLER, 635, "circuit_assembler", RecipeMaps.CIRCUIT_ASSEMBLER_RECIPES, - Textures.ASSEMBLER_OVERLAY, true, GTUtility.hvCappedTankSizeFunction); + Textures.CIRCUIT_ASSEMBLER_OVERLAY, true, GTUtility.hvCappedTankSizeFunction); // Rock Breaker, IDs 665-679 registerMetaTileEntities(ROCK_BREAKER, 665, "rock_breaker", @@ -683,7 +685,7 @@ public static void init() { new MetaTileEntityImplosionCompressor(gregtechId("implosion_compressor"))); PYROLYSE_OVEN = registerMetaTileEntity(1004, new MetaTileEntityPyrolyseOven(gregtechId("pyrolyse_oven"))); DISTILLATION_TOWER = registerMetaTileEntity(1005, - new MetaTileEntityDistillationTower(gregtechId("distillation_tower"))); + new MetaTileEntityDistillationTower(gregtechId("distillation_tower"), true)); MULTI_FURNACE = registerMetaTileEntity(1006, new MetaTileEntityMultiSmelter(gregtechId("multi_furnace"))); LARGE_COMBUSTION_ENGINE = registerMetaTileEntity(1007, new MetaTileEntityLargeCombustionEngine(gregtechId("large_combustion_engine"), GTValues.EV)); @@ -1253,17 +1255,26 @@ public static void registerMetaTileEntities( } } - public static T registerMetaTileEntity(int id, T sampleMetaTileEntity) { - if (sampleMetaTileEntity instanceof IMultiblockAbilityPart abilityPart) { - MultiblockAbility.registerMultiblockAbility(abilityPart.getAbility(), sampleMetaTileEntity); + /** + * Register a MetaTileEntity + * + * @param id the numeric ID to use as item metadata + * @param mte the MTE to register + * @return the MTE + * @param the MTE class + */ + public static @NotNull T registerMetaTileEntity(int id, @NotNull T mte) { + if (mte instanceof IMultiblockAbilityPartabilityPart) { + MultiblockAbility.registerMultiblockAbility(abilityPart.getAbility(), mte); } - if (sampleMetaTileEntity instanceof MultiblockControllerBase && Mods.JustEnoughItems.isModLoaded()) { - if (((MultiblockControllerBase) sampleMetaTileEntity).shouldShowInJei()) { - MultiblockInfoCategory.registerMultiblock((MultiblockControllerBase) sampleMetaTileEntity); - } + + if (Mods.JustEnoughItems.isModLoaded() && mte instanceof MultiblockControllerBase controller && + controller.shouldShowInJei()) { + MultiblockInfoCategory.registerMultiblock(controller); } - GregTechAPI.MTE_REGISTRY.register(id, sampleMetaTileEntity.metaTileEntityId, sampleMetaTileEntity); - return sampleMetaTileEntity; + + mte.getRegistry().register(id, mte.metaTileEntityId, mte); + return mte; } @SuppressWarnings("unused") diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityAssemblyLine.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityAssemblyLine.java index 4432cd61a21..fb2de88df33 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityAssemblyLine.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityAssemblyLine.java @@ -65,6 +65,7 @@ public class MetaTileEntityAssemblyLine extends RecipeMapMultiblockController { @SideOnly(Side.CLIENT) private GTLaserBeamParticle[][] beamParticles; private int beamCount; + private int beamTime; public MetaTileEntityAssemblyLine(ResourceLocation metaTileEntityId) { super(metaTileEntityId, RecipeMaps.ASSEMBLY_LINE_RECIPES); @@ -189,14 +190,22 @@ public void update() { // beams and the maximum progress in the recipe. int beamTime = Math.max(1, maxProgress / maxBeams); - int currentBeamCount = Math.min(maxBeams, getRecipeMapWorkable().getProgress() / beamTime); + int beamCount = Math.min(maxBeams, getRecipeMapWorkable().getProgress() / beamTime + 1); - if (currentBeamCount != beamCount) { - beamCount = currentBeamCount; + if (beamCount != this.beamCount) { + if (beamCount < this.beamCount) { + // if beam count decreases, the last beam in the queue needs to be removed for the sake of fade + // time. + this.beamCount = Math.max(0, beamCount - 1); + writeCustomData(GregtechDataCodes.UPDATE_PARTICLE, this::writeParticles); + } + this.beamTime = beamTime; + this.beamCount = beamCount; writeCustomData(GregtechDataCodes.UPDATE_PARTICLE, this::writeParticles); } } else if (beamCount != 0) { - beamCount = 0; + this.beamTime = 0; + this.beamCount = 0; writeCustomData(GregtechDataCodes.UPDATE_PARTICLE, this::writeParticles); } } @@ -239,11 +248,13 @@ public void onRemoval() { private void writeParticles(@NotNull PacketBuffer buf) { buf.writeVarInt(beamCount); + buf.writeVarInt(beamTime); } @SideOnly(Side.CLIENT) private void readParticles(@NotNull PacketBuffer buf) { beamCount = buf.readVarInt(); + beamTime = buf.readVarInt(); if (beamParticles == null) { beamParticles = new GTLaserBeamParticle[17][2]; } @@ -306,7 +317,7 @@ private void readParticles(@NotNull PacketBuffer buf) { @NotNull @SideOnly(Side.CLIENT) private GTLaserBeamParticle createALParticles(Vector3 startPos, Vector3 endPos) { - return new GTLaserBeamParticle(this, startPos, endPos) + return new GTLaserBeamParticle(this, startPos, endPos, beamTime) .setBody(LASER_LOCATION) .setBeamHeight(0.125f) // Try commenting or adjusting on the next four lines to see what happens 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 c09b9b91203..73163307e2a 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java @@ -1,6 +1,8 @@ package gregtech.common.metatileentities.multi.electric; import gregtech.api.GTValues; +import gregtech.api.GregTechAPI; +import gregtech.api.block.ICleanroomFilter; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IEnergyContainer; @@ -44,7 +46,6 @@ import gregtech.common.metatileentities.multi.electric.centralmonitor.MetaTileEntityCentralMonitor; import gregtech.core.sound.GTSoundEvents; -import net.minecraft.block.Block; import net.minecraft.block.BlockDoor; import net.minecraft.block.state.IBlockState; import net.minecraft.client.resources.I18n; @@ -61,6 +62,7 @@ import net.minecraft.util.math.BlockPos; 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.TextFormatting; import net.minecraft.world.World; @@ -73,7 +75,6 @@ import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; -import org.apache.commons.lang3.ArrayUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -81,6 +82,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -105,6 +107,7 @@ public class MetaTileEntityCleanroom extends MultiblockWithDisplayBase private IEnergyContainer energyContainer; + private ICleanroomFilter cleanroomFilter; private final CleanroomLogic cleanroomLogic; private final Collection cleanroomReceivers = new HashSet<>(); @@ -130,21 +133,15 @@ private void resetTileAbilities() { protected void formStructure(PatternMatchContext context) { super.formStructure(context); initializeAbilities(); - Object type = context.get("FilterType"); - if (type instanceof BlockCleanroomCasing.CasingType) { - BlockCleanroomCasing.CasingType casingType = (BlockCleanroomCasing.CasingType) type; - - if (casingType.equals(BlockCleanroomCasing.CasingType.FILTER_CASING)) { - this.cleanroomType = CleanroomType.CLEANROOM; - } else if (casingType.equals(BlockCleanroomCasing.CasingType.FILTER_CASING_STERILE)) { - this.cleanroomType = CleanroomType.STERILE_CLEANROOM; - } - } + this.cleanroomFilter = context.get("FilterType"); + this.cleanroomType = cleanroomFilter.getCleanroomType(); + // max progress is based on the dimensions of the structure: (x^3)-(x^2) // taller cleanrooms take longer than wider ones // minimum of 100 is a 5x5x5 cleanroom: 125-25=100 ticks this.cleanroomLogic.setMaxProgress(Math.max(100, ((lDist + rDist + 1) * (bDist + fDist + 1) * hDist) - ((lDist + rDist + 1) * (bDist + fDist + 1)))); + this.cleanroomLogic.setMinEnergyTier(cleanroomFilter.getMinTier()); } @Override @@ -390,14 +387,13 @@ protected BlockPattern createStructurePattern() { protected TraceabilityPredicate filterPredicate() { return new TraceabilityPredicate(blockWorldState -> { IBlockState blockState = blockWorldState.getBlockState(); - Block block = blockState.getBlock(); - if (block instanceof BlockCleanroomCasing) { - BlockCleanroomCasing.CasingType casingType = ((BlockCleanroomCasing) blockState.getBlock()) - .getState(blockState); - if (casingType.equals(BlockCleanroomCasing.CasingType.PLASCRETE)) return false; - - Object currentFilter = blockWorldState.getMatchContext().getOrPut("FilterType", casingType); - if (!currentFilter.toString().equals(casingType.getName())) { + if (GregTechAPI.CLEANROOM_FILTERS.containsKey(blockState)) { + ICleanroomFilter cleanroomFilter = GregTechAPI.CLEANROOM_FILTERS.get(blockState); + if (cleanroomFilter.getCleanroomType() == null) return false; + + ICleanroomFilter currentFilter = blockWorldState.getMatchContext().getOrPut("FilterType", + cleanroomFilter); + if (!currentFilter.getCleanroomType().equals(cleanroomFilter.getCleanroomType())) { blockWorldState.setError(new PatternStringError("gregtech.multiblock.pattern.error.filters")); return false; } @@ -405,12 +401,12 @@ protected TraceabilityPredicate filterPredicate() { return true; } return false; - }, () -> ArrayUtils.addAll( - Arrays.stream(BlockCleanroomCasing.CasingType.values()) - .filter(type -> !type.equals(BlockCleanroomCasing.CasingType.PLASCRETE)) - .map(type -> new BlockInfo(MetaBlocks.CLEANROOM_CASING.getState(type), null)) - .toArray(BlockInfo[]::new))) - .addTooltips("gregtech.multiblock.pattern.error.filters"); + }, () -> GregTechAPI.CLEANROOM_FILTERS.entrySet().stream() + .filter(entry -> entry.getValue().getCleanroomType() != null) + .sorted(Comparator.comparingInt(entry -> entry.getValue().getTier())) + .map(entry -> new BlockInfo(entry.getKey(), null)) + .toArray(BlockInfo[]::new)) + .addTooltips("gregtech.multiblock.pattern.error.filters"); } @SideOnly(Side.CLIENT) @@ -453,10 +449,9 @@ protected TraceabilityPredicate innerPredicate() { return false; // the machine does not need a cleanroom, so do nothing more - if (!(metaTileEntity instanceof ICleanroomReceiver)) return true; + if (!(metaTileEntity instanceof ICleanroomReceiver cleanroomReceiver)) return true; // give the machine this cleanroom if it doesn't have this one - ICleanroomReceiver cleanroomReceiver = (ICleanroomReceiver) metaTileEntity; if (cleanroomReceiver.getCleanroom() != this) { cleanroomReceiver.setCleanroom(this); cleanroomReceivers.add(cleanroomReceiver); @@ -511,6 +506,15 @@ protected void addDisplayText(List textList) { cleanState)); } }) + .addCustom(tl -> { + if (!cleanroomLogic.isVoltageHighEnough()) { + ITextComponent energyNeeded = new TextComponentString( + GTValues.VNF[cleanroomFilter.getMinTier()]); + tl.add(TextComponentUtil.translationWithColor(TextFormatting.YELLOW, + "gregtech.multiblock.cleanroom.low_tier", energyNeeded)); + } + }) + .addEnergyUsageExactLine(isClean() ? 4 : GTValues.VA[getEnergyTier()]) .addWorkingStatusLine() .addProgressLine(getProgressPercent() / 100.0); } @@ -593,7 +597,8 @@ public boolean isClean() { @Override public List getDataInfo() { return Collections.singletonList(new TextComponentTranslation( - isClean() ? "gregtech.multiblock.cleanroom.clean_state" : "gregtech.multiblock.cleanroom.dirty_state")); + isClean() ? "gregtech.multiblock.cleanroom.clean_state" : "gregtech.multiblock.cleanroom.dirty_state", + this.cleanAmount)); } @Override @@ -639,7 +644,7 @@ public long getEnergyInputPerSecond() { } public boolean drainEnergy(boolean simulate) { - long energyToDrain = isClean() ? (long) Math.min(4, Math.pow(4, getEnergyTier())) : + long energyToDrain = isClean() ? 4 : GTValues.VA[getEnergyTier()]; long resultEnergy = energyContainer.getEnergyStored() - energyToDrain; if (resultEnergy >= 0L && resultEnergy <= energyContainer.getEnergyCapacity()) { @@ -761,10 +766,11 @@ public List getMatchingShapes() { .where('R', Blocks.IRON_DOOR.getDefaultState().withProperty(BlockDoor.FACING, EnumFacing.NORTH) .withProperty(BlockDoor.HALF, BlockDoor.EnumDoorHalf.UPPER)); - Arrays.stream(BlockCleanroomCasing.CasingType.values()) - .filter(casingType -> !casingType.equals(BlockCleanroomCasing.CasingType.PLASCRETE)) - .forEach(casingType -> shapeInfo - .add(builder.where('F', MetaBlocks.CLEANROOM_CASING.getState(casingType)).build())); + GregTechAPI.CLEANROOM_FILTERS.entrySet().stream() + .filter(entry -> entry.getValue().getCleanroomType() != null) + .sorted(Comparator.comparingInt(entry -> entry.getValue().getTier())) + .forEach(entry -> shapeInfo.add(builder.where('F', entry.getKey()).build())); + return shapeInfo; } diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java index 553dae63de4..41e1da2ea88 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java @@ -1,13 +1,21 @@ package gregtech.common.metatileentities.multi.electric; +import gregtech.api.capability.IMultipleTankHandler; +import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.MultiblockRecipeLogic; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.IMultiblockPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; import gregtech.api.pattern.BlockPattern; import gregtech.api.pattern.FactoryBlockPattern; +import gregtech.api.pattern.PatternMatchContext; +import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMaps; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; import gregtech.api.util.RelativeDirection; import gregtech.api.util.TextComponentUtil; @@ -15,8 +23,7 @@ import gregtech.client.renderer.texture.Textures; import gregtech.common.blocks.BlockMetalCasing.MetalCasingType; import gregtech.common.blocks.MetaBlocks; -import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiFluidHatch; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEOutputHatch; +import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockPart; import gregtech.core.sound.GTSoundEvents; import net.minecraft.block.state.IBlockState; @@ -26,25 +33,44 @@ import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.items.IItemHandlerModifiable; +import com.cleanroommc.modularui.utils.FluidTankHandler; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; import org.jetbrains.annotations.NotNull; import java.util.List; import java.util.function.Function; +import java.util.stream.Collectors; import static gregtech.api.util.RelativeDirection.*; public class MetaTileEntityDistillationTower extends RecipeMapMultiblockController { + private final boolean useAdvHatchLogic; + + protected int layerCount; + protected List orderedFluidOutputs; + public MetaTileEntityDistillationTower(ResourceLocation metaTileEntityId) { + this(metaTileEntityId, false); + } + + public MetaTileEntityDistillationTower(ResourceLocation metaTileEntityId, boolean useAdvHatchLogic) { super(metaTileEntityId, RecipeMaps.DISTILLATION_RECIPES); + this.useAdvHatchLogic = useAdvHatchLogic; + if (useAdvHatchLogic) { + this.recipeMapWorkable = new DistillationTowerRecipeLogic(this); + } } @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { - return new MetaTileEntityDistillationTower(metaTileEntityId); + return new MetaTileEntityDistillationTower(metaTileEntityId, this.useAdvHatchLogic); } @Override @@ -52,6 +78,10 @@ protected Function multiblockPartSorter() { return RelativeDirection.UP.getSorter(getFrontFacing(), getUpwardsFacing(), isFlipped()); } + /** + * Whether this multi can be rotated or face upwards.
+ * There will be consequences if this returns true. Go override {@link #determineOrderedFluidOutputs()} + */ @Override public boolean allowsExtendedFacing() { return false; @@ -74,7 +104,74 @@ protected void addDisplayText(List textList) { } @Override - protected BlockPattern createStructurePattern() { + protected void formStructure(PatternMatchContext context) { + super.formStructure(context); + if (!useAdvHatchLogic || this.structurePattern == null) return; + this.layerCount = determineLayerCount(this.structurePattern); + this.orderedFluidOutputs = determineOrderedFluidOutputs(); + } + + /** + * Needs to be overriden for multiblocks that have different assemblies than the standard distillation tower. + * + * @param structurePattern the structure pattern + * @return the number of layers that could hold output hatches + */ + protected int determineLayerCount(@NotNull BlockPattern structurePattern) { + return structurePattern.formedRepetitionCount[1] + 1; + } + + /** + * Needs to be overriden for multiblocks that have different assemblies than the standard distillation tower. + * + * @return the fluid hatches of the multiblock, in order, with null entries for layers that do not have hatches. + */ + protected List determineOrderedFluidOutputs() { + List fluidExportParts = this.getMultiblockParts().stream() + .filter(iMultiblockPart -> iMultiblockPart instanceof IMultiblockAbilityPartabilityPart && + abilityPart.getAbility() == MultiblockAbility.EXPORT_FLUIDS && + abilityPart instanceof MetaTileEntityMultiblockPart) + .map(iMultiblockPart -> (MetaTileEntityMultiblockPart) iMultiblockPart) + .collect(Collectors.toList()); + // the fluidExportParts should come sorted in smallest Y first, largest Y last. + List orderedHandlerList = new ObjectArrayList<>(); + int firstY = this.getPos().getY() + 1; + int exportIndex = 0; + for (int y = firstY; y < firstY + this.layerCount; y++) { + if (fluidExportParts.size() <= exportIndex) { + orderedHandlerList.add(null); + continue; + } + MetaTileEntityMultiblockPart part = fluidExportParts.get(exportIndex); + if (part.getPos().getY() == y) { + List hatchTanks = new ObjectArrayList<>(); + // noinspection unchecked + ((IMultiblockAbilityPart) part).registerAbilities(hatchTanks); + if (hatchTanks.size() == 1) + orderedHandlerList.add(FluidTankHandler.getTankFluidHandler(hatchTanks.get(0))); + else orderedHandlerList.add(new FluidTankList(false, hatchTanks)); + exportIndex++; + } else if (part.getPos().getY() > y) { + orderedHandlerList.add(null); + } else { + GTLog.logger.error("The Distillation Tower at " + this.getPos() + + " had a fluid export hatch with an unexpected Y position."); + this.invalidateStructure(); + return new ObjectArrayList<>(); + } + } + return orderedHandlerList; + } + + @Override + public void invalidateStructure() { + super.invalidateStructure(); + this.layerCount = 0; + this.orderedFluidOutputs = null; + } + + @Override + protected @NotNull BlockPattern createStructurePattern() { return FactoryBlockPattern.start(RIGHT, FRONT, UP) .aisle("YSY", "YYY", "YYY") .aisle("XXX", "X#X", "XXX").setRepeatable(1, 11) @@ -85,11 +182,7 @@ protected BlockPattern createStructurePattern() { .or(abilities(MultiblockAbility.INPUT_ENERGY).setMinGlobalLimited(1).setMaxGlobalLimited(3)) .or(abilities(MultiblockAbility.IMPORT_FLUIDS).setExactLimit(1))) .where('X', states(getCasingState()) - .or(metaTileEntities(MultiblockAbility.REGISTRY.get(MultiblockAbility.EXPORT_FLUIDS).stream() - .filter(mte -> !(mte instanceof MetaTileEntityMultiFluidHatch) && - !(mte instanceof MetaTileEntityMEOutputHatch)) - .toArray(MetaTileEntity[]::new)) - .setMinLayerLimited(1).setMaxLayerLimited(1)) + .or(abilities(MultiblockAbility.EXPORT_FLUIDS).setMaxLayerLimited(1, 1)) .or(autoAbilities(true, false))) .where('#', air()) .build(); @@ -124,6 +217,70 @@ protected ICubeRenderer getFrontOverlay() { @Override public int getFluidOutputLimit() { - return getOutputFluidInventory().getTanks(); + return this.layerCount; + } + + protected class DistillationTowerRecipeLogic extends MultiblockRecipeLogic { + + public DistillationTowerRecipeLogic(MetaTileEntityDistillationTower tileEntity) { + super(tileEntity); + } + + protected boolean applyFluidToOutputs(List fluids, boolean doFill) { + boolean valid = true; + for (int i = 0; i < fluids.size(); i++) { + IFluidHandler handler = orderedFluidOutputs.get(i); + // void if no hatch is found on that fluid's layer + // this is considered trimming and thus ignores canVoid + if (handler == null) continue; + int accepted = handler.fill(fluids.get(i), doFill); + if (accepted != fluids.get(i).amount) valid = false; + if (!doFill && !valid) break; + } + return valid; + } + + @Override + protected void outputRecipeOutputs() { + GTTransferUtils.addItemsToItemHandler(getOutputInventory(), false, itemOutputs); + this.applyFluidToOutputs(fluidOutputs, true); + } + + @Override + protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, + @NotNull IItemHandlerModifiable importInventory, + @NotNull IMultipleTankHandler importFluids) { + this.overclockResults = calculateOverclock(recipe); + + modifyOverclockPost(overclockResults, recipe.getRecipePropertyStorage()); + + if (!hasEnoughPower(overclockResults)) { + return false; + } + + IItemHandlerModifiable exportInventory = getOutputInventory(); + + // We have already trimmed outputs and chanced outputs at this time + // Attempt to merge all outputs + chanced outputs into the output bus, to prevent voiding chanced outputs + if (!metaTileEntity.canVoidRecipeItemOutputs() && + !GTTransferUtils.addItemsToItemHandler(exportInventory, true, recipe.getAllItemOutputs())) { + this.isOutputsFull = true; + return false; + } + + // Perform layerwise fluid checks + if (!metaTileEntity.canVoidRecipeFluidOutputs() && + !this.applyFluidToOutputs(recipe.getAllFluidOutputs(), false)) { + this.isOutputsFull = true; + return false; + } + + this.isOutputsFull = false; + if (recipe.matches(true, importInventory, importFluids)) { + this.metaTileEntity.addNotifiedInput(importInventory); + return true; + } + return false; + } } } 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 35c06785bab..6b735dcc96c 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java @@ -691,18 +691,20 @@ public void renderBloomEffect(@NotNull BufferBuilder buffer, @NotNull EffectRend EnumFacing.Axis axis = RelativeDirection.UP.getRelativeFacing(getFrontFacing(), getUpwardsFacing(), isFlipped()) .getAxis(); + buffer.begin(GL11.GL_QUAD_STRIP, DefaultVertexFormats.POSITION_COLOR); RenderBufferHelper.renderRing(buffer, getPos().getX() - context.cameraX() + relativeBack.getXOffset() * 7 + 0.5, getPos().getY() - context.cameraY() + relativeBack.getYOffset() * 7 + 0.5, getPos().getZ() - context.cameraZ() + relativeBack.getZOffset() * 7 + 0.5, 6, 0.2, 10, 20, r, g, b, a, axis); + Tessellator.getInstance().draw(); } @Override @SideOnly(Side.CLIENT) public boolean shouldRenderBloomEffect(@NotNull EffectRenderContext context) { - return this.hasFusionRingColor(); + return this.hasFusionRingColor() && context.camera().isBoundingBoxInFrustum(getRenderBoundingBox()); } @Override @@ -753,14 +755,10 @@ public void preDraw(@NotNull BufferBuilder buffer) { GlStateManager.color(1, 1, 1, 1); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240.0F, 240.0F); GlStateManager.disableTexture2D(); - - buffer.begin(GL11.GL_QUAD_STRIP, DefaultVertexFormats.POSITION_COLOR); } @Override public void postDraw(@NotNull BufferBuilder buffer) { - Tessellator.getInstance().draw(); - GlStateManager.enableTexture2D(); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, lastBrightnessX, lastBrightnessY); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPyrolyseOven.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPyrolyseOven.java index 15c3f450c0a..20dbb3d5ca5 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPyrolyseOven.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPyrolyseOven.java @@ -180,8 +180,12 @@ protected void modifyOverclockPost(int[] resultOverclock, @NotNull IRecipeProper return; if (coilTier == 0) { - resultOverclock[1] *= 5.0 / 4; // 25% slower with cupronickel (coilTier = 0) - } else resultOverclock[1] *= 2.0f / (coilTier + 1); // each coil above kanthal (coilTier = 1) is 50% faster + // 75% speed with cupronickel (coilTier = 0) + resultOverclock[1] = 4 * resultOverclock[1] / 3; + } else { + // each coil above kanthal (coilTier = 1) is 50% faster + resultOverclock[1] = resultOverclock[1] * 2 / (coilTier + 1); + } resultOverclock[1] = Math.max(1, resultOverclock[1]); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java index 949f47b77ca..4467ae2b8c9 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java @@ -312,9 +312,13 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { workingStateValue::setBoolValue)) .overlay(GTGuiTextures.BUTTON_ITEM_OUTPUT) .tooltipBuilder(t -> t.setAutoUpdate(true) - .addLine(workingStateValue.getBoolValue() ? - IKey.lang("gregtech.gui.item_auto_output.tooltip.enabled") : - IKey.lang("gregtech.gui.item_auto_output.tooltip.disabled")))) + .addLine(isExportHatch ? + (workingStateValue.getBoolValue() ? + IKey.lang("gregtech.gui.item_auto_output.tooltip.enabled") : + IKey.lang("gregtech.gui.item_auto_output.tooltip.disabled")) : + (workingStateValue.getBoolValue() ? + IKey.lang("gregtech.gui.item_auto_input.tooltip.enabled") : + IKey.lang("gregtech.gui.item_auto_input.tooltip.disabled"))))) .child(new ToggleButton() .top(18) .value(new BoolValue.Dynamic(collapseStateValue::getBoolValue, 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 1c8f73e6837..9084eeed969 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 @@ -101,8 +101,11 @@ public void receiveInitialSyncData(PacketBuffer buf) { public void receiveCustomData(int dataId, PacketBuffer buf) { super.receiveCustomData(dataId, buf); if (dataId == UPDATE_ONLINE_STATUS) { - this.isOnline = buf.readBoolean(); - scheduleRenderUpdate(); + boolean isOnline = buf.readBoolean(); + if (this.isOnline != isOnline) { + this.isOnline = isOnline; + scheduleRenderUpdate(); + } } } @@ -139,18 +142,17 @@ public void setFrontFacing(EnumFacing frontFacing) { public void gridChanged() {} /** - * Update me network connection status. + * Get the me network connection status, updating it if on serverside. * * @return the updated status. */ public boolean updateMEStatus() { - if (this.aeProxy != null) { - this.isOnline = this.aeProxy.isActive() && this.aeProxy.isPowered(); - } else { - this.isOnline = false; - } if (!getWorld().isRemote) { - writeCustomData(UPDATE_ONLINE_STATUS, buf -> buf.writeBoolean(this.isOnline)); + boolean isOnline = this.aeProxy != null && this.aeProxy.isActive() && this.aeProxy.isPowered(); + if (this.isOnline != isOnline) { + writeCustomData(UPDATE_ONLINE_STATUS, buf -> buf.writeBoolean(isOnline)); + this.isOnline = isOnline; + } } return this.isOnline; } diff --git a/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamCoalBoiler.java b/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamCoalBoiler.java index 0411582217a..555595b007f 100755 --- a/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamCoalBoiler.java +++ b/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamCoalBoiler.java @@ -7,6 +7,7 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.recipes.ModHandler; +import gregtech.api.recipes.category.ICategoryOverride; import gregtech.client.renderer.texture.Textures; import net.minecraft.entity.player.EntityPlayer; @@ -18,7 +19,7 @@ import org.jetbrains.annotations.NotNull; -public class SteamCoalBoiler extends SteamBoiler { +public class SteamCoalBoiler extends SteamBoiler implements ICategoryOverride { public SteamCoalBoiler(ResourceLocation metaTileEntityId, boolean isHighPressure) { super(metaTileEntityId, isHighPressure, Textures.COAL_BOILER_OVERLAY); @@ -92,4 +93,9 @@ public ModularUI createUI(EntityPlayer player) { GuiTextures.PROGRESS_BAR_BOILER_FUEL.get(isHighPressure), MoveType.VERTICAL) .build(getHolder(), player); } + + @Override + public @NotNull String @NotNull [] getJEICategoryOverrides() { + return new String[] { "minecraft.fuel" }; + } } diff --git a/src/main/java/gregtech/common/terminal/app/guide/MultiBlockGuideApp.java b/src/main/java/gregtech/common/terminal/app/guide/MultiBlockGuideApp.java index 6e261666def..4f731b0572e 100644 --- a/src/main/java/gregtech/common/terminal/app/guide/MultiBlockGuideApp.java +++ b/src/main/java/gregtech/common/terminal/app/guide/MultiBlockGuideApp.java @@ -7,6 +7,8 @@ import gregtech.api.util.GTUtility; import gregtech.common.metatileentities.MetaTileEntities; +import net.minecraft.util.ResourceLocation; + import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -22,8 +24,10 @@ public MetaTileEntity ofJson(JsonObject json) { if (json.isJsonObject()) { for (String valid : valids) { JsonElement id = json.getAsJsonObject().get(valid); - if (id != null && id.isJsonPrimitive()) - return GregTechAPI.MTE_REGISTRY.getObject(GTUtility.gregtechId(id.getAsString())); + if (id != null && id.isJsonPrimitive()) { + ResourceLocation location = GTUtility.gregtechId(id.getAsString()); + return GregTechAPI.mteManager.getRegistry(location.getNamespace()).getObject(location); + } } } return null; diff --git a/src/main/java/gregtech/common/terminal/app/guide/SimpleMachineGuideApp.java b/src/main/java/gregtech/common/terminal/app/guide/SimpleMachineGuideApp.java index 171f108dfbb..cec7ee6d88f 100644 --- a/src/main/java/gregtech/common/terminal/app/guide/SimpleMachineGuideApp.java +++ b/src/main/java/gregtech/common/terminal/app/guide/SimpleMachineGuideApp.java @@ -8,6 +8,8 @@ import gregtech.api.util.GTUtility; import gregtech.common.metatileentities.MetaTileEntities; +import net.minecraft.util.ResourceLocation; + import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -38,8 +40,10 @@ public MetaTileEntity ofJson(JsonObject json) { if (json.isJsonObject()) { for (String valid : valids) { JsonElement id = json.getAsJsonObject().get(valid); - if (id != null && id.isJsonPrimitive()) - return GregTechAPI.MTE_REGISTRY.getObject(GTUtility.gregtechId(id.getAsString())); + if (id != null && id.isJsonPrimitive()) { + ResourceLocation location = GTUtility.gregtechId(id.getAsString()); + return GregTechAPI.mteManager.getRegistry(location.getNamespace()).getObject(location); + } } } return null; diff --git a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/GuideConfigEditor.java b/src/main/java/gregtech/common/terminal/app/guideeditor/widget/GuideConfigEditor.java index 83f6ad93091..0e23f2b6e46 100644 --- a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/GuideConfigEditor.java +++ b/src/main/java/gregtech/common/terminal/app/guideeditor/widget/GuideConfigEditor.java @@ -6,9 +6,16 @@ import gregtech.api.gui.Widget; import gregtech.api.gui.resources.ColorRectTexture; import gregtech.api.gui.resources.TextTexture; -import gregtech.api.gui.widgets.*; +import gregtech.api.gui.widgets.AbstractWidgetGroup; +import gregtech.api.gui.widgets.ImageWidget; +import gregtech.api.gui.widgets.LabelWidget; +import gregtech.api.gui.widgets.PhantomSlotWidget; +import gregtech.api.gui.widgets.TabGroup; +import gregtech.api.gui.widgets.TextFieldWidget; +import gregtech.api.gui.widgets.WidgetGroup; import gregtech.api.gui.widgets.tab.IGuiTextureTabInfo; import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.registry.MTERegistry; import gregtech.api.terminal.TerminalRegistry; import gregtech.api.terminal.app.AbstractApplication; import gregtech.api.terminal.gui.CustomTabListRenderer; @@ -275,10 +282,12 @@ private JsonObject saveType(JsonObject jsonObject) { } } else if ((app instanceof MultiBlockGuideApp || app instanceof SimpleMachineGuideApp) && stack.getItem() instanceof MachineItemBlock) { - MetaTileEntity mte = GregTechAPI.MTE_REGISTRY.getObjectById(stack.getItemDamage()); + MTERegistry registry = GregTechAPI.mteManager.getRegistry( + Objects.requireNonNull(stack.getItem().getRegistryName()).getNamespace()); + MetaTileEntity mte = registry.getObjectById(stack.getItemDamage()); if (mte != null) { jsonObject.addProperty("metatileentity", - GregTechAPI.MTE_REGISTRY.getNameForObject(mte).getPath()); + registry.getNameForObject(mte).getPath()); } else { TerminalDialogWidget.showInfoDialog(app.getOs(), "terminal.component.warning", "terminal.guide_editor.error_type").setClientSide().open(); diff --git a/src/main/java/gregtech/core/CoreModule.java b/src/main/java/gregtech/core/CoreModule.java index c05116355f7..6648efa62bf 100644 --- a/src/main/java/gregtech/core/CoreModule.java +++ b/src/main/java/gregtech/core/CoreModule.java @@ -11,6 +11,8 @@ import gregtech.api.gui.UIFactory; import gregtech.api.items.gui.PlayerInventoryUIFactory; import gregtech.api.metatileentity.MetaTileEntityUIFactory; +import gregtech.api.metatileentity.registry.MTEManager; +import gregtech.api.metatileentity.registry.MTERegistry; import gregtech.api.modules.GregTechModule; import gregtech.api.modules.IGregTechModule; import gregtech.api.mui.GTGuiTextures; @@ -36,6 +38,7 @@ import gregtech.common.ConfigHolder; import gregtech.common.MetaEntities; import gregtech.common.blocks.BlockBatteryPart; +import gregtech.common.blocks.BlockCleanroomCasing; import gregtech.common.blocks.BlockWireCoil; import gregtech.common.blocks.MetaBlocks; import gregtech.common.command.CommandHand; @@ -184,6 +187,12 @@ public void preInit(FMLPreInitializationEvent event) { managerInternal.freezeRegistries(); /* End Material Registration */ + // need to do this before MetaBlocks runs, to make sure all addons get their own BlockMachine + /* Start MTE Registry Addition */ + GregTechAPI.mteManager = MTEManager.getInstance(); + MinecraftForge.EVENT_BUS.post(new MTEManager.MTERegistryEvent()); + /* End MTE Registry Addition */ + OreDictUnifier.init(); MetaBlocks.init(); @@ -191,8 +200,10 @@ public void preInit(FMLPreInitializationEvent event) { ToolItems.init(); GTFluidRegistration.INSTANCE.register(); - /* Start MetaTileEntity Registration */ - MTE_REGISTRY.unfreeze(); + /* Start CEu MetaTileEntity Registration */ + for (MTERegistry registry : mteManager.getRegistries()) { + registry.unfreeze(); + } logger.info("Registering GTCEu Meta Tile Entities"); MetaTileEntities.init(); /* End CEu MetaTileEntity Registration */ @@ -207,6 +218,9 @@ public void preInit(FMLPreInitializationEvent event) { for (BlockBatteryPart.BatteryPartType type : BlockBatteryPart.BatteryPartType.values()) { PSS_BATTERIES.put(MetaBlocks.BATTERY_BLOCK.getState(type), type); } + for (BlockCleanroomCasing.CasingType type : BlockCleanroomCasing.CasingType.values()) { + CLEANROOM_FILTERS.put(MetaBlocks.CLEANROOM_CASING.getState(type), type); + } /* End API Block Registration */ proxy.onPreLoad(); @@ -232,7 +246,10 @@ public void registerPackets() { @Override public void init(FMLInitializationEvent event) { - MTE_REGISTRY.freeze(); // freeze once addon preInit is finished + // freeze once addon preInit is finished + for (MTERegistry registry : mteManager.getRegistries()) { + registry.freeze(); + } proxy.onLoad(); if (RecipeMap.isFoundInvalidRecipe()) { logger.fatal("Seems like invalid recipe was found."); diff --git a/src/main/java/gregtech/core/network/packets/PacketRecoverMTE.java b/src/main/java/gregtech/core/network/packets/PacketRecoverMTE.java index f90fb9af678..fe3f1d1f898 100644 --- a/src/main/java/gregtech/core/network/packets/PacketRecoverMTE.java +++ b/src/main/java/gregtech/core/network/packets/PacketRecoverMTE.java @@ -1,6 +1,5 @@ package gregtech.core.network.packets; -import gregtech.api.GregTechAPI; import gregtech.api.block.machines.BlockMachine; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.network.IPacket; @@ -45,11 +44,11 @@ public void decode(PacketBuffer buf) { public void executeServer(NetHandlerPlayServer handler) { World world = FMLCommonHandler.instance().getMinecraftServerInstance().getWorld(dimension); TileEntity te = world.getTileEntity(pos); - if (te instanceof IGregTechTileEntity && ((IGregTechTileEntity) te).isValid()) { - IGregTechTileEntity holder = (IGregTechTileEntity) te; + if (te instanceof IGregTechTileEntity holder && holder.isValid()) { holder.writeCustomData(INITIALIZE_MTE, buffer -> { buffer.writeVarInt( - GregTechAPI.MTE_REGISTRY.getIdByObjectName(holder.getMetaTileEntity().metaTileEntityId)); + holder.getMetaTileEntity().getRegistry() + .getIdByObjectName(holder.getMetaTileEntity().metaTileEntityId)); holder.getMetaTileEntity().writeInitialSyncData(buffer); }); } else if (!(world.getBlockState(pos).getBlock() instanceof BlockMachine)) { diff --git a/src/main/java/gregtech/core/unification/material/internal/MaterialRegistryManager.java b/src/main/java/gregtech/core/unification/material/internal/MaterialRegistryManager.java index 265e2a875d0..ff26e95cdd2 100644 --- a/src/main/java/gregtech/core/unification/material/internal/MaterialRegistryManager.java +++ b/src/main/java/gregtech/core/unification/material/internal/MaterialRegistryManager.java @@ -140,6 +140,11 @@ private MaterialRegistryImpl createInternalRegistry() { return registry; } + @NotNull + public MaterialRegistry getDefaultRegistry() { + return gregtechRegistry; + } + @NotNull public Material getDefaultFallback() { return gregtechRegistry.getFallbackMaterial(); diff --git a/src/main/java/gregtech/datafix/GTDataFixers.java b/src/main/java/gregtech/datafix/GTDataFixers.java new file mode 100644 index 00000000000..d6b731d38be --- /dev/null +++ b/src/main/java/gregtech/datafix/GTDataFixers.java @@ -0,0 +1,75 @@ +package gregtech.datafix; + +import gregtech.api.GTValues; +import gregtech.api.GregTechAPI; +import gregtech.api.metatileentity.registry.MTERegistry; +import gregtech.datafix.migration.impl.MigrateMTEBlockTE; +import gregtech.datafix.migration.impl.MigrateMTEItems; +import gregtech.datafix.migration.lib.MTERegistriesMigrator; +import gregtech.datafix.walker.WalkItemStackLike; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.datafix.FixTypes; +import net.minecraft.util.datafix.IDataWalker; +import net.minecraftforge.common.util.CompoundDataFixer; +import net.minecraftforge.common.util.ModFixs; +import net.minecraftforge.fml.common.FMLCommonHandler; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; + +public final class GTDataFixers { + + public static final Logger LOGGER = LogManager.getLogger("GregTech DataFixers"); + private static final IDataWalker ITEM_STACK_WALKER = new WalkItemStackLike(); + + private GTDataFixers() {} + + public static void init() { + final CompoundDataFixer forgeFixer = FMLCommonHandler.instance().getDataFixer(); + registerWalkers(forgeFixer); + registerFixes(forgeFixer); + migrateMTERegistries(); + } + + private static void registerWalkers(@NotNull CompoundDataFixer fixer) { + fixer.registerVanillaWalker(FixTypes.BLOCK_ENTITY, ITEM_STACK_WALKER); + fixer.registerVanillaWalker(FixTypes.ENTITY, ITEM_STACK_WALKER); + fixer.registerVanillaWalker(FixTypes.PLAYER, ITEM_STACK_WALKER); + } + + private static void registerFixes(@NotNull CompoundDataFixer forgeFixer) { + LOGGER.info("GT data version is: {}", GTDataVersion.currentVersion()); + ModFixs fixer = forgeFixer.init(GTValues.MODID, GTDataVersion.currentVersion().ordinal()); + + for (GTDataVersion version : GTDataVersion.VALUES) { + registerFixes(version, fixer); + } + } + + private static void registerFixes(@NotNull GTDataVersion version, @NotNull ModFixs fixer) { + if (version != GTDataVersion.V0_PRE_MTE) { + LOGGER.info("Registering fixer for data version {}", version); + } + switch (version) { + case V1_POST_MTE -> { + MTERegistriesMigrator migrator = GregTechAPI.MIGRATIONS.registriesMigrator(); + fixer.registerFix(GTFixType.ITEM_STACK_LIKE, new MigrateMTEItems(migrator)); + fixer.registerFix(FixTypes.CHUNK, new MigrateMTEBlockTE(migrator)); + } + default -> {} + } + } + + /** + * Migrate all MTEs to the new blocks automatically + */ + private static void migrateMTERegistries() { + MTERegistriesMigrator migrator = GregTechAPI.MIGRATIONS.registriesMigrator(); + MTERegistry registry = GregTechAPI.mteManager.getRegistry(GTValues.MODID); + for (ResourceLocation key : registry.getKeys()) { + migrator.migrate(key.getNamespace(), (short) registry.getIdByObjectName(key)); + } + } +} diff --git a/src/main/java/gregtech/datafix/GTDataVersion.java b/src/main/java/gregtech/datafix/GTDataVersion.java new file mode 100644 index 00000000000..e077b5ed729 --- /dev/null +++ b/src/main/java/gregtech/datafix/GTDataVersion.java @@ -0,0 +1,27 @@ +package gregtech.datafix; + +import org.jetbrains.annotations.NotNull; + +/** + * Versions of GT data. + */ +public enum GTDataVersion { + + /** + * Version of data before multiple MTE registries were possible + */ + V0_PRE_MTE, + /** + * Version of data after multiple MTE registries were possible + */ + V1_POST_MTE; + + static final @NotNull GTDataVersion @NotNull [] VALUES = values(); + + /** + * @return the current version of GT data + */ + public static @NotNull GTDataVersion currentVersion() { + return VALUES[VALUES.length - 1]; + } +} diff --git a/src/main/java/gregtech/datafix/GTFixType.java b/src/main/java/gregtech/datafix/GTFixType.java new file mode 100644 index 00000000000..748c5602d1c --- /dev/null +++ b/src/main/java/gregtech/datafix/GTFixType.java @@ -0,0 +1,14 @@ +package gregtech.datafix; + +import net.minecraft.util.datafix.IFixType; + +public enum GTFixType implements IFixType { + /** + * Any NBTTagCompound that looks like an ItemStack. + *

+ * It must have the fields: {@code String id}, {@code int count}, {@code short Damage}. + * + * @see gregtech.datafix.walker.WalkItemStackLike + */ + ITEM_STACK_LIKE, +} diff --git a/src/main/java/gregtech/datafix/migration/api/AbstractMTEMigrator.java b/src/main/java/gregtech/datafix/migration/api/AbstractMTEMigrator.java new file mode 100644 index 00000000000..bd25912caf0 --- /dev/null +++ b/src/main/java/gregtech/datafix/migration/api/AbstractMTEMigrator.java @@ -0,0 +1,15 @@ +package gregtech.datafix.migration.api; + +public abstract class AbstractMTEMigrator implements MTEMigrator { + + private final int fixVersion; + + protected AbstractMTEMigrator(int fixVersion) { + this.fixVersion = fixVersion; + } + + @Override + public int fixVersion() { + return fixVersion; + } +} diff --git a/src/main/java/gregtech/datafix/migration/api/MTEMigrator.java b/src/main/java/gregtech/datafix/migration/api/MTEMigrator.java new file mode 100644 index 00000000000..e18ffb75064 --- /dev/null +++ b/src/main/java/gregtech/datafix/migration/api/MTEMigrator.java @@ -0,0 +1,43 @@ +package gregtech.datafix.migration.api; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface MTEMigrator { + + /** + * @return the fix version + */ + int fixVersion(); + + /** + * @param original the original MTE registry name + * @return the new MTE registry name + */ + @Nullable + ResourceLocation fixMTEid(@NotNull ResourceLocation original); + + /** + * @param original the original MTE registry name + * @param tag the MTE's "MetaTileEntity" tag to fix + */ + void fixMTEData(@NotNull ResourceLocation original, @NotNull NBTTagCompound tag); + + /** + * @param itemName the original name for the ItemBlock of the MTE + * @param meta the original metadata for the ItemBlock + * @return the new metadata, or the old meta if no migration is needed + */ + short fixItemMeta(@NotNull ResourceLocation itemName, short meta); + + /** + * @param original the original name for the ItemBlock of the MTE + * @param originalMeta the original metadata for the ItemBlock's ItemStack + * @return the new name for the ItemBlock, or null if no migration is needed + */ + @Nullable + ResourceLocation fixItemName(@NotNull ResourceLocation original, short originalMeta); +} diff --git a/src/main/java/gregtech/datafix/migration/impl/MigrateMTEBlockTE.java b/src/main/java/gregtech/datafix/migration/impl/MigrateMTEBlockTE.java new file mode 100644 index 00000000000..f5a2443168d --- /dev/null +++ b/src/main/java/gregtech/datafix/migration/impl/MigrateMTEBlockTE.java @@ -0,0 +1,153 @@ +package gregtech.datafix.migration.impl; + +import gregtech.api.GregTechAPI; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.registry.MTERegistry; +import gregtech.datafix.migration.api.MTEMigrator; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.datafix.IFixableData; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.chunk.NibbleArray; +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.registries.GameData; + +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; + +import static gregtech.datafix.util.DataFixConstants.*; + +public class MigrateMTEBlockTE implements IFixableData { + + private static final String META_ID = "MetaId"; + private static final String META_TILE_ENTITY = "MetaTileEntity"; + + private static final String X = "x"; + private static final String Y = "y"; + private static final String Z = "z"; + private static final String X_POS = "xPos"; + private static final String Z_POS = "zPos"; + private static final String CHUNK_SECTION_Y = "Y"; + private static final String CHUNK_SECTION_BLOCKS = "Blocks"; + private static final String CHUNK_SECTION_DATA = "Data"; + private static final String CHUNK_SECTION_ADD = "Add"; + + private static final int BLOCKS_PER_SECTION = 4096; + + private final MTEMigrator migrator; + + public MigrateMTEBlockTE(@NotNull MTEMigrator migrator) { + this.migrator = migrator; + } + + @Override + public int getFixVersion() { + return migrator.fixVersion(); + } + + @Override + public @NotNull NBTTagCompound fixTagCompound(@NotNull NBTTagCompound compound) { + if (!compound.hasKey(LEVEL_TAG, Constants.NBT.TAG_COMPOUND)) { + return compound; + } + + NBTTagCompound level = compound.getCompoundTag(LEVEL_TAG); + processChunkSections(level, gatherMTEs(level)); + return compound; + } + + /** + * @param level the level tag + * @return the MTEs in the level + */ + private @NotNull Map gatherMTEs(@NotNull NBTTagCompound level) { + Map mteIds = new Object2ObjectOpenHashMap<>(); + NBTTagList tileEntityTagList = level.getTagList(TILE_ENTITIES_TAG, Constants.NBT.TAG_COMPOUND); + for (int i = 0; i < tileEntityTagList.tagCount(); i++) { + NBTTagCompound tileEntityTag = tileEntityTagList.getCompoundTagAt(i); + if (tileEntityTag.hasKey(META_ID, Constants.NBT.TAG_STRING) && + tileEntityTag.hasKey(META_TILE_ENTITY, Constants.NBT.TAG_COMPOUND)) { + BlockPos pos = new BlockPos(tileEntityTag.getInteger(X), tileEntityTag.getInteger(Y), + tileEntityTag.getInteger(Z)); + ResourceLocation mteId = new ResourceLocation(tileEntityTag.getString(META_ID)); + migrator.fixMTEData(mteId, tileEntityTag.getCompoundTag(META_TILE_ENTITY)); + + ResourceLocation fixedId = migrator.fixMTEid(mteId); + if (fixedId != null) { + tileEntityTag.setString(META_ID, fixedId.toString()); + mteId = fixedId; + } + mteIds.put(pos, mteId); + } + } + return mteIds; + } + + /** + * Processes the chunk sections to remap blocks. + * + * @param level the level tag + * @param mteIds the MTEs present in the chunk section + */ + private static void processChunkSections(@NotNull NBTTagCompound level, + @NotNull Map mteIds) { + if (mteIds.isEmpty()) { + return; + } + + var blockStateIDMap = GameData.getBlockStateIDMap(); + ChunkPos chunkPos = new ChunkPos(level.getInteger(X_POS), level.getInteger(Z_POS)); + NBTTagList sectionTagList = level.getTagList(SECTIONS, Constants.NBT.TAG_COMPOUND); + for (int i = 0; i < sectionTagList.tagCount(); i++) { + NBTTagCompound chunkSectionTag = sectionTagList.getCompoundTagAt(i); + + int sectionY = chunkSectionTag.getByte(CHUNK_SECTION_Y); + byte[] blockIDs = chunkSectionTag.getByteArray(CHUNK_SECTION_BLOCKS); + NibbleArray blockData = new NibbleArray(chunkSectionTag.getByteArray(CHUNK_SECTION_DATA)); + NibbleArray extendedIDs = chunkSectionTag.hasKey(CHUNK_SECTION_ADD, Constants.NBT.TAG_BYTE_ARRAY) ? + new NibbleArray(chunkSectionTag.getByteArray(CHUNK_SECTION_ADD)) : null; + for (int j = 0; j < BLOCKS_PER_SECTION; j++) { + int x = j & 0x0F; + int y = j >> 8 & 0x0F; + int z = j >> 4 & 0x0F; + + BlockPos pos = chunkPos.getBlock(x, sectionY << 4 | y, z); + ResourceLocation mteID = mteIds.get(pos); + if (mteID == null) { + continue; + } + + MTERegistry registry = GregTechAPI.mteManager.getRegistry(mteID.getNamespace()); + MetaTileEntity mte = registry.getObject(mteID); + if (mte == null) { + continue; + } + + int newStateID = blockStateIDMap.get(mte.getBlock().getDefaultState()); + byte newBlockID = (byte) (newStateID >> 4 & 0xFF); + byte newBlockIDExt = (byte) (newStateID >> 12 & 0x0F); + byte newBlockData = (byte) (newStateID & 0x0F); + + blockIDs[j] = newBlockID; + if (newBlockIDExt != 0) { + if (extendedIDs == null) { + extendedIDs = new NibbleArray(); + } + extendedIDs.set(x, y, z, newBlockIDExt); + } + blockData.set(x, y, z, newBlockData); + } + + chunkSectionTag.setByteArray(CHUNK_SECTION_BLOCKS, blockIDs); + chunkSectionTag.setByteArray(CHUNK_SECTION_DATA, blockData.getData()); + if (extendedIDs != null) { + chunkSectionTag.setByteArray(CHUNK_SECTION_ADD, extendedIDs.getData()); + } + } + } +} diff --git a/src/main/java/gregtech/datafix/migration/impl/MigrateMTEItems.java b/src/main/java/gregtech/datafix/migration/impl/MigrateMTEItems.java new file mode 100644 index 00000000000..239947f6c01 --- /dev/null +++ b/src/main/java/gregtech/datafix/migration/impl/MigrateMTEItems.java @@ -0,0 +1,50 @@ +package gregtech.datafix.migration.impl; + +import gregtech.datafix.migration.api.MTEMigrator; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.datafix.IFixableData; + +import org.jetbrains.annotations.NotNull; + +import static gregtech.datafix.util.DataFixConstants.*; + +public class MigrateMTEItems implements IFixableData { + + private final MTEMigrator migrator; + + public MigrateMTEItems(@NotNull MTEMigrator migrator) { + this.migrator = migrator; + } + + @Override + public int getFixVersion() { + return migrator.fixVersion(); + } + + @Override + public @NotNull NBTTagCompound fixTagCompound(@NotNull NBTTagCompound compound) { + final String id = compound.getString(ITEM_ID); + if (id.isEmpty()) { + return compound; + } + + // must check hasKey() since non-items can have ITEM_ID but not have ITEM_DAMAGE and ITEM_COUNT + if (compound.hasKey(ITEM_DAMAGE) && compound.hasKey(ITEM_COUNT)) { + ResourceLocation itemBlockId = new ResourceLocation(id); + final short meta = compound.getShort(ITEM_DAMAGE); + ResourceLocation fixedName = migrator.fixItemName(itemBlockId, meta); + if (fixedName != null) { + compound.setString(ITEM_ID, fixedName.toString()); + } + + short fixedMeta = migrator.fixItemMeta(itemBlockId, meta); + if (fixedMeta != meta) { + compound.setShort(ITEM_DAMAGE, fixedMeta); + } + } + + return compound; + } +} diff --git a/src/main/java/gregtech/datafix/migration/lib/MTEDataMigrator.java b/src/main/java/gregtech/datafix/migration/lib/MTEDataMigrator.java new file mode 100644 index 00000000000..3fbdf740a31 --- /dev/null +++ b/src/main/java/gregtech/datafix/migration/lib/MTEDataMigrator.java @@ -0,0 +1,135 @@ +package gregtech.datafix.migration.lib; + +import gregtech.api.GregTechAPI; +import gregtech.datafix.GTFixType; +import gregtech.datafix.migration.api.AbstractMTEMigrator; +import gregtech.datafix.migration.impl.MigrateMTEBlockTE; +import gregtech.datafix.migration.impl.MigrateMTEItems; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.datafix.FixTypes; +import net.minecraftforge.common.util.ModFixs; + +import it.unimi.dsi.fastutil.objects.Object2ObjectMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.shorts.Short2ShortMap; +import it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; +import java.util.function.Consumer; + +/** + * Performs arbitrary data migration for MTEs. + *

+ * Has the following capabilities: + *

    + *
  • Migrating MTE registry names to new mod ids and name values
  • + *
  • Migrating MTE metadata to new values
  • + *
  • Migrating MTE NBT tags to new arbitrary tags
  • + *
+ *

+ * Usage: + *

    + *
  1. Use a data versioning scheme like {@link gregtech.datafix.GTDataVersion}
  2. + *
  3. In FMLPreInit, get the FML data fixer with + * {@link net.minecraftforge.fml.common.FMLCommonHandler#getDataFixer()}
  4. + *
  5. Call {@link net.minecraftforge.common.util.CompoundDataFixer#init(String, int)} to create a data fixer for your + * mod
  6. + *
  7. Create a new migrator with {@link #MTEDataMigrator(ModFixs, int)}
  8. + *
  9. Once a migrator has been applied to a world, future migrations need to be done in a new migrator instance
  10. + *
+ */ +public final class MTEDataMigrator extends AbstractMTEMigrator { + + private final Object2ObjectMap nameMap = new Object2ObjectOpenHashMap<>(); + private final Map itemBlockMeta = new Object2ObjectOpenHashMap<>(); + private final Map> mteMigrators = new Object2ObjectOpenHashMap<>(); + + /** + * This data migrator will first attempt to migrate the registries over in case forge runs this before GT does the + * dedicated migration. + *

+ * DataFixer application order is non-deterministic across different mod ids, so we have to ensure other mods only + * need to interact with the post mte registry migration metadata + */ + private final MTERegistriesMigrator registriesMigrator = GregTechAPI.MIGRATIONS.registriesMigrator(); + + /** + * @param fixer the fixer owning the migration + * @param fixVersion the version this migration will bring the mod data to + */ + public MTEDataMigrator(@NotNull ModFixs fixer, int fixVersion) { + super(fixVersion); + fixer.registerFix(GTFixType.ITEM_STACK_LIKE, new MigrateMTEItems(this)); + fixer.registerFix(FixTypes.CHUNK, new MigrateMTEBlockTE(this)); + } + + /** + * Migrate an MTE's registry name to something else + * + * @param preRegistryName the original registry name + * @param postRegistryName the new registry name + */ + public void migrateMTEName(@NotNull ResourceLocation preRegistryName, @NotNull ResourceLocation postRegistryName) { + nameMap.put(preRegistryName, postRegistryName); + } + + /** + * Migrate an MTE's data to something else + * + * @param preRegistryName the original registry name + * @param migrator a data migrator operating on the MTE's NBT tag compound + */ + public void migrateMTEData(@NotNull ResourceLocation preRegistryName, + @NotNull Consumer<@NotNull NBTTagCompound> migrator) { + mteMigrators.put(preRegistryName, migrator); + } + + /** + * @param modid the modid for the MTE's ItemBlock + * @param preMeta the original metadata for the MTE's ItemBlock + * @param postMeta the new metadata for the MTE's ItemBlock + */ + public void migrateMTEMeta(@NotNull String modid, int preMeta, int postMeta) { + itemBlockMeta.computeIfAbsent(modid, k -> { + var map = new Short2ShortOpenHashMap(); + map.defaultReturnValue((short) -1); + map.put((short) preMeta, (short) postMeta); + return map; + }); + } + + @Override + public @Nullable ResourceLocation fixMTEid(@NotNull ResourceLocation original) { + return nameMap.get(original); + } + + @Override + public void fixMTEData(@NotNull ResourceLocation original, @NotNull NBTTagCompound tag) { + var migrator = mteMigrators.get(original); + if (migrator != null) { + migrator.accept(tag); + } + } + + @Override + public short fixItemMeta(@NotNull ResourceLocation itemName, short meta) { + meta = registriesMigrator.fixItemMeta(itemName, meta); + Short2ShortMap map = itemBlockMeta.get(itemName.getNamespace()); + if (map != null) { + short newMeta = map.get(meta); + if (newMeta > 0) { + return newMeta; + } + } + return meta; + } + + @Override + public @Nullable ResourceLocation fixItemName(@NotNull ResourceLocation original, short originalMeta) { + return registriesMigrator.fixItemName(original, originalMeta); + } +} diff --git a/src/main/java/gregtech/datafix/migration/lib/MTERegistriesMigrator.java b/src/main/java/gregtech/datafix/migration/lib/MTERegistriesMigrator.java new file mode 100644 index 00000000000..159fd1450fa --- /dev/null +++ b/src/main/java/gregtech/datafix/migration/lib/MTERegistriesMigrator.java @@ -0,0 +1,86 @@ +package gregtech.datafix.migration.lib; + +import gregtech.api.util.GTUtility; +import gregtech.datafix.GTDataVersion; +import gregtech.datafix.migration.api.AbstractMTEMigrator; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; + +import it.unimi.dsi.fastutil.shorts.Short2ObjectMap; +import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.shorts.Short2ShortMap; +import it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Performs migration to an independent MTE registry. + *

+ * This only performs migration to a new registry. + * Use {@link MTEDataMigrator} for a generic migration. + */ +public final class MTERegistriesMigrator extends AbstractMTEMigrator { + + private static final ResourceLocation OLD_BLOCK_ID = GTUtility.gregtechId("machine"); + private static final String NEW_BLOCK_NAME = "mte"; + + private final Short2ObjectMap metaModidMap = new Short2ObjectOpenHashMap<>(); + private final Short2ShortMap metaMetaMap = new Short2ShortOpenHashMap(); + + @ApiStatus.Internal + public MTERegistriesMigrator() { + super(GTDataVersion.V1_POST_MTE.ordinal()); + metaMetaMap.defaultReturnValue((short) -1); + } + + /** + * Register a data fix entry for the multiple MTE registry transition with an additional metadata transition. + *

+ * The general migration is automatically performed. + * + * @param preMeta the original MTE metadata value + * @param postMeta the new MTE metadata value + */ + public void migrate(int preMeta, int postMeta) { + metaMetaMap.put((short) preMeta, (short) postMeta); + } + + /** + * Register a data fix entry for the multiple MTE registry transition. + * + * @param modid the registry's modid + * @param meta the metadata value to migrate + */ + @ApiStatus.Internal + public void migrate(@NotNull String modid, short meta) { + metaModidMap.put(meta, modid); + } + + @Override + public @Nullable ResourceLocation fixMTEid(@NotNull ResourceLocation original) { + return null; + } + + @Override + public void fixMTEData(@NotNull ResourceLocation original, @NotNull NBTTagCompound tag) {} + + @Override + public @Nullable ResourceLocation fixItemName(@NotNull ResourceLocation original, short originalMeta) { + if (OLD_BLOCK_ID.equals(original)) { + String modid = metaModidMap.get(originalMeta); + if (modid == null) { + return null; + } + return new ResourceLocation(modid, NEW_BLOCK_NAME); + } + return null; + } + + @Override + public short fixItemMeta(@NotNull ResourceLocation itemName, short meta) { + short fixed = metaMetaMap.get(meta); + return fixed < 0 ? meta : fixed; + } +} diff --git a/src/main/java/gregtech/datafix/migration/lib/MigrationAPI.java b/src/main/java/gregtech/datafix/migration/lib/MigrationAPI.java new file mode 100644 index 00000000000..227840f084b --- /dev/null +++ b/src/main/java/gregtech/datafix/migration/lib/MigrationAPI.java @@ -0,0 +1,15 @@ +package gregtech.datafix.migration.lib; + +import org.jetbrains.annotations.NotNull; + +public final class MigrationAPI { + + private final MTERegistriesMigrator registriesMigrator = new MTERegistriesMigrator(); + + /** + * @return the data migrator for the Multiple MTE Registries functionality + */ + public @NotNull MTERegistriesMigrator registriesMigrator() { + return registriesMigrator; + } +} diff --git a/src/main/java/gregtech/datafix/util/DataFixConstants.java b/src/main/java/gregtech/datafix/util/DataFixConstants.java new file mode 100644 index 00000000000..83f374add07 --- /dev/null +++ b/src/main/java/gregtech/datafix/util/DataFixConstants.java @@ -0,0 +1,14 @@ +package gregtech.datafix.util; + +public final class DataFixConstants { + + public static final String LEVEL_TAG = "Level"; + public static final String TILE_ENTITIES_TAG = "TileEntities"; + public static final String SECTIONS = "Sections"; + + public static final String ITEM_ID = "id"; + public static final String ITEM_COUNT = "Count"; + public static final String ITEM_DAMAGE = "Damage"; + + private DataFixConstants() {} +} diff --git a/src/main/java/gregtech/datafix/util/DataFixHelper.java b/src/main/java/gregtech/datafix/util/DataFixHelper.java new file mode 100644 index 00000000000..75636ca1474 --- /dev/null +++ b/src/main/java/gregtech/datafix/util/DataFixHelper.java @@ -0,0 +1,63 @@ +package gregtech.datafix.util; + +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraftforge.common.util.Constants; + +import org.jetbrains.annotations.NotNull; + +import java.util.function.UnaryOperator; + +public final class DataFixHelper { + + private DataFixHelper() {} + + /** + * Recursively rewrites NBTTagCompounds + * + * @param tag the tag to rewrite + * @param rewriter the tag rewriter + */ + public static void rewriteCompoundTags(@NotNull NBTTagCompound tag, + @NotNull UnaryOperator rewriter) { + for (String key : tag.getKeySet()) { + NBTBase child = tag.getTag(key); + + final byte id = child.getId(); + if (id == Constants.NBT.TAG_LIST) { + rewriteCompoundTags((NBTTagList) child, rewriter); + } else if (id == Constants.NBT.TAG_COMPOUND) { + NBTTagCompound childCompound = (NBTTagCompound) child; + rewriteCompoundTags(childCompound, rewriter); + childCompound = rewriter.apply(childCompound); + if (childCompound != null) { + tag.setTag(key, childCompound); + } + } + } + } + + /** + * @param tagList recursively rewrites NBTTagCompounds in an NBTTagList + * @param rewriter the tag rewriter + */ + public static void rewriteCompoundTags(@NotNull NBTTagList tagList, + @NotNull UnaryOperator rewriter) { + for (int i = 0; i < tagList.tagCount(); i++) { + NBTBase child = tagList.get(i); + + final byte id = child.getId(); + if (id == Constants.NBT.TAG_LIST) { + rewriteCompoundTags((NBTTagList) child, rewriter); + } else if (id == Constants.NBT.TAG_COMPOUND) { + NBTTagCompound childCompound = (NBTTagCompound) child; + rewriteCompoundTags(childCompound, rewriter); + childCompound = rewriter.apply(childCompound); + if (childCompound != null) { + tagList.set(i, childCompound); + } + } + } + } +} diff --git a/src/main/java/gregtech/datafix/walker/WalkItemStackLike.java b/src/main/java/gregtech/datafix/walker/WalkItemStackLike.java new file mode 100644 index 00000000000..f22c7f751dc --- /dev/null +++ b/src/main/java/gregtech/datafix/walker/WalkItemStackLike.java @@ -0,0 +1,28 @@ +package gregtech.datafix.walker; + +import gregtech.datafix.GTFixType; +import gregtech.datafix.util.DataFixHelper; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.datafix.IDataFixer; +import net.minecraft.util.datafix.IDataWalker; +import net.minecraftforge.common.util.Constants; + +import org.jetbrains.annotations.NotNull; + +import static gregtech.datafix.util.DataFixConstants.*; + +public final class WalkItemStackLike implements IDataWalker { + + @Override + public @NotNull NBTTagCompound process(@NotNull IDataFixer fixer, @NotNull NBTTagCompound compound, int versionIn) { + DataFixHelper.rewriteCompoundTags(compound, tag -> { + if (tag.hasKey(ITEM_ID, Constants.NBT.TAG_STRING) && tag.hasKey(ITEM_COUNT, Constants.NBT.TAG_INT) && + tag.hasKey(ITEM_DAMAGE, Constants.NBT.TAG_SHORT)) { + return fixer.process(GTFixType.ITEM_STACK_LIKE, tag, versionIn); + } + return null; + }); + return compound; + } +} diff --git a/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java b/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java index aeef7c2ac07..c0ae3b20efa 100644 --- a/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java +++ b/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java @@ -60,7 +60,7 @@ public static String getIconSet(Material m) { @ZenGetter public static boolean isGaseous(Material m) { FluidProperty prop = m.getProperty(PropertyKey.FLUID); - return prop != null && prop.getStorage().get(FluidStorageKeys.GAS) != null; + return prop != null && prop.get(FluidStorageKeys.GAS) != null; } // TODO May need to move this to Material diff --git a/src/main/java/gregtech/integration/crafttweaker/material/MaterialPropertyExpansion.java b/src/main/java/gregtech/integration/crafttweaker/material/MaterialPropertyExpansion.java index bf4624282cb..244d99174e1 100644 --- a/src/main/java/gregtech/integration/crafttweaker/material/MaterialPropertyExpansion.java +++ b/src/main/java/gregtech/integration/crafttweaker/material/MaterialPropertyExpansion.java @@ -3,7 +3,6 @@ import gregtech.api.fluids.FluidBuilder; import gregtech.api.fluids.FluidState; import gregtech.api.fluids.attribute.FluidAttributes; -import gregtech.api.fluids.store.FluidStorage; import gregtech.api.fluids.store.FluidStorageKeys; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.properties.*; @@ -147,7 +146,7 @@ public static void addFluid(Material m) { if (checkFrozen("add a Fluid to a material")) return; if (!m.hasProperty(PropertyKey.FLUID)) { FluidProperty property = new FluidProperty(); - property.getStorage().enqueueRegistration(FluidStorageKeys.LIQUID, new FluidBuilder()); + property.enqueueRegistration(FluidStorageKeys.LIQUID, new FluidBuilder()); m.setProperty(PropertyKey.FLUID, property); } } @@ -162,18 +161,17 @@ public static void addFluid(Material m, @Optional String fluidTypeName, @Optiona m.setProperty(PropertyKey.FLUID, property); } - FluidStorage storage = property.getStorage(); FluidBuilder builder = switch (type) { - case LIQUID -> storage.getQueuedBuilder(FluidStorageKeys.LIQUID); - case GAS -> storage.getQueuedBuilder(FluidStorageKeys.GAS); - case PLASMA -> storage.getQueuedBuilder(FluidStorageKeys.PLASMA); + case LIQUID -> property.getQueuedBuilder(FluidStorageKeys.LIQUID); + case GAS -> property.getQueuedBuilder(FluidStorageKeys.GAS); + case PLASMA -> property.getQueuedBuilder(FluidStorageKeys.PLASMA); }; if (builder == null) { builder = new FluidBuilder(); switch (type) { - case LIQUID -> storage.enqueueRegistration(FluidStorageKeys.LIQUID, builder); - case GAS -> storage.enqueueRegistration(FluidStorageKeys.GAS, builder.state(FluidState.GAS)); - case PLASMA -> storage.enqueueRegistration(FluidStorageKeys.PLASMA, builder.state(FluidState.PLASMA)); + case LIQUID -> property.enqueueRegistration(FluidStorageKeys.LIQUID, builder); + case GAS -> property.enqueueRegistration(FluidStorageKeys.GAS, builder.state(FluidState.GAS)); + case PLASMA -> property.enqueueRegistration(FluidStorageKeys.PLASMA, builder.state(FluidState.PLASMA)); } } if (hasBlock) builder.block(); @@ -218,7 +216,7 @@ public static void addPlasma(Material m) { if (checkFrozen("add a Plasma to a material")) return; if (!m.hasProperty(PropertyKey.FLUID)) { FluidProperty property = new FluidProperty(); - property.getStorage().enqueueRegistration(FluidStorageKeys.PLASMA, + property.enqueueRegistration(FluidStorageKeys.PLASMA, new FluidBuilder().state(FluidState.PLASMA)); m.setProperty(PropertyKey.FLUID, property); } diff --git a/src/main/java/gregtech/integration/crafttweaker/recipe/MetaTileEntityBracketHandler.java b/src/main/java/gregtech/integration/crafttweaker/recipe/MetaTileEntityBracketHandler.java index b516bfe282f..8be5fd8e44a 100644 --- a/src/main/java/gregtech/integration/crafttweaker/recipe/MetaTileEntityBracketHandler.java +++ b/src/main/java/gregtech/integration/crafttweaker/recipe/MetaTileEntityBracketHandler.java @@ -3,6 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.registry.MTERegistry; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; @@ -39,7 +40,8 @@ public MetaTileEntityBracketHandler() { @Nullable public static ItemStack getMetaTileEntityItem(String[] split) { - MetaTileEntity metaTileEntity = GregTechAPI.MTE_REGISTRY.getObject(new ResourceLocation(split[0], split[1])); + MTERegistry registry = GregTechAPI.mteManager.getRegistry(split[0]); + MetaTileEntity metaTileEntity = registry.getObject(new ResourceLocation(split[0], split[1])); return metaTileEntity == null ? null : metaTileEntity.getStackForm(); } diff --git a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java index 610c93e3d5f..82019c6c8c8 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java @@ -4,12 +4,12 @@ import gregtech.api.unification.OreDictUnifier; 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.forestry.ForestryModule; import gregtech.integration.forestry.ForestryUtil; +import gregtech.integration.forestry.mutation.MaterialMutationCondition; import net.minecraft.init.Blocks; import net.minecraft.init.Items; @@ -46,6 +46,7 @@ import java.util.function.Supplier; import static forestry.api.apiculture.EnumBeeChromosome.*; +import static gregtech.api.unification.material.Materials.*; public enum GTBeeDefinition implements IBeeDefinition { @@ -153,7 +154,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(BeeDefinition.INDUSTRIOUS, PEAT, 9); - mutation.requireResource("blockCoal"); + mutation.addMutationCondition(new MaterialMutationCondition(Coal)); }), OIL(GTBranchDefinition.GT_ORGANIC, "Oleum", true, 0x4C4C4C, 0x333333, beeSpecies -> { @@ -221,7 +222,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(ASH, COAL, 10); - mutation.requireResource("blockApatite"); + mutation.addMutationCondition(new MaterialMutationCondition(Apatite)); }), BIOMASS(GTBranchDefinition.GT_ORGANIC, "Taeda", true, 0x21E118, 0x17AF0E, beeSpecies -> { @@ -272,7 +273,7 @@ public enum GTBeeDefinition implements IBeeDefinition { dis -> { IBeeMutationBuilder mutation = dis.registerMutation(APATITE, ASH, 12); mutation.restrictTemperature(EnumTemperature.HOT); - mutation.requireResource("blockTricalciumPhosphate"); + mutation.addMutationCondition(new MaterialMutationCondition(TricalciumPhosphate)); }), SANDWICH(GTBranchDefinition.GT_ORGANIC, "Sandwico", true, 0x32CD32, 0xDAA520, beeSpecies -> { @@ -316,7 +317,7 @@ public enum GTBeeDefinition implements IBeeDefinition { dis -> { IBeeMutationBuilder mutation = dis.registerMutation(BeeDefinition.INDUSTRIOUS, BeeDefinition.DEMONIC, 10); - mutation.requireResource("blockRedstone"); + mutation.addMutationCondition(new MaterialMutationCondition(Redstone)); }), LAPIS(GTBranchDefinition.GT_GEM, "Lapidi", true, 0x1947D1, 0x476CDA, beeSpecies -> { @@ -328,7 +329,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(BeeDefinition.DEMONIC, BeeDefinition.IMPERIAL, 10); - mutation.requireResource("blockLapis"); + mutation.addMutationCondition(new MaterialMutationCondition(Lapis)); }), CERTUS(GTBranchDefinition.GT_GEM, "Quarzeus", true, 0x57CFFB, 0xBBEEFF, beeSpecies -> { @@ -340,7 +341,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(BeeDefinition.HERMITIC, LAPIS, 10); - mutation.requireResource("blockCertusQuartz"); + mutation.addMutationCondition(new MaterialMutationCondition(CertusQuartz)); }), FLUIX(GTBranchDefinition.GT_GEM, "", true, 0xA375FF, 0xB591FF, beeSpecies -> { @@ -367,7 +368,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(CERTUS, COAL, 3); - mutation.requireResource("blockDiamond"); + mutation.addMutationCondition(new MaterialMutationCondition(Diamond)); }), RUBY(GTBranchDefinition.GT_GEM, "Rubinus", false, 0xE6005C, 0xCC0052, beeSpecies -> { @@ -380,7 +381,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(REDSTONE, DIAMOND, 5); - mutation.requireResource("blockRuby"); + mutation.addMutationCondition(new MaterialMutationCondition(Ruby)); }), SAPPHIRE(GTBranchDefinition.GT_GEM, "Sapphirus", true, 0x0033CC, 0x00248F, beeSpecies -> { @@ -392,7 +393,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(CERTUS, LAPIS, 5); - mutation.requireResource("blockSapphire"); + mutation.addMutationCondition(new MaterialMutationCondition(Sapphire)); }), OLIVINE(GTBranchDefinition.GT_GEM, "Olivinum", true, 0x248F24, 0xCCFFCC, beeSpecies -> { @@ -416,7 +417,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(OLIVINE, DIAMOND, 4); - mutation.requireResource("blockEmerald"); + mutation.addMutationCondition(new MaterialMutationCondition(Emerald)); }), SPARKLING(GTBranchDefinition.GT_GEM, "Vesperstella", true, 0x7A007A, 0xFFFFFF, beeSpecies -> { @@ -438,7 +439,7 @@ public enum GTBeeDefinition implements IBeeDefinition { IBeeMutationBuilder mutation = dis.registerMutation( ForestryUtil.getSpecies(Mods.MagicBees, "Withering"), ForestryUtil.getSpecies(Mods.MagicBees, "Draconic"), 1); - mutation.requireResource("blockNetherStar"); + mutation.addMutationCondition(new MaterialMutationCondition(NetherStar)); mutation.restrictBiomeType(BiomeDictionary.Type.END); }, Mods.MagicBees::isModLoaded), @@ -455,7 +456,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(BeeDefinition.MAJESTIC, CLAY, 13); - mutation.requireResource("blockCopper"); + mutation.addMutationCondition(new MaterialMutationCondition(Copper)); }), TIN(GTBranchDefinition.GT_METAL, "Stannum", true, 0xD4D4D4, 0xDDDDDD, beeSpecies -> { @@ -468,7 +469,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(CLAY, BeeDefinition.DILIGENT, 13); - mutation.requireResource("blockTin"); + mutation.addMutationCondition(new MaterialMutationCondition(Tin)); }), LEAD(GTBranchDefinition.GT_METAL, "Plumbum", true, 0x666699, 0xA3A3CC, beeSpecies -> { @@ -481,7 +482,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(COAL, COPPER, 13); - mutation.requireResource("blockLead"); + mutation.addMutationCondition(new MaterialMutationCondition(Lead)); }), IRON(GTBranchDefinition.GT_METAL, "Ferrum", true, 0xDA9147, 0xDE9C59, beeSpecies -> { @@ -494,7 +495,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(TIN, COPPER, 13); - mutation.requireResource("blockIron"); + mutation.addMutationCondition(new MaterialMutationCondition(Iron)); }), STEEL(GTBranchDefinition.GT_METAL, "Chalybe", true, 0x808080, 0x999999, beeSpecies -> { @@ -507,7 +508,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(IRON, COAL, 10); - mutation.requireResource("blockSteel"); + mutation.addMutationCondition(new MaterialMutationCondition(Steel)); mutation.restrictTemperature(EnumTemperature.HOT); }), NICKEL(GTBranchDefinition.GT_METAL, "Nichelium", true, 0x8585AD, 0x8585AD, @@ -521,7 +522,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(IRON, COPPER, 13); - mutation.requireResource("blockNickel"); + mutation.addMutationCondition(new MaterialMutationCondition(Nickel)); }), ZINC(GTBranchDefinition.GT_METAL, "Cadmiae", true, 0xF0DEF0, 0xF2E1F2, beeSpecies -> { @@ -534,7 +535,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(IRON, TIN, 13); - mutation.requireResource("blockZinc"); + mutation.addMutationCondition(new MaterialMutationCondition(Zinc)); }), SILVER(GTBranchDefinition.GT_METAL, "Argenti", true, 0xC2C2D6, 0xCECEDE, beeSpecies -> { @@ -547,7 +548,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(LEAD, TIN, 10); - mutation.requireResource("blockSilver"); + mutation.addMutationCondition(new MaterialMutationCondition(Silver)); }), GOLD(GTBranchDefinition.GT_METAL, "Aurum", true, 0xEBC633, 0xEDCC47, beeSpecies -> { @@ -560,7 +561,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(LEAD, COPPER, 13); - mutation.requireResource("blockGold"); + mutation.addMutationCondition(new MaterialMutationCondition(Gold)); mutation.restrictTemperature(EnumTemperature.HOT); }), ARSENIC(GTBranchDefinition.GT_METAL, "Arsenicum", true, 0x736C52, 0x292412, @@ -573,7 +574,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(ZINC, SILVER, 10); - mutation.requireResource("blockArsenic"); + mutation.addMutationCondition(new MaterialMutationCondition(Arsenic)); }), SILICON(GTBranchDefinition.GT_ORGANIC, "Silex", false, 0xADA2A7, 0x736675, beeSpecies -> { @@ -606,7 +607,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(NICKEL, ZINC, 9); - mutation.requireResource("blockAluminium"); + mutation.addMutationCondition(new MaterialMutationCondition(Aluminium)); }), TITANIUM(GTBranchDefinition.GT_RAREMETAL, "Titanus", true, 0xCC99FF, 0xDBB8FF, beeSpecies -> { @@ -619,7 +620,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(REDSTONE, ALUMINIUM, 5); - mutation.requireResource("blockTitanium"); + mutation.addMutationCondition(new MaterialMutationCondition(Titanium)); }), // todo glowstone? CHROME(GTBranchDefinition.GT_RAREMETAL, "Chroma", true, 0xEBA1EB, 0xF2C3F2, @@ -633,7 +634,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(TITANIUM, RUBY, 5); - mutation.requireResource("blockChrome"); + mutation.addMutationCondition(new MaterialMutationCondition(Chrome)); }), MANGANESE(GTBranchDefinition.GT_RAREMETAL, "Manganum", true, 0xD5D5D5, 0xAAAAAA, beeSpecies -> { @@ -646,7 +647,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(TITANIUM, ALUMINIUM, 5); - mutation.requireResource("blockManganese"); + mutation.addMutationCondition(new MaterialMutationCondition(Manganese)); }), TUNGSTEN(GTBranchDefinition.GT_RAREMETAL, "Wolframium", false, 0x5C5C8A, 0x7D7DA1, beeSpecies -> { @@ -659,7 +660,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(BeeDefinition.HEROIC, MANGANESE, 5); - mutation.requireResource("blockTungsten"); + mutation.addMutationCondition(new MaterialMutationCondition(Tungsten)); }), PLATINUM(GTBranchDefinition.GT_RAREMETAL, "Platina", false, 0xE6E6E6, 0xFFFFCC, beeSpecies -> { @@ -672,7 +673,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(DIAMOND, CHROME, 5); - mutation.requireResource("blockPlatinum"); + mutation.addMutationCondition(new MaterialMutationCondition(Platinum)); }), IRIDIUM(GTBranchDefinition.GT_RAREMETAL, "Iris", false, 0xDADADA, 0xD1D1E0, beeSpecies -> { @@ -686,7 +687,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(TUNGSTEN, PLATINUM, 5); - mutation.requireResource("blockIridium"); + mutation.addMutationCondition(new MaterialMutationCondition(Iridium)); }), OSMIUM(GTBranchDefinition.GT_RAREMETAL, "Osmia", false, 0x2B2BDA, 0x8B8B8B, beeSpecies -> { @@ -700,7 +701,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(TUNGSTEN, PLATINUM, 5); - mutation.requireResource("blockOsmium"); + mutation.addMutationCondition(new MaterialMutationCondition(Osmium)); }), SALTY(GTBranchDefinition.GT_RAREMETAL, "Sal", true, 0xF0C8C8, 0xFAFAFA, beeSpecies -> { @@ -713,7 +714,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(CLAY, ALUMINIUM, 5); - mutation.requireResource("blockSalt"); + mutation.addMutationCondition(new MaterialMutationCondition(Salt)); }), LITHIUM(GTBranchDefinition.GT_RAREMETAL, "Lithos", false, 0xF0328C, 0xE1DCFF, beeSpecies -> { @@ -726,7 +727,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(SALTY, ALUMINIUM, 5); - mutation.requireResource("blockLithium"); + mutation.addMutationCondition(new MaterialMutationCondition(Lithium)); }), ELECTROTINE(GTBranchDefinition.GT_RAREMETAL, "Electrum", false, 0x1E90FF, 0x3CB4C8, beeSpecies -> { @@ -739,7 +740,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(REDSTONE, GOLD, 5); - mutation.requireResource("blockElectrotine"); + mutation.addMutationCondition(new MaterialMutationCondition(Electrotine)); }), SULFUR(GTBranchDefinition.GT_RAREMETAL, "Sulphur", false, 0x1E90FF, 0x3CB4C8, beeSpecies -> { @@ -759,7 +760,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWEST), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(LEAD, OSMIUM, 1); - mutation.requireResource("blockIndium"); + mutation.addMutationCondition(new MaterialMutationCondition(Indium)); mutation.restrictBiomeType(BiomeDictionary.Type.END); }), @@ -793,7 +794,7 @@ public enum GTBeeDefinition implements IBeeDefinition { } else { mutation = dis.registerMutation(BeeDefinition.DEMONIC, BeeDefinition.FIENDISH, 10); } - mutation.requireResource("blockRedstone"); + mutation.addMutationCondition(new MaterialMutationCondition(Redstone)); }), LAPOTRON(GTBranchDefinition.GT_INDUSTRIAL, "Azureus", false, 0xFFEBC4, 0xE36400, beeSpecies -> { @@ -815,7 +816,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(LAPIS, ENERGY, 6); - mutation.requireResource("blockLapis"); + mutation.addMutationCondition(new MaterialMutationCondition(Lapis)); mutation.restrictTemperature(EnumTemperature.ICY); }), EXPLOSIVE(GTBranchDefinition.GT_INDUSTRIAL, "Explosionis", false, 0x7E270F, 0x747474, @@ -853,7 +854,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(COPPER, REDSTONE, 10); - mutation.requireResource("blockRedAlloy"); + mutation.addMutationCondition(new MaterialMutationCondition(RedAlloy)); }), STAINLESSSTEEL(GTBranchDefinition.GT_ALLOY, "Nonferrugo", false, 0xC8C8DC, 0x778899, beeSpecies -> { @@ -871,7 +872,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(CHROME, STEEL, 9); - mutation.requireResource("blockStainlessSteel"); + mutation.addMutationCondition(new MaterialMutationCondition(StainlessSteel)); }), // Radioactive @@ -889,7 +890,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(BeeDefinition.AVENGING, PLATINUM, 2); - mutation.requireResource("blockUranium"); + mutation.addMutationCondition(new MaterialMutationCondition(Uranium238)); }), PLUTONIUM(GTBranchDefinition.GT_RADIOACTIVE, "Plutos", true, 0x570000, 0x240000, beeSpecies -> { @@ -906,7 +907,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(URANIUM, EMERALD, 2); - mutation.requireResource("blockPlutonium"); + mutation.addMutationCondition(new MaterialMutationCondition(Plutonium239)); }), NAQUADAH(GTBranchDefinition.GT_RADIOACTIVE, "Nasquis", false, 0x003300, 0x002400, beeSpecies -> { @@ -923,7 +924,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(PLUTONIUM, IRIDIUM, 1); - mutation.requireResource("blockNaquadah"); + mutation.addMutationCondition(new MaterialMutationCondition(Naquadah)); }), NAQUADRIA(GTBranchDefinition.GT_RADIOACTIVE, "Nasquidrius", false, 0x000000, 0x002400, beeSpecies -> { @@ -941,7 +942,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(PLUTONIUM, IRIDIUM, 1); - mutation.requireResource("blockNaquadria"); + mutation.addMutationCondition(new MaterialMutationCondition(Naquadria)); }), TRINIUM(GTBranchDefinition.GT_RADIOACTIVE, "Trinium", false, 0xB0E0E6, 0xC8C8D2, beeSpecies -> { @@ -955,7 +956,7 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, SPEED, GTAlleleBeeSpecies.speedBlinding), dis -> { IBeeMutationBuilder mutation = dis.registerMutation(IRIDIUM, NAQUADAH, 4); - mutation.requireResource("blockTrinium"); + mutation.addMutationCondition(new MaterialMutationCondition(Trinium)); }), THORIUM(GTBranchDefinition.GT_RADIOACTIVE, "Thorax", false, 0x005000, 0x001E00, beeSpecies -> { @@ -970,7 +971,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IMutationBuilder mutation = dis.registerMutation(COAL, URANIUM, 2).setIsSecret(); - mutation.requireResource("blockThorium"); + mutation.addMutationCondition(new MaterialMutationCondition(Thorium)); }), LUTETIUM(GTBranchDefinition.GT_RADIOACTIVE, "Lutetia", false, 0x00AAFF, 0x0059FF, beeSpecies -> { @@ -992,7 +993,7 @@ public enum GTBeeDefinition implements IBeeDefinition { mutation = dis.registerMutation(THORIUM, BeeDefinition.IMPERIAL, 1); } mutation.setIsSecret(); - mutation.requireResource("blockLutetium"); + mutation.addMutationCondition(new MaterialMutationCondition(Lutetium)); }), AMERICIUM(GTBranchDefinition.GT_RADIOACTIVE, "Libertas", false, 0x287869, 0x0C453A, beeSpecies -> { @@ -1008,7 +1009,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IMutationBuilder mutation = dis.registerMutation(LUTETIUM, CHROME, 1).setIsSecret(); - mutation.requireResource("blockAmericium"); + mutation.addMutationCondition(new MaterialMutationCondition(Americium)); }), NEUTRONIUM(GTBranchDefinition.GT_RADIOACTIVE, "Media", false, 0xFFF0F0, 0xFAFAFA, beeSpecies -> { @@ -1024,7 +1025,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IMutationBuilder mutation = dis.registerMutation(NAQUADRIA, AMERICIUM, 1).setIsSecret(); - mutation.requireResource(new UnificationEntry(OrePrefix.block, Materials.Neutronium).toString()); + mutation.addMutationCondition(new MaterialMutationCondition(Neutronium)); }), // Noble Gases diff --git a/src/main/java/gregtech/integration/forestry/mutation/MaterialMutationCondition.java b/src/main/java/gregtech/integration/forestry/mutation/MaterialMutationCondition.java new file mode 100644 index 00000000000..a4ea54cdf23 --- /dev/null +++ b/src/main/java/gregtech/integration/forestry/mutation/MaterialMutationCondition.java @@ -0,0 +1,63 @@ +package gregtech.integration.forestry.mutation; + +import gregtech.api.unification.OreDictUnifier; +import gregtech.api.unification.material.Material; +import gregtech.api.util.LocalizationUtils; + +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import forestry.api.apiculture.IBeeHousing; +import forestry.api.climate.IClimateProvider; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IGenome; +import forestry.api.genetics.IMutationCondition; +import forestry.core.tiles.TileUtil; + +import java.util.HashSet; +import java.util.Set; + +import static org.apache.commons.lang3.StringUtils.capitalize; + +public class MaterialMutationCondition implements IMutationCondition { + + private final Set acceptedBlocks = new HashSet(); + private final String displayName; + + public MaterialMutationCondition(Material material) { + this.displayName = LocalizationUtils.format("gregtech.mutation.block_of", material.getLocalizedName()); + String oredictName = "block" + capitalize(material.getName()); + + for (ItemStack ore : OreDictUnifier.getAllWithOreDictionaryName(oredictName)) { + if (!ore.isEmpty()) { + Item oreItem = ore.getItem(); + Block oreBlock = Block.getBlockFromItem(oreItem); + if (oreBlock != Blocks.AIR) { + this.acceptedBlocks.addAll(oreBlock.getBlockState().getValidStates()); + } + } + } + } + + public float getChance(World world, BlockPos pos, IAllele allele0, IAllele allele1, IGenome genome0, + IGenome genome1, IClimateProvider climate) { + TileEntity tile; + do { + pos = pos.down(); + tile = TileUtil.getTile(world, pos); + } while (tile instanceof IBeeHousing); + + IBlockState blockState = world.getBlockState(pos); + return this.acceptedBlocks.contains(blockState) ? 1.0F : 0.0F; + } + + public String getDescription() { + return LocalizationUtils.format("for.mutation.condition.resource", this.displayName); + } +} diff --git a/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java b/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java index 2b67fa26844..f132c8ea481 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java +++ b/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java @@ -108,10 +108,16 @@ public static Material.Builder components(Material.Builder builder, Object... ob materialStacks.add(materialStack); } else if (o instanceof Material material) { materialStacks.add(new MaterialStack(material, 1)); + } else if (o instanceof Integer) { + GroovyLog.msg("Error creating GregTech material") + .add("Tried to use old method for material components in the shape of (material1, amount1, material2, amount2)") + .add("Please change this into (material1 * amount1, material2 * amount2)") + .error().post(); } else { - GroovyLog.get() - .error("Material components must be of type Material or MaterialStack, but was of type {}", - o == null ? null : o.getClass()); + GroovyLog.msg("Error creating GregTech material") + .add("Material components must be of type Material or MaterialStack, but was of type {}", + o == null ? null : o.getClass()) + .error().post(); } } return builder.components(materialStacks.toArray(new MaterialStack[0])); diff --git a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java index 8ce7fefb0f0..a3409b37941 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java +++ b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java @@ -5,9 +5,12 @@ import gregtech.api.fluids.FluidBuilder; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.registry.MTEManager; +import gregtech.api.metatileentity.registry.MTERegistry; import gregtech.api.modules.GregTechModule; import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; +import gregtech.api.recipes.ingredients.GTRecipeOreInput; import gregtech.api.unification.Element; import gregtech.api.unification.Elements; import gregtech.api.unification.material.Material; @@ -15,6 +18,7 @@ import gregtech.api.unification.material.event.PostMaterialEvent; import gregtech.api.unification.material.registry.MaterialRegistry; import gregtech.api.unification.ore.OrePrefix; +import gregtech.api.util.GTUtility; import gregtech.api.util.Mods; import gregtech.common.blocks.BlockCompressed; import gregtech.common.blocks.BlockFrame; @@ -36,11 +40,11 @@ import com.cleanroommc.groovyscript.GroovyScript; import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.GroovyPlugin; -import com.cleanroommc.groovyscript.api.IGameObjectParser; +import com.cleanroommc.groovyscript.api.IObjectParser; import com.cleanroommc.groovyscript.api.Result; import com.cleanroommc.groovyscript.compat.mods.GroovyContainer; -import com.cleanroommc.groovyscript.compat.mods.ModPropertyContainer; -import com.cleanroommc.groovyscript.gameobjects.GameObjectHandler; +import com.cleanroommc.groovyscript.compat.mods.GroovyPropertyContainer; +import com.cleanroommc.groovyscript.event.ScriptRunEvent; import com.cleanroommc.groovyscript.helper.EnumHelper; import com.cleanroommc.groovyscript.sandbox.expand.ExpansionHelper; import com.google.common.collect.ImmutableList; @@ -72,6 +76,8 @@ public class GroovyScriptModule extends IntegrationSubmodule implements GroovyPl private static GroovyContainer modSupportContainer; private static final Object2ObjectOpenHashMap> metaItems = new Object2ObjectOpenHashMap<>(); + private static final ResourceLocation MODULE_ID = GTUtility.gregtechId(GregTechModules.MODULE_GRS); + @NotNull @Override public List> getEventBusSubscribers() { @@ -83,6 +89,20 @@ public static void onRecipeEvent(RegistryEvent.Register event) { GroovyScriptModule.loadMetaItemBracketHandler(); } + @SubscribeEvent + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) + public static void afterScriptLoad(ScriptRunEvent.Post event) { + // Not Needed if JEI Module is enabled + if (!GregTechAPI.moduleManager.isModuleEnabled(GregTechModules.MODULE_JEI)) + GTRecipeOreInput.refreshStackCache(); + } + + @SubscribeEvent + public static void onMTERegistries(MTEManager.MTERegistryEvent event) { + // automatically create a registry for groovyscript to store its MTEs + GregTechAPI.mteManager.createRegistry(GroovyScriptModule.getPackId()); + } + public static boolean isCurrentlyRunning() { return GregTechAPI.moduleManager.isModuleEnabled(GregTechModules.MODULE_GRS) && GroovyScript.getSandbox().isRunning(); @@ -108,6 +128,7 @@ public static > T parseAndValidateEnumValue(Class clazz, St return t; } + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public static GroovyContainer getInstance() { return modSupportContainer; } @@ -142,7 +163,8 @@ public static ItemStack getMetaItem(String name) { @Nullable public static ItemStack getMetaTileEntityItem(String[] split) { - MetaTileEntity metaTileEntity = GregTechAPI.MTE_REGISTRY.getObject(new ResourceLocation(split[0], split[1])); + MTERegistry registry = GregTechAPI.mteManager.getRegistry(split[0]); + MetaTileEntity metaTileEntity = registry.getObject(new ResourceLocation(split[0], split[1])); return metaTileEntity == null ? null : metaTileEntity.getStackForm(); } @@ -228,34 +250,31 @@ public static void loadMetaItemBracketHandler() { @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) @Override - public @Nullable ModPropertyContainer createModPropertyContainer() { + public @Nullable GroovyPropertyContainer createGroovyPropertyContainer() { return new PropertyContainer(); } + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) @Override - public void onCompatLoaded(GroovyContainer groovyContainer) { - GroovyScriptModule.modSupportContainer = groovyContainer; - GameObjectHandler.builder("recipemap", RecipeMap.class) - .mod(GTValues.MODID) - .parser(IGameObjectParser.wrapStringGetter(RecipeMap::getByName)) + public void onCompatLoaded(GroovyContainer container) { + GroovyScriptModule.modSupportContainer = container; + container.objectMapperBuilder("recipemap", RecipeMap.class) + .parser(IObjectParser.wrapStringGetter(RecipeMap::getByName)) .completerOfNamed(RecipeMap::getRecipeMaps, RecipeMap::getUnlocalizedName) .register(); - GameObjectHandler.builder("material", Material.class) - .mod(GTValues.MODID) - .parser(IGameObjectParser.wrapStringGetter(GregTechAPI.materialManager::getMaterial)) + container.objectMapperBuilder("material", Material.class) + .parser(IObjectParser.wrapStringGetter(GregTechAPI.materialManager::getMaterial)) .completerOfNamed(GregTechAPI.materialManager::getRegisteredMaterials, mat -> mat.getResourceLocation().toString()) .register(); - GameObjectHandler.builder("oreprefix", OrePrefix.class) - .mod(GTValues.MODID) - .parser(IGameObjectParser.wrapStringGetter(OrePrefix::getPrefix)) + container.objectMapperBuilder("oreprefix", OrePrefix.class) + .parser(IObjectParser.wrapStringGetter(OrePrefix::getPrefix)) .completerOfNamed(OrePrefix::values, v -> v.name) .register(); - GameObjectHandler.builder("metaitem", ItemStack.class) - .mod(GTValues.MODID) - .parser(IGameObjectParser.wrapStringGetter(GroovyScriptModule::getMetaItem)) + container.objectMapperBuilder("metaitem", ItemStack.class) + .parser(IObjectParser.wrapStringGetter(GroovyScriptModule::getMetaItem)) .completer((paramIndex, items) -> { if (paramIndex != 0) return; for (var iterator = metaItems.object2ObjectEntrySet().fastIterator(); iterator.hasNext();) { @@ -270,8 +289,7 @@ public void onCompatLoaded(GroovyContainer groovyContainer) { }) .register(); - GameObjectHandler.builder("element", Element.class) - .mod(GTValues.MODID) + container.objectMapperBuilder("element", Element.class) .parser((s, args) -> { Element element = Elements.get(s); if (element != null) return Result.some(element); @@ -312,4 +330,14 @@ protected static void logError(Material m, String cause, String type) { "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()); } + + /** + * @return the modid used in scripts + */ + public static @NotNull String getPackId() { + if (GregTechAPI.moduleManager.isModuleEnabled(MODULE_ID)) { + return GroovyScript.getRunConfig().getPackOrModId(); + } + return ""; + } } diff --git a/src/main/java/gregtech/integration/groovy/MaterialExpansion.java b/src/main/java/gregtech/integration/groovy/MaterialExpansion.java index 70b92dd04d9..6d5f5e7ac2f 100644 --- a/src/main/java/gregtech/integration/groovy/MaterialExpansion.java +++ b/src/main/java/gregtech/integration/groovy/MaterialExpansion.java @@ -53,7 +53,7 @@ public static String getIconSet(Material m) { public static boolean isGaseous(Material m) { FluidProperty prop = m.getProperty(PropertyKey.FLUID); - return prop != null && prop.getStorage().get(FluidStorageKeys.GAS) != null; + return prop != null && prop.get(FluidStorageKeys.GAS) != null; } /////////////////////////////////// diff --git a/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java b/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java index 83ceb1b27a7..79cc7c810aa 100644 --- a/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java +++ b/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java @@ -174,7 +174,7 @@ private static void addFluidInternal(Material m, FluidStorageKey key, FluidBuild property = new FluidProperty(); m.setProperty(PropertyKey.FLUID, property); } - property.getStorage().enqueueRegistration(key, builder); + property.enqueueRegistration(key, builder); } public static void addLiquid(Material m, FluidBuilder builder) { diff --git a/src/main/java/gregtech/integration/groovy/PropertyContainer.java b/src/main/java/gregtech/integration/groovy/PropertyContainer.java index 35da8ce4905..30930c68f9c 100644 --- a/src/main/java/gregtech/integration/groovy/PropertyContainer.java +++ b/src/main/java/gregtech/integration/groovy/PropertyContainer.java @@ -7,7 +7,7 @@ import com.cleanroommc.groovyscript.GroovyScript; import com.cleanroommc.groovyscript.api.GroovyLog; -import com.cleanroommc.groovyscript.compat.mods.ModPropertyContainer; +import com.cleanroommc.groovyscript.compat.mods.GroovyPropertyContainer; import com.cleanroommc.groovyscript.event.EventBusType; import com.cleanroommc.groovyscript.event.GroovyEventManager; import com.cleanroommc.groovyscript.sandbox.ClosureHelper; @@ -15,7 +15,7 @@ import groovy.lang.Closure; import groovy.lang.DelegatesTo; -public class PropertyContainer extends ModPropertyContainer { +public class PropertyContainer extends GroovyPropertyContainer { public void materialEvent(EventPriority priority, @DelegatesTo(MaterialEvent.class) Closure eventListener) { if (GroovyScriptModule.isCurrentlyRunning() && diff --git a/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java b/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java index 6bd80f4db05..ff2e351d811 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().getRegistrar().addRegistry(this); + GroovyScriptModule.getInstance().addProperty(this); } @Override diff --git a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java index 491db7fb1f1..5ce3cff1cb9 100644 --- a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java +++ b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java @@ -10,11 +10,13 @@ import gregtech.api.items.metaitem.MetaItem; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.SteamMetaTileEntity; +import gregtech.api.metatileentity.registry.MTERegistry; import gregtech.api.modules.GregTechModule; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMap; -import gregtech.api.recipes.RecipeMaps; import gregtech.api.recipes.category.GTRecipeCategory; +import gregtech.api.recipes.category.ICategoryOverride; +import gregtech.api.recipes.ingredients.GTRecipeOreInput; import gregtech.api.recipes.ingredients.IntCircuitIngredient; import gregtech.api.recipes.machines.IScannerRecipeMap; import gregtech.api.recipes.machines.RecipeMapFurnace; @@ -113,8 +115,10 @@ public void registerItemSubtypes(@NotNull ISubtypeRegistry subtypeRegistry) { for (MetaItem metaItem : MetaItems.ITEMS) { subtypeRegistry.registerSubtypeInterpreter(metaItem, subtype); } - subtypeRegistry.registerSubtypeInterpreter(Item.getItemFromBlock(MetaBlocks.MACHINE), - new MachineSubtypeHandler()); + for (MTERegistry registry : GregTechAPI.mteManager.getRegistries()) { + subtypeRegistry.registerSubtypeInterpreter(Item.getItemFromBlock(registry.getBlock()), + new MachineSubtypeHandler()); + } } @Override @@ -190,31 +194,48 @@ public void register(IModRegistry registry) { } } - for (ResourceLocation metaTileEntityId : GregTechAPI.MTE_REGISTRY.getKeys()) { - MetaTileEntity metaTileEntity = GregTechAPI.MTE_REGISTRY.getObject(metaTileEntityId); - assert metaTileEntity != null; - if (metaTileEntity.getCapability(GregtechTileCapabilities.CAPABILITY_CONTROLLABLE, null) != null) { - IControllable workableCapability = metaTileEntity - .getCapability(GregtechTileCapabilities.CAPABILITY_CONTROLLABLE, null); + for (MTERegistry mteRegistry : GregTechAPI.mteManager.getRegistries()) { + for (ResourceLocation metaTileEntityId : mteRegistry.getKeys()) { + MetaTileEntity metaTileEntity = mteRegistry.getObject(metaTileEntityId); + assert metaTileEntity != null; + + if (metaTileEntity instanceof ICategoryOverride override && override.shouldOverride()) { + for (RecipeMap recipeMap : override.getJEIRecipeMapCategoryOverrides()) { + registerRecipeMapCatalyst(registry, recipeMap, metaTileEntity); + } + if (override.getJEICategoryOverrides().length != 0) + registry.addRecipeCatalyst(metaTileEntity.getStackForm(), override.getJEICategoryOverrides()); + if (override.shouldReplace()) continue; + } + + if (metaTileEntity.getCapability(GregtechTileCapabilities.CAPABILITY_CONTROLLABLE, null) != null) { + IControllable workableCapability = metaTileEntity + .getCapability(GregtechTileCapabilities.CAPABILITY_CONTROLLABLE, null); - if (workableCapability instanceof AbstractRecipeLogic logic) { - if (metaTileEntity instanceof IMultipleRecipeMaps) { - for (RecipeMap recipeMap : ((IMultipleRecipeMaps) metaTileEntity).getAvailableRecipeMaps()) { + if (workableCapability instanceof ICategoryOverride override && override.shouldOverride()) { + for (RecipeMap recipeMap : override.getJEIRecipeMapCategoryOverrides()) { registerRecipeMapCatalyst(registry, recipeMap, metaTileEntity); } - } else if (logic.getRecipeMap() != null) { - registerRecipeMapCatalyst(registry, logic.getRecipeMap(), metaTileEntity); + if (override.getJEICategoryOverrides().length != 0) + registry.addRecipeCatalyst(metaTileEntity.getStackForm(), + override.getJEICategoryOverrides()); + if (override.shouldReplace()) continue; + } + + if (workableCapability instanceof AbstractRecipeLogic logic) { + if (metaTileEntity instanceof IMultipleRecipeMaps) { + for (RecipeMap recipeMap : ((IMultipleRecipeMaps) metaTileEntity) + .getAvailableRecipeMaps()) { + registerRecipeMapCatalyst(registry, recipeMap, metaTileEntity); + } + } else if (logic.getRecipeMap() != null) { + registerRecipeMapCatalyst(registry, logic.getRecipeMap(), metaTileEntity); + } } } } } - String semiFluidMapId = GTValues.MODID + ":" + RecipeMaps.SEMI_FLUID_GENERATOR_FUELS.getUnlocalizedName(); - registry.addRecipeCatalyst(MetaTileEntities.LARGE_BRONZE_BOILER.getStackForm(), semiFluidMapId); - registry.addRecipeCatalyst(MetaTileEntities.LARGE_STEEL_BOILER.getStackForm(), semiFluidMapId); - registry.addRecipeCatalyst(MetaTileEntities.LARGE_TITANIUM_BOILER.getStackForm(), semiFluidMapId); - registry.addRecipeCatalyst(MetaTileEntities.LARGE_TUNGSTENSTEEL_BOILER.getStackForm(), semiFluidMapId); - List oreByproductList = new ArrayList<>(); for (Material material : GregTechAPI.materialManager.getRegisteredMaterials()) { if (material.hasProperty(PropertyKey.ORE)) { @@ -296,6 +317,9 @@ public void register(IModRegistry registry) { }); registry.addIngredientInfo(new ItemStack(MetaBlocks.BRITTLE_CHARCOAL), VanillaTypes.ITEM, I18n.format("tile.brittle_charcoal.tooltip.1", I18n.format("tile.brittle_charcoal.tooltip.2"))); + + // Refresh Ore Ingredients Cache + GTRecipeOreInput.refreshStackCache(); } private void setupInputHandler() { diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/ElectricContainerInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/ElectricContainerInfoProvider.java index 4b2e970d7c6..a15622a1160 100644 --- a/src/main/java/gregtech/integration/theoneprobe/provider/ElectricContainerInfoProvider.java +++ b/src/main/java/gregtech/integration/theoneprobe/provider/ElectricContainerInfoProvider.java @@ -3,7 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechCapabilities; import gregtech.api.capability.IEnergyContainer; -import gregtech.api.util.TextFormattingUtil; +import gregtech.api.capability.ILaserContainer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; @@ -11,6 +11,8 @@ import mcjty.theoneprobe.api.IProbeHitData; import mcjty.theoneprobe.api.IProbeInfo; +import mcjty.theoneprobe.api.NumberFormat; +import mcjty.theoneprobe.apiimpl.elements.ElementProgress; import org.jetbrains.annotations.NotNull; public class ElectricContainerInfoProvider extends CapabilityInfoProvider { @@ -28,18 +30,21 @@ protected Capability getCapability() { @Override protected boolean allowDisplaying(@NotNull IEnergyContainer capability) { - return !capability.isOneProbeHidden(); + return !capability.isOneProbeHidden() && !(capability instanceof ILaserContainer); } @Override protected void addProbeInfo(@NotNull IEnergyContainer capability, @NotNull IProbeInfo probeInfo, EntityPlayer player, @NotNull TileEntity tileEntity, @NotNull IProbeHitData data) { long maxStorage = capability.getEnergyCapacity(); + long stored = capability.getEnergyStored(); if (maxStorage == 0) return; // do not add empty max storage progress bar probeInfo.progress(capability.getEnergyStored(), maxStorage, probeInfo.defaultProgressStyle() - .suffix(" / " + TextFormattingUtil.formatNumbers(maxStorage) + " EU") + .numberFormat(player.isSneaking() || stored < 10000 ? NumberFormat.FULL : NumberFormat.COMPACT) + .suffix(" / " + (player.isSneaking() || maxStorage < 10000 ? maxStorage + " EU" : + ElementProgress.format(maxStorage, NumberFormat.COMPACT, "EU"))) .filledColor(0xFFEEE600) .alternateFilledColor(0xFFEEE600) - .borderColor(0xFF555555).numberFormat(mcjty.theoneprobe.api.NumberFormat.COMMAS)); + .borderColor(0xFF555555)); } } diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/LaserContainerInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/LaserContainerInfoProvider.java index 404bf223680..af1ba0bca7d 100644 --- a/src/main/java/gregtech/integration/theoneprobe/provider/LaserContainerInfoProvider.java +++ b/src/main/java/gregtech/integration/theoneprobe/provider/LaserContainerInfoProvider.java @@ -3,7 +3,6 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.ILaserContainer; -import gregtech.api.util.TextFormattingUtil; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; @@ -12,6 +11,7 @@ import mcjty.theoneprobe.api.IProbeHitData; import mcjty.theoneprobe.api.IProbeInfo; import mcjty.theoneprobe.api.NumberFormat; +import mcjty.theoneprobe.apiimpl.elements.ElementProgress; import org.jetbrains.annotations.NotNull; public class LaserContainerInfoProvider extends CapabilityInfoProvider { @@ -31,12 +31,15 @@ protected boolean allowDisplaying(@NotNull ILaserContainer capability) { protected void addProbeInfo(ILaserContainer capability, IProbeInfo probeInfo, EntityPlayer player, TileEntity tileEntity, IProbeHitData data) { long maxStorage = capability.getEnergyCapacity(); + long stored = capability.getEnergyStored(); if (maxStorage == 0) return; // do not add empty max storage progress bar - probeInfo.progress(capability.getEnergyStored(), maxStorage, probeInfo.defaultProgressStyle() - .suffix(" / " + TextFormattingUtil.formatNumbers(maxStorage) + " EU") + probeInfo.progress(stored, maxStorage, probeInfo.defaultProgressStyle() + .numberFormat(player.isSneaking() || stored < 10000 ? NumberFormat.FULL : NumberFormat.COMPACT) + .suffix(" / " + (player.isSneaking() || maxStorage < 10000 ? maxStorage + " EU" : + ElementProgress.format(maxStorage, NumberFormat.COMPACT, "EU"))) .filledColor(0xFFEEE600) .alternateFilledColor(0xFFEEE600) - .borderColor(0xFF555555).numberFormat(NumberFormat.COMMAS)); + .borderColor(0xFF555555)); } @Override diff --git a/src/main/java/gregtech/loaders/recipe/chemistry/MixerRecipes.java b/src/main/java/gregtech/loaders/recipe/chemistry/MixerRecipes.java index f4ae4d431af..d6ebaa3b9ac 100644 --- a/src/main/java/gregtech/loaders/recipe/chemistry/MixerRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/chemistry/MixerRecipes.java @@ -102,6 +102,13 @@ public static void init() { .fluidOutputs(DrillingFluid.getFluid(5000)) .duration(64).EUt(16).buildAndRegister(); + MIXER_RECIPES.recipeBuilder() + .input(dust, Stone) + .fluidInputs(Lubricant.getFluid(20)) + .fluidInputs(DistilledWater.getFluid(4980)) + .fluidOutputs(DrillingFluid.getFluid(5000)) + .duration(48).EUt(16).buildAndRegister(); + MIXER_RECIPES.recipeBuilder().duration(160).EUt(VA[HV]) .input(dust, Beryllium) .input(dust, Potassium, 4) diff --git a/src/main/java/gregtech/loaders/recipe/handlers/PolarizingRecipeHandler.java b/src/main/java/gregtech/loaders/recipe/handlers/PolarizingRecipeHandler.java index 9a412ddf7ab..940bbb946aa 100644 --- a/src/main/java/gregtech/loaders/recipe/handlers/PolarizingRecipeHandler.java +++ b/src/main/java/gregtech/loaders/recipe/handlers/PolarizingRecipeHandler.java @@ -20,7 +20,7 @@ public class PolarizingRecipeHandler { private static final OrePrefix[] POLARIZING_PREFIXES = new OrePrefix[] { OrePrefix.stick, OrePrefix.stickLong, OrePrefix.plate, OrePrefix.ingot, OrePrefix.plateDense, OrePrefix.rotor, - OrePrefix.bolt, OrePrefix.screw, OrePrefix.wireFine, OrePrefix.foil, OrePrefix.ring }; + OrePrefix.bolt, OrePrefix.screw, OrePrefix.wireFine, OrePrefix.foil, OrePrefix.ring, OrePrefix.block }; public static void register() { for (OrePrefix orePrefix : POLARIZING_PREFIXES) { diff --git a/src/main/java/gregtech/mixins/GregTechLateMixinLoadingPlugin.java b/src/main/java/gregtech/mixins/GregTechLateMixinLoadingPlugin.java new file mode 100644 index 00000000000..a582e924088 --- /dev/null +++ b/src/main/java/gregtech/mixins/GregTechLateMixinLoadingPlugin.java @@ -0,0 +1,37 @@ +package gregtech.mixins; + +import gregtech.api.util.Mods; + +import zone.rong.mixinbooter.ILateMixinLoader; + +import java.util.ArrayList; +import java.util.List; + +public class GregTechLateMixinLoadingPlugin implements ILateMixinLoader { + + @Override + public List getMixinConfigs() { + List configs = new ArrayList<>(); + + configs.add("mixins.gregtech.theoneprobe.json"); + configs.add("mixins.gregtech.jei.json"); + configs.add("mixins.gregtech.ctm.json"); + configs.add("mixins.gregtech.ccl.json"); + configs.add("mixins.gregtech.littletiles.json"); + configs.add("mixins.gregtech.vintagium.json"); + + return configs; + } + + @Override + public boolean shouldMixinConfigQueue(String mixinConfig) { + return switch (mixinConfig) { + case "mixins.gregtech.theoneprobe.json" -> Mods.TheOneProbe.isModLoaded(); + case "mixins.gregtech.jei.json" -> Mods.JustEnoughItems.isModLoaded(); + case "mixin.gregtech.ctm.json" -> Mods.CTM.isModLoaded(); + case "mixins.gregtech.littletiles.json" -> Mods.LittleTiles.isModLoaded(); + case "mixins.gregtech.vintagium.json" -> Mods.Vintagium.isModLoaded(); + default -> true; + }; + } +} diff --git a/src/main/java/gregtech/mixins/ccl/CCLDescriptionMixin.java b/src/main/java/gregtech/mixins/ccl/CCLDescriptionMixin.java new file mode 100644 index 00000000000..ffd11f06b6e --- /dev/null +++ b/src/main/java/gregtech/mixins/ccl/CCLDescriptionMixin.java @@ -0,0 +1,17 @@ +package gregtech.mixins.ccl; + +import codechicken.lib.internal.ModDescriptionEnhancer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +// CCL's supporter stuff is broken, the link no longer works +@Mixin(ModDescriptionEnhancer.class) +public class CCLDescriptionMixin { + + @Inject(method = "init", at = @At("HEAD"), remap = false, cancellable = true) + private static void stopDescriptionEnhancement(CallbackInfo ci) { + ci.cancel(); + } +} diff --git a/src/main/java/gregtech/mixins/ctm/AbstractCTMBakedModelMixin.java b/src/main/java/gregtech/mixins/ctm/AbstractCTMBakedModelMixin.java new file mode 100644 index 00000000000..038f9d90023 --- /dev/null +++ b/src/main/java/gregtech/mixins/ctm/AbstractCTMBakedModelMixin.java @@ -0,0 +1,28 @@ +package gregtech.mixins.ctm; + +import gregtech.asm.hooks.CTMHooks; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import com.llamalad7.mixinextras.sugar.Local; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import team.chisel.ctm.client.model.AbstractCTMBakedModel; + +import java.util.List; + +@Mixin(AbstractCTMBakedModel.class) +public class AbstractCTMBakedModelMixin { + + @ModifyReturnValue(method = "getQuads", at = @At(value = "RETURN", ordinal = 1)) + private List getQuadsWithOptifine(List original, @Local(ordinal = 0) BlockRenderLayer layer, + @Local(ordinal = 0) IBlockState state, + @Local(ordinal = 0) EnumFacing side, @Local(ordinal = 0) long rand) { + return CTMHooks.getQuadsWithOptiFine(original, layer, (IBakedModel) this, state, side, rand); + } +} diff --git a/src/main/java/gregtech/mixins/ctm/CTMRenderInLayerMixin.java b/src/main/java/gregtech/mixins/ctm/CTMRenderInLayerMixin.java new file mode 100644 index 00000000000..12914a5cc5f --- /dev/null +++ b/src/main/java/gregtech/mixins/ctm/CTMRenderInLayerMixin.java @@ -0,0 +1,28 @@ +package gregtech.mixins.ctm; + +import gregtech.asm.hooks.CTMModHooks; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.util.BlockRenderLayer; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.sugar.Local; +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import team.chisel.ctm.client.asm.CTMCoreMethods; +import team.chisel.ctm.client.model.AbstractCTMBakedModel; + +@Mixin(CTMCoreMethods.class) +public class CTMRenderInLayerMixin { + + @ModifyExpressionValue(method = "canRenderInLayer", + at = @At(value = "INVOKE_ASSIGN", + target = "Lteam/chisel/ctm/api/model/IModelCTM;canRenderInLayer(Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/util/BlockRenderLayer;)Z"), + remap = false) + private static Boolean checkRenderInLayer(Boolean originalResult, @NotNull IBlockState state, + @NotNull BlockRenderLayer layer, @Local(ordinal = 0) IBakedModel model) { + return CTMModHooks.canRenderInLayer(((AbstractCTMBakedModel) model).getModel(), state, layer); + } +} diff --git a/src/main/java/gregtech/mixins/forge/ModelLoaderRegistryMixin.java b/src/main/java/gregtech/mixins/forge/ModelLoaderRegistryMixin.java new file mode 100644 index 00000000000..85cc8d099e8 --- /dev/null +++ b/src/main/java/gregtech/mixins/forge/ModelLoaderRegistryMixin.java @@ -0,0 +1,20 @@ +package gregtech.mixins.forge; + +import gregtech.api.unification.material.info.MaterialIconType; + +import net.minecraft.client.resources.IResourceManager; +import net.minecraftforge.client.model.ModelLoaderRegistry; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ModelLoaderRegistry.class) +public class ModelLoaderRegistryMixin { + + @Inject(method = "clearModelCache", at = @At("TAIL"), remap = false) + private static void clearCache(IResourceManager manager, CallbackInfo ci) { + MaterialIconType.clearCache(); + } +} diff --git a/src/main/java/gregtech/mixins/forge/SpecialArmorPropertiesMixin.java b/src/main/java/gregtech/mixins/forge/SpecialArmorPropertiesMixin.java new file mode 100644 index 00000000000..668335c9b4c --- /dev/null +++ b/src/main/java/gregtech/mixins/forge/SpecialArmorPropertiesMixin.java @@ -0,0 +1,38 @@ +package gregtech.mixins.forge; + +import gregtech.api.items.armor.IArmorItem; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.DamageSource; +import net.minecraft.util.NonNullList; +import net.minecraftforge.common.ISpecialArmor; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(ISpecialArmor.ArmorProperties.class) +public class SpecialArmorPropertiesMixin { + + @ModifyExpressionValue(method = "applyArmor", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/util/CombatRules;getDamageAfterAbsorb(FFF)F"), + remap = false) + private static float adjustArmorAbsorption(float originalDamage, EntityLivingBase entity, + NonNullList inventory, + DamageSource damageSource, double damage) { + double armorDamage = Math.max(1.0F, damage / 4.0F); + for (int i = 0; i < inventory.size(); i++) { + ItemStack itemStack = inventory.get(i); + if (itemStack.getItem() instanceof IArmorItem) { + ((IArmorItem) itemStack.getItem()).damageArmor(entity, itemStack, damageSource, (int) armorDamage, i); + if (inventory.get(i).getCount() == 0) { + inventory.set(i, ItemStack.EMPTY); + } + } + } + + return originalDamage; + } +} diff --git a/src/main/java/gregtech/mixins/jei/JEITooltipMixin.java b/src/main/java/gregtech/mixins/jei/JEITooltipMixin.java new file mode 100644 index 00000000000..aa971bfd814 --- /dev/null +++ b/src/main/java/gregtech/mixins/jei/JEITooltipMixin.java @@ -0,0 +1,32 @@ +package gregtech.mixins.jei; + +import gregtech.api.util.FluidTooltipUtil; + +import net.minecraftforge.fluids.FluidStack; + +import mezz.jei.api.ingredients.IIngredientHelper; +import mezz.jei.startup.ForgeModIdHelper; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.List; + +@Mixin(ForgeModIdHelper.class) +public class JEITooltipMixin { + + @Inject(method = "addModNameToIngredientTooltip", at = @At("HEAD"), remap = false) + public void addTooltip(List tooltip, Object ingredient, IIngredientHelper ingredientHelper, + CallbackInfoReturnable> cir) { + if (ingredient instanceof FluidStack) { + List formula = FluidTooltipUtil.getFluidTooltip((FluidStack) ingredient); + if (formula != null) { + for (String s : formula) { + if (s.isEmpty()) continue; + tooltip.add(s); + } + } + } + } +} diff --git a/src/main/java/gregtech/mixins/littletiles/LittleTilesRenderMangerMixin.java b/src/main/java/gregtech/mixins/littletiles/LittleTilesRenderMangerMixin.java new file mode 100644 index 00000000000..8f09a26d1fa --- /dev/null +++ b/src/main/java/gregtech/mixins/littletiles/LittleTilesRenderMangerMixin.java @@ -0,0 +1,28 @@ +package gregtech.mixins.littletiles; + +import gregtech.asm.hooks.LittleTilesHooks; + +import com.creativemd.littletiles.client.render.cache.LayeredRenderBoxCache; +import com.creativemd.littletiles.client.render.world.TileEntityRenderManager; +import com.creativemd.littletiles.common.tileentity.TileEntityLittleTiles; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(value = TileEntityRenderManager.class, remap = false) +public class LittleTilesRenderMangerMixin { + + @Mutable + @Shadow + @Final + private LayeredRenderBoxCache boxCache; + + @Inject(method = "", at = @At("TAIL"), remap = false) + public void adjustRenderLayerdBox(TileEntityLittleTiles te, CallbackInfo ci) { + boxCache = LittleTilesHooks.initLayeredRenderBoxCache(); + } +} diff --git a/src/main/java/gregtech/mixins/minecraft/BlockConcretePowderMixin.java b/src/main/java/gregtech/mixins/minecraft/BlockConcretePowderMixin.java new file mode 100644 index 00000000000..4106a70e1c1 --- /dev/null +++ b/src/main/java/gregtech/mixins/minecraft/BlockConcretePowderMixin.java @@ -0,0 +1,24 @@ +package gregtech.mixins.minecraft; + +import gregtech.common.ConfigHolder; + +import net.minecraft.block.BlockConcretePowder; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(BlockConcretePowder.class) +public class BlockConcretePowderMixin { + + @Inject(method = "tryTouchWater", at = @At("HEAD"), cancellable = true) + public void disableConversion(World worldIn, BlockPos pos, IBlockState state, CallbackInfoReturnable cir) { + if (ConfigHolder.recipes.disableConcreteInWorld) { + cir.setReturnValue(false); + } + } +} diff --git a/src/main/java/gregtech/mixins/minecraft/BlockMixin.java b/src/main/java/gregtech/mixins/minecraft/BlockMixin.java new file mode 100644 index 00000000000..f2271c71f49 --- /dev/null +++ b/src/main/java/gregtech/mixins/minecraft/BlockMixin.java @@ -0,0 +1,33 @@ +package gregtech.mixins.minecraft; + +import gregtech.api.util.Mods; +import gregtech.asm.hooks.BlockHooks; + +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.BlockRenderLayer; +import net.minecraftforge.fml.common.Loader; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +/** + * Apply our block hooks for our custom models when CTM is not loaded + */ +@Mixin(Block.class) +public class BlockMixin { + + @Inject(method = "canRenderInLayer", at = @At("HEAD"), cancellable = true, remap = false) + private void canRenderInLayer(IBlockState state, BlockRenderLayer layer, CallbackInfoReturnable cir) { + if (!Loader.instance().getIndexedModList().containsKey(Mods.Names.CONNECTED_TEXTURES_MOD)) { + Boolean result = BlockHooks.canRenderInLayer(state, layer); + + if (result != null) { + cir.setReturnValue(result); + cir.cancel(); + } + } + } +} diff --git a/src/main/java/gregtech/mixins/minecraft/DamageSourceMixin.java b/src/main/java/gregtech/mixins/minecraft/DamageSourceMixin.java new file mode 100644 index 00000000000..9247f2ab945 --- /dev/null +++ b/src/main/java/gregtech/mixins/minecraft/DamageSourceMixin.java @@ -0,0 +1,25 @@ +package gregtech.mixins.minecraft; + +import gregtech.api.damagesources.DamageSources; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.DamageSource; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(DamageSource.class) +public class DamageSourceMixin { + + @ModifyReturnValue(method = "causePlayerDamage", at = @At("RETURN")) + private static DamageSource modifyPlayerDamageWithTool(DamageSource originalReturnValue, EntityPlayer source) { + return DamageSources.getPlayerDamage(source); + } + + @ModifyReturnValue(method = "causeMobDamage", at = @At("RETURN")) + private static DamageSource modifyMobDamageWithTool(DamageSource originalReturnValue, EntityLivingBase source) { + return DamageSources.getMobDamage(source); + } +} diff --git a/src/main/java/gregtech/mixins/minecraft/EnchantmentCanApplyMixin.java b/src/main/java/gregtech/mixins/minecraft/EnchantmentCanApplyMixin.java new file mode 100644 index 00000000000..3f97d2b66f4 --- /dev/null +++ b/src/main/java/gregtech/mixins/minecraft/EnchantmentCanApplyMixin.java @@ -0,0 +1,23 @@ +package gregtech.mixins.minecraft; + +import gregtech.api.items.toolitem.IGTTool; + +import net.minecraft.enchantment.Enchantment; +import net.minecraft.item.ItemStack; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import com.llamalad7.mixinextras.sugar.Local; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(Enchantment.class) +public class EnchantmentCanApplyMixin { + + @ModifyReturnValue(method = "canApply", at = @At("RETURN")) + private boolean enchantmentCanApply(boolean originalResult, @Local(ordinal = 0) ItemStack stack) { + if (stack.getItem() instanceof IGTTool) { + return originalResult && stack.getItem().canApplyAtEnchantingTable(stack, ((Enchantment) (Object) this)); + } + return originalResult; + } +} diff --git a/src/main/java/gregtech/mixins/minecraft/EntityRendererMixin.java b/src/main/java/gregtech/mixins/minecraft/EntityRendererMixin.java new file mode 100644 index 00000000000..472f1d98c45 --- /dev/null +++ b/src/main/java/gregtech/mixins/minecraft/EntityRendererMixin.java @@ -0,0 +1,26 @@ +package gregtech.mixins.minecraft; + +import gregtech.client.utils.BloomEffectUtil; + +import net.minecraft.client.renderer.EntityRenderer; +import net.minecraft.client.renderer.RenderGlobal; +import net.minecraft.entity.Entity; +import net.minecraft.util.BlockRenderLayer; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(EntityRenderer.class) +public class EntityRendererMixin { + + @WrapOperation(method = "renderWorldPass", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/client/renderer/RenderGlobal;renderBlockLayer(Lnet/minecraft/util/BlockRenderLayer;DILnet/minecraft/entity/Entity;)I", + ordinal = 3)) + public int renderBloomBlockLayer(RenderGlobal instance, BlockRenderLayer layer, double partialTicks, int pass, + Entity entity, Operation original) { + return BloomEffectUtil.renderBloomBlockLayer(instance, layer, partialTicks, pass, entity); + } +} diff --git a/src/main/java/gregtech/mixins/minecraft/LayerArmorBaseMixin.java b/src/main/java/gregtech/mixins/minecraft/LayerArmorBaseMixin.java new file mode 100644 index 00000000000..7363d82d575 --- /dev/null +++ b/src/main/java/gregtech/mixins/minecraft/LayerArmorBaseMixin.java @@ -0,0 +1,79 @@ +package gregtech.mixins.minecraft; + +import gregtech.api.items.armor.IArmorItem; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.layers.LayerArmorBase; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.ForgeHooksClient; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(LayerArmorBase.class) +public class LayerArmorBaseMixin { + + @Inject(method = "renderArmorLayer", at = @At("TAIL")) + public void renderGTArmor(EntityLivingBase entityLivingBaseIn, float limbSwing, float limbSwingAmount, + float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale, + EntityEquipmentSlot slotIn, CallbackInfo ci) { + ItemStack itemStack = entityLivingBaseIn.getItemStackFromSlot(slotIn); + + if ((itemStack.getItem() instanceof IArmorItem armorItem && + itemStack.getItem().getEquipmentSlot(itemStack) == slotIn)) { + @SuppressWarnings("unchecked") + LayerArmorBase layer = (LayerArmorBase) (Object) this; + ModelBase armorModel = layer.getModelFromSlot(slotIn); + if (armorModel instanceof ModelBiped) { + armorModel = ForgeHooksClient.getArmorModel(entityLivingBaseIn, itemStack, slotIn, + (ModelBiped) armorModel); + } + armorModel.setModelAttributes(layer.renderer.getMainModel()); + armorModel.setLivingAnimations(entityLivingBaseIn, limbSwing, limbSwingAmount, partialTicks); + layer.setModelSlotVisible(armorModel, slotIn); + + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + + int layers = armorItem.getArmorLayersAmount(itemStack); + for (int layerIndex = 0; layerIndex < layers; layerIndex++) { + int i = armorItem.getArmorLayerColor(itemStack, layerIndex); + float f = (float) (i >> 16 & 255) / 255.0F; + float f1 = (float) (i >> 8 & 255) / 255.0F; + float f2 = (float) (i & 255) / 255.0F; + GlStateManager.color(f, f1, f2, 1.0f); + String type = layerIndex == 0 ? null : "layer_" + layerIndex; + layer.renderer.bindTexture(gregTechCEu$getArmorTexture(entityLivingBaseIn, itemStack, slotIn, type)); + armorModel.render(entityLivingBaseIn, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, + scale); + } + if (itemStack.hasEffect()) { + LayerArmorBase.renderEnchantedGlint(layer.renderer, entityLivingBaseIn, armorModel, limbSwing, + limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale); + } + } + } + + @Unique + private static ResourceLocation gregTechCEu$getArmorTexture(EntityLivingBase entity, ItemStack itemStack, + EntityEquipmentSlot slot, String type) { + ResourceLocation registryName = itemStack.getItem().getRegistryName(); + if (registryName == null) { + throw new IllegalArgumentException( + "ItemStack " + itemStack.getTranslationKey() + "has a null registry name"); + } + + String s1 = String.format("%s:textures/models/armor/%s_layer_%d%s.png", registryName.getNamespace(), + registryName.getPath(), + (slot == EntityEquipmentSlot.LEGS ? 2 : 1), type == null ? "" : String.format("_%s", type)); + return new ResourceLocation(ForgeHooksClient.getArmorTexture(entity, itemStack, s1, slot, type)); + } +} diff --git a/src/main/java/gregtech/mixins/minecraft/LayerCustomHeadMixin.java b/src/main/java/gregtech/mixins/minecraft/LayerCustomHeadMixin.java new file mode 100644 index 00000000000..d6f69a7d3bb --- /dev/null +++ b/src/main/java/gregtech/mixins/minecraft/LayerCustomHeadMixin.java @@ -0,0 +1,38 @@ +package gregtech.mixins.minecraft; + +import gregtech.api.items.armor.IArmorItem; + +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.entity.layers.LayerCustomHead; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.ItemStack; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(LayerCustomHead.class) +public class LayerCustomHeadMixin { + + @WrapOperation(method = "doRenderLayer", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/client/renderer/ItemRenderer;renderItem(Lnet/minecraft/entity/EntityLivingBase;Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/renderer/block/model/ItemCameraTransforms$TransformType;)V")) + public void shouldNotRenderHead(ItemRenderer instance, EntityLivingBase entitylivingbaseIn, ItemStack itemstack, + ItemCameraTransforms.TransformType transformType, Operation original) { + if (gregTechCEu$shouldNotRenderHeadItem(entitylivingbaseIn)) { + return; + } + original.call(instance, entitylivingbaseIn, itemstack, transformType); + } + + @Unique + private static boolean gregTechCEu$shouldNotRenderHeadItem(EntityLivingBase entityLivingBase) { + ItemStack itemStack = entityLivingBase.getItemStackFromSlot(EntityEquipmentSlot.HEAD); + return (itemStack.getItem() instanceof IArmorItem && + itemStack.getItem().getEquipmentSlot(itemStack) == EntityEquipmentSlot.HEAD); + } +} diff --git a/src/main/java/gregtech/mixins/minecraft/MinecraftMixin.java b/src/main/java/gregtech/mixins/minecraft/MinecraftMixin.java new file mode 100644 index 00000000000..31ada3545f0 --- /dev/null +++ b/src/main/java/gregtech/mixins/minecraft/MinecraftMixin.java @@ -0,0 +1,22 @@ +package gregtech.mixins.minecraft; + +import net.minecraft.client.Minecraft; +import net.minecraft.util.text.TextComponentTranslation; + +import org.lwjgl.input.Keyboard; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(Minecraft.class) +public class MinecraftMixin { + + @Inject(method = "processKeyF3", at = @At("HEAD")) + public void addGregTechDebugMessage(int auxKey, CallbackInfoReturnable cir) { + if (auxKey == Keyboard.KEY_H && !Minecraft.getMinecraft().gameSettings.advancedItemTooltips) { + Minecraft.getMinecraft().ingameGUI.getChatGUI() + .printChatMessage(new TextComponentTranslation("gregtech.debug.f3_h.enabled")); + } + } +} diff --git a/src/main/java/gregtech/mixins/minecraft/RecipeRepairItemMixin.java b/src/main/java/gregtech/mixins/minecraft/RecipeRepairItemMixin.java new file mode 100644 index 00000000000..5cd275b6cf8 --- /dev/null +++ b/src/main/java/gregtech/mixins/minecraft/RecipeRepairItemMixin.java @@ -0,0 +1,102 @@ +package gregtech.mixins.minecraft; + +import gregtech.api.items.toolitem.IGTTool; +import gregtech.api.items.toolitem.ToolHelper; + +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.RecipeRepairItem; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.NonNullList; +import net.minecraft.world.World; +import net.minecraftforge.common.ForgeHooks; +import net.minecraftforge.event.ForgeEventFactory; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Local; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.List; + +@Mixin(RecipeRepairItem.class) +public class RecipeRepairItemMixin { + + @Inject(method = "matches(Lnet/minecraft/inventory/InventoryCrafting;Lnet/minecraft/world/World;)Z", + at = @At(value = "INVOKE", + target = "Ljava/util/List;get(I)Ljava/lang/Object;", + shift = At.Shift.AFTER), + cancellable = true) + public void gregtechCEu$matches(InventoryCrafting inv, World worldIn, CallbackInfoReturnable cir, + @Local(ordinal = 0) ItemStack itemstack, @Local(ordinal = 0) List list) { + ItemStack itemstack1 = list.get(0); + if (itemstack.getItem() instanceof IGTTool first && + itemstack1.getItem() instanceof IGTTool second) { + if (first.isElectric() || second.isElectric()) { + cir.setReturnValue(false); + } else { + cir.setReturnValue(first.getToolMaterial(itemstack) == second.getToolMaterial(itemstack1)); + } + } + } + + @Inject(method = "getCraftingResult(Lnet/minecraft/inventory/InventoryCrafting;)Lnet/minecraft/item/ItemStack;", + at = @At(value = "INVOKE_ASSIGN", + target = "Ljava/util/List;get(I)Ljava/lang/Object;", + ordinal = 0, + shift = At.Shift.BY, + by = 2), + cancellable = true) + public void gregtechCEu$getCraftingResultFirst(InventoryCrafting inv, CallbackInfoReturnable cir, + @Local(ordinal = 0) ItemStack itemstack, + @Local(ordinal = 1) ItemStack itemstack1) { + if (itemstack.getItem() instanceof IGTTool tool && tool.isElectric()) { + cir.setReturnValue(ItemStack.EMPTY); + } else if (itemstack1.getItem() instanceof IGTTool tool && tool.isElectric()) { + cir.setReturnValue(ItemStack.EMPTY); + } + } + + /* + * @Inject(method = "getCraftingResult(Lnet/minecraft/inventory/InventoryCrafting;)Lnet/minecraft/item/ItemStack;", + * at = @At(value = "RETURN", ordinal = 1), + * cancellable = true) + */ + @ModifyReturnValue(method = "getCraftingResult", at = @At(value = "RETURN", ordinal = 1)) + public ItemStack gregtechCEu$getCraftingResultSecond(ItemStack originalResult, InventoryCrafting inv, + @Local(ordinal = 3) int itemDamage, + @Local(ordinal = 0) ItemStack itemstack2, + @Local(ordinal = 1) ItemStack itemstack3) { + if (itemstack2.getItem() instanceof IGTTool first && itemstack3.getItem() instanceof IGTTool) { + // do not allow repairing tools if both are full durability + if (itemstack2.getItemDamage() == 0 && itemstack3.getItemDamage() == 0) { + return ItemStack.EMPTY; + } else { + ItemStack output = first.get(first.getToolMaterial(itemstack2)); + NBTTagCompound outputTag = ToolHelper.getToolTag(output); + outputTag.setInteger(ToolHelper.DURABILITY_KEY, itemDamage); + return output; + } + } + + return originalResult; + } + + @WrapOperation(method = "getRemainingItems", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/util/NonNullList;set(ILjava/lang/Object;)Ljava/lang/Object;")) + public Object gregtechCEU$getRemainingItemsWrap(NonNullList instance, int index, Object newValue, + Operation original, + @Local(ordinal = 0) ItemStack itemStack) { + if (itemStack.getItem() instanceof IGTTool) { + ForgeEventFactory.onPlayerDestroyItem(ForgeHooks.getCraftingPlayer(), itemStack, null); + return instance.get(index); + } else { + return instance.set(index, newValue); + } + } +} diff --git a/src/main/java/gregtech/mixins/minecraft/RegionRenderCacheBuilderMixin.java b/src/main/java/gregtech/mixins/minecraft/RegionRenderCacheBuilderMixin.java new file mode 100644 index 00000000000..52b73576d86 --- /dev/null +++ b/src/main/java/gregtech/mixins/minecraft/RegionRenderCacheBuilderMixin.java @@ -0,0 +1,26 @@ +package gregtech.mixins.minecraft; + +import gregtech.client.utils.BloomEffectUtil; + +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.RegionRenderCacheBuilder; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(RegionRenderCacheBuilder.class) +public class RegionRenderCacheBuilderMixin { + + @Final + @Shadow + private BufferBuilder[] worldRenderers; + + @Inject(method = "", at = @At("TAIL")) + public void initBloom(CallbackInfo ci) { + worldRenderers[BloomEffectUtil.getBloomLayer().ordinal()] = new BufferBuilder(131072); + } +} diff --git a/src/main/java/gregtech/mixins/minecraft/RenderChunkMixin.java b/src/main/java/gregtech/mixins/minecraft/RenderChunkMixin.java new file mode 100644 index 00000000000..5c18f5ad4ea --- /dev/null +++ b/src/main/java/gregtech/mixins/minecraft/RenderChunkMixin.java @@ -0,0 +1,30 @@ +package gregtech.mixins.minecraft; + +import gregtech.api.metatileentity.MetaTileEntityHolder; + +import net.minecraft.client.renderer.chunk.RenderChunk; +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.tileentity.TileEntity; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(RenderChunk.class) +public class RenderChunkMixin { + + @WrapOperation(method = "rebuildChunk", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher;getRenderer(Lnet/minecraft/tileentity/TileEntity;)Lnet/minecraft/client/renderer/tileentity/TileEntitySpecialRenderer;")) + public TileEntitySpecialRenderer adjustMTERenderer(TileEntityRendererDispatcher original, + TileEntity tileentity, + Operation> originalRenderer) { + // TODO, adjust when implementing second part of IGregTileEntity + if (tileentity instanceof MetaTileEntityHolder && !((MetaTileEntityHolder) tileentity).hasTESR()) { + return null; + } + return originalRenderer.call(original, tileentity); + } +} diff --git a/src/main/java/gregtech/mixins/minecraft/RenderGlobalMixin.java b/src/main/java/gregtech/mixins/minecraft/RenderGlobalMixin.java new file mode 100644 index 00000000000..1a12dcb82d0 --- /dev/null +++ b/src/main/java/gregtech/mixins/minecraft/RenderGlobalMixin.java @@ -0,0 +1,50 @@ +package gregtech.mixins.minecraft; + +import gregtech.api.items.metaitem.MetaItem; +import gregtech.api.items.metaitem.MusicDiscStats; +import gregtech.api.items.metaitem.stats.IItemBehaviour; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.WorldClient; +import net.minecraft.client.renderer.RenderGlobal; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.math.BlockPos; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(RenderGlobal.class) +public class RenderGlobalMixin { + + @Shadow + private WorldClient world; + + @Final + @Shadow + private Minecraft mc; + + @Inject(method = "playEvent", at = @At("HEAD"), cancellable = true) + public void playMusicDisc(EntityPlayer player, int type, BlockPos blockPosIn, int data, CallbackInfo ci) { + if (type == MusicDiscStats.SOUND_TYPE) { + for (MetaItem metaItem : MetaItem.getMetaItems()) { + MetaItem.MetaValueItem valueItem = metaItem.getItem((short) data); + if (valueItem != null) { + for (IItemBehaviour behavior : valueItem.getBehaviours()) { + if (behavior instanceof MusicDiscStats musicBehavior) { + world.playRecord(blockPosIn, musicBehavior.getSound()); + this.mc.ingameGUI.setRecordPlayingMessage(I18n.format(musicBehavior.getName())); + ci.cancel(); + return; + } + } + + } + } + } + } +} diff --git a/src/main/java/gregtech/mixins/minecraft/RenderItemMixin.java b/src/main/java/gregtech/mixins/minecraft/RenderItemMixin.java new file mode 100644 index 00000000000..5bbea635153 --- /dev/null +++ b/src/main/java/gregtech/mixins/minecraft/RenderItemMixin.java @@ -0,0 +1,38 @@ +package gregtech.mixins.minecraft; + +import gregtech.api.util.Mods; +import gregtech.asm.hooks.RenderItemHooks; + +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.RenderItem; +import net.minecraft.item.ItemStack; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(RenderItem.class) +public class RenderItemMixin { + + // The easy part of translating the item render stuff + @Inject(method = "renderItemOverlayIntoGUI", at = @At(value = "HEAD")) + private void renderItemOverlayIntoGUIInject(FontRenderer fr, ItemStack stack, int xPosition, int yPosition, + String text, CallbackInfo ci) { + if (!stack.isEmpty()) { + RenderItemHooks.renderLampOverlay(stack, xPosition, yPosition); + } + } + + @Inject(method = "renderItemOverlayIntoGUI", + at = @At(value = "INVOKE_ASSIGN", + target = "Lnet/minecraft/client/Minecraft;getMinecraft()Lnet/minecraft/client/Minecraft;", + shift = At.Shift.BEFORE, + ordinal = 0)) + public void showDurabilityBarMixin(FontRenderer fr, ItemStack stack, int xPosition, int yPosition, String text, + CallbackInfo ci) { + if (!Mods.EnderCore.isModLoaded()) { + RenderItemHooks.renderElectricBar(stack, xPosition, yPosition); + } + } +} diff --git a/src/main/java/gregtech/mixins/theoneprobe/TheOneProbeMixin.java b/src/main/java/gregtech/mixins/theoneprobe/TheOneProbeMixin.java new file mode 100644 index 00000000000..7f92a7526cd --- /dev/null +++ b/src/main/java/gregtech/mixins/theoneprobe/TheOneProbeMixin.java @@ -0,0 +1,40 @@ +package gregtech.mixins.theoneprobe; + +import gregtech.api.block.machines.BlockMachine; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import mcjty.theoneprobe.api.ProbeMode; +import mcjty.theoneprobe.network.PacketGetInfo; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +/** + * Makes TheOneProbe call {@link IBlockState#getActualState(IBlockAccess, BlockPos)} when + * looking at GT machines to show the correct harvest tool and level + */ +@Mixin(PacketGetInfo.class) +@SuppressWarnings("deprecation") +public class TheOneProbeMixin { + + @ModifyExpressionValue(method = "getProbeInfo", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/world/World;getBlockState(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/state/IBlockState;")) + private static IBlockState getActualState(IBlockState originalState, EntityPlayer player, ProbeMode mode, + World world, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, + ItemStack pickBlock) { + IBlockState modifiedState = world.getBlockState(blockPos); + if (modifiedState.getBlock() instanceof BlockMachine) { + return modifiedState.getBlock().getActualState(modifiedState, world, blockPos); + } + return originalState; + } +} diff --git a/src/main/java/gregtech/mixins/vintagium/BlockRenderManagerMixin.java b/src/main/java/gregtech/mixins/vintagium/BlockRenderManagerMixin.java new file mode 100644 index 00000000000..9c97a40b7fd --- /dev/null +++ b/src/main/java/gregtech/mixins/vintagium/BlockRenderManagerMixin.java @@ -0,0 +1,32 @@ +package gregtech.mixins.vintagium; + +import gregtech.client.utils.BloomEffectUtil; +import gregtech.client.utils.BloomEffectVintagiumUtil; + +import net.minecraft.util.BlockRenderLayer; + +import com.llamalad7.mixinextras.sugar.Local; +import me.jellysquid.mods.sodium.client.render.chunk.passes.BlockRenderPass; +import me.jellysquid.mods.sodium.client.render.chunk.passes.BlockRenderPassManager; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(BlockRenderPassManager.class) +public abstract class BlockRenderManagerMixin { + + @Shadow(remap = false) + protected abstract void addMapping(BlockRenderLayer layer, BlockRenderPass type); + + @SuppressWarnings("UnresolvedMixinReference") + @Inject(method = "createDefaultMappings", + at = @At(value = "RETURN"), + remap = false) + private static void gregtech$addMapping(CallbackInfoReturnable cir, + @Local BlockRenderPassManager mapper) { + ((BlockRenderManagerMixin) (Object) mapper).addMapping(BloomEffectUtil.getBloomLayer(), + BloomEffectVintagiumUtil.getBloomPass()); + } +} diff --git a/src/main/java/gregtech/mixins/vintagium/BlockRenderPassMixin.java b/src/main/java/gregtech/mixins/vintagium/BlockRenderPassMixin.java new file mode 100644 index 00000000000..5544bd8069e --- /dev/null +++ b/src/main/java/gregtech/mixins/vintagium/BlockRenderPassMixin.java @@ -0,0 +1,47 @@ +package gregtech.mixins.vintagium; + +import gregtech.client.utils.BloomEffectUtil; +import gregtech.client.utils.BloomEffectVintagiumUtil; + +import net.minecraft.util.BlockRenderLayer; +import net.minecraftforge.common.util.EnumHelper; + +import me.jellysquid.mods.sodium.client.render.chunk.passes.BlockRenderPass; +import me.jellysquid.mods.sodium.client.util.BufferSizeUtil; +import me.jellysquid.mods.sodium.client.util.EnumUtil; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(BlockRenderPass.class) +public abstract class BlockRenderPassMixin { + + @Final + @Mutable + @Shadow(remap = false) + public static BlockRenderPass[] VALUES; + + @Final + @Mutable + @Shadow(remap = false) + public static int COUNT; + + @SuppressWarnings("UnresolvedMixinReference") + @Inject(method = "", + at = @At(value = "TAIL"), + remap = false) + private static void init(CallbackInfo ci) { + EnumUtil.LAYERS = BlockRenderLayer.values(); + BufferSizeUtil.BUFFER_SIZES.put(BloomEffectUtil.getBloomLayer(), 131072); + + var params = new Class[] { BlockRenderLayer.class, boolean.class }; + var values = new Object[] { BloomEffectUtil.getBloomLayer(), true }; + BloomEffectVintagiumUtil.bloom = EnumHelper.addEnum(BlockRenderPass.class, "BLOOM", params, values); + VALUES = BlockRenderPass.values(); + COUNT = VALUES.length; + } +} diff --git a/src/main/resources/assets/gregtech/advancements/extreme_voltage/51_large_combustion_engine.json b/src/main/resources/assets/gregtech/advancements/extreme_voltage/51_large_combustion_engine.json index f3a253f5a4b..5f0346665f6 100644 --- a/src/main/resources/assets/gregtech/advancements/extreme_voltage/51_large_combustion_engine.json +++ b/src/main/resources/assets/gregtech/advancements/extreme_voltage/51_large_combustion_engine.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.extreme_voltage.51_large_combustion_engine.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1007 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1007 } ] diff --git a/src/main/resources/assets/gregtech/advancements/high_voltage/41_vacuum_freezer.json b/src/main/resources/assets/gregtech/advancements/high_voltage/41_vacuum_freezer.json index b0fba61e8b5..734a6d1db2a 100644 --- a/src/main/resources/assets/gregtech/advancements/high_voltage/41_vacuum_freezer.json +++ b/src/main/resources/assets/gregtech/advancements/high_voltage/41_vacuum_freezer.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.high_voltage.41_vacuum_freezer.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1002 }, "frame": "challenge" @@ -18,7 +18,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1002 } ] diff --git a/src/main/resources/assets/gregtech/advancements/high_voltage/43_multi_smelter.json b/src/main/resources/assets/gregtech/advancements/high_voltage/43_multi_smelter.json index f8ff7f93c6c..389e2f87777 100644 --- a/src/main/resources/assets/gregtech/advancements/high_voltage/43_multi_smelter.json +++ b/src/main/resources/assets/gregtech/advancements/high_voltage/43_multi_smelter.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.high_voltage.43_multi_smelter.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1006 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1006 } ] diff --git a/src/main/resources/assets/gregtech/advancements/high_voltage/44_distillation_tower.json b/src/main/resources/assets/gregtech/advancements/high_voltage/44_distillation_tower.json index 36cdf28edab..ef5fed04fb9 100644 --- a/src/main/resources/assets/gregtech/advancements/high_voltage/44_distillation_tower.json +++ b/src/main/resources/assets/gregtech/advancements/high_voltage/44_distillation_tower.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.high_voltage.44_distillation_tower.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1005 }, "frame": "challenge" @@ -18,7 +18,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1005 } ] diff --git a/src/main/resources/assets/gregtech/advancements/high_voltage/45_large_steam_turbine.json b/src/main/resources/assets/gregtech/advancements/high_voltage/45_large_steam_turbine.json index 245b45831d3..a92f91320e4 100644 --- a/src/main/resources/assets/gregtech/advancements/high_voltage/45_large_steam_turbine.json +++ b/src/main/resources/assets/gregtech/advancements/high_voltage/45_large_steam_turbine.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.high_voltage.45_large_steam_turbine.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1010 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1010 } ] diff --git a/src/main/resources/assets/gregtech/advancements/high_voltage/46_hv_macerator.json b/src/main/resources/assets/gregtech/advancements/high_voltage/46_hv_macerator.json index 08eca658c7d..7834f6aa043 100644 --- a/src/main/resources/assets/gregtech/advancements/high_voltage/46_hv_macerator.json +++ b/src/main/resources/assets/gregtech/advancements/high_voltage/46_hv_macerator.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.high_voltage.46_hv_macerator.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 67 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 67 } ] diff --git a/src/main/resources/assets/gregtech/advancements/high_voltage/82_large_chemical_reactor.json b/src/main/resources/assets/gregtech/advancements/high_voltage/82_large_chemical_reactor.json index f387315a3cf..8e53d0a213c 100644 --- a/src/main/resources/assets/gregtech/advancements/high_voltage/82_large_chemical_reactor.json +++ b/src/main/resources/assets/gregtech/advancements/high_voltage/82_large_chemical_reactor.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.high_voltage.82_large_chemical_reactor.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1023 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1023 } ] diff --git a/src/main/resources/assets/gregtech/advancements/insane_voltage/root_iv.json b/src/main/resources/assets/gregtech/advancements/insane_voltage/root_iv.json index 5e01b0942b8..b8725682f0f 100644 --- a/src/main/resources/assets/gregtech/advancements/insane_voltage/root_iv.json +++ b/src/main/resources/assets/gregtech/advancements/insane_voltage/root_iv.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.root_iv.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1015 }, "background": "gregtech:textures/blocks/casings/solid/machine_casing_robust_tungstensteel.png" diff --git a/src/main/resources/assets/gregtech/advancements/low_voltage/19_lv_pump_block.json b/src/main/resources/assets/gregtech/advancements/low_voltage/19_lv_pump_block.json index d1755a9b9a1..227ccc3ddff 100644 --- a/src/main/resources/assets/gregtech/advancements/low_voltage/19_lv_pump_block.json +++ b/src/main/resources/assets/gregtech/advancements/low_voltage/19_lv_pump_block.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.low_voltage.19_lv_pump_block.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1530 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1530 } ] diff --git a/src/main/resources/assets/gregtech/advancements/low_voltage/23_lv_assembler.json b/src/main/resources/assets/gregtech/advancements/low_voltage/23_lv_assembler.json index 8da7dbe4d66..70443cc216b 100644 --- a/src/main/resources/assets/gregtech/advancements/low_voltage/23_lv_assembler.json +++ b/src/main/resources/assets/gregtech/advancements/low_voltage/23_lv_assembler.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.low_voltage.23_lv_assembler.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 110 }, "frame": "goal" @@ -18,7 +18,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 110 } ] diff --git a/src/main/resources/assets/gregtech/advancements/low_voltage/25_large_boiler.json b/src/main/resources/assets/gregtech/advancements/low_voltage/25_large_boiler.json index f44ba3ddaaa..8e042d8f5fa 100644 --- a/src/main/resources/assets/gregtech/advancements/low_voltage/25_large_boiler.json +++ b/src/main/resources/assets/gregtech/advancements/low_voltage/25_large_boiler.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.low_voltage.25_large_boiler.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1013 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1013 } ] diff --git a/src/main/resources/assets/gregtech/advancements/low_voltage/26_arc_furnace.json b/src/main/resources/assets/gregtech/advancements/low_voltage/26_arc_furnace.json index e5818422b79..2a1f0de1729 100644 --- a/src/main/resources/assets/gregtech/advancements/low_voltage/26_arc_furnace.json +++ b/src/main/resources/assets/gregtech/advancements/low_voltage/26_arc_furnace.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.low_voltage.26_arc_furnace.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 95 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 95 } ] diff --git a/src/main/resources/assets/gregtech/advancements/low_voltage/27_electric_blast_furnace.json b/src/main/resources/assets/gregtech/advancements/low_voltage/27_electric_blast_furnace.json index 791e9bb9d4f..255783772a0 100644 --- a/src/main/resources/assets/gregtech/advancements/low_voltage/27_electric_blast_furnace.json +++ b/src/main/resources/assets/gregtech/advancements/low_voltage/27_electric_blast_furnace.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.low_voltage.27_electric_blast_furnace.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1001 }, "frame": "challenge" @@ -18,7 +18,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1001 } ] diff --git a/src/main/resources/assets/gregtech/advancements/low_voltage/28_lv_energy_hatch.json b/src/main/resources/assets/gregtech/advancements/low_voltage/28_lv_energy_hatch.json index 1377f0e61c7..25857905ea7 100644 --- a/src/main/resources/assets/gregtech/advancements/low_voltage/28_lv_energy_hatch.json +++ b/src/main/resources/assets/gregtech/advancements/low_voltage/28_lv_energy_hatch.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.low_voltage.28_lv_energy_hatch.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1211 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1211 } ] diff --git a/src/main/resources/assets/gregtech/advancements/low_voltage/29_lv_battery_buffer.json b/src/main/resources/assets/gregtech/advancements/low_voltage/29_lv_battery_buffer.json index f604815f2b0..9900679ba74 100644 --- a/src/main/resources/assets/gregtech/advancements/low_voltage/29_lv_battery_buffer.json +++ b/src/main/resources/assets/gregtech/advancements/low_voltage/29_lv_battery_buffer.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.low_voltage.29_lv_battery_buffer.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1316 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1316 } ] diff --git a/src/main/resources/assets/gregtech/advancements/low_voltage/root_lv.json b/src/main/resources/assets/gregtech/advancements/low_voltage/root_lv.json index 2524c250234..5d8ef9447c9 100644 --- a/src/main/resources/assets/gregtech/advancements/low_voltage/root_lv.json +++ b/src/main/resources/assets/gregtech/advancements/low_voltage/root_lv.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.root_lv.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 950 }, "frame": "challenge", @@ -19,7 +19,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 950 } ] diff --git a/src/main/resources/assets/gregtech/advancements/ludicrous_voltage/60_fusion.json b/src/main/resources/assets/gregtech/advancements/ludicrous_voltage/60_fusion.json index 8a950a8f15e..886ac01e731 100644 --- a/src/main/resources/assets/gregtech/advancements/ludicrous_voltage/60_fusion.json +++ b/src/main/resources/assets/gregtech/advancements/ludicrous_voltage/60_fusion.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.ludicrous_voltage.60_fusion.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1020 }, "frame": "challenge" @@ -18,7 +18,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1020 } ] diff --git a/src/main/resources/assets/gregtech/advancements/ludicrous_voltage/68_large_plasma_turbine.json b/src/main/resources/assets/gregtech/advancements/ludicrous_voltage/68_large_plasma_turbine.json index 2103805ed0e..6db740f9fc6 100644 --- a/src/main/resources/assets/gregtech/advancements/ludicrous_voltage/68_large_plasma_turbine.json +++ b/src/main/resources/assets/gregtech/advancements/ludicrous_voltage/68_large_plasma_turbine.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.ludicrous_voltage.68_large_plasma_turbine.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1012 }, "frame": "goal" @@ -18,7 +18,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1012 } ] diff --git a/src/main/resources/assets/gregtech/advancements/ludicrous_voltage/root_luv.json b/src/main/resources/assets/gregtech/advancements/ludicrous_voltage/root_luv.json index b3ec8120e54..41cfa45a35a 100644 --- a/src/main/resources/assets/gregtech/advancements/ludicrous_voltage/root_luv.json +++ b/src/main/resources/assets/gregtech/advancements/ludicrous_voltage/root_luv.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.root_luv.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1019 }, "frame": "challenge", @@ -19,7 +19,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1019 } ] diff --git a/src/main/resources/assets/gregtech/advancements/medium_voltage/31_mv_energy_hatch.json b/src/main/resources/assets/gregtech/advancements/medium_voltage/31_mv_energy_hatch.json index 2bbcaf835d3..7959365598c 100644 --- a/src/main/resources/assets/gregtech/advancements/medium_voltage/31_mv_energy_hatch.json +++ b/src/main/resources/assets/gregtech/advancements/medium_voltage/31_mv_energy_hatch.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.medium_voltage.31_mv_energy_hatch.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1212 }, "frame": "goal" @@ -18,7 +18,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1212 } ] diff --git a/src/main/resources/assets/gregtech/advancements/medium_voltage/38_super_chest.json b/src/main/resources/assets/gregtech/advancements/medium_voltage/38_super_chest.json index 89ad55894c2..db440e0ef57 100644 --- a/src/main/resources/assets/gregtech/advancements/medium_voltage/38_super_chest.json +++ b/src/main/resources/assets/gregtech/advancements/medium_voltage/38_super_chest.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.medium_voltage.38_super_chest.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1560 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1560 } ] diff --git a/src/main/resources/assets/gregtech/advancements/medium_voltage/39_super_tank.json b/src/main/resources/assets/gregtech/advancements/medium_voltage/39_super_tank.json index f8e2bf26fc2..fba6919d754 100644 --- a/src/main/resources/assets/gregtech/advancements/medium_voltage/39_super_tank.json +++ b/src/main/resources/assets/gregtech/advancements/medium_voltage/39_super_tank.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.medium_voltage.39_super_tank.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1575 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1575 } ] diff --git a/src/main/resources/assets/gregtech/advancements/medium_voltage/root_mv.json b/src/main/resources/assets/gregtech/advancements/medium_voltage/root_mv.json index 975445f38d6..b2c7d2fc3cf 100644 --- a/src/main/resources/assets/gregtech/advancements/medium_voltage/root_mv.json +++ b/src/main/resources/assets/gregtech/advancements/medium_voltage/root_mv.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.root_mv.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1001 }, "frame": "goal", diff --git a/src/main/resources/assets/gregtech/advancements/steam/16_steel_boiler.json b/src/main/resources/assets/gregtech/advancements/steam/16_steel_boiler.json index ea0d8fe3568..623a7c5598a 100644 --- a/src/main/resources/assets/gregtech/advancements/steam/16_steel_boiler.json +++ b/src/main/resources/assets/gregtech/advancements/steam/16_steel_boiler.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.steam.16_steel_boiler.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 2 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 2 } ] diff --git a/src/main/resources/assets/gregtech/advancements/steam/4_bronze_boiler.json b/src/main/resources/assets/gregtech/advancements/steam/4_bronze_boiler.json index 11b0681994e..41b0ade9f05 100644 --- a/src/main/resources/assets/gregtech/advancements/steam/4_bronze_boiler.json +++ b/src/main/resources/assets/gregtech/advancements/steam/4_bronze_boiler.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.steam.4_bronze_boiler.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1 }, "frame": "goal" @@ -18,7 +18,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1 } ] diff --git a/src/main/resources/assets/gregtech/advancements/steam/5_bronze_forge_hammer.json b/src/main/resources/assets/gregtech/advancements/steam/5_bronze_forge_hammer.json index 16ca5173cf8..0b918d24ef0 100644 --- a/src/main/resources/assets/gregtech/advancements/steam/5_bronze_forge_hammer.json +++ b/src/main/resources/assets/gregtech/advancements/steam/5_bronze_forge_hammer.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.steam.5_bronze_forge_hammer.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 13 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 13 } ] diff --git a/src/main/resources/assets/gregtech/advancements/steam/6_bronze_alloy_smelter.json b/src/main/resources/assets/gregtech/advancements/steam/6_bronze_alloy_smelter.json index fde3406c076..f0bfdcc3ae1 100644 --- a/src/main/resources/assets/gregtech/advancements/steam/6_bronze_alloy_smelter.json +++ b/src/main/resources/assets/gregtech/advancements/steam/6_bronze_alloy_smelter.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.steam.6_bronze_alloy_smelter.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 17 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 17 } ] diff --git a/src/main/resources/assets/gregtech/advancements/steam/7_bronze_extractor.json b/src/main/resources/assets/gregtech/advancements/steam/7_bronze_extractor.json index 23a6cc1aafd..c5be88cda8a 100644 --- a/src/main/resources/assets/gregtech/advancements/steam/7_bronze_extractor.json +++ b/src/main/resources/assets/gregtech/advancements/steam/7_bronze_extractor.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.steam.7_bronze_extractor.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 7 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 7 } ] diff --git a/src/main/resources/assets/gregtech/advancements/steam/81_crafting_station.json b/src/main/resources/assets/gregtech/advancements/steam/81_crafting_station.json index 49f60243cc5..fd6be7b3d53 100644 --- a/src/main/resources/assets/gregtech/advancements/steam/81_crafting_station.json +++ b/src/main/resources/assets/gregtech/advancements/steam/81_crafting_station.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.steam.81_crafting_station.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1647 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1647 } ] diff --git a/src/main/resources/assets/gregtech/advancements/steam/83_hp_solar_boiler.json b/src/main/resources/assets/gregtech/advancements/steam/83_hp_solar_boiler.json index 9a20f7a7345..a5add911587 100644 --- a/src/main/resources/assets/gregtech/advancements/steam/83_hp_solar_boiler.json +++ b/src/main/resources/assets/gregtech/advancements/steam/83_hp_solar_boiler.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.steam.83_hp_solar_boiler.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 4 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 4 } ] diff --git a/src/main/resources/assets/gregtech/advancements/steam/8_bronze_solar_boiler.json b/src/main/resources/assets/gregtech/advancements/steam/8_bronze_solar_boiler.json index d02a561d17c..b3bb4bbabc3 100644 --- a/src/main/resources/assets/gregtech/advancements/steam/8_bronze_solar_boiler.json +++ b/src/main/resources/assets/gregtech/advancements/steam/8_bronze_solar_boiler.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.steam.8_bronze_solar_boiler.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 3 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 3 } ] diff --git a/src/main/resources/assets/gregtech/advancements/steam/90_primitive_pump.json b/src/main/resources/assets/gregtech/advancements/steam/90_primitive_pump.json index 43d8965ae95..eb33f333c3c 100644 --- a/src/main/resources/assets/gregtech/advancements/steam/90_primitive_pump.json +++ b/src/main/resources/assets/gregtech/advancements/steam/90_primitive_pump.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.steam.90_primitive_pump.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1648 }, "frame": "goal" @@ -18,7 +18,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1648 } ] diff --git a/src/main/resources/assets/gregtech/advancements/steam/91_primitive_blast_furnace.json b/src/main/resources/assets/gregtech/advancements/steam/91_primitive_blast_furnace.json index dd449df67a0..25a6dbe84f0 100644 --- a/src/main/resources/assets/gregtech/advancements/steam/91_primitive_blast_furnace.json +++ b/src/main/resources/assets/gregtech/advancements/steam/91_primitive_blast_furnace.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.steam.91_primitive_blast_furnace.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1000 }, "frame": "goal" @@ -18,7 +18,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1000 } ] diff --git a/src/main/resources/assets/gregtech/advancements/steam/9_coke_oven.json b/src/main/resources/assets/gregtech/advancements/steam/9_coke_oven.json index ad009e02e0f..f49bb1b136b 100644 --- a/src/main/resources/assets/gregtech/advancements/steam/9_coke_oven.json +++ b/src/main/resources/assets/gregtech/advancements/steam/9_coke_oven.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.steam.9_coke_oven.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1017 }, "frame": "goal" @@ -18,7 +18,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1017 } ] diff --git a/src/main/resources/assets/gregtech/advancements/ultimate_voltage/75_fusion_reactor_3.json b/src/main/resources/assets/gregtech/advancements/ultimate_voltage/75_fusion_reactor_3.json index 89f83660049..bcde504d605 100644 --- a/src/main/resources/assets/gregtech/advancements/ultimate_voltage/75_fusion_reactor_3.json +++ b/src/main/resources/assets/gregtech/advancements/ultimate_voltage/75_fusion_reactor_3.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.ultimate_voltage.75_fusion_reactor_3.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1022 }, "frame": "challenge" @@ -18,7 +18,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1022 } ] diff --git a/src/main/resources/assets/gregtech/advancements/zero_point_module/80_hpca.json b/src/main/resources/assets/gregtech/advancements/zero_point_module/80_hpca.json index 84377c7a6e1..7f01b06ba52 100644 --- a/src/main/resources/assets/gregtech/advancements/zero_point_module/80_hpca.json +++ b/src/main/resources/assets/gregtech/advancements/zero_point_module/80_hpca.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.zero_point_module.80_hpca.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1039 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1039 } ] diff --git a/src/main/resources/assets/gregtech/advancements/zero_point_module/81_research_station.json b/src/main/resources/assets/gregtech/advancements/zero_point_module/81_research_station.json index b2e5e093157..9016117fb7f 100644 --- a/src/main/resources/assets/gregtech/advancements/zero_point_module/81_research_station.json +++ b/src/main/resources/assets/gregtech/advancements/zero_point_module/81_research_station.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.zero_point_module.81_research_station.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1038 } }, @@ -17,7 +17,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1038 } ] diff --git a/src/main/resources/assets/gregtech/advancements/zero_point_module/root_zpm.json b/src/main/resources/assets/gregtech/advancements/zero_point_module/root_zpm.json index ad8f47e1581..da44ac03c2d 100644 --- a/src/main/resources/assets/gregtech/advancements/zero_point_module/root_zpm.json +++ b/src/main/resources/assets/gregtech/advancements/zero_point_module/root_zpm.json @@ -7,7 +7,7 @@ "translate": "gregtech.advancement.root_zpm.name" }, "icon": { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1021 }, "frame": "challenge", @@ -19,7 +19,7 @@ "conditions": { "items": [ { - "item": "gregtech:machine", + "item": "gregtech:mte", "data": 1021 } ] diff --git a/src/main/resources/assets/gregtech/blockstates/machine.json b/src/main/resources/assets/gregtech/blockstates/mte.json similarity index 100% rename from src/main/resources/assets/gregtech/blockstates/machine.json rename to src/main/resources/assets/gregtech/blockstates/mte.json diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 78cbaeb9f2d..8e9b4091db2 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -4831,6 +4831,7 @@ gregtech.multiblock.cleanroom.clean_status=Status: %s gregtech.multiblock.cleanroom.clean_state=Clean (%s%%) gregtech.multiblock.cleanroom.dirty_state=Contaminated (%s%%) gregtech.multiblock.cleanroom.warning_contaminated=Contaminated! +gregtech.multiblock.cleanroom.low_tier=Energy tier too low, minimum of %s! gregtech.machine.charcoal_pile.name=Charcoal Pile Igniter gregtech.machine.charcoal_pile.tooltip.1=Turns Logs into §aCharcoal§7 when §cignited§7. @@ -5431,6 +5432,8 @@ gregtech.gui.overclock.off=X gregtech.gui.sort=Sort gregtech.gui.fluid_auto_output.tooltip.enabled=Fluid Auto-Output Enabled gregtech.gui.fluid_auto_output.tooltip.disabled=Fluid Auto-Output Disabled +gregtech.gui.item_auto_input.tooltip.enabled=Item Auto-Input Enabled +gregtech.gui.item_auto_input.tooltip.disabled=Item Auto-Input Disabled gregtech.gui.item_auto_output.tooltip.enabled=Item Auto-Output Enabled gregtech.gui.item_auto_output.tooltip.disabled=Item Auto-Output Disabled gregtech.gui.item_auto_collapse.tooltip.enabled=Item Auto-Collapse Enabled @@ -6286,3 +6289,8 @@ gregtech.scanner.forestry.larvae=§oScanned Larvae gregtech.scanner.forestry.serum=§oScanned Serum gregtech.scanner.forestry.caterpillar=§oScanned Caterpillar gregtech.scanner.forestry.pollen=§oScanned Pollen + +# Mutation +gregtech.mutation.block_of=Block of %s + +record.sus=Leonz - Among Us Drip diff --git a/src/main/resources/assets/gregtech/lang/zh_cn.lang b/src/main/resources/assets/gregtech/lang/zh_cn.lang index 67437657210..1cc9087cde0 100644 --- a/src/main/resources/assets/gregtech/lang/zh_cn.lang +++ b/src/main/resources/assets/gregtech/lang/zh_cn.lang @@ -47,7 +47,7 @@ gregtech.machine.steam_hatch.name=蒸汽仓 gregtech.machine.steam.steam_hatch.tooltip=§e可接受流体:§f蒸汽 gregtech.machine.steam_import_bus.name=输入总线(蒸汽) gregtech.machine.steam_export_bus.name=输出总线(蒸汽) -gregtech.machine.steam_bus.tooltip=无法作用于非蒸汽驱动的多方块机器 +gregtech.machine.steam_bus.tooltip=无法作用于非蒸汽驱动的多方块结构 gregtech.machine.steam_oven.name=蒸汽熔炼炉 gregtech.multiblock.steam_oven.description=蒸汽时代的多方块熔炉。需要至少6块青铜机械方块成型。仅可使用输入/输出总线(蒸汽),并且只能用蒸汽仓供给蒸汽。蒸汽仓必须放置于结构底层,数量至多为一个。 gregtech.multiblock.require_steam_parts=需要蒸汽仓与输入/输出总线(蒸汽)! @@ -104,6 +104,21 @@ gregtech.top.ld_pipe_output=输出 gregtech.top.ld_pipe_input_endpoint=输入接口: gregtech.top.ld_pipe_output_endpoint=输出接口: +option.gregtech.block_ore=矿石 +option.gregtech.controllable=机器控制器 +option.gregtech.converter=能量转换器 +option.gregtech.diode=二极管 +option.gregtech.energy=能量容器 +option.gregtech.block_lamp=灯方块 +option.gregtech.maintenance=维护问题 +option.gregtech.multi_recipemap=机器模式 +option.gregtech.multiblock=多方块结构 +option.gregtech.primitive_pump=原始水泵 +option.gregtech.recipe_logic=配方 +option.gregtech.steam_boiler=蒸汽锅炉 +option.gregtech.transformer=变压器 +option.gregtech.workable=机器工作状态 + gregtech.waila.energy_stored=能量:%d EU / %d EU gregtech.waila.progress_idle=闲置 gregtech.waila.progress_tick=进度:%d t / %d t @@ -124,17 +139,17 @@ gregtech.multiblock.electric_blast_furnace.description=电力高炉(EBF)是 gregtech.multiblock.multi_furnace.description=工业熔炉是种用于一次性烧制大量物品的多方块结构。不同级别的线圈会提供速度增幅和能量效率增幅。每次运作的基础烧制数量为32,且可以使用高等级的线圈增加烧制数量。 gregtech.multiblock.large_boiler.description=大型锅炉是种使用水和能量源产生蒸汽的多方块结构。这里说的“能量源”通常是指固体燃料和高密度流体。不同等级的锅炉仅在蒸汽产量上有所差别。 gregtech.multiblock.large_turbine.description=大型涡轮是种使用蒸汽、燃气或等离子体转动涡轮转子来发电的多方块结构。转子效率和转子转速会影响能量的输出。 -gregtech.multiblock.assembly_line.description=装配线是台由5到16“片”相同的结构所组成的大型多方块机器。理论上讲,它就是个大号组装机,用以生产高级合成组件。 -gregtech.multiblock.fusion_reactor.luv.description=核聚变反应堆MK-I是台大型多方块机器,用于融合元素形成更重的元素。它仅可使用LuV,ZPM或UV等级的能源仓。每个能源仓可增加10MEU的能量缓存,最大能量缓存为160MEU。 -gregtech.multiblock.fusion_reactor.zpm.description=核聚变反应堆MK-II是台大型多方块机器,用于融合元素形成更重的元素。它仅可使用ZPM或UV等级的能源仓。每个能源仓可增加20MEU的能量缓存,最大能量缓存为320MEU。 -gregtech.multiblock.fusion_reactor.uv.description=核聚变反应堆MK-III是台大型多方块机器,用于融合元素形成更重的元素。它仅可使用UV等级的能源仓。每个能源仓可增加40MEU的能量缓存,最大能量缓存为640MEU。 +gregtech.multiblock.assembly_line.description=装配线是台由5到16“片”相同的结构所组成的大型多方块结构。理论上讲,它就是个大号组装机,用以生产高级合成组件。 +gregtech.multiblock.fusion_reactor.luv.description=核聚变反应堆MK-I是台大型多方块结构,用于融合元素形成更重的元素。它仅可使用LuV,ZPM或UV等级的能源仓。每个能源仓可增加10MEU的能量缓存,最大能量缓存为160MEU。 +gregtech.multiblock.fusion_reactor.zpm.description=核聚变反应堆MK-II是台大型多方块结构,用于融合元素形成更重的元素。它仅可使用ZPM或UV等级的能源仓。每个能源仓可增加20MEU的能量缓存,最大能量缓存为320MEU。 +gregtech.multiblock.fusion_reactor.uv.description=核聚变反应堆MK-III是台大型多方块结构,用于融合元素形成更重的元素。它仅可使用UV等级的能源仓。每个能源仓可增加40MEU的能量缓存,最大能量缓存为640MEU。 gregtech.multiblock.fusion_reactor.heat=热量:%s -gregtech.multiblock.large_chemical_reactor.description=大型化学反应釜能够以100%的能效进行化学反应。每次超频将使处理速度与能耗均提升4倍。该多方块机器需要在中心位置的聚四氟乙烯管道外壳旁放置一个白铜线圈方块。 -gregtech.multiblock.primitive_water_pump.description=原始水泵是台前蒸汽时代的多方块机器。它每秒收集一次水资源,基础收集量取决于其所处的生物群系。水泵输出仓以及ULV和LV的输出仓都可以使用,输出仓的等级越高,水资源收集量也会越多。收集量的公式为:生物群系系数*输出仓倍数。 +gregtech.multiblock.large_chemical_reactor.description=大型化学反应釜能够以100%的能效进行化学反应。每次超频将使处理速度与能耗均提升4倍。该多方块结构需要在中心位置的聚四氟乙烯管道外壳旁放置一个白铜线圈方块。 +gregtech.multiblock.primitive_water_pump.description=原始水泵是台前蒸汽时代的多方块结构。它每秒收集一次水资源,基础收集量取决于其所处的生物群系。水泵输出仓以及ULV和LV的输出仓都可以使用,输出仓的等级越高,水资源收集量也会越多。收集量的公式为:生物群系系数*输出仓倍数。 gregtech.multiblock.primitive_water_pump.extra1=生物群系系数:/n 海洋(Ocean)、河流(River):1000 L/s/n 沼泽(Swamp):800 L/s/n 丛林(Jungle):350 L/s/n 积雪的(Snowy):300 L/s/n 平原(Plains)、森林(Forest):250 L/s/n 针叶林(Taiga):175 L/s/n 沙滩(Beach):170 L/s/n 其他:100 L/s gregtech.multiblock.primitive_water_pump.extra2=输出仓倍数:/n水泵输出仓:1x/nULV输出仓:2x/nLV输出仓:4x -gregtech.multiblock.processing_array.description=处理阵列可将最多16个单方块机器集成在一个多方块机器中,以实现更高效的自动化。 -gregtech.multiblock.advanced_processing_array.description=处理阵列可将最多64个单方块机器集成在一个多方块机器中,以实现更高效的自动化。 +gregtech.multiblock.processing_array.description=处理阵列可将最多16个单方块机器集成在一个多方块结构中,以实现更高效的自动化。 +gregtech.multiblock.advanced_processing_array.description=处理阵列可将最多64个单方块机器集成在一个多方块结构中,以实现更高效的自动化。 item.invalid.name=无效物品 fluid.empty=空 @@ -822,6 +837,7 @@ metaitem.fluid_filter.name=流体过滤卡 metaitem.fluid_filter.tooltip=作§f覆盖板§7时过滤§f流体§7的输入/输出。/n可用于升级§f电动泵§7与§f流体校准器§7。 metaitem.smart_item_filter.name=智能物品过滤卡 metaitem.smart_item_filter.tooltip=作§f覆盖板§7时以§f机器的配方§7过滤§f物品§7的输入/输出。/n亦可为§f运送模块§7和§f机械臂§7提供此种过滤功能。 +behaviour.filter_ui_manager=§f右键点击§7以配置,§fShift+右键§7清除配置 metaitem.cover.controller.name=机器控制覆盖板 metaitem.cover.controller.tooltip=作§f覆盖板§7时可以§f开/关§7机器。 @@ -1178,7 +1194,9 @@ 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在表达式开头添加 §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.match_all=匹配所有:%s +cover.ore_dictionary_filter.case_sensitive=匹配大小写:%s 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 @@ -1189,8 +1207,8 @@ 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.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=匹配物品的所有矿词条目 @@ -1243,6 +1261,7 @@ cover.fluid_filter.mode.filter_drain=过滤输出 cover.fluid_filter.mode.filter_both=过滤两者 cover.item_filter.title=物品过滤 +cover.filter.mode.title=过滤模式 cover.filter.mode.filter_insert=过滤输入 cover.filter.mode.filter_extract=过滤输出 cover.filter.mode.filter_both=过滤两者 @@ -1250,9 +1269,11 @@ cover.item_filter.ignore_damage.enabled=无视损坏值 cover.item_filter.ignore_damage.disabled=匹配损坏值 cover.item_filter.ignore_nbt.enabled=忽略NBT cover.item_filter.ignore_nbt.disabled=匹配NBT +cover.item_filter.config_amount=向上或向下滚动鼠标滚轮以增加或减少数量。\nShift[§6x4§r],Ctrl[§ex16§r],Shift+Ctrl[§ax64§r]\n亦可通过右击或左击来增减数量。\nShift+左键以清除 cover.voiding.voiding_mode.void_any=销毁匹配 cover.voiding.voiding_mode.void_overflow=销毁溢出 +cover.voiding.voiding_mode=销毁模式 cover.voiding.voiding_mode.description=§e销毁匹配§r:匹配过滤规则即销毁。/n§e溢出销毁§r:匹配过滤规则即销毁超出设定数量的部分物品/流体。 cover.fluid.voiding.title=流体销毁设置 cover.fluid.voiding.advanced.title=进阶流体销毁设置 @@ -1273,13 +1294,18 @@ cover.smart_item_filter.filtering_mode.centrifuge=离心机 cover.smart_item_filter.filtering_mode.sifter=筛选机 cover.smart_item_filter.filtering_mode.description=为该智能覆盖板选择目标机器。/n它能够自动传输符合机器配方的物品。 +cover.generic.transfer_mode=传输模式 +cover.generic.manual_io=特殊I/O模式 +cover.generic.io=I/O模式 +cover.pump.mode=泵模式 cover.conveyor.title=传送带覆盖板设置(%s) cover.conveyor.transfer_rate=§7件物品/秒 cover.conveyor.mode.export=模式:过滤输出 cover.conveyor.mode.import=模式:过滤输入 -cover.conveyor.distribution.round_robin_enhanced=分配模式/n§b增强轮询调度§r/n§7将物品平分至所有的物品存储空间 -cover.conveyor.distribution.round_robin=分配模式/n§b轮询调度§r(次序式)/n§7尝试将物品平分至物品存储空间 -cover.conveyor.distribution.first_insert=分配模式/n§b最近优先§r/n§7将物品输入至所搜寻到的首个物品存储空间 +cover.conveyor.distribution.name=分配模式 +cover.conveyor.distribution.round_robin_enhanced=§b增强轮询调度§r\n§7将物品平分至所有的物品存储空间 +cover.conveyor.distribution.round_robin=§b轮询调度§r(次序式)\n§7尝试将物品平分至物品存储空间 +cover.conveyor.distribution.first_insert=§b最近优先§r\n§7将物品输入至所搜寻到的首个物品存储空间 cover.conveyor.blocks_input.enabled=若启用,覆盖板设置为将物品从存储空间输出至管道时将阻止物品从所在面输入。/n§a已启用 cover.conveyor.blocks_input.disabled=若启用,覆盖板设置为将物品从存储空间输出至管道时将阻止物品从所在面输入。/n§c已禁用 cover.universal.manual_import_export.mode.disabled=特殊I/O模式:禁用 @@ -1290,6 +1316,7 @@ cover.conveyor.item_filter.title=物品过滤 cover.conveyor.ore_dictionary.title=矿物词典 cover.conveyor.ore_dictionary.title2=(*可作通配符) cover.robotic_arm.title=机械臂设置(%s) +cover.robotic_arm.exact=§7物品 cover.robotic_arm.transfer_mode.transfer_any=任意传输 cover.robotic_arm.transfer_mode.transfer_exact=精确补给 cover.robotic_arm.transfer_mode.keep_exact=保持补给 @@ -1300,8 +1327,12 @@ cover.pump.transfer_rate=%s cover.pump.mode.export=模式:输出 cover.pump.mode.import=模式:输入 cover.pump.fluid_filter.title=流体过滤 -cover.bucket.mode.bucket=kL/s -cover.bucket.mode.milli_bucket=L/s +cover.bucket.mode.bucket=流体单位:kL +cover.bucket.mode.milli_bucket=流体单位: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=流体校准器设置(%s) cover.fluid_regulator.transfer_mode.description=§e任意传输§r - 在此模式下,覆盖板将尽可能传输一切符合过滤设置的流体。/n§e精确供应-在此模式下,覆盖板会将此按钮下方窗口中指定的流体按指定量打包传输。若流体量小于指定量,流体不会被传输。/n§e保持供应-在此模式下,覆盖板将在目标容器中保持指定数量的液体,低于保持量时传输相应量的流体。/n§7小提示:按住Shift/Crtl把增加或减少的数量乘以10/100。 cover.fluid_regulator.supply_exact=精确补给:%s @@ -1324,7 +1355,7 @@ cover.machine_controller.disable_with_redstone=接收红石信号时关闭 cover.ender_fluid_link.title=末影流体连接 cover.ender_fluid_link.iomode.enabled=已启用I/O cover.ender_fluid_link.iomode.disabled=已禁用I/O -cover.ender_fluid_link.private.tooltip.disabled=切换至私有储罐模式/n私有权归最初加装该覆盖板的玩家所有 +cover.ender_fluid_link.private.tooltip.disabled=切换至私有储罐模式\n私有权归最初加装该覆盖板的玩家所有 cover.ender_fluid_link.private.tooltip.enabled=切换至公共储罐模式 cover.ender_fluid_link.incomplete_hex=输入的颜色不正确!/n输入正确的八位十六进制颜色码方可应用/n此时关闭界面将导致丢失编辑内容! @@ -2400,9 +2431,9 @@ behavior.tricorder.machine_progress=处理进度/总计:%s / %s behavior.tricorder.energy_container_in=输入上限:%s(%s)EU,%s A behavior.tricorder.energy_container_out=输出上限:%s(%s)EU,%s A behavior.tricorder.energy_container_storage=电量:%s EU / %s EU -behavior.tricorder.bedrock_fluid.amount=流体蕴含量:%s %s - %s%% -behavior.tricorder.bedrock_fluid.amount_unknown=流体蕴含量:%s%% -behavior.tricorder.bedrock_fluid.nothing=流体蕴含量:§6无§r +behavior.tricorder.bedrock_fluid.amount=流体储量:%s %s - %s%% +behavior.tricorder.bedrock_fluid.amount_unknown=流体储量:%s%% +behavior.tricorder.bedrock_fluid.nothing=流体储量:§6无§r behavior.tricorder.eut_per_sec=最后一秒 %s EU/t behavior.tricorder.amp_per_sec=最后一秒 %s A behavior.tricorder.workable_progress=处理进度:%s s / %s s @@ -5100,13 +5131,13 @@ gregtech.machine.rotor_holder.zpm.name=§cZPM§r转子支架 gregtech.machine.rotor_holder.uv.name=§3UV§r转子支架 gregtech.machine.maintenance_hatch.name=维护仓 -gregtech.machine.maintenance_hatch.tooltip=用以对多方块机器进行维护 +gregtech.machine.maintenance_hatch.tooltip=用以对多方块结构进行维护 gregtech.machine.maintenance_hatch_configurable.name=可配置维护仓 gregtech.machine.maintenance_hatch_configurable.tooltip=更精细的维修多方块结构/n起手无需维护! gregtech.machine.maintenance_hatch_full_auto.name=自动维护仓 -gregtech.machine.maintenance_hatch_full_auto.tooltip=可以自动维修多方块机器 +gregtech.machine.maintenance_hatch_full_auto.tooltip=可以自动维修多方块结构 gregtech.machine.maintenance_hatch_cleanroom_auto.name=自动过滤维护仓 -gregtech.machine.maintenance_hatch_cleanroom_auto.tooltip.1=可以自动维修多方块机器,附带清洁功能! +gregtech.machine.maintenance_hatch_cleanroom_auto.tooltip.1=可以自动维修多方块结构,附带清洁功能! gregtech.machine.maintenance_hatch.cleanroom_auto.tooltip.2=清洁方式: gregtech.machine.maintenance_hatch_tool_slot.tooltip=所需工具处于物品栏时空手点击该槽位来进行维护 gregtech.machine.maintenance_hatch_tape_slot.tooltip=放入胶带以防止发生故障 @@ -5278,6 +5309,11 @@ 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自动拉取已禁用 +gregtech.machine.me.copy_paste.tooltip=左键点击闪存以复制设置,右键点击以应用 +gregtech.machine.me.import_copy_settings=已将设置保存到闪存 +gregtech.machine.me.import_paste_settings=已从闪存应用设置 +gregtech.machine.me.item_import.data_stick.name=§oME输入总线配置数据 +gregtech.machine.me.fluid_import.data_stick.name=§oME输入仓配置数据 # Universal tooltips gregtech.universal.tooltip.voltage_in=§a输入电压:§f%,d EU/t(%s§f) @@ -5337,6 +5373,7 @@ gregtech.recipe.temperature=温度:%,dK(%s) gregtech.recipe.explosive=爆炸物:%s gregtech.recipe.eu_to_start=启动耗能:%sEU gregtech.recipe.dimensions=维度:%s +gregtech.recipe.dimensions_blocked=禁用维度:%s gregtech.recipe.cleanroom=需要%s gregtech.recipe.cleanroom.display_name=超净间 gregtech.recipe.cleanroom_sterile.display_name=无菌超净间 @@ -5680,7 +5717,7 @@ gregtech.multiblock.power_substation.passive_drain=被动损失:%s 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.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秒 @@ -5946,7 +5983,7 @@ terminal.store.close=关闭 terminal.ar.open=开启AR -terminal.multiblock_ar.description=还记得§c自由扳手§r吗?不好意思,它和我们说拜拜了。但是问题不大,现在我们手里掌握着一种新兴的科技。这款应用程序能够协助你搭建多方块机器。 +terminal.multiblock_ar.description=还记得§c自由扳手§r吗?不好意思,它和我们说拜拜了。但是问题不大,现在我们手里掌握着一种新兴的科技。这款应用程序能够协助你搭建多方块结构。 terminal.multiblock_ar.tier.0=AR相机 terminal.multiblock_ar.tier.1=3D搭建器 terminal.multiblock_ar.unlock=升级后方可解锁该模式 diff --git a/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_front.png b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_front.png new file mode 100644 index 00000000000..71b4efec65b Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_front.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_front_active.png b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_front_active.png new file mode 100644 index 00000000000..9e46f30b5b1 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_front_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_front_active_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_front_active_emissive.png new file mode 100644 index 00000000000..fbc8babefdf Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_front_active_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_front_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_front_emissive.png new file mode 100644 index 00000000000..2673ecbc929 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_front_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_front_paused.png b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_front_paused.png new file mode 100644 index 00000000000..8f139ba6ab3 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_front_paused.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_front_paused_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/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/machines/circuit_assembler/overlay_front_paused_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_top.png b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_top.png new file mode 100644 index 00000000000..7e0ba95ed03 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_top.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_top_active.png b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_top_active.png new file mode 100644 index 00000000000..9c0b2e3454b Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_top_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_top_active_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_top_active_emissive.png new file mode 100644 index 00000000000..8ae471e1606 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_top_active_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_top_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_top_emissive.png new file mode 100644 index 00000000000..8ae471e1606 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/machines/circuit_assembler/overlay_top_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/large_turbine/rotor_spinning.png b/src/main/resources/assets/gregtech/textures/blocks/multiblock/large_turbine/rotor_spinning.png index aae8d966cb4..e520608908a 100644 Binary files a/src/main/resources/assets/gregtech/textures/blocks/multiblock/large_turbine/rotor_spinning.png and b/src/main/resources/assets/gregtech/textures/blocks/multiblock/large_turbine/rotor_spinning.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_in.png similarity index 100% rename from src/main/resources/assets/gregtech/textures/gui/overlay/manual_io_overlay.png rename to src/main/resources/assets/gregtech/textures/gui/overlay/manual_io_overlay_in.png diff --git a/src/main/resources/assets/gregtech/textures/gui/overlay/manual_io_overlay_out.png b/src/main/resources/assets/gregtech/textures/gui/overlay/manual_io_overlay_out.png new file mode 100644 index 00000000000..f1fcb854902 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/overlay/manual_io_overlay_out.png differ diff --git a/src/main/resources/mixins.gregtech.ccl.json b/src/main/resources/mixins.gregtech.ccl.json new file mode 100644 index 00000000000..696d44a7275 --- /dev/null +++ b/src/main/resources/mixins.gregtech.ccl.json @@ -0,0 +1,12 @@ +{ + "package" : "gregtech.mixins.ccl", + "refmap" : "mixins.gregtech.refmap.json", + "target" : "@env(DEFAULT)", + "minVersion" : "0.8", + "compatibilityLevel" : "JAVA_8", + "mixins" : [ + "CCLDescriptionMixin" + ], + "client" : [], + "server" : [] +} diff --git a/src/main/resources/mixins.gregtech.ctm.json b/src/main/resources/mixins.gregtech.ctm.json new file mode 100644 index 00000000000..7e46fde66ab --- /dev/null +++ b/src/main/resources/mixins.gregtech.ctm.json @@ -0,0 +1,13 @@ +{ + "package" : "gregtech.mixins.ctm", + "refmap" : "mixins.gregtech.refmap.json", + "target" : "@env(DEFAULT)", + "minVersion" : "0.8", + "compatibilityLevel" : "JAVA_8", + "mixins" : [ + "AbstractCTMBakedModelMixin", + "CTMRenderInLayerMixin" + ], + "client" : [], + "server" : [] +} diff --git a/src/main/resources/mixins.gregtech.forge.json b/src/main/resources/mixins.gregtech.forge.json new file mode 100644 index 00000000000..81605c0c9dc --- /dev/null +++ b/src/main/resources/mixins.gregtech.forge.json @@ -0,0 +1,13 @@ +{ + "package": "gregtech.mixins.forge", + "refmap": "mixins.gregtech.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins" : [ + "ModelLoaderRegistryMixin", + "SpecialArmorPropertiesMixin" + ], + "client": [], + "server": [] +} diff --git a/src/main/resources/mixins.gregtech.jei.json b/src/main/resources/mixins.gregtech.jei.json new file mode 100644 index 00000000000..2520843c7d6 --- /dev/null +++ b/src/main/resources/mixins.gregtech.jei.json @@ -0,0 +1,12 @@ +{ + "package" : "gregtech.mixins.jei", + "refmap" : "mixins.gregtech.refmap.json", + "target" : "@env(DEFAULT)", + "minVersion" : "0.8", + "compatibilityLevel" : "JAVA_8", + "mixins" : [ + "JEITooltipMixin" + ], + "client" : [], + "server" : [] +} diff --git a/src/main/resources/mixins.gregtech.littletiles.json b/src/main/resources/mixins.gregtech.littletiles.json new file mode 100644 index 00000000000..6671ea6d5b6 --- /dev/null +++ b/src/main/resources/mixins.gregtech.littletiles.json @@ -0,0 +1,12 @@ +{ + "package" : "gregtech.mixins.littletiles", + "refmap" : "mixins.gregtech.refmap.json", + "target" : "@env(DEFAULT)", + "minVersion" : "0.8", + "compatibilityLevel" : "JAVA_8", + "mixins" : [ + "LittleTilesRenderMangerMixin" + ], + "client": [], + "server" : [] +} diff --git a/src/main/resources/mixins.gregtech.minecraft.json b/src/main/resources/mixins.gregtech.minecraft.json new file mode 100644 index 00000000000..3c9abf97778 --- /dev/null +++ b/src/main/resources/mixins.gregtech.minecraft.json @@ -0,0 +1,28 @@ +{ + "package": "gregtech.mixins.minecraft", + "refmap": "mixins.gregtech.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "injectors": { + "maxShiftBy": 10 + }, + "mixins": [ + "BlockConcretePowderMixin", + "DamageSourceMixin", + "EnchantmentCanApplyMixin", + "MinecraftMixin" + ], + "client": [ + "BlockMixin", + "EntityRendererMixin", + "LayerArmorBaseMixin", + "LayerCustomHeadMixin", + "RecipeRepairItemMixin", + "RegionRenderCacheBuilderMixin", + "RenderChunkMixin", + "RenderGlobalMixin", + "RenderItemMixin" + ], + "server": [] +} diff --git a/src/main/resources/mixins.gregtech.theoneprobe.json b/src/main/resources/mixins.gregtech.theoneprobe.json new file mode 100644 index 00000000000..0f7038d94c4 --- /dev/null +++ b/src/main/resources/mixins.gregtech.theoneprobe.json @@ -0,0 +1,10 @@ +{ + "package": "gregtech.mixins.theoneprobe", + "refmap": "mixins.gregtech.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": ["TheOneProbeMixin"], + "client": [], + "server": [] +} diff --git a/src/main/resources/mixins.gregtech.vintagium.json b/src/main/resources/mixins.gregtech.vintagium.json new file mode 100644 index 00000000000..7058a0de4da --- /dev/null +++ b/src/main/resources/mixins.gregtech.vintagium.json @@ -0,0 +1,13 @@ +{ + "package": "gregtech.mixins.vintagium", + "refmap": "mixins.gregtech.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": [], + "client": [ + "BlockRenderManagerMixin", + "BlockRenderPassMixin" + ], + "server": [] +} diff --git a/src/test/java/gregtech/Bootstrap.java b/src/test/java/gregtech/Bootstrap.java index 6993ca15851..642fcf38144 100644 --- a/src/test/java/gregtech/Bootstrap.java +++ b/src/test/java/gregtech/Bootstrap.java @@ -3,6 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.fluids.GTFluidRegistration; +import gregtech.api.metatileentity.registry.MTEManager; import gregtech.api.unification.material.Materials; import gregtech.api.unification.material.registry.MarkerMaterialRegistry; import gregtech.api.unification.ore.OrePrefix; @@ -19,7 +20,13 @@ import net.minecraft.util.IThreadListener; import net.minecraft.util.text.translation.LanguageMap; import net.minecraftforge.common.util.CompoundDataFixer; -import net.minecraftforge.fml.common.*; +import net.minecraftforge.fml.common.DummyModContainer; +import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.fml.common.IFMLSidedHandler; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.ModContainer; +import net.minecraftforge.fml.common.ModMetadata; +import net.minecraftforge.fml.common.StartupQuery; import net.minecraftforge.fml.common.eventhandler.EventBus; import net.minecraftforge.fml.relauncher.CoreModManager; import net.minecraftforge.fml.relauncher.Side; @@ -80,6 +87,9 @@ public static void perform() { OrePrefix.runMaterialHandlers(); GTFluidRegistration.INSTANCE.register(); MetaItems.init(); + + GregTechAPI.mteManager = MTEManager.getInstance(); + bootstrapped = true; } diff --git a/src/test/java/gregtech/api/capability/impl/AbstractRecipeLogicTest.java b/src/test/java/gregtech/api/capability/impl/AbstractRecipeLogicTest.java index 68ae9384de7..056f025c8e0 100644 --- a/src/test/java/gregtech/api/capability/impl/AbstractRecipeLogicTest.java +++ b/src/test/java/gregtech/api/capability/impl/AbstractRecipeLogicTest.java @@ -30,10 +30,93 @@ public static void bootstrap() { @Test public void trySearchNewRecipe() { + AbstractRecipeLogic arl = createTestLogic(1, 1); + arl.trySearchNewRecipe(); + + // no recipe found + MatcherAssert.assertThat(arl.invalidInputsForRecipes, is(true)); + MatcherAssert.assertThat(arl.isActive, is(false)); + MatcherAssert.assertThat(arl.previousRecipe, nullValue()); + + queryTestRecipe(arl); + MatcherAssert.assertThat(arl.invalidInputsForRecipes, is(false)); + MatcherAssert.assertThat(arl.previousRecipe, notNullValue()); + MatcherAssert.assertThat(arl.isActive, is(true)); + MatcherAssert.assertThat(arl.getInputInventory().getStackInSlot(0).getCount(), is(15)); + + // Save a reference to the old recipe so we can make sure it's getting reused + Recipe prev = arl.previousRecipe; + + // Finish the recipe, the output should generate, and the next iteration should begin + arl.update(); + MatcherAssert.assertThat(arl.previousRecipe, is(prev)); + MatcherAssert.assertThat(AbstractRecipeLogic.areItemStacksEqual(arl.getOutputInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE, 1)), is(true)); + MatcherAssert.assertThat(arl.isActive, is(true)); + + // Complete the second iteration, but the machine stops because its output is now full + arl.getOutputInventory().setStackInSlot(0, new ItemStack(Blocks.STONE, 63)); + arl.getOutputInventory().setStackInSlot(1, new ItemStack(Blocks.STONE, 64)); + arl.update(); + MatcherAssert.assertThat(arl.isActive, is(false)); + MatcherAssert.assertThat(arl.isOutputsFull, is(true)); + + // Try to process again and get failed out because of full buffer. + arl.update(); + MatcherAssert.assertThat(arl.isActive, is(false)); + MatcherAssert.assertThat(arl.isOutputsFull, is(true)); + + // Some room is freed in the output bus, so we can continue now. + arl.getOutputInventory().setStackInSlot(1, ItemStack.EMPTY); + arl.update(); + MatcherAssert.assertThat(arl.isActive, is(true)); + MatcherAssert.assertThat(arl.isOutputsFull, is(false)); + MatcherAssert.assertThat(AbstractRecipeLogic.areItemStacksEqual(arl.getOutputInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE, 1)), is(true)); + } + + @Test + public void euAndSpeedBonus() { + final int initialEUt = 30; + final int initialDuration = 100; + + AbstractRecipeLogic arl = createTestLogic(initialEUt, initialDuration); + arl.setEUDiscount(0.75); // 75% EU cost required + arl.setSpeedBonus(0.2); // 20% faster than normal + + queryTestRecipe(arl); + MatcherAssert.assertThat(arl.recipeEUt, is((int) Math.round(initialEUt * 0.75))); + MatcherAssert.assertThat(arl.maxProgressTime, is((int) Math.round(initialDuration * 0.2))); + } + + @Test + public void euAndSpeedBonusParallel() { + final int initialEUt = 30; + final int initialDuration = 100; + + AbstractRecipeLogic arl = createTestLogic(initialEUt, initialDuration); + arl.setEUDiscount(0.5); // 50% EU cost required + arl.setSpeedBonus(0.2); // 20% faster than normal + arl.setParallelLimit(4); // Allow parallels + + queryTestRecipe(arl); + + // The EU discount should drop the EU/t of this recipe to 15 EU/t. As a result, this should now + // be able to parallel 2 times. + MatcherAssert.assertThat(arl.parallelRecipesPerformed, is(2)); + // Because of the parallel, now the paralleled recipe EU/t should be back to 30 EU/t. + MatcherAssert.assertThat(arl.recipeEUt, is(30)); + // Duration should be static regardless of parallels. + MatcherAssert.assertThat(arl.maxProgressTime, is((int) Math.round(initialDuration * 0.2))); + } + + private static int TEST_ID = 190; + + private static AbstractRecipeLogic createTestLogic(int testRecipeEUt, int testRecipeDuration) { World world = DummyWorld.INSTANCE; // Create an empty recipe map to work with - RecipeMap map = new RecipeMap<>("test_reactor", + RecipeMap map = new RecipeMap<>("test_reactor_" + TEST_ID, 2, 2, 3, @@ -41,9 +124,9 @@ public void trySearchNewRecipe() { new SimpleRecipeBuilder().EUt(30), false); - MetaTileEntity at = MetaTileEntities.registerMetaTileEntity(190, + MetaTileEntity at = MetaTileEntities.registerMetaTileEntity(TEST_ID, new SimpleMachineMetaTileEntity( - GTUtility.gregtechId("chemical_reactor.lv"), + GTUtility.gregtechId("chemical_reactor.lv_" + TEST_ID), map, null, 1, false)); @@ -52,9 +135,11 @@ public void trySearchNewRecipe() { map.recipeBuilder() .inputs(new ItemStack(Blocks.COBBLESTONE)) .outputs(new ItemStack(Blocks.STONE)) - .EUt(1).duration(1) + .EUt(testRecipeEUt).duration(testRecipeDuration) .buildAndRegister(); + TEST_ID++; + AbstractRecipeLogic arl = new AbstractRecipeLogic(atte, map) { @Override @@ -85,51 +170,13 @@ public long getMaxVoltage() { arl.isOutputsFull = false; arl.invalidInputsForRecipes = false; - arl.trySearchNewRecipe(); - - // no recipe found - MatcherAssert.assertThat(arl.invalidInputsForRecipes, is(true)); - MatcherAssert.assertThat(arl.isActive, is(false)); - MatcherAssert.assertThat(arl.previousRecipe, nullValue()); + return arl; + } + private static void queryTestRecipe(AbstractRecipeLogic arl) { // put an item in the inventory that will trigger recipe recheck arl.getInputInventory().insertItem(0, new ItemStack(Blocks.COBBLESTONE, 16), false); - // Inputs change. did we detect it ? MatcherAssert.assertThat(arl.hasNotifiedInputs(), is(true)); arl.trySearchNewRecipe(); - MatcherAssert.assertThat(arl.invalidInputsForRecipes, is(false)); - MatcherAssert.assertThat(arl.previousRecipe, notNullValue()); - MatcherAssert.assertThat(arl.isActive, is(true)); - MatcherAssert.assertThat(arl.getInputInventory().getStackInSlot(0).getCount(), is(15)); - - // Save a reference to the old recipe so we can make sure it's getting reused - Recipe prev = arl.previousRecipe; - - // Finish the recipe, the output should generate, and the next iteration should begin - arl.update(); - MatcherAssert.assertThat(arl.previousRecipe, is(prev)); - MatcherAssert.assertThat(AbstractRecipeLogic.areItemStacksEqual(arl.getOutputInventory().getStackInSlot(0), - new ItemStack(Blocks.STONE, 1)), is(true)); - MatcherAssert.assertThat(arl.isActive, is(true)); - - // Complete the second iteration, but the machine stops because its output is now full - arl.getOutputInventory().setStackInSlot(0, new ItemStack(Blocks.STONE, 63)); - arl.getOutputInventory().setStackInSlot(1, new ItemStack(Blocks.STONE, 64)); - arl.update(); - MatcherAssert.assertThat(arl.isActive, is(false)); - MatcherAssert.assertThat(arl.isOutputsFull, is(true)); - - // Try to process again and get failed out because of full buffer. - arl.update(); - MatcherAssert.assertThat(arl.isActive, is(false)); - MatcherAssert.assertThat(arl.isOutputsFull, is(true)); - - // Some room is freed in the output bus, so we can continue now. - arl.getOutputInventory().setStackInSlot(1, ItemStack.EMPTY); - arl.update(); - MatcherAssert.assertThat(arl.isActive, is(true)); - MatcherAssert.assertThat(arl.isOutputsFull, is(false)); - MatcherAssert.assertThat(AbstractRecipeLogic.areItemStacksEqual(arl.getOutputInventory().getStackInSlot(0), - new ItemStack(Blocks.STONE, 1)), is(true)); } } diff --git a/src/test/java/gregtech/api/capability/impl/EnergyContainerListTest.java b/src/test/java/gregtech/api/capability/impl/EnergyContainerListTest.java index f0f75d75580..2ed1ded84e2 100644 --- a/src/test/java/gregtech/api/capability/impl/EnergyContainerListTest.java +++ b/src/test/java/gregtech/api/capability/impl/EnergyContainerListTest.java @@ -1,15 +1,15 @@ package gregtech.api.capability.impl; +import gregtech.Bootstrap; import gregtech.api.capability.IEnergyContainer; -import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.ResourceLocation; import org.hamcrest.MatcherAssert; import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import java.util.ArrayList; @@ -20,18 +20,16 @@ public class EnergyContainerListTest { - @NotNull - private static MetaTileEntity createDummyMTE() { - return new MetaTileEntity(new ResourceLocation("")) { + private static MetaTileEntity dummyMTE; - @Override - public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { - return null; - } + @BeforeAll + public static void prepare() { + Bootstrap.perform(); + dummyMTE = new MetaTileEntity(new ResourceLocation(MODID, "dummy")) { @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { + return dummyMTE; } }; } @@ -43,7 +41,7 @@ private static IEnergyContainer createContainer(int amps) { @NotNull private static IEnergyContainer createContainer(int amps, int tier) { - return EnergyContainerHandler.receiverContainer(createDummyMTE(), + return EnergyContainerHandler.receiverContainer(dummyMTE, V[tier] * 64L * amps, V[tier], amps); }