diff --git a/.github/actions/build_setup/action.yml b/.github/actions/build_setup/action.yml new file mode 100644 index 00000000000..7d53a2dbea2 --- /dev/null +++ b/.github/actions/build_setup/action.yml @@ -0,0 +1,30 @@ +name: Build Setup +description: Setup for standard Java builds + +inputs: + update-cache: + description: If cache should be updated + required: false + default: false + +runs: + using: 'composite' + + steps: + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: zulu + java-version: 17 + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v3 + with: + cache-write-only: ${{ inputs.update-cache }} + generate-job-summary: false + gradle-home-cache-includes: | + caches + caches/retro_futura_gradle + notifications + jdks + wrapper diff --git a/.github/workflows/format_java.yml b/.github/workflows/format_java.yml new file mode 100644 index 00000000000..a838fb89497 --- /dev/null +++ b/.github/workflows/format_java.yml @@ -0,0 +1,27 @@ +# Runs formatting requirements +name: Java Formatting + +on: + push: + branches: + - master + pull_request: + +concurrency: + group: formatting-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +jobs: + formatting: + name: Formatting + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup Build + uses: ./.github/actions/build_setup + + - name: Run Spotless Formatting Check with Gradle + run: ./gradlew spotlessCheck --warning-mode all --build-cache diff --git a/.github/workflows/manage_pr_labels.yml b/.github/workflows/manage_pr_labels.yml new file mode 100644 index 00000000000..7dcddd620b4 --- /dev/null +++ b/.github/workflows/manage_pr_labels.yml @@ -0,0 +1,39 @@ +# Manages labels on PRs before allowing merging +name: Pull Request Labels + +on: + pull_request: + types: + - opened + - labeled + - unlabeled + - synchronize + +# if a second commit is pushed quickly after the first, cancel the first one's build +concurrency: + group: pr-labels-${{ github.head_ref }} + cancel-in-progress: true + +jobs: + Labels: + runs-on: ubuntu-latest + + permissions: + pull-requests: read # needed to utilize required-labels + + steps: + - name: Check for Merge-Blocking Labels # blocks merge if present + uses: mheap/github-action-required-labels@v5 + with: + mode: exactly + count: 0 + labels: 'status: do not merge' + exit_type: failure + + - name: Check for Required Labels # require at least one of these labels + uses: mheap/github-action-required-labels@v5 + with: + mode: minimum + count: 1 + labels: 'type: feature, type: bug, type: refactor, type: translation, ignore changelog' + exit_type: failure diff --git a/.github/workflows/nuclear_test_release.yml b/.github/workflows/nuclear_test_release.yml new file mode 100644 index 00000000000..5f8d389ee63 --- /dev/null +++ b/.github/workflows/nuclear_test_release.yml @@ -0,0 +1,49 @@ +name: Nuclear Test Release + +on: + push: + branches: + - nuclear-fission +jobs: + build: + runs-on: ubuntu-latest + + permissions: + contents: write # needed to create GitHub releases + + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Declare some variables + id: vars + shell: bash + run: | + echo "::set-output name=sha_short::$(git rev-parse --short $GITHUB_SHA)" + + - name: Setup Java + uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: '17' + + - name: Build Project + uses: gradle/gradle-build-action@v2 + with: + arguments: 'build --build-cache --daemon' # use the daemon here so the rest of the process is faster + generate-job-summary: false + gradle-home-cache-includes: | + caches + jdks + notifications + wrapper + + - name: Publish to GitHub + uses: softprops/action-gh-release@v1 + with: + files: "build/libs/*.jar" + fail_on_unmatched_files: true + prerelease: true + tag_name: "nuclear-testing" + name: "Nuclear Testing ${{ steps.vars.outputs.sha_short }}" + body: "Testing Pre-release for GTCEu Nuclear Update" diff --git a/.github/workflows/pr_artifact.yml b/.github/workflows/pr_artifact.yml deleted file mode 100644 index 54187e2e326..00000000000 --- a/.github/workflows/pr_artifact.yml +++ /dev/null @@ -1,77 +0,0 @@ -# Creates a built artifact jar for apropriately labeled Pull Requests -name: PR Artifact - -on: - pull_request: - types: - - labeled - - synchronize - -# if a second commit is pushed quickly after the first, cancel the first one's build -concurrency: - group: build-artifact-${{github.head_ref}} - cancel-in-progress: true - -env: - ARTIFACT_NAME: 'gregtech-dev' - NOTIFICATION_BODY: | - This Pull Request has automatic artifact deployment enabled. Download the latest build [here](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}), and extract the contents. - -jobs: - Build_Artifact: - if: contains(github.event.pull_request.labels.*.name, format('deployment{0} artifact', ':')) - runs-on: ubuntu-latest - - permissions: - pull-requests: write # needed to make a comment - contents: read # needed to checkout the repo if defining other permissions - - steps: - - name: Checkout Repository - uses: actions/checkout@v3 - - - name: Setup Java - uses: actions/setup-java@v3 - with: - distribution: 'zulu' - java-version: '17' - - - name: Build Project - uses: gradle/gradle-build-action@v2 - with: - arguments: 'build --build-cache --no-daemon ' # disable daemon since only one gradle operation will happen - generate-job-summary: false - gradle-home-cache-includes: | - caches - jdks - notifications - wrapper - - - name: Determine Artifact Name - id: artifact_name - run: | - FILE=(build/libs/*) - echo "artifact_name=${FILE[0]}" >> $GITHUB_OUTPUT - - - name: Publish Artifact - uses: actions/upload-artifact@v3 - with: - name: "${{env.ARTIFACT_NAME}}-${{github.head_ref}}-${{github.sha}}" - path: "${{steps.artifact_name.outputs.artifact_name}}" - if-no-files-found: error - - - name: Find Existing Comment - uses: peter-evans/find-comment@v2 - id: find-existing - with: - issue-number: ${{github.event.pull_request.number}} - comment-author: 'github-actions[bot]' - body-includes: 'Download the latest build [here]' - - - name: Create or Update Artifact Publish Notification - uses: peter-evans/create-or-update-comment@v2 - with: - issue-number: ${{github.event.pull_request.number}} - comment-id: ${{steps.find-existing.outputs.comment-id}} - edit-mode: replace - body: ${{env.NOTIFICATION_BODY}} diff --git a/.github/workflows/pr_labels.yml b/.github/workflows/pr_labels.yml deleted file mode 100644 index a47b267ec3c..00000000000 --- a/.github/workflows/pr_labels.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Manages labels on PRs before allowing merging -name: PR labels - -on: - pull_request: - types: [opened, labeled, unlabeled, synchronize] - -# if a second commit is pushed quickly after the first, cancel the first one's build -concurrency: - group: pr-labels-${{github.head_ref}} - cancel-in-progress: true - -jobs: - Labels: - runs-on: ubuntu-latest - - permissions: - pull-requests: read # needed to utilize required-labels - - steps: - - name: Merge-Blocking Labels # blocks merge if present - uses: mheap/github-action-required-labels@v3 - with: - mode: exactly - count: 0 - labels: "status: do not merge" - exit_type: failure - - - name: Required Changelog Labels # require at least one of these labels - uses: mheap/github-action-required-labels@v3 - with: - mode: minimum - count: 1 - labels: "type: feature, type: bug, type: refactor, type: translation, ignore changelog" - exit_type: failure diff --git a/.github/workflows/pr_testing.yml b/.github/workflows/pr_testing.yml deleted file mode 100644 index 7761d2a8555..00000000000 --- a/.github/workflows/pr_testing.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Runs tests and other checks on Pull Requests -name: PR Testing - -on: - pull_request: - branches: - - master - -# if a second commit is pushed quickly after the first, cancel the first one's build -concurrency: - group: pr-testing-${{github.head_ref}} - cancel-in-progress: true - -jobs: - Test: - runs-on: ubuntu-latest - - steps: - - name: Checkout Repository - uses: actions/checkout@v3 - - - name: Setup Java - uses: actions/setup-java@v3 - with: - distribution: 'zulu' - java-version: '17' - - - name: Run Tests - uses: gradle/gradle-build-action@v2 - with: - arguments: 'test --build-cache --no-daemon' # disable daemon since only one gradle operation will happen - generate-job-summary: false - gradle-home-cache-includes: | - caches - jdks - notifications - wrapper - - Formatting: - runs-on: ubuntu-latest - - steps: - - name: Checkout Repository - uses: actions/checkout@v3 - - - name: Setup Java - uses: actions/setup-java@v3 - with: - distribution: 'zulu' - java-version: '17' - - - name: Run Spotless - uses: gradle/gradle-build-action@v2 - with: - arguments: 'spotlessCheck --build-cache' - gradle-home-cache-includes: | - caches - jdks - notifications - wrapper diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index df5366133a1..00000000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Publishes built jars to distribution platforms -name: Publish - -on: - push: - tags: - - 'v[0-9]+.[0-9]+.[0-9]+' # any semver tag, e.g. v1.2.3 - -env: - # link to the changelog with a format code for the version - CHANGELOG_LOCATION: "Changelog is available [here](https://github.com/${{github.repository}}/releases/tag/${{github.ref_name}})" - # type of release - RELEASE_TYPE: "beta" - -jobs: - Publish: - runs-on: ubuntu-latest - - permissions: - contents: write # needed to create GitHub releases - - steps: - - name: Checkout Repository - uses: actions/checkout@v3 - - - name: Check for Duplicate Tags - run: | - if git rev-parse -q --verify "refs/tags/${{ github.ref }}" >/dev/null; then - echo "Tag already exists. A version bump is required." - exit 1 - fi - - - name: Setup Java - uses: actions/setup-java@v3 - with: - distribution: 'zulu' - java-version: '17' - - - name: Build Project - uses: gradle/gradle-build-action@v2 - with: - arguments: 'build --build-cache --daemon' # use the daemon here so the rest of the process is faster - generate-job-summary: false - gradle-home-cache-includes: | - caches - jdks - notifications - wrapper - - - name: Publish to GitHub - uses: softprops/action-gh-release@v1 - with: - files: "build/libs/*.jar" - generate_release_notes: true - fail_on_unmatched_files: true - - - name: Publish to Curseforge - uses: gradle/gradle-build-action@v2 - env: - CURSEFORGE_API_KEY: "${{secrets.CURSEFORGE_API_KEY}}" - CURSEFORGE_PROJECT_ID: "${{secrets.CURSEFORGE_PROJECT_ID}}" - CHANGELOG_LOCATION: "${{env.CHANGELOG_LOCATION}}" - RELEASE_TYPE: "${{env.RELEASE_TYPE}}" - with: - arguments: 'curseforge --daemon' - generate-job-summary: false - gradle-home-cache-includes: | - caches - jdks - notifications - wrapper - - - name: Publish to Modrinth - uses: gradle/gradle-build-action@v2 - env: - MODRINTH_API_KEY: "${{secrets.MODRINTH_API_KEY}}" - MODRINTH_PROJECT_ID: "${{secrets.MODRINTH_PROJECT_ID}}" - CHANGELOG_LOCATION: "${{env.CHANGELOG_LOCATION}}" - RELEASE_TYPE: "${{env.RELEASE_TYPE}}" - with: - arguments: 'modrinth --daemon' - generate-job-summary: false - gradle-home-cache-includes: | - caches - jdks - notifications - wrapper diff --git a/.github/workflows/publish_project.yml b/.github/workflows/publish_project.yml new file mode 100644 index 00000000000..28aa35e34ac --- /dev/null +++ b/.github/workflows/publish_project.yml @@ -0,0 +1,64 @@ +# Publishes the project to GitHub Releases, CurseForge, and Modrinth +name: Publish Project + +on: + push: + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' # any SemVer tag, e.g. v1.2.3 + +env: + # link to the changelog with a format code for the version + CHANGELOG_LOCATION: "Changelog is available [here](https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }})" + # type of release + RELEASE_TYPE: 'beta' + +concurrency: + group: publish-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +jobs: + publish: + name: Publish + runs-on: ubuntu-latest + + permissions: + contents: write # needed to create GitHub releases + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup Build + uses: ./.github/actions/build_setup + + - name: Build Project + run: ./gradlew build --warning-mode all --build-cache + + - name: Publish to GitHub + uses: softprops/action-gh-release@v2 + with: + files: "build/libs/*.jar" + generate_release_notes: true + fail_on_unmatched_files: true + + - name: Publish to Maven + env: + MAVEN_USER: "${{ secrets.MAVEN_USER }}" + MAVEN_PASSWORD: "${{ secrets.MAVEN_PASSWORD }}" + run: ./gradlew publish + + - name: Publish to Curseforge + env: + CURSEFORGE_API_KEY: "${{ secrets.CURSEFORGE_API_KEY }}" + CURSEFORGE_PROJECT_ID: "${{ secrets.CURSEFORGE_PROJECT_ID }}" + CHANGELOG_LOCATION: "${{ env.CHANGELOG_LOCATION }}" + RELEASE_TYPE: "${{ env.RELEASE_TYPE }}" + run: ./gradlew curseforge --warning-mode all --build-cache + + - name: Publish to Modrinth + env: + MODRINTH_API_KEY: "${{ secrets.MODRINTH_API_KEY }}" + MODRINTH_PROJECT_ID: "${{ secrets.MODRINTH_PROJECT_ID }}" + CHANGELOG_LOCATION: "${{ env.CHANGELOG_LOCATION }}" + RELEASE_TYPE: "${{ env.RELEASE_TYPE }}" + run: ./gradlew modrinth --warning-mode all --build-cache diff --git a/.github/workflows/test_java.yml b/.github/workflows/test_java.yml new file mode 100644 index 00000000000..5ee8e5d2ed6 --- /dev/null +++ b/.github/workflows/test_java.yml @@ -0,0 +1,27 @@ +# Runs tests +name: Java Tests + +on: + push: + branches: + - master + pull_request: + +concurrency: + group: tests-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +jobs: + test: + name: Tests + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup Build + uses: ./.github/actions/build_setup + + - name: Run Tests with Gradle + run: ./gradlew test --warning-mode all --build-cache diff --git a/.github/workflows/update_buildscript.yml b/.github/workflows/update_buildscript.yml index f8107f648d5..f9c923fe09c 100644 --- a/.github/workflows/update_buildscript.yml +++ b/.github/workflows/update_buildscript.yml @@ -1,41 +1,33 @@ # Checks daily to see if the buildscript is in need of an update -name: Buildscript Updating +name: Update Buildscript on: workflow_dispatch: schedule: - - cron: "0 0 * * *" # "min hr day month year", so run once per day + - cron: '0 0 * * *' # "min hr day month year", so run once per day jobs: buildscript-update: runs-on: ubuntu-latest + # Avoid running this workflow on forks if: github.repository == 'GregTechCEu/GregTech' + permissions: contents: write pull-requests: write + steps: - - name: Checkout - uses: actions/checkout@v3 + - name: Checkout Repository + uses: actions/checkout@v4 - - name: Setup Java - uses: actions/setup-java@v3 - with: - distribution: 'zulu' - java-version: '17' + - name: Setup Build + uses: ./.github/actions/build_setup - - name: Run script updater - uses: gradle/gradle-build-action@v2 - with: - arguments: 'updateBuildScript' - generate-job-summary: false - gradle-home-cache-includes: | - caches - jdks - notifications - wrapper + - name: Run Buildscript Updater + run: ./gradlew updateBuildScript --warning-mode all --build-cache - - name: Get new script version + - name: Get New Buildscript Version id: version-check run: | new_version=$(head -1 build.gradle | sed -r 's|//version: (.*)|\1|g') @@ -43,24 +35,19 @@ jobs: - name: Create Pull Request id: create-pull-request - uses: peter-evans/create-pull-request@v4 + 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 }} body: This pull request is created by the buildscript-update workflow labels: ignore changelog - - name: Enable pull request auto-merge - id: pull-request-auto-merge + - name: Enable Pull-Request Auto-Merge if: steps.create-pull-request.outputs.pull-request-operation == 'created' - uses: peter-evans/enable-pull-request-automerge@v3 - with: - token: ${{ secrets.BUILDSCRIPT_UPDATER_TOKEN }} - pull-request-number: ${{ steps.create-pull-request.outputs.pull-request-number }} - merge-method: squash + run: gh pr merge --squash --auto "${{ steps.create-pull-request.outputs.pull-request-number }}" + env: + GH_TOKEN: ${{ secrets.BUILDSCRIPT_UPDATER_TOKEN }} diff --git a/.github/workflows/update_gradle_cache.yml b/.github/workflows/update_gradle_cache.yml index 9853000d7ac..ba93b16779a 100644 --- a/.github/workflows/update_gradle_cache.yml +++ b/.github/workflows/update_gradle_cache.yml @@ -1,39 +1,30 @@ -# Updates the Gradle Cache when relevant files change +# Updates the Gradle Cache when necessary name: Update Gradle Cache on: - workflow_dispatch: push: branches: - master - paths: - - "gradle**" # covers gradle folder, gradle.properties, gradlew - - "build.gradle*" - - "settings.gradle*" - - "src/main/resources/*_at.cfg" # access transformers + paths: ['gradle/**', '**.gradle', 'gradle.properties', 'gradlew**', 'src/main/resources/*_at.cfg'] + workflow_dispatch: + +concurrency: + group: gradle-cache-${{ github.ref }} + cancel-in-progress: true jobs: - Update_Cache: + update-cache: + name: Update Grade Cache runs-on: ubuntu-latest steps: - name: Checkout Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - - name: Setup Java - uses: actions/setup-java@v3 + - name: Setup Build + uses: ./.github/actions/build_setup with: - distribution: 'zulu' - java-version: '17' + update-cache: true - - name: Update Cache - uses: gradle/gradle-build-action@v2 - with: - arguments: 'test --build-cache --no-daemon' # disable daemon since only one gradle operation will happen - generate-job-summary: false - gradle-home-cache-includes: | - caches - jdks - notifications - wrapper - cache-write-only: true + - name: Build Project with Gradle + run: ./gradlew assemble --warning-mode all --build-cache diff --git a/.github/workflows/validate_gradle_wrapper.yml b/.github/workflows/validate_gradle_wrapper.yml index 6f7a9d4cbe9..f8463eac5e4 100644 --- a/.github/workflows/validate_gradle_wrapper.yml +++ b/.github/workflows/validate_gradle_wrapper.yml @@ -1,4 +1,4 @@ -# Validates the integrity of the Gradle wrapper +# Validates the integrity of the Gradle Wrapper name: Validate Gradle Wrapper on: @@ -8,14 +8,11 @@ on: paths: - 'gradle/**' pull_request: - branches: - - '*' paths: - 'gradle/**' -# if a second commit is pushed quickly after the first, cancel the first one's build concurrency: - group: gradle-wrapper-validation-${{github.head_ref}} + group: gradle-wrapper-validation-${{ github.head_ref || github.ref }} cancel-in-progress: true jobs: @@ -24,7 +21,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Validate Gradle Wrapper - uses: gradle/wrapper-validation-action@v1 + uses: gradle/actions/wrapper-validation@v3 diff --git a/.gitignore b/.gitignore index 755fbb2ab6d..c2fb66e1e33 100644 --- a/.gitignore +++ b/.gitignore @@ -81,3 +81,5 @@ local.properties run/ logs/ + +libs/ diff --git a/README.md b/README.md index 5876b6d1b60..8a4fcfa7209 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Anything else? Sure come to [Discord](https://discord.gg/bWSWuYvURP). ## Credited Works Heating Coil Textures, Wooden Forms, World Accelerators, and the Extreme Combustion Engine are from the **[GregTech: New Horizons Modpack](https://www.curseforge.com/minecraft/modpacks/gt-new-horizons)**. -Primitive Water Pump and Super Tank GUI Textures are from the **[IMPACT: GREGTECH EDITION Modpack](https://gtimpact.space/)**. +Primitive Water Pump and Super Tank GUI Textures are from the **[IMPACT: GREGTECH EDITION Modpack](https://gt-impact.github.io/)**. Ender Fluid Link Cover, Auto-Maintenance Hatch, Optical Fiber, and Data Bank Textures are from **[TecTech](https://github.com/Technus/TecTech)**. diff --git a/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 29b2ba602bf..892add04600 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -//version: 1702244235 +//version: 1723428048 /* * 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,16 +33,17 @@ 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.25' - id 'net.darkhax.curseforgegradle' version '1.1.17' apply false - id 'com.modrinth.minotaur' version '2.8.6' 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 id 'com.github.johnrengelman.shadow' version '8.1.1' apply false 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,20 +69,26 @@ 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", "") 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) propertyDefaultIfUnset("minimizeShadowedDependencies", true) propertyDefaultIfUnset("relocateShadowedDependencies", true) propertyDefaultIfUnset("separateRunDirectories", false) +propertyDefaultIfUnset("versionDisplayFormat", '$MOD_NAME \u2212 $VERSION') propertyDefaultIfUnsetWithEnvVar("modrinthProjectId", "", "MODRINTH_PROJECT_ID") propertyDefaultIfUnset("modrinthRelations", "") propertyDefaultIfUnsetWithEnvVar("curseForgeProjectId", "", "CURSEFORGE_PROJECT_ID") @@ -104,9 +121,16 @@ if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists( } if (apiPackage) { - targetPackageJava = javaSourceDir + modGroupPath + '/' + apiPackagePath - targetPackageScala = scalaSourceDir + modGroupPath + '/' + apiPackagePath - targetPackageKotlin = kotlinSourceDir + modGroupPath + '/' + apiPackagePath + final String endApiPath = modGroupPath + '/' + apiPackagePath + if (useSrcApiPath.toBoolean()) { + targetPackageJava = 'src/api/java/' + endApiPath + targetPackageScala = 'src/api/scala/' + endApiPath + targetPackageKotlin = 'src/api/kotlin/' + endApiPath + } else { + targetPackageJava = javaSourceDir + endApiPath + targetPackageScala = scalaSourceDir + endApiPath + targetPackageKotlin = kotlinSourceDir + endApiPath + } if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists() && !getFile(targetPackageKotlin).exists()) { throw new GradleException("Could not resolve \"apiPackage\"! Could not find ${targetPackageJava} or ${targetPackageScala} or ${targetPackageKotlin}") } @@ -360,6 +384,14 @@ minecraft { '-Dlegacy.debugClassLoadingSave=true' ]) } + + if (additionalJavaArguments.size() != 0) { + extraRunJvmArguments.addAll(additionalJavaArguments.split(';')) + } + + if (enableJava17RunTasks.toBoolean()) { + lwjgl3Version = "3.3.2" + } } if (coreModClass) { @@ -435,8 +467,11 @@ repositories { } maven { name 'GTNH Maven' - url 'http://jenkins.usrv.eu:8081/nexus/content/groups/public' - allowInsecureProtocol = true + url 'https://nexus.gtnewhorizons.com/repository/public/' + } + maven { + name 'GTCEu Maven' + url 'https://maven.gtceu.com' } } if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) { @@ -465,9 +500,25 @@ configurations { config.extendsFrom(shadowCompile) } } + + create("runtimeOnlyNonPublishable") { + description = "Runtime only dependencies that are not published alongside the jar" + canBeConsumed = false + canBeResolved = false + } + create("devOnlyNonPublishable") { + description = "Runtime and compiletime dependencies that are not published alongside the jar (compileOnly + runtimeOnlyNonPublishable)" + canBeConsumed = false + canBeResolved = false + } + + compileOnly.extendsFrom(devOnlyNonPublishable) + runtimeOnlyNonPublishable.extendsFrom(devOnlyNonPublishable) + runtimeClasspath.extendsFrom(runtimeOnlyNonPublishable) + testRuntimeClasspath.extendsFrom(runtimeOnlyNonPublishable) } -String mixinProviderSpec = 'zone.rong:mixinbooter:8.9' +String mixinProviderSpec = 'zone.rong:mixinbooter:9.1' dependencies { if (usesMixins.toBoolean()) { annotationProcessor 'org.ow2.asm:asm-debug-all:5.2' @@ -476,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 } @@ -485,7 +536,7 @@ dependencies { transitive = false } } else if (forceEnableMixins.toBoolean()) { - runtimeOnly(mixinProviderSpec) + runtimeOnlyNonPublishable(mixinProviderSpec) } if (enableJUnit.toBoolean()) { @@ -495,8 +546,8 @@ dependencies { } if (enableModernJavaSyntax.toBoolean()) { - annotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.0' - compileOnly('com.github.bsideup.jabel:jabel-javac-plugin:1.0.0') { + annotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.1' + compileOnly('com.github.bsideup.jabel:jabel-javac-plugin:1.0.1') { transitive = false } // workaround for https://github.com/bsideup/jabel/issues/174 @@ -505,8 +556,8 @@ dependencies { patchedMinecraft 'me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0' // allow Jabel to work in tests - testAnnotationProcessor "com.github.bsideup.jabel:jabel-javac-plugin:1.0.0" - testCompileOnly("com.github.bsideup.jabel:jabel-javac-plugin:1.0.0") { + testAnnotationProcessor "com.github.bsideup.jabel:jabel-javac-plugin:1.0.1" + testCompileOnly("com.github.bsideup.jabel:jabel-javac-plugin:1.0.1") { transitive = false // We only care about the 1 annotation class } testCompileOnly "me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0" @@ -518,10 +569,18 @@ dependencies { transitive = false } + if ((usesMixins.toBoolean() || forceEnableMixins.toBoolean()) && stripForgeRequirements.toBoolean()) { + runtimeOnlyNonPublishable 'com.cleanroommc:strip-latest-forge-requirements:1.0' + } + if (includeCommonDevEnvMods.toBoolean()) { - implementation 'mezz.jei:jei_1.12.2:4.16.1.302' - //noinspection DependencyNotationArgument - implementation rfg.deobf('curse.maven:top-245211:2667280') // TOP 1.4.28 + if (!(modId.equals('jei'))) { + implementation 'mezz.jei:jei_1.12.2:4.16.1.302' + } + if (!(modId.equals('theoneprobe'))) { + //noinspection DependencyNotationArgument + implementation rfg.deobf('curse.maven:top-245211:2667280') // TOP 1.4.28 + } } } @@ -533,6 +592,12 @@ pluginManager.withPlugin('org.jetbrains.kotlin.kapt') { } } +configurations.configureEach { + resolutionStrategy.dependencySubstitution { + substitute module('org.scala-lang:scala-library:2.11.1') using module('org.scala-lang:scala-library:2.11.5') because('To allow mixing with Java 8 targets') + } +} + if (getFile('dependencies.gradle').exists()) { apply from: 'dependencies.gradle' } else if (getFile('dependencies.gradle.kts').exists()) { @@ -641,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}", @@ -674,6 +738,19 @@ jar { it.isDirectory() ? it : zipTree(it) } } + + if (useSrcApiPath && apiPackage) { + from sourceSets.api.output + dependsOn apiClasses + + include "${modGroupPath}/**" + include "assets/**" + include "mcmod.info" + include "pack.mcmeta" + if (accessTransformersFile) { + include "META-INF/${accessTransformersFile}" + } + } } // Configure default run tasks @@ -690,12 +767,21 @@ if (separateRunDirectories.toBoolean()) { // Create API library jar tasks.register('apiJar', Jar) { archiveClassifier.set 'api' - from(sourceSets.main.java) { - include "${modGroupPath}/${apiPackagePath}/**" - } + if (useSrcApiPath) { + from(sourceSets.api.java) { + include "${modGroupPath}/${apiPackagePath}/**" + } + from(sourceSets.api.output) { + include "${modGroupPath}/${apiPackagePath}/**" + } + } else { + from(sourceSets.main.java) { + include "${modGroupPath}/${apiPackagePath}/**" + } - from(sourceSets.main.output) { - include "${modGroupPath}/${apiPackagePath}/**" + from(sourceSets.main.output) { + include "${modGroupPath}/${apiPackagePath}/**" + } } } @@ -760,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 { @@ -784,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'] } @@ -889,7 +1203,7 @@ if (cfApiKey.isPresent() || deploymentDebug.toBoolean()) { def changelogFile = getChangelog() def changelogRaw = changelogFile.exists() ? changelogFile.getText('UTF-8') : "" - mainFile.displayName = "${modName}: ${modVersion}" + mainFile.displayName = versionDisplayFormat.replace('$MOD_NAME', modName).replace('$VERSION', modVersion) mainFile.releaseType = getReleaseType() mainFile.changelog = changelogRaw mainFile.changelogType = 'markdown' @@ -905,6 +1219,12 @@ if (cfApiKey.isPresent() || deploymentDebug.toBoolean()) { } String[] parts = dep.split(':') String type = parts[0], slug = parts[1] + def types = [ + 'req' : 'requiredDependency', 'required': 'requiredDependency', + 'opt' : 'optionalDependency', 'optional': 'optionalDependency', + 'embed' : 'embeddedLibrary', 'embedded': 'embeddedLibrary', + 'incomp': 'incompatible', 'fail' : 'incompatible'] + if (types.containsKey(type)) type = types[type] if (!(type in ['requiredDependency', 'embeddedLibrary', 'optionalDependency', 'tool', 'incompatible'])) { throw new Exception('Invalid Curseforge dependency type: ' + type) } @@ -917,6 +1237,30 @@ if (cfApiKey.isPresent() || deploymentDebug.toBoolean()) { additionalFile.changelog = changelogRaw } } + doLast { + // No File IDs in Debug Mode + if (!deploymentDebug.toBoolean()) { + def list = [] + for (def artifact : tasks.curseforge.getUploadArtifacts()) { + list.add(artifact) + for (def additionalArtifact : artifact.getAdditionalArtifacts()) { + list.add(additionalArtifact) + } + } + def summary = "## CurseForge Build Summary (Mod ${modName} | Project ID ${curseForgeProjectId})" + for (def artifact : list) { + def fileId = artifact.getCurseFileId() + def fileName = artifact.getArtifact().getSingleFile().name + println("Uploaded File ${fileName}, With File ID: ${fileId}") + summary = summary + "\n - File: ${fileName} | File ID: ${fileId}" + } + println(summary) + def stepSummary = providers.environmentVariable("GITHUB_STEP_SUMMARY") + if (stepSummary.isPresent()) { + file(stepSummary.get()).write(summary) + } + } + } } tasks.curseforge.dependsOn(build) tasks.curseforge.dependsOn('generateChangelog') @@ -929,6 +1273,7 @@ if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) { modrinth { token = modrinthApiKey.getOrElse('debug_token') projectId = modrinthProjectId + versionName = versionDisplayFormat.replace('$MOD_NAME', modName).replace('$VERSION', modVersion) changelog = changelogFile.exists() ? changelogFile.getText('UTF-8') : "" versionType = getReleaseType() versionNumber = modVersion @@ -946,7 +1291,7 @@ if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) { } String[] parts = dep.split(':') String[] qual = parts[0].split('-') - addModrinthDep(qual[0], qual[1], parts[1]) + addModrinthDep(qual[0], qual.length > 1 ? qual[1] : 'project', parts[1]) } } tasks.modrinth.dependsOn(build) @@ -955,9 +1300,17 @@ if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) { def addModrinthDep(String scope, String type, String name) { com.modrinth.minotaur.dependencies.Dependency dep + def types = [ + 'req' : 'required', + 'opt' : 'optional', + 'embed' : 'embedded', + 'incomp': 'incompatible', 'fail': 'incompatible'] + if (types.containsKey(scope)) scope = types[scope] if (!(scope in ['required', 'optional', 'incompatible', 'embedded'])) { throw new Exception('Invalid modrinth dependency scope: ' + scope) } + types = ['proj': 'project', '': 'project', 'p': 'project', 'ver': 'version', 'v': 'version'] + if (types.containsKey(type)) type = types[type] switch (type) { case 'project': dep = new ModDependency(name, scope) @@ -1038,7 +1391,7 @@ def getChangelog() { // Buildscript updating -def buildscriptGradleVersion = '8.5' +def buildscriptGradleVersion = '8.9' tasks.named('wrapper', Wrapper).configure { gradleVersion = buildscriptGradleVersion diff --git a/dependencies.gradle b/dependencies.gradle index 2205a0f2ae3..b896e29efb5 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,74 +1,72 @@ //file:noinspection DependencyNotationArgument // TODO remove when fixed in RFG ^ /* - * Add your dependencies here. Common configurations: - * - implementation("group:name:version:classifier"): if you need this for internal implementation details of the mod. - * Available at compiletime and runtime for your environment. - * - * - compileOnlyApi("g:n:v:c"): if you need this for internal implementation details of the mod. - * Available at compiletime but not runtime for your environment. - * + * Add your dependencies here. Supported configurations: + * - api("group:name:version:classifier"): if you use the types from this dependency in the public API of this mod + * Available at runtime and compiletime for mods depending on this mod + * - implementation("g:n:v:c"): if you need this for internal implementation details of the mod, but none of it is visible via the public API + * Available at runtime but not compiletime for mods depending on this mod + * - compileOnly("g:n:v:c"): if the mod you're building doesn't need this dependency during runtime at all, e.g. for optional mods + * Not available at all for mods depending on this mod, only visible at compiletime for this mod + * - compileOnlyApi("g:n:v:c"): like compileOnly, but also visible at compiletime for mods depending on this mod + * Available at compiletime but not runtime for mods depending on this mod + * - runtimeOnlyNonPublishable("g:n:v:c"): if you want to include a mod in this mod's runClient/runServer runs, but not publish it as a dependency + * Not available at all for mods depending on this mod, only visible at runtime for this mod + * - devOnlyNonPublishable("g:n:v:c"): a combination of runtimeOnlyNonPublishable and compileOnly for dependencies present at both compiletime and runtime, + * but not published as Maven dependencies - useful for RFG-deobfuscated dependencies or local testing + * - runtimeOnly("g:n:v:c"): if you don't need this at compile time, but want it to be present at runtime + * Available at runtime for mods depending on this mod * - annotationProcessor("g:n:v:c"): mostly for java compiler plugins, if you know you need this, use it, otherwise don't worry + * - testCONFIG("g:n:v:c") - replace CONFIG by one of the above (except api), same as above but for the test sources instead of main + * + * - shadowImplementation("g:n:v:c"): effectively the same as API, but the dependency is included in your jar under a renamed package name + * Requires you to enable usesShadowedDependencies in gradle.properties + * For more info, see https://github.com/GregTechCEu/Buildscripts/blob/master/docs/shadow.md * - * - testCONFIG("g:n:v:c"): replace CONFIG by one of the above, same as above but for the test sources instead of main + * You can exclude transitive dependencies (dependencies of the chosen dependency) by appending { transitive = false } if needed, + * but use this sparingly as it can break using your mod as another mod's dependency if you're not careful. * - * You can exclude transitive dependencies (dependencies of the chosen dependency) by appending { transitive = false } if needed. + * To depend on obfuscated jars you can use `devOnlyNonPublishable(rfg.deobf("dep:spec:1.2.3"))` to fetch an obfuscated jar from maven, + * or `devOnlyNonPublishable(rfg.deobf(project.files("libs/my-mod-jar.jar")))` to use a file. * * To add a mod with CurseMaven, replace '("g:n:v:c")' in the above with 'rfg.deobf("curse.maven:project_slug-project_id:file_id")' - * Example: implementation rfg.deobf("curse.maven:gregtech-ce-unofficial-557242:4527757") + * Example: devOnlyNonPublishable(rfg.deobf("curse.maven:top-245211:2667280")) * - * For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph + * Gradle names for some of the configuration can be misleading, compileOnlyApi and runtimeOnly both get published as dependencies in Maven, but compileOnly does not. + * The buildscript adds runtimeOnlyNonPublishable to also have a runtime dependency that's not published. + * + * For more details, see https://docs.gradle.org/8.4/userguide/java_library_plugin.html#sec:java_library_configurations_graph */ dependencies { - // Hard Dependencies - - // the CCL deobf jar uses very old MCP mappings, making it error at runtime in runClient/runServer - // therefore we manually deobf the regular jar - implementation rfg.deobf("curse.maven:codechicken-lib-1-8-242818:2779848") // CCL 3.2.3.358 - implementation("com.cleanroommc:modularui:2.4.1") { transitive = false } + // Published dependencies + api("codechicken:codechickenlib:3.2.3.358") + api("com.cleanroommc:modularui:2.5.0-rc1") { transitive = false } + api("com.cleanroommc:groovyscript:1.2.0-hotfix1") { transitive = false } + api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.700") + api("appeng:ae2-uel:v0.56.4") { transitive = false } + api rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31 - // Soft Dependencies - // Can change any of these from compileOnlyApi -> implementation to test them in-game. - - implementation "CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.684" - implementation rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31 - implementation("com.cleanroommc:groovyscript:0.7.1") { transitive = false } - implementation rfg.deobf("curse.maven:ae2-extended-life-570458:4402048") // AE2UEL 0.55.6 - - compileOnlyApi rfg.deobf("curse.maven:opencomputers-223008:4526246") // OpenComputers 1.8.0+9833087 - compileOnlyApi "curse.maven:journeymap-32274:2916002" // Journeymap 5.7.1 - compileOnlyApi "curse.maven:voxelmap-225179:3029445" // VoxelMap 1.9.28 - compileOnlyApi "curse.maven:xaeros-263420:4516832" // Xaero's Minimap 23.4.1 - compileOnlyApi rfg.deobf("curse.maven:hwyla-253449:2568751") // HWYLA 1.8.26-B41 - compileOnlyApi rfg.deobf("curse.maven:baubles-227083:2518667") // Baubles 1.5.2 - compileOnlyApi rfg.deobf("curse.maven:forestry-59751:2684780") // Forestry 5.8.2.387 - compileOnlyApi rfg.deobf("curse.maven:exnihilo-274456:2817545") // Ex Nihilo Creatio 0.4.7.2 - compileOnlyApi rfg.deobf("curse.maven:chisel-235279:2915375") // Chisel 1.0.2.45 + // Non-published dependencies + // Change any to devOnlyNonPublishable to test them in-game. + compileOnly("curse.maven:journeymap-32274:5172461") // Journeymap 5.7.1p3 + compileOnly("curse.maven:voxelmap-225179:3029445") // VoxelMap 1.9.28 + 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 + compileOnly rfg.deobf("curse.maven:exnihilo-274456:2817545") // Ex Nihilo Creatio 0.4.7.2 // Mods with Soft compat but which have no need to be in code, such as isModLoaded() checks and getModItem() recipes. // Uncomment any of these to test them in-game. - // runtimeOnly rfg.deobf("curse.maven:beebetteratbees-244516:2627215") // BeeBetterAtBees 2.0.3 (recommended to enable when testing Forestry compat) - // runtimeOnly rfg.deobf("curse.maven:jei-bees-248370:2490058") // JEIBees 0.9.0.5 (recommended to enable when testing Forestry compat) - // runtimeOnly rfg.deobf("curse.maven:binnies-mods-223525:2916129") // Binnie 2.5.1.203 - // runtimeOnly rfg.deobf("curse.maven:magic-bees-65764:2855061") // Magic Bees 3.2.25 - // runtimeOnly rfg.deobf("curse.maven:gendustry-70492:2516215") // Gendustry 1.6.5.8 - // runtimeOnly rfg.deobf("curse.maven:bdlib-70496:2518031") // BdLib 1.14.3.12 -} - -minecraft { - injectedTags.put('DEP_VERSION_STRING', "required-after:gregtech@[${modVersion},);") -} - -configurations { - implementation { - // 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" - } -} + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:beebetteratbees-244516:2627215") // BeeBetterAtBees 2.0.3 (recommended to enable when testing Forestry compat) + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:jei-bees-248370:2490058") // JEIBees 0.9.0.5 (recommended to enable when testing Forestry compat) + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:binnies-mods-223525:2916129") // Binnie 2.5.1.203 + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:magic-bees-65764:2855061") // Magic Bees 3.2.25 + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:gendustry-70492:2516215") // Gendustry 1.6.5.8 + // runtimeOnlyNonPublishable rfg.deobf("curse.maven:bdlib-70496:2518031") // BdLib 1.14.3.12 +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 8cc69185de4..7520aad5201 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ modGroup = gregtech # Version of your mod. # This field can be left empty if you want your mod's version to be determined by the latest git tag instead. -modVersion = 2.8.5-beta +modVersion = 2.8.7-beta # Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version) includeMCVersionJar = true @@ -26,11 +26,20 @@ minecraftVersion = 1.12.2 # Do you need to test how your custom blocks interacts with a player that is not the owner? -> leave name empty # Alternatively this can be set with the 'DEV_USERNAME' environment variable. developmentEnvironmentUserName = Developer +# Additional arguments applied to the JVM when launching minecraft +# Syntax: -arg1=value1;-arg2=value2;... +# Example value: -Dmixin.debug.verify=true;-XX:+UnlockExperimentalVMOptions +additionalJavaArguments= # Enables using modern java syntax (up to version 17) via Jabel, while still targeting JVM 8. # See https://github.com/bsideup/jabel for details on how this works. # Using this requires that you use a Java 17 JDK for development. enableModernJavaSyntax = true +# Enables runClient/runServer tasks for Java 17 and Java 21 using LWJGL3ify. +# This is primarily used to test if your mod is compatible with platforms running +# Minecraft 1.12.2 on modern versions of Java and LWJGL, and assist in fixing any problems with it. +# Using this requires that you use a Java 17/Java 21 JDK for development. +enableJava17RunTasks=false # Generate a class with String fields for the mod id, name and version named with the fields below generateGradleTokenClass = gregtech.GTInternalTags @@ -43,39 +52,49 @@ gradleTokenVersion = VERSION # Example value: apiPackage = api + modGroup = com.myname.mymodid -> com.myname.mymodid.api apiPackage = +# If you want to keep your API code in src/api instead of src/main +useSrcApiPath=false + # Specify the configuration file for Forge's access transformers here. It must be placed into /src/main/resources/ # There can be multiple files in a comma-separated list. # Example value: mymodid_at.cfg,jei_at.cfg 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 +# Location of the mixin config refmap. If left, blank, defaults to "mixins.${modId}.refmap.json". Target file must have the "json" extension. +mixinConfigRefmap= # 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 includeCommonDevEnvMods = true +# Some mods require a specific forge version to launch in. When you need to use one of those mods as a dependency, +# and cannot launch with the forge version required, enable this to strip the forge version requirements from that mod. +# This will add 'strip-latest-forge-requirements' as 'runtimeOnlyNonPublishable'. +# Requires useMixins or forceEnableMixins to be true, as the mod uses mixins to function. +stripForgeRequirements=false # If enabled, you may use 'shadowCompile' for dependencies. They will be integrated in your jar. It is your @@ -91,6 +110,9 @@ relocateShadowedDependencies = true # Useful for debugging a server and client simultaneously. If not enabled, it will be in the standard location "run/" separateRunDirectories = false +# The display name format of versions published to Curse and Modrinth. $MOD_NAME and $VERSION are available variables. +# Default: $MOD_NAME \u2212 $VERSION. \u2212 is the minus character which looks much better than the hyphen minus on Curse. +versionDisplayFormat=$MOD_NAME: $VERSION # Publishing to modrinth requires you to set the MODRINTH_API_KEY environment variable to your current modrinth API token. @@ -140,7 +162,7 @@ noPublishedSources = false # For maven credentials: # Username is set with the 'MAVEN_USER' environment variable, default to "NONE" # Password is set with the 'MAVEN_PASSWORD' environment variable, default to "NONE" -customMavenPublishUrl= +customMavenPublishUrl= https://maven.gtceu.com # The group for maven artifacts. Defaults to the 'project.modGroup' until the last '.' (if any). # So 'mymod' becomes 'mymod' and 'com.myname.mymodid' 'becomes com.myname' mavenArtifactGroup= diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 033e24c4cdf..e6441136f3d 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1af9e0930b8..09523c0e549 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index fcb6fca147c..b740cf13397 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -83,7 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -201,11 +202,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradlew.bat b/gradlew.bat index 6689b85beec..7101f8e4676 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/settings.gradle b/settings.gradle index b6371aad5ab..771def37e1f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,9 +3,7 @@ pluginManagement { maven { // RetroFuturaGradle name 'GTNH Maven' - //noinspection HttpUrlsUsage - url 'http://jenkins.usrv.eu:8081/nexus/content/groups/public/' - allowInsecureProtocol = true + url 'https://nexus.gtnewhorizons.com/repository/public/' //noinspection GroovyAssignabilityCheck mavenContent { includeGroup 'com.gtnewhorizons' diff --git a/src/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/api/java/meldexun/nothirium/api/renderer/chunk/ChunkRenderPass.java b/src/api/java/meldexun/nothirium/api/renderer/chunk/ChunkRenderPass.java new file mode 100644 index 00000000000..355ce0daa04 --- /dev/null +++ b/src/api/java/meldexun/nothirium/api/renderer/chunk/ChunkRenderPass.java @@ -0,0 +1,12 @@ +package meldexun.nothirium.api.renderer.chunk; + +/** + * Adapted and minimized from ChunkRenderPass.java + */ +public enum ChunkRenderPass { + ; + + public static final ChunkRenderPass[] ALL = ChunkRenderPass.values(); + +} diff --git a/src/main/java/gregtech/GregTechMod.java b/src/main/java/gregtech/GregTechMod.java index f39383f5c08..d9ce8166b32 100644 --- a/src/main/java/gregtech/GregTechMod.java +++ b/src/main/java/gregtech/GregTechMod.java @@ -3,6 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.modules.ModuleContainerRegistryEvent; +import gregtech.api.persistence.PersistentData; import gregtech.client.utils.BloomEffectUtil; import gregtech.modules.GregTechModules; import gregtech.modules.ModuleManager; @@ -26,14 +27,14 @@ import net.minecraftforge.fml.common.event.FMLServerStoppingEvent; @Mod(modid = GTValues.MODID, - name = "GregTech", + name = GTValues.MOD_NAME, acceptedMinecraftVersions = "[1.12.2,1.13)", version = GTInternalTags.VERSION, dependencies = "required:forge@[14.23.5.2847,);" + "required-after:codechickenlib@[3.2.3,);" + "required-after:modularui@[2.3,);" + "required-after:mixinbooter@[8.0,);" + "after:appliedenergistics2;" + "after:forestry;" + "after:extrabees;" + "after:extratrees;" + "after:genetics;" + "after:magicbees;" + - "after:jei@[4.15.0,);" + "after:crafttweaker@[4.1.20,);" + "after:groovyscript@[0.7.0,);" + - "after:theoneprobe;" + "after:hwyla;" + "after:exnihilocreatio;") + "after:jei@[4.15.0,);" + "after:crafttweaker@[4.1.20,);" + "after:groovyscript@[1.2.0,);" + + "after:theoneprobe;" + "after:hwyla;" + "after:exnihilocreatio;") public class GregTechMod { // Hold this so that we can reference non-interface methods without @@ -50,6 +51,7 @@ public GregTechMod() { @EventHandler public void onConstruction(FMLConstructionEvent event) { + PersistentData.instance().init(); moduleManager = ModuleManager.getInstance(); GregTechAPI.moduleManager = moduleManager; moduleManager.registerContainer(new GregTechModules()); diff --git a/src/main/java/gregtech/api/GTValues.java b/src/main/java/gregtech/api/GTValues.java index 4549dc6c075..be3cfde2e9e 100644 --- a/src/main/java/gregtech/api/GTValues.java +++ b/src/main/java/gregtech/api/GTValues.java @@ -7,6 +7,8 @@ import net.minecraftforge.fml.relauncher.FMLLaunchHandler; import net.minecraftforge.oredict.OreDictionary; +import org.jetbrains.annotations.ApiStatus; + import java.time.LocalDate; import java.util.Random; import java.util.function.Supplier; @@ -52,7 +54,7 @@ public class GTValues { * The Voltage Tiers. Use this Array instead of the old named Voltage Variables */ public static final long[] V = { 8, 32, 128, 512, 2048, 8192, 32768, 131072, 524288, 2097152, 8388608, 33554432, - 134217728, 536870912, Integer.MAX_VALUE }; + 134217728, 536870912, 2147483648L }; /** * The Voltage Tiers divided by 2. @@ -72,6 +74,15 @@ public class GTValues { public static final int[] VHA = { 7, 16, 60, 240, 960, 3840, 15360, 61440, 245760, 983040, 3932160, 15728640, 62914560, 251658240, 1006632960 }; + /** + * The Voltage Tiers extended all the way to max Long value for overclocking + */ + public static final long[] VOC = { 8, 32, 128, 512, 2048, 8192, 32768, 131072, 524288, 2097152, 8388608, 33554432, + 134217728, 536870912, 2147483648L, 8589934592L, 34359738368L, 137438953472L, 549755813888L, + 2199023255552L, 8796093022208L, 35184372088832L, 140737488355328L, 562949953421312L, 2251799813685248L, + 9007199254740992L, 36028797018963968L, 144115188075855872L, 576460752303423488L, 2305843009213693952L, + Long.MAX_VALUE }; + public static final int ULV = 0; public static final int LV = 1; public static final int MV = 2; @@ -88,6 +99,7 @@ public class GTValues { public static final int UXV = 12; public static final int OpV = 13; public static final int MAX = 14; + public static final int MAX_TRUE = 30; /** * The short names for the voltages, used for registration primarily @@ -95,6 +107,17 @@ public class GTValues { public static final String[] VN = new String[] { "ULV", "LV", "MV", "HV", "EV", "IV", "LuV", "ZPM", "UV", "UHV", "UEV", "UIV", "UXV", "OpV", "MAX" }; + /** + * The short names for the voltages, up to max Long, used for registration primarily + */ + public static final String[] VOCN = new String[] { "ULV", "LV", "MV", "HV", "EV", "IV", "LuV", "ZPM", "UV", "UHV", + "UEV", "UIV", "UXV", "OpV", "MAX", "MAX+1", "MAX+2", "MAX+3", "MAX+4", "MAX+5", "MAX+6", "MAX+7", "MAX+8", + "MAX+9", "MAX+10", "MAX+11", "MAX+12", "MAX+13", "MAX+14", "MAX+15", "MAX+16", + }; + + private static final String MAX_PLUS = RED.toString() + BOLD + "M" + YELLOW + BOLD + "A" + GREEN + BOLD + "X" + + AQUA + BOLD + "+" + LIGHT_PURPLE + BOLD; + /** * The short names for the voltages, formatted for text */ @@ -105,6 +128,20 @@ public class GTValues { DARK_RED + "UHV", GREEN + "UEV", DARK_GREEN + "UIV", YELLOW + "UXV", BLUE + "OpV", RED.toString() + BOLD + "MAX" }; + /** + * The short names for the voltages, up to max Long, formatted for text + */ + public static final String[] VOCNF = new String[] { + DARK_GRAY + "ULV", GRAY + "LV", AQUA + "MV", + GOLD + "HV", DARK_PURPLE + "EV", DARK_BLUE + "IV", + LIGHT_PURPLE + "LuV", RED + "ZPM", DARK_AQUA + "UV", + DARK_RED + "UHV", GREEN + "UEV", DARK_GREEN + "UIV", + YELLOW + "UXV", BLUE + "OpV", RED.toString() + BOLD + "MAX", + MAX_PLUS + "1", MAX_PLUS + "2", MAX_PLUS + "3", MAX_PLUS + "4", + MAX_PLUS + "5", MAX_PLUS + "6", MAX_PLUS + "7", MAX_PLUS + "8", + MAX_PLUS + "9", MAX_PLUS + "10", MAX_PLUS + "11", MAX_PLUS + "12", + MAX_PLUS + "13", MAX_PLUS + "14", MAX_PLUS + "15", MAX_PLUS + "16", }; + /** * Color values for the voltages */ @@ -120,10 +157,19 @@ public class GTValues { "Overpowered Voltage", "Maximum Voltage" }; /** - * ModID strings, since they are quite common parameters + * GregTech Mod ID */ - public static final String MODID = "gregtech", - MODID_FR = "forestry", + public static final String MODID = "gregtech"; + + /** + * GregTech Mod Name + */ + public static final String MOD_NAME = "GregTech"; + + /** @deprecated Use {@link gregtech.api.util.Mods} instead */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") + public static final String MODID_FR = "forestry", MODID_CT = "crafttweaker", MODID_TOP = "theoneprobe", MODID_CTM = "ctm", @@ -159,7 +205,9 @@ public class GTValues { MODID_EN = "exnihilocreatio", MODID_PROJRED_CORE = "projectred-core", MODID_RC = "railcraft", - MODID_CHISEL = "chisel"; + MODID_CHISEL = "chisel", + 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 f3279eb5b3b..4e3bc8bc69c 100644 --- a/src/main/java/gregtech/api/GregTechAPI.java +++ b/src/main/java/gregtech/api/GregTechAPI.java @@ -1,34 +1,27 @@ 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.recipes.properties.RecipePropertyRegistry; import gregtech.api.sound.ISoundManager; -import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Material; -import gregtech.api.unification.material.Materials; import gregtech.api.unification.material.registry.IMaterialRegistryManager; import gregtech.api.unification.material.registry.MarkerMaterialRegistry; -import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.ore.StoneType; -import gregtech.api.util.BaseCreativeTab; import gregtech.api.util.GTControlledRegistry; import gregtech.api.util.GTLog; import gregtech.api.util.IBlockOre; import gregtech.common.ConfigHolder; -import gregtech.common.blocks.BlockWarningSign; -import gregtech.common.blocks.MetaBlocks; -import gregtech.common.items.MetaItems; -import gregtech.common.items.ToolItems; -import gregtech.common.metatileentities.MetaTileEntities; +import gregtech.datafix.migration.lib.MigrationAPI; import net.minecraft.block.state.IBlockState; import net.minecraft.util.ResourceLocation; @@ -60,40 +53,26 @@ 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(); + public static final RecipePropertyRegistry RECIPE_PROPERTIES = new RecipePropertyRegistry(); /** 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 BaseCreativeTab TAB_GREGTECH = new BaseCreativeTab(GTValues.MODID + ".main", - () -> MetaItems.LOGO.getStackForm(), true); - public static final BaseCreativeTab TAB_GREGTECH_MACHINES = new BaseCreativeTab(GTValues.MODID + ".machines", - () -> MetaTileEntities.ELECTRIC_BLAST_FURNACE.getStackForm(), true); - public static final BaseCreativeTab TAB_GREGTECH_CABLES = new BaseCreativeTab(GTValues.MODID + ".cables", - () -> OreDictUnifier.get(OrePrefix.cableGtDouble, Materials.Aluminium), true); - public static final BaseCreativeTab TAB_GREGTECH_PIPES = new BaseCreativeTab(GTValues.MODID + ".pipes", - () -> OreDictUnifier.get(OrePrefix.pipeNormalFluid, Materials.Aluminium), true); - public static final BaseCreativeTab TAB_GREGTECH_TOOLS = new BaseCreativeTab(GTValues.MODID + ".tools", - () -> ToolItems.HARD_HAMMER.get(Materials.Aluminium), true); - public static final BaseCreativeTab TAB_GREGTECH_MATERIALS = new BaseCreativeTab(GTValues.MODID + ".materials", - () -> OreDictUnifier.get(OrePrefix.ingot, Materials.Aluminium), true); - public static final BaseCreativeTab TAB_GREGTECH_ORES = new BaseCreativeTab(GTValues.MODID + ".ores", - () -> OreDictUnifier.get(OrePrefix.ore, Materials.Aluminium), true); - public static final BaseCreativeTab TAB_GREGTECH_DECORATIONS = new BaseCreativeTab(GTValues.MODID + ".decorations", - () -> MetaBlocks.WARNING_SIGN.getItemVariant(BlockWarningSign.SignType.YELLOW_STRIPES), true); + 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/IHeatingCoilBlockStats.java b/src/main/java/gregtech/api/block/IHeatingCoilBlockStats.java index 5f6e5c49c06..0e2b7427591 100644 --- a/src/main/java/gregtech/api/block/IHeatingCoilBlockStats.java +++ b/src/main/java/gregtech/api/block/IHeatingCoilBlockStats.java @@ -1,6 +1,6 @@ package gregtech.api.block; -import gregtech.api.recipes.recipeproperties.TemperatureProperty; +import gregtech.api.recipes.properties.impl.TemperatureProperty; import gregtech.api.unification.material.Material; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/gregtech/api/block/VariantActiveBlock.java b/src/main/java/gregtech/api/block/VariantActiveBlock.java index 4818c4a933a..ba4ac712a03 100644 --- a/src/main/java/gregtech/api/block/VariantActiveBlock.java +++ b/src/main/java/gregtech/api/block/VariantActiveBlock.java @@ -1,6 +1,6 @@ package gregtech.api.block; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.client.model.ActiveVariantBlockBakedModel; import gregtech.client.utils.BloomEffectUtil; import gregtech.common.ConfigHolder; @@ -22,7 +22,6 @@ import net.minecraftforge.common.property.ExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -135,7 +134,7 @@ public IExtendedBlockState getExtendedState(@NotNull IBlockState state, @NotNull .withProperty(ACTIVE, Minecraft.getMinecraft().world != null && isBlockActive(Minecraft.getMinecraft().world.provider.getDimension(), pos)); - if (Loader.isModLoaded(GTValues.MODID_CTM)) { + if (Mods.CTM.isModLoaded()) { // if the Connected Textures Mod is loaded we wrap our IExtendedBlockState with their wrapper, // so that the CTM renderer can render the block properly. return new CTMExtendedState(ext, world, pos); diff --git a/src/main/java/gregtech/api/block/VariantBlock.java b/src/main/java/gregtech/api/block/VariantBlock.java index 5b0310263ef..7e31dd48c3b 100644 --- a/src/main/java/gregtech/api/block/VariantBlock.java +++ b/src/main/java/gregtech/api/block/VariantBlock.java @@ -1,7 +1,7 @@ package gregtech.api.block; -import gregtech.api.GregTechAPI; import gregtech.api.util.LocalizationUtils; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.Block; import net.minecraft.block.material.Material; @@ -43,7 +43,7 @@ public VariantBlock(Material materialIn) { state); } } - setCreativeTab(GregTechAPI.TAB_GREGTECH); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH); setDefaultState(this.blockState.getBaseState().withProperty(VARIANT, VALUES[0])); } diff --git a/src/main/java/gregtech/api/block/machines/BlockMachine.java b/src/main/java/gregtech/api/block/machines/BlockMachine.java index f9a77ccbe07..2a04cf5d441 100644 --- a/src/main/java/gregtech/api/block/machines/BlockMachine.java +++ b/src/main/java/gregtech/api/block/machines/BlockMachine.java @@ -1,10 +1,10 @@ package gregtech.api.block.machines; -import gregtech.api.GTValues; import gregtech.api.GregTechAPI; 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; @@ -13,9 +13,12 @@ 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; import gregtech.client.renderer.handler.MetaTileEntityRenderer; +import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.items.MetaItems; import gregtech.integration.ctm.IFacadeWrapper; @@ -40,7 +43,11 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.*; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumBlockRenderType; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; @@ -51,7 +58,6 @@ import net.minecraftforge.common.property.ExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -63,7 +69,13 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Random; +import java.util.Set; import static gregtech.api.util.GTUtility.getMetaTileEntity; @@ -83,7 +95,7 @@ public class BlockMachine extends BlockCustomParticle implements ITileEntityProv public BlockMachine() { super(Material.IRON); - setCreativeTab(GregTechAPI.TAB_GREGTECH_MACHINES); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_MACHINES); setSoundType(SoundType.METAL); setHardness(6.0f); setResistance(6.0f); @@ -194,6 +206,15 @@ public ItemStack getPickBlock(@NotNull IBlockState state, @NotNull RayTraceResul return ItemStack.EMPTY; } + @NotNull + @Override + public ItemStack getItem(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState state) { + MetaTileEntity metaTileEntity = getMetaTileEntity(world, pos); + if (metaTileEntity == null) + return ItemStack.EMPTY; + return metaTileEntity.getStackForm(); + } + @Override public void addCollisionBoxToList(@NotNull IBlockState state, @NotNull World worldIn, @NotNull BlockPos pos, @NotNull AxisAlignedBB entityBox, @NotNull List collidingBoxes, @@ -246,17 +267,42 @@ 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()); - 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()); + MTERegistry registry = GregTechAPI.mteManager.getRegistry( + Objects.requireNonNull(stack.getItem().getRegistryName()).getNamespace()); + + MetaTileEntity sampleMetaTileEntity = registry.getObjectById(stack.getItemDamage()); + if (holder == null || sampleMetaTileEntity == null) + return; + + // TODO Fix this + if (stack.hasDisplayName() && holder instanceof MetaTileEntityHolder) { + ((MetaTileEntityHolder) holder).setCustomName(stack.getDisplayName()); + } + var stackTag = stack.getTagCompound(); + NBTTagCompound mteTag = null; + 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); + + mteTag = blockTag.getCompoundTag(GregtechDataCodes.TAG_KEY_MTE); + List removed = new ArrayList<>(); + for (var key : mteTag.getKeySet()) { + var trait = sampleMetaTileEntity.getMTETrait(key); + if (trait == null) continue; + + removed.add(key); + } + removed.forEach(mteTag::removeTag); } + } + MetaTileEntity metaTileEntity = holder.setMetaTileEntity(sampleMetaTileEntity, mteTag); + if (mteTag == null) { + if (stackTag != null && !stackTag.isEmpty()) + metaTileEntity.initFromItemStackData(stackTag); + if (metaTileEntity.isValidFrontFacing(EnumFacing.UP)) { metaTileEntity.setFrontFacing(EnumFacing.getDirectionFromEntityLiving(pos, placer)); } else { @@ -272,26 +318,26 @@ public void onBlockPlacedBy(World worldIn, @NotNull BlockPos pos, @NotNull IBloc } } } - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { - if (metaTileEntity.getProxy() != null) { - metaTileEntity.getProxy().setOwner((EntityPlayer) placer); - } + } + if (Mods.AppliedEnergistics2.isModLoaded()) { + if (metaTileEntity.getProxy() != null) { + metaTileEntity.getProxy().setOwner((EntityPlayer) placer); } + } - // Color machines on place if holding spray can in off-hand - if (placer instanceof EntityPlayer) { - ItemStack offhand = placer.getHeldItemOffhand(); - for (int i = 0; i < EnumDyeColor.values().length; i++) { - if (offhand.isItemEqual(MetaItems.SPRAY_CAN_DYES[i].getStackForm())) { - MetaItems.SPRAY_CAN_DYES[i].getBehaviours().get(0).onItemUse((EntityPlayer) placer, worldIn, - pos, EnumHand.OFF_HAND, EnumFacing.UP, 0, 0, 0); - break; - } + // Color machines on place if holding spray can in off-hand + if (placer instanceof EntityPlayer) { + ItemStack offhand = placer.getHeldItemOffhand(); + for (int i = 0; i < EnumDyeColor.values().length; i++) { + if (offhand.isItemEqual(MetaItems.SPRAY_CAN_DYES[i].getStackForm())) { + MetaItems.SPRAY_CAN_DYES[i].getBehaviours().get(0).onItemUse((EntityPlayer) placer, worldIn, + pos, EnumHand.OFF_HAND, EnumFacing.UP, 0, 0, 0); + break; } } - - metaTileEntity.onPlacement(); } + + metaTileEntity.onPlacement(placer); } @Override @@ -299,7 +345,7 @@ public void breakBlock(@NotNull World worldIn, @NotNull BlockPos pos, @NotNull I MetaTileEntity metaTileEntity = getMetaTileEntity(worldIn, pos); if (metaTileEntity != null) { if (!metaTileEntity.keepsInventory()) { - NonNullList inventoryContents = NonNullList.create(); + List inventoryContents = new ArrayList<>(); metaTileEntity.clearMachineInventory(inventoryContents); for (ItemStack itemStack : inventoryContents) { Block.spawnAsEntity(worldIn, pos, itemStack); @@ -423,7 +469,7 @@ public void harvestBlock(@NotNull World worldIn, @NotNull EntityPlayer player, @ @NotNull IBlockState state, @Nullable TileEntity te, @NotNull ItemStack stack) { tileEntities.set(te == null ? tileEntities.get() : ((IGregTechTileEntity) te).getMetaTileEntity()); super.harvestBlock(worldIn, player, pos, state, te, stack); - tileEntities.set(null); + tileEntities.remove(); } @Nullable @@ -473,12 +519,15 @@ public int getLightValue(@NotNull IBlockState state, @NotNull IBlockAccess world public int getLightOpacity(@NotNull IBlockState state, @NotNull IBlockAccess world, @NotNull BlockPos pos) { // since it is called on neighbor blocks MetaTileEntity metaTileEntity = getMetaTileEntity(world, pos); - return metaTileEntity == null ? 0 : metaTileEntity.getLightOpacity(); + return metaTileEntity == null ? 255 : metaTileEntity.getLightOpacity(); } @Override 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 1186eaefa7c..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; @@ -10,6 +9,7 @@ import gregtech.api.util.LocalizationUtils; import gregtech.client.utils.TooltipHelper; import gregtech.common.ConfigHolder; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; @@ -47,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. @@ -61,8 +61,8 @@ public class MachineItemBlock extends ItemBlock { */ public static void addCreativeTab(CreativeTabs creativeTab) { Preconditions.checkNotNull(creativeTab, "creativeTab"); - if (creativeTab == GregTechAPI.TAB_GREGTECH_MACHINES) { - throw new IllegalArgumentException("Adding " + GregTechAPI.TAB_GREGTECH_MACHINES.tabLabel + + if (creativeTab == GTCreativeTabs.TAB_GREGTECH_MACHINES) { + throw new IllegalArgumentException("Adding " + GTCreativeTabs.TAB_GREGTECH_MACHINES.tabLabel + " as additional creative tab is redundant."); } else if (creativeTab == CreativeTabs.SEARCH) { throw new IllegalArgumentException( @@ -91,7 +91,7 @@ public boolean placeBlockAt(@NotNull ItemStack stack, @NotNull EntityPlayer play // prevent rendering glitch before meta tile entity sync to client, but after block placement // set opaque property on the placing on block, instead during set of meta tile entity boolean superVal = super.placeBlockAt(stack, player, world, pos, side, hitX, hitY, hitZ, - newState.withProperty(BlockMachine.OPAQUE, metaTileEntity != null && metaTileEntity.isOpaqueCube())); + newState.withProperty(BlockMachine.OPAQUE, metaTileEntity == null || metaTileEntity.isOpaqueCube())); if (superVal && !world.isRemote) { BlockPos possiblePipe = pos.offset(side.getOpposite()); Block block = world.getBlockState(possiblePipe).getBlock(); @@ -202,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/GregtechCapabilities.java b/src/main/java/gregtech/api/capability/GregtechCapabilities.java index 985d6c5a7fe..df163402aeb 100644 --- a/src/main/java/gregtech/api/capability/GregtechCapabilities.java +++ b/src/main/java/gregtech/api/capability/GregtechCapabilities.java @@ -2,7 +2,6 @@ import gregtech.api.GTValues; import gregtech.api.capability.impl.EUToFEProvider; -import gregtech.api.terminal.hardware.HardwareProvider; import gregtech.api.util.GTUtility; import gregtech.common.metatileentities.converter.ConverterTrait; @@ -26,9 +25,6 @@ public class GregtechCapabilities { @CapabilityInject(IMultiblockController.class) public static Capability CAPABILITY_MULTIBLOCK_CONTROLLER = null; - @CapabilityInject(HardwareProvider.class) - public static Capability CAPABILITY_HARDWARE_PROVIDER = null; - @CapabilityInject(ConverterTrait.class) public static Capability CAPABILITY_CONVERTER = null; diff --git a/src/main/java/gregtech/api/capability/GregtechDataCodes.java b/src/main/java/gregtech/api/capability/GregtechDataCodes.java index e425d3339e4..6054957ac0a 100644 --- a/src/main/java/gregtech/api/capability/GregtechDataCodes.java +++ b/src/main/java/gregtech/api/capability/GregtechDataCodes.java @@ -23,6 +23,9 @@ public static int assignId() { public static final int UPDATE_AUTO_OUTPUT_FLUIDS = assignId(); public static final int UPDATE_IS_VOIDING = assignId(); + // Robotic Arm + public static final int UPDATE_TRANSFER_MODE = assignId(); + // Drum public static final int UPDATE_AUTO_OUTPUT = assignId(); @@ -137,6 +140,11 @@ public static int assignId() { public static final int UPDATE_ITEM_COUNT = assignId(); public static final int UPDATE_FLUID_AMOUNT = assignId(); + // Quantum Storage Controller + public static final int UPDATE_CONTROLLER_POS = assignId(); + public static final int REMOVE_CONTROLLER = assignId(); + public static final int LOCATE_CONTROLLER = assignId(); + // Detector Covers public static final int UPDATE_INVERTED = assignId(); @@ -149,6 +157,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"; @@ -166,4 +176,8 @@ public static int assignId() { // Alarm public static final int UPDATE_SOUND = assignId(); public static final int UPDATE_RADIUS = assignId(); + + // ME Parts + public static final int UPDATE_AUTO_PULL = assignId(); + public static final int UPDATE_ONLINE_STATUS = assignId(); } diff --git a/src/main/java/gregtech/api/capability/IDataStickIntractable.java b/src/main/java/gregtech/api/capability/IDataStickIntractable.java new file mode 100644 index 00000000000..4b9d36ee6ff --- /dev/null +++ b/src/main/java/gregtech/api/capability/IDataStickIntractable.java @@ -0,0 +1,11 @@ +package gregtech.api.capability; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +public interface IDataStickIntractable { + + void onDataStickLeftClick(EntityPlayer player, ItemStack dataStick); + + boolean onDataStickRightClick(EntityPlayer player, ItemStack dataStick); +} diff --git a/src/main/java/gregtech/api/capability/IDistillationTower.java b/src/main/java/gregtech/api/capability/IDistillationTower.java new file mode 100644 index 00000000000..e7bf447518b --- /dev/null +++ b/src/main/java/gregtech/api/capability/IDistillationTower.java @@ -0,0 +1,22 @@ +package gregtech.api.capability; + +import gregtech.api.metatileentity.multiblock.IMultiblockPart; + +import net.minecraft.util.math.BlockPos; + +import java.util.List; + +/** + * intended for use in conjunction with {@link gregtech.api.capability.impl.DistillationTowerLogicHandler} + * use with distillation tower type multiblocks + */ +public interface IDistillationTower { + + List getMultiblockParts(); + + BlockPos getPos(); + + void invalidateStructure(); + + boolean allowSameFluidFillForOutputs(); +} diff --git a/src/main/java/gregtech/api/capability/IDualHandler.java b/src/main/java/gregtech/api/capability/IDualHandler.java new file mode 100644 index 00000000000..595efc6a9f2 --- /dev/null +++ b/src/main/java/gregtech/api/capability/IDualHandler.java @@ -0,0 +1,14 @@ +package gregtech.api.capability; + +import net.minecraftforge.items.IItemHandler; + +public interface IDualHandler { + + boolean hasFluidTanks(); + + boolean hasItemHandlers(); + + IMultipleTankHandler getFluidTanks(); + + IItemHandler getItemHandlers(); +} diff --git a/src/main/java/gregtech/api/capability/IQuantumController.java b/src/main/java/gregtech/api/capability/IQuantumController.java new file mode 100644 index 00000000000..f2e5d333a5a --- /dev/null +++ b/src/main/java/gregtech/api/capability/IQuantumController.java @@ -0,0 +1,34 @@ +package gregtech.api.capability; + +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.common.capabilities.ICapabilityProvider; + +// ICapabilityProvider is needed because getCapability is called in the quantum proxy against this interface +public interface IQuantumController extends ICapabilityProvider { + + /** + * Constructs the network upon placement and when storages are added/removed + *
+ */ + void rebuildNetwork(); + + /** + * Return whether this storage block can connect. Can be used to implement a maximum distance from controller for + * example. + */ + boolean canConnect(IQuantumStorage storage); + + BlockPos getPos(); + + IDualHandler getHandler(); + + boolean isPowered(); + + long getEnergyUsage(); + + int getCount(IQuantumStorage.Type type); + + long getTypeEnergy(IQuantumStorage storage); + + void updateHandler(); +} diff --git a/src/main/java/gregtech/api/capability/IQuantumStorage.java b/src/main/java/gregtech/api/capability/IQuantumStorage.java new file mode 100644 index 00000000000..8a60ca63bf9 --- /dev/null +++ b/src/main/java/gregtech/api/capability/IQuantumStorage.java @@ -0,0 +1,77 @@ +package gregtech.api.capability; + +import gregtech.api.cover.CoverableView; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; + +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; + +import org.jetbrains.annotations.Nullable; + +public interface IQuantumStorage extends CoverableView { + + Type getType(); + + void setConnected(IQuantumController controller); + + void setDisconnected(); + + BlockPos getControllerPos(); + + @Nullable + IQuantumController getQuantumController(); + + BlockPos getPos(); + + default boolean isConnected() { + // use controllerPos here because it is synced + // on both sides, where controller is not + return getControllerPos() != null; + } + + default void tryFindNetwork() { + for (EnumFacing facing : EnumFacing.VALUES) { + var offset = getPos().offset(facing); + var state = getWorld().getBlockState(offset); + if (state.getBlock().isAir(state, getWorld(), offset)) continue; + MetaTileEntity mte; + if (getNeighbor(facing) instanceof IGregTechTileEntity gtte) { + mte = gtte.getMetaTileEntity(); + } else { + continue; + } + + IQuantumController candidate = null; + if (mte instanceof IQuantumStoragestorage) { + if (storage.isConnected()) { + IQuantumController controller = storage.getQuantumController(); + if (controller != null && controller.canConnect(this)) { + candidate = controller; + } + } + } else if (mte instanceof IQuantumController quantumController) { + if (quantumController.canConnect(this)) { + candidate = quantumController; + } + } + if (candidate != null) { + candidate.rebuildNetwork(); + return; + } + } + } + + T getTypeValue(); + + enum Type { + + ITEM, + FLUID, + EXTENDER, + PROXY, + ENERGY; + + public static final Type[] VALUES = values(); + } +} diff --git a/src/main/java/gregtech/api/capability/SimpleCapabilityManager.java b/src/main/java/gregtech/api/capability/SimpleCapabilityManager.java index 8aad39dc29c..f517b473bab 100644 --- a/src/main/java/gregtech/api/capability/SimpleCapabilityManager.java +++ b/src/main/java/gregtech/api/capability/SimpleCapabilityManager.java @@ -3,7 +3,6 @@ import gregtech.api.capability.impl.AbstractRecipeLogic; import gregtech.api.cover.CoverHolder; import gregtech.api.metatileentity.multiblock.IMaintenance; -import gregtech.api.terminal.hardware.HardwareProvider; import gregtech.api.worldgen.generator.GTWorldGenCapability; import gregtech.common.metatileentities.converter.ConverterTrait; @@ -48,7 +47,6 @@ public static void init() { registerCapabilityWithNoDefault(AbstractRecipeLogic.class); registerCapabilityWithNoDefault(IDataAccessHatch.class); registerCapabilityWithNoDefault(IOpticalComputationProvider.class); - registerCapabilityWithNoDefault(HardwareProvider.class); registerCapabilityWithNoDefault(ConverterTrait.class); registerCapabilityWithNoDefault(ILaserContainer.class); diff --git a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java index cc2ce878aee..455ae3afd47 100644 --- a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java @@ -1,7 +1,11 @@ package gregtech.api.capability.impl; import gregtech.api.GTValues; -import gregtech.api.capability.*; +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IMultiblockController; +import gregtech.api.capability.IMultipleTankHandler; +import gregtech.api.capability.IWorkable; import gregtech.api.metatileentity.MTETrait; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.multiblock.CleanroomType; @@ -9,10 +13,15 @@ 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.IRecipePropertyStorage; +import gregtech.api.recipes.logic.OCParams; +import gregtech.api.recipes.logic.OCResult; +import gregtech.api.recipes.properties.RecipePropertyStorage; +import gregtech.api.recipes.properties.impl.CleanroomProperty; +import gregtech.api.recipes.properties.impl.DimensionProperty; +import gregtech.api.util.GTLog; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; import gregtech.common.ConfigHolder; @@ -21,7 +30,6 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.network.PacketBuffer; -import net.minecraft.util.NonNullList; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.Constants; @@ -29,6 +37,7 @@ import net.minecraftforge.fluids.IFluidTank; import net.minecraftforge.items.IItemHandlerModifiable; +import org.jetbrains.annotations.MustBeInvokedByOverriders; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -45,19 +54,23 @@ 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; - private long overclockVoltage = 0; - protected int[] overclockResults; + private long overclockVoltage; + private final OCParams ocParams = new OCParams(); + private final OCResult ocResult = new OCResult(); protected boolean canRecipeProgress = true; protected int progressTime; protected int maxProgressTime; - protected int recipeEUt; + protected long recipeEUt; protected List fluidOutputs; - protected NonNullList itemOutputs; + protected List itemOutputs; protected boolean isActive; protected boolean workingEnabled = true; @@ -66,7 +79,7 @@ public abstract class AbstractRecipeLogic extends MTETrait implements IWorkable, protected boolean isOutputsFull; protected boolean invalidInputsForRecipes; - protected boolean hasPerfectOC = false; + protected boolean hasPerfectOC; /** * DO NOT use the parallelLimit field directly, EVER @@ -107,7 +120,7 @@ public AbstractRecipeLogic(MetaTileEntity tileEntity, RecipeMap recipeMap, bo * @param simulate whether to simulate energy extraction or not * @return true if the energy can/was drained, otherwise false */ - protected abstract boolean drawEnergy(int recipeEUt, boolean simulate); + protected abstract boolean drawEnergy(long recipeEUt, boolean simulate); /** * @return the maximum voltage the machine can use/handle for recipe searching @@ -234,16 +247,16 @@ protected boolean shouldSearchForRecipes() { * @return true if input inventory contents have changed */ protected boolean hasNotifiedInputs() { - return (metaTileEntity.getNotifiedItemInputList().size() > 0 || - metaTileEntity.getNotifiedFluidInputList().size() > 0); + return !metaTileEntity.getNotifiedItemInputList().isEmpty() || + !metaTileEntity.getNotifiedFluidInputList().isEmpty(); } /** * @return true if output inventory contents have changed */ protected boolean hasNotifiedOutputs() { - return (metaTileEntity.getNotifiedItemOutputList().size() > 0 || - metaTileEntity.getNotifiedFluidOutputList().size() > 0); + return !metaTileEntity.getNotifiedItemOutputList().isEmpty() || + !metaTileEntity.getNotifiedFluidOutputList().isEmpty(); } /** @@ -403,7 +416,7 @@ protected boolean checkPreviousRecipe() { * @return true if the recipe is allowed to be used, else false */ public boolean checkRecipe(@NotNull Recipe recipe) { - return checkCleanroomRequirement(recipe); + return checkCleanroomRequirement(recipe) && checkDimensionRequirement(recipe); } /** @@ -427,39 +440,86 @@ protected boolean checkCleanroomRequirement(@NotNull Recipe recipe) { return false; } + protected boolean checkDimensionRequirement(@NotNull Recipe recipe) { + DimensionProperty.DimensionPropertyList list = recipe.getProperty(DimensionProperty.getInstance(), null); + if (list == null) { + return true; + } + return list.checkDimension(this.getMetaTileEntity().getWorld().provider.getDimension()); + } + /** * Prepares the recipe to be run. *
    *
  1. The recipe is run in parallel if possible.
  2. *
  3. The potentially parallel recipe is then checked to exist.
  4. - *
  5. If it exists, it checks if the recipe is runnable with the current inputs.
  6. + *
  7. If it exists, it checks if the recipe is runnable with the inputs provided.
  8. *
* If the above conditions are met, the recipe is engaged to be run * - * @param recipe the recipe to prepare + * @param recipe the recipe to prepare + * @param inputInventory the inventory to draw items from + * @param inputFluidInventory the fluid tanks to draw fluid from * @return true if the recipe was successfully prepared, else false */ - protected boolean prepareRecipe(Recipe recipe) { + public boolean prepareRecipe(Recipe recipe, IItemHandlerModifiable inputInventory, + IMultipleTankHandler inputFluidInventory) { recipe = Recipe.trimRecipeOutputs(recipe, getRecipeMap(), metaTileEntity.getItemOutputLimit(), metaTileEntity.getFluidOutputLimit()); + // 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, - getInputInventory(), - getInputTank(), + inputInventory, + inputFluidInventory, getOutputInventory(), getOutputTank(), getMaxParallelVoltage(), getParallelLimit()); - if (recipe != null && setupAndConsumeRecipeInputs(recipe, getInputInventory())) { - setupRecipe(recipe); - return true; + if (recipe != null) { + recipe = setupAndConsumeRecipeInputs(recipe, inputInventory, inputFluidInventory); + if (recipe != null) { + setupRecipe(recipe); + return true; + } } return false; } + /** + * Prepares the recipe to be run. + *
    + *
  1. The recipe is run in parallel if possible.
  2. + *
  3. The potentially parallel recipe is then checked to exist.
  4. + *
  5. If it exists, it checks if the recipe is runnable with the current inputs.
  6. + *
+ * If the above conditions are met, the recipe is engaged to be run + * + * @param recipe the recipe to prepare + * @return true if the recipe was successfully prepared from the default inventory, else false + */ + public boolean prepareRecipe(Recipe recipe) { + return prepareRecipe(recipe, getInputInventory(), getInputTank()); + } + /** * DO NOT use the parallelLimit field directly, EVER * @@ -478,6 +538,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 */ @@ -541,31 +650,72 @@ protected static boolean areItemStacksEqual(@NotNull ItemStack stackA, @NotNull /** * Determines if the provided recipe is possible to run from the provided inventory, or if there is anything - * preventing - * the Recipe from being completed. + * preventing the Recipe from being completed. *

* Will consume the inputs of the Recipe if it is possible to run. * - * @param recipe - The Recipe that will be consumed from the inputs and ran in the machine - * @param importInventory - The inventory that the recipe should be consumed from. - * Used mainly for Distinct bus implementation for multiblocks to specify - * a specific bus - * @return - true if the recipe is successful, false if the recipe is not successful + * @param recipe The Recipe that will be consumed from the inputs and ran in the machine + * @param importInventory The inventory that the recipe should be consumed from. Used mainly for Distinct bus + * implementation for multiblocks to specify a specific bus + * @return the recipe if the setup is successful, null if the setup is not successful */ - protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, - @NotNull IItemHandlerModifiable importInventory) { - this.overclockResults = calculateOverclock(recipe); + @MustBeInvokedByOverriders + protected @Nullable Recipe setupAndConsumeRecipeInputs(@NotNull Recipe recipe, + @NotNull IItemHandlerModifiable importInventory) { + return setupAndConsumeRecipeInputs(recipe, importInventory, this.getInputTank()); + } - modifyOverclockPost(overclockResults, recipe.getRecipePropertyStorage()); + /** + * Determines if the provided recipe is possible to run from the provided inventory, or if there is anything + * preventing the Recipe from being completed. + *

+ * Will consume the inputs of the Recipe if it is possible to run. + * + * @param recipe The Recipe that will be consumed from the inputs and ran in the machine + * @param importInventory The inventory that the recipe should be consumed from. Used mainly for Distinct bus + * implementation for multiblocks to specify a specific bus, or for addons to use external + * inventories. + * @param importFluids The tanks that the recipe should be consumed from Used currently in addons to use + * external tanks. + * @return the recipe if the setup is successful, null if the setup is not successful + */ + protected final @Nullable Recipe setupAndConsumeRecipeInputs(@NotNull Recipe recipe, + @NotNull IItemHandlerModifiable importInventory, + @NotNull IMultipleTankHandler importFluids) { + calculateOverclock(recipe); + + modifyOverclockPost(ocResult, recipe.propertyStorage()); + + if (ocResult.parallel() > 1) { + recipe = subTickOC(ocResult, recipe, importInventory, importFluids); + if (recipe == null) { + invalidateInputs(); + return null; + } + } - if (!hasEnoughPower(overclockResults)) { - return false; + if (!hasEnoughPower(ocResult.eut(), ocResult.duration())) { + ocResult.reset(); + return null; } - IItemHandlerModifiable exportInventory = getOutputInventory(); - IMultipleTankHandler importFluids = getInputTank(); - IMultipleTankHandler exportFluids = getOutputTank(); + if (checkOutputSpaceItems(recipe, getOutputInventory()) && checkOutputSpaceFluids(recipe, getOutputTank())) { + this.isOutputsFull = false; + if (recipe.matches(true, importInventory, importFluids)) { + this.metaTileEntity.addNotifiedInput(importInventory); + return recipe; + } + } + + return null; + } + /** + * @param recipe the recipe to check + * @param exportInventory the inventory to output to + * @return if the recipe can be successfully output to the inventory + */ + protected boolean checkOutputSpaceItems(@NotNull Recipe recipe, @NotNull IItemHandlerModifiable exportInventory) { // 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() && @@ -573,105 +723,140 @@ protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, this.isOutputsFull = true; return false; } + return true; + } + /** + * @param recipe the recipe to check + * @param exportFluids the inventory to output to + * @return if the recipe can be successfully output to the inventory + */ + protected boolean checkOutputSpaceFluids(@NotNull Recipe recipe, @NotNull IMultipleTankHandler exportFluids) { // We have already trimmed fluid outputs at this time if (!metaTileEntity.canVoidRecipeFluidOutputs() && !GTTransferUtils.addFluidsToFluidHandler(exportFluids, true, recipe.getAllFluidOutputs())) { this.isOutputsFull = true; return false; } + return true; + } - this.isOutputsFull = false; - if (recipe.matches(true, importInventory, importFluids)) { - this.metaTileEntity.addNotifiedInput(importInventory); - return true; + /** + * Overclock a recipe beyond a duration of 1 tick using parallelization. + * + * @param ocResult the result of the overclock + * @param recipe the recipe to overclock + * @param importInventory the input item inventory + * @param importFluids the input fluid inventory + * @return the recipe if a valid recipe is produced, otherwise null + */ + protected @Nullable Recipe subTickOC(@NotNull OCResult ocResult, @NotNull Recipe recipe, + @NotNull IItemHandlerModifiable importInventory, + @NotNull IMultipleTankHandler importFluids) { + RecipeMap map = getRecipeMap(); + if (map == null) { + return null; } - return false; + + Recipe r = new RecipeBuilder<>(recipe, map) + .EUt(ocResult.eut()) + .build() + .getResult(); + + if (r == null) { + // should be impossible, but check anyway + return recipe; + } + + RecipeBuilder builder = findMultipliedParallelRecipe(map, r, importInventory, importFluids, + getOutputInventory(), getOutputTank(), ocResult.parallel(), ocResult.parallelEUt(), + getMetaTileEntity()); + + if (builder == null) { + return null; + } + + if (builder.getParallel() == 0) { + return recipe; + } + + ocResult.setEut(builder.getEUt()); + r = builder.EUt(builder.getEUt()) + .build() + .getResult(); + + if (r == null) { + return recipe; + } + + return r; } /** - * @param resultOverclock the overclock data to use. Format: {@code [EUt, duration]}. + * @param eut the overclocked EUt to check + * @param duration the overclocked duration to check * @return true if there is enough energy to continue recipe progress */ - protected boolean hasEnoughPower(@NotNull int[] resultOverclock) { - // Format of resultOverclock: EU/t, duration - int totalEUt = resultOverclock[0] * resultOverclock[1]; - - // RIP Ternary - // Power Consumption case - if (totalEUt >= 0) { - int capacity; - // If the total consumed power is greater than half the internal capacity - if (totalEUt > getEnergyCapacity() / 2) { - // Only draw 1A of power from the internal buffer to allow for recharging of the internal buffer from - // external sources - capacity = resultOverclock[0]; - } else { - // If the total consumed power is less than half the capacity, just drain the whole thing - capacity = totalEUt; - } - - // Return true if we have enough energy stored to progress the recipe, either 1A or the whole amount - return getEnergyStored() >= capacity; - } - // Power Generation case - else { - // This is the EU/t generated by the generator - int power = resultOverclock[0]; + protected boolean hasEnoughPower(long eut, int duration) { + if (eut >= 0) { + // Power Consumption case + // ensure it can run for at least 8 ticks. Arbitrary value, but should prevent instant failures + return getEnergyStored() >= (eut << 3); + } else { + // Power Generation case // Return true if we can fit at least 1A of energy into the energy output - return getEnergyStored() - (long) power <= getEnergyCapacity(); + return getEnergyStored() - eut <= getEnergyCapacity(); } } /** - * Method for modifying the overclock results, such as for Multiblock coil bonuses. - * Is always called, even if no overclocks are performed. + * Method for modifying the overclock results, such as for Multiblock coil bonuses. Is always called, even if no + * overclocks are performed. * - * @param overclockResults The overclocked recipe EUt and duration, in format [EUt, duration] - * @param storage the RecipePropertyStorage of the recipe being processed + * @param ocResult The overclock result + * @param storage the RecipePropertyStorage of the recipe being processed */ - protected void modifyOverclockPost(int[] overclockResults, @NotNull IRecipePropertyStorage storage) {} + protected void modifyOverclockPost(@NotNull OCResult ocResult, @NotNull RecipePropertyStorage storage) {} /** * Calculates the overclocked Recipe's final duration and EU/t * * @param recipe the recipe to run - * @return an int array of {OverclockedEUt, OverclockedDuration} */ - @NotNull - protected int[] calculateOverclock(@NotNull Recipe recipe) { + protected final void calculateOverclock(@NotNull Recipe recipe) { // perform the actual overclocking - return performOverclocking(recipe); + ocParams.initialize(recipe.getEUt(), recipe.getDuration(), getNumberOfOCs(recipe.getEUt())); + performOverclocking(recipe, this.ocParams, this.ocResult); + ocParams.reset(); } /** - * Determines the maximum number of overclocks that can be performed for a recipe. - * Then performs overclocking on the Recipe. + * Determines the maximum number of overclocks that can be performed for a recipe. Then performs overclocking on the + * Recipe. * - * @param recipe the recipe to overclock - * @return an int array of {OverclockedEUt, OverclockedDuration} + * @param recipe the recipe to overclock + * @param ocParams the parameters for overclocking + * @param ocResult the result of overclocking */ - protected int @NotNull [] performOverclocking(@NotNull Recipe recipe) { - int[] values = { recipe.getEUt(), recipe.getDuration(), getNumberOfOCs(recipe.getEUt()) }; - modifyOverclockPre(values, recipe.getRecipePropertyStorage()); + protected void performOverclocking(@NotNull Recipe recipe, @NotNull OCParams ocParams, @NotNull OCResult ocResult) { + modifyOverclockPre(ocParams, recipe.propertyStorage()); - if (values[2] <= 0) { + if (ocParams.ocAmount() <= 0) { // number of OCs is <= 0, so do not overclock - return new int[] { values[0], values[1] }; + ocResult.init(ocParams.eut(), ocParams.duration()); + } else { + runOverclockingLogic(ocParams, ocResult, recipe.propertyStorage(), getMaximumOverclockVoltage()); } - - return runOverclockingLogic(recipe.getRecipePropertyStorage(), values[0], getMaximumOverclockVoltage(), - values[1], values[2]); } /** * @param recipeEUt the EUt of the recipe * @return the number of times to overclock the recipe */ - protected int getNumberOfOCs(int recipeEUt) { + protected int getNumberOfOCs(long recipeEUt) { if (!isAllowOverclocking()) return 0; - int recipeTier = GTUtility.getTierByVoltage(recipeEUt); + int recipeTier = GTUtility.getOCTierByVoltage(recipeEUt); int maximumTier = getOverclockForTier(getMaximumOverclockVoltage()); if (maximumTier <= GTValues.LV) return 0; @@ -684,50 +869,40 @@ protected int getNumberOfOCs(int recipeEUt) { } /** - * Perform changes to the recipe EUt, duration, and OC count before overclocking. - * Is always called, even if no overclocks are to be performed. + * Perform changes to the recipe EUt, duration, and OC count before overclocking. Is always called, even if no + * overclocks are to be performed. * - * @param values an array of [recipeEUt, recipeDuration, numberOfOCs] - * @param storage the RecipePropertyStorage of the recipe being processed + * @param ocParams an array of [recipeEUt, recipeDuration, numberOfOCs] + * @param storage the RecipePropertyStorage of the recipe being processed */ - protected void modifyOverclockPre(@NotNull int[] values, @NotNull IRecipePropertyStorage storage) {} + protected void modifyOverclockPre(@NotNull OCParams ocParams, @NotNull RecipePropertyStorage storage) {} /** - * Calls the desired overclocking logic to be run for the recipe. - * Performs the actual overclocking on the provided recipe. - * Override this to call custom overclocking mechanics + * Calls the desired overclocking logic to be run for the recipe. Performs the actual overclocking on the provided + * recipe. Override this to call custom overclocking mechanics * + * @param ocParams the parameters for the overclock + * @param ocResult the result to store the overclock in * @param propertyStorage the recipe's property storage - * @param recipeEUt the EUt of the recipe * @param maxVoltage the maximum voltage the recipe is allowed to be run at - * @param duration the duration of the recipe - * @param amountOC the maximum amount of overclocks to perform - * @return an int array of {OverclockedEUt, OverclockedDuration} */ - @NotNull - protected int[] runOverclockingLogic(@NotNull IRecipePropertyStorage propertyStorage, int recipeEUt, - long maxVoltage, int duration, int amountOC) { - return standardOverclockingLogic( - Math.abs(recipeEUt), - maxVoltage, - duration, - amountOC, - getOverclockingDurationDivisor(), - getOverclockingVoltageMultiplier()); + protected void runOverclockingLogic(@NotNull OCParams ocParams, @NotNull OCResult ocResult, + @NotNull RecipePropertyStorage propertyStorage, long maxVoltage) { + standardOC(ocParams, ocResult, maxVoltage, getOverclockingDurationFactor(), getOverclockingVoltageFactor()); } /** - * @return the divisor to use for reducing duration upon overclocking + * @return the multiplier to use for reducing duration upon overclocking */ - protected double getOverclockingDurationDivisor() { - return hasPerfectOC ? PERFECT_OVERCLOCK_DURATION_DIVISOR : STANDARD_OVERCLOCK_DURATION_DIVISOR; + protected double getOverclockingDurationFactor() { + return hasPerfectOC ? PERFECT_DURATION_FACTOR : STD_DURATION_FACTOR; } /** * @return the multiplier to use for increasing voltage upon overclocking */ - protected double getOverclockingVoltageMultiplier() { - return STANDARD_OVERCLOCK_VOLTAGE_MULTIPLIER; + protected double getOverclockingVoltageFactor() { + return STD_VOLTAGE_FACTOR; } /** @@ -738,7 +913,7 @@ protected double getOverclockingVoltageMultiplier() { * @return the highest voltage tier the machine should use to overclock with */ protected int getOverclockForTier(long voltage) { - return GTUtility.getTierByVoltage(voltage); + return GTUtility.getOCTierByVoltage(voltage); } /** @@ -762,16 +937,22 @@ public String[] getAvailableOverclockingTiers() { * * @param recipe the recipe to run */ - protected void setupRecipe(Recipe recipe) { + @MustBeInvokedByOverriders + protected void setupRecipe(@NotNull Recipe recipe) { this.progressTime = 1; - setMaxProgress(overclockResults[1]); - this.recipeEUt = overclockResults[0]; + setMaxProgress(ocResult.duration()); + this.recipeEUt = consumesEnergy() ? ocResult.eut() : -ocResult.eut(); + int recipeTier = GTUtility.getTierByVoltage(recipe.getEUt()); int machineTier = getOverclockForTier(getMaximumOverclockVoltage()); - this.fluidOutputs = GTUtility - .copyFluidList(recipe.getResultFluidOutputs(recipeTier, machineTier, getRecipeMap())); - this.itemOutputs = GTUtility - .copyStackList(recipe.getResultItemOutputs(recipeTier, machineTier, getRecipeMap())); + + RecipeMap map = getRecipeMap(); + if (map != null) { + this.fluidOutputs = GTUtility + .copyFluidList(recipe.getResultFluidOutputs(recipeTier, machineTier, map)); + this.itemOutputs = GTUtility + .copyStackList(recipe.getResultItemOutputs(recipeTier, machineTier, map)); + } if (this.wasActiveAndNeedsUpdate) { this.wasActiveAndNeedsUpdate = false; @@ -793,7 +974,7 @@ protected void completeRecipe() { this.hasNotEnoughEnergy = false; this.wasActiveAndNeedsUpdate = true; this.parallelRecipesPerformed = 0; - this.overclockResults = new int[] { 0, 0 }; + this.ocResult.reset(); } /** @@ -824,14 +1005,14 @@ public int getMaxProgress() { /** * @return the current recipe's EU/t */ - public int getRecipeEUt() { + public long getRecipeEUt() { return recipeEUt; } /** * @return the current recipe's EU/t for TOP/Waila/Tricorder */ - public int getInfoProviderEUt() { + public long getInfoProviderEUt() { return getRecipeEUt(); } @@ -967,6 +1148,24 @@ public void setOverclockTier(final int tier) { setMaximumOverclockVoltage(GTValues.V[tier]); } + /** + * Used to reset cached values in the Recipe Logic on events such as multiblock structure deformation + */ + @MustBeInvokedByOverriders + public void invalidate() { + previousRecipe = null; + progressTime = 0; + maxProgressTime = 0; + recipeEUt = 0; + fluidOutputs = null; + itemOutputs = null; + parallelRecipesPerformed = 0; + isOutputsFull = false; + invalidInputsForRecipes = false; + this.ocResult.reset(); + setActive(false); // this marks dirty for us + } + @Override public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { if (dataId == GregtechDataCodes.WORKABLE_ACTIVE) { @@ -1001,7 +1200,7 @@ public NBTTagCompound serializeNBT() { if (progressTime > 0) { compound.setInteger("Progress", progressTime); compound.setInteger("MaxProgress", maxProgressTime); - compound.setInteger("RecipeEUt", this.recipeEUt); + compound.setLong("RecipeEUt", this.recipeEUt); NBTTagList itemOutputsList = new NBTTagList(); for (ItemStack itemOutput : itemOutputs) { itemOutputsList.appendTag(itemOutput.writeToNBT(new NBTTagCompound())); @@ -1027,9 +1226,9 @@ public void deserializeNBT(@NotNull NBTTagCompound compound) { if (progressTime > 0) { this.isActive = true; this.maxProgressTime = compound.getInteger("MaxProgress"); - this.recipeEUt = compound.getInteger("RecipeEUt"); + this.recipeEUt = compound.getLong("RecipeEUt"); NBTTagList itemOutputsList = compound.getTagList("ItemOutputs", Constants.NBT.TAG_COMPOUND); - this.itemOutputs = NonNullList.create(); + this.itemOutputs = new ArrayList<>(itemOutputsList.tagCount()); for (int i = 0; i < itemOutputsList.tagCount(); i++) { this.itemOutputs.add(new ItemStack(itemOutputsList.getCompoundTagAt(i))); } diff --git a/src/main/java/gregtech/api/capability/impl/BoilerRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/BoilerRecipeLogic.java index 292437e8921..28b2ee7afd0 100644 --- a/src/main/java/gregtech/api/capability/impl/BoilerRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/BoilerRecipeLogic.java @@ -4,9 +4,12 @@ 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.api.util.GTUtility; import gregtech.common.ConfigHolder; import gregtech.common.metatileentities.multi.MetaTileEntityLargeBoiler; @@ -14,8 +17,11 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.tileentity.TileEntityFurnace; -import net.minecraft.util.NonNullList; -import net.minecraftforge.fluids.*; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidUtil; +import net.minecraftforge.fluids.IFluidTank; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.items.IItemHandlerModifiable; @@ -23,26 +29,27 @@ import org.jetbrains.annotations.Nullable; import java.util.Collections; -import java.util.List; 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; + private static final int STEAM_PER_WATER = 160; private static final int FLUID_DRAIN_MULTIPLIER = 100; private static final int FLUID_BURNTIME_TO_EU = 800 / FLUID_DRAIN_MULTIPLIER; private int currentHeat; private int lastTickSteamOutput; - private int excessWater, excessFuel, excessProjectedEU; + private int excessWater; + private int excessFuel; + private int excessProjectedEU; public BoilerRecipeLogic(MetaTileEntityLargeBoiler tileEntity) { super(tileEntity, null); this.fluidOutputs = Collections.emptyList(); - this.itemOutputs = NonNullList.create(); + this.itemOutputs = Collections.emptyList(); } @Override @@ -71,7 +78,6 @@ protected void trySearchNewRecipe() { // can optimize with an override of checkPreviousRecipe() and a check here IMultipleTankHandler importFluids = boiler.getImportFluids(); - List dummyList = NonNullList.create(); boolean didStartRecipe = false; for (IFluidTank fluidTank : importFluids.getFluidTanks()) { @@ -79,28 +85,31 @@ protected void trySearchNewRecipe() { if (fuelStack == null || CommonFluidFilters.BOILER_FLUID.test(fuelStack)) continue; Recipe dieselRecipe = RecipeMaps.COMBUSTION_GENERATOR_FUELS.findRecipe( - GTValues.V[GTValues.MAX], dummyList, Collections.singletonList(fuelStack)); + GTValues.V[GTValues.MAX], Collections.emptyList(), Collections.singletonList(fuelStack)); // run only if it can apply a certain amount of "parallel", this is to mitigate int division if (dieselRecipe != null && fuelStack.amount >= dieselRecipe.getFluidInputs().get(0).getAmount() * FLUID_DRAIN_MULTIPLIER) { fluidTank.drain(dieselRecipe.getFluidInputs().get(0).getAmount() * FLUID_DRAIN_MULTIPLIER, true); // divide by 2, as it is half burntime for combustion setMaxProgress(adjustBurnTimeForThrottle(Math.max(1, boiler.boilerType.runtimeBoost( - (Math.abs(dieselRecipe.getEUt()) * dieselRecipe.getDuration()) / FLUID_BURNTIME_TO_EU / 2)))); + GTUtility.safeCastLongToInt((Math.abs(dieselRecipe.getEUt()) * dieselRecipe.getDuration()) / + FLUID_BURNTIME_TO_EU / 2))))); didStartRecipe = true; break; } Recipe denseFuelRecipe = RecipeMaps.SEMI_FLUID_GENERATOR_FUELS.findRecipe( - GTValues.V[GTValues.MAX], dummyList, Collections.singletonList(fuelStack)); + GTValues.V[GTValues.MAX], Collections.emptyList(), Collections.singletonList(fuelStack)); // run only if it can apply a certain amount of "parallel", this is to mitigate int division if (denseFuelRecipe != null && fuelStack.amount >= denseFuelRecipe.getFluidInputs().get(0).getAmount() * FLUID_DRAIN_MULTIPLIER) { fluidTank.drain(denseFuelRecipe.getFluidInputs().get(0).getAmount() * FLUID_DRAIN_MULTIPLIER, true); // multiply by 2, as it is 2x burntime for semi-fluid setMaxProgress(adjustBurnTimeForThrottle( - Math.max(1, boiler.boilerType.runtimeBoost((Math.abs(denseFuelRecipe.getEUt()) * - denseFuelRecipe.getDuration() / FLUID_BURNTIME_TO_EU * 2))))); + Math.max(1, + boiler.boilerType + .runtimeBoost(GTUtility.safeCastLongToInt((Math.abs(denseFuelRecipe.getEUt()) * + denseFuelRecipe.getDuration() / FLUID_BURNTIME_TO_EU * 2)))))); didStartRecipe = true; break; } @@ -140,14 +149,15 @@ protected void trySearchNewRecipe() { @Override protected void updateRecipeProgress() { if (canRecipeProgress) { - int generatedSteam = this.recipeEUt * getMaximumHeatFromMaintenance() / getMaximumHeat(); + int generatedSteam = GTUtility + .safeCastLongToInt(this.recipeEUt * getMaximumHeatFromMaintenance() / getMaximumHeat()); if (generatedSteam > 0) { - long amount = (generatedSteam + STEAM_PER_WATER) / STEAM_PER_WATER; + int amount = (generatedSteam + STEAM_PER_WATER) / STEAM_PER_WATER; excessWater += amount * STEAM_PER_WATER - generatedSteam; amount -= excessWater / STEAM_PER_WATER; excessWater %= STEAM_PER_WATER; - FluidStack drainedWater = getBoilerFluidFromContainer(getInputTank(), (int) amount); + FluidStack drainedWater = getBoilerFluidFromContainer(getInputTank(), amount); if (amount != 0 && (drainedWater == null || drainedWater.amount < amount)) { getMetaTileEntity().explodeMultiblock((1.0f * currentHeat / getMaximumHeat()) * 8.0f); } else { @@ -174,7 +184,7 @@ private int getMaximumHeatFromMaintenance() { private int adjustEUtForThrottle(int rawEUt) { int throttle = ((MetaTileEntityLargeBoiler) metaTileEntity).getThrottle(); - return Math.max(25, (int) (rawEUt * (throttle / 100.0))); + return (int) Math.max(25, rawEUt * (throttle / 100.0)); } private int adjustBurnTimeForThrottle(int rawBurnTime) { @@ -182,7 +192,7 @@ private int adjustBurnTimeForThrottle(int rawBurnTime) { int EUt = boiler.boilerType.steamPerTick(); int adjustedEUt = adjustEUtForThrottle(EUt); int adjustedBurnTime = rawBurnTime * EUt / adjustedEUt; - this.excessProjectedEU += EUt * rawBurnTime - adjustedEUt * adjustedBurnTime; + this.excessProjectedEU += (EUt * rawBurnTime) - (adjustedEUt * adjustedBurnTime); adjustedBurnTime += this.excessProjectedEU / adjustedEUt; this.excessProjectedEU %= adjustedEUt; return adjustedBurnTime; @@ -209,13 +219,13 @@ public int getLastTickSteam() { public void setLastTickSteam(int lastTickSteamOutput) { if (lastTickSteamOutput != this.lastTickSteamOutput && !metaTileEntity.getWorld().isRemote) { - writeCustomData(BOILER_LAST_TICK_STEAM, b -> b.writeVarInt(lastTickSteamOutput)); + writeCustomData(BOILER_LAST_TICK_STEAM, b -> b.writeInt(lastTickSteamOutput)); } this.lastTickSteamOutput = lastTickSteamOutput; } @Override - public int getInfoProviderEUt() { + public long getInfoProviderEUt() { return this.lastTickSteamOutput; } @@ -224,11 +234,9 @@ public boolean consumesEnergy() { return false; } + @Override public void invalidate() { - progressTime = 0; - maxProgressTime = 0; - recipeEUt = 0; - setActive(false); + super.invalidate(); setLastTickSteam(0); } @@ -270,14 +278,14 @@ public void deserializeNBT(@NotNull NBTTagCompound compound) { public void writeInitialSyncData(@NotNull PacketBuffer buf) { super.writeInitialSyncData(buf); buf.writeVarInt(currentHeat); - buf.writeVarInt(lastTickSteamOutput); + buf.writeInt(lastTickSteamOutput); } @Override public void receiveInitialSyncData(@NotNull PacketBuffer buf) { super.receiveInitialSyncData(buf); this.currentHeat = buf.readVarInt(); - this.lastTickSteamOutput = buf.readVarInt(); + this.lastTickSteamOutput = buf.readInt(); } @Override @@ -286,7 +294,7 @@ public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { if (dataId == BOILER_HEAT) { this.currentHeat = buf.readVarInt(); } else if (dataId == BOILER_LAST_TICK_STEAM) { - this.lastTickSteamOutput = buf.readVarInt(); + this.lastTickSteamOutput = buf.readInt(); } } @@ -311,7 +319,7 @@ protected long getEnergyCapacity() { } @Override - protected boolean drawEnergy(int recipeEUt, boolean simulate) { + protected boolean drawEnergy(long recipeEUt, boolean simulate) { GTLog.logger.error("Large Boiler called drawEnergy(), this should not be possible!"); return false; } @@ -347,4 +355,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/capability/impl/ComputationRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/ComputationRecipeLogic.java index ffd91c5d3ff..67c3c03fbc9 100644 --- a/src/main/java/gregtech/api/capability/impl/ComputationRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/ComputationRecipeLogic.java @@ -4,8 +4,8 @@ import gregtech.api.capability.IOpticalComputationReceiver; import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; import gregtech.api.recipes.Recipe; -import gregtech.api.recipes.recipeproperties.ComputationProperty; -import gregtech.api.recipes.recipeproperties.TotalComputationProperty; +import gregtech.api.recipes.properties.impl.ComputationProperty; +import gregtech.api.recipes.properties.impl.TotalComputationProperty; import net.minecraft.nbt.NBTTagCompound; @@ -49,16 +49,17 @@ public boolean checkRecipe(@NotNull Recipe recipe) { if (!super.checkRecipe(recipe)) { return false; } - if (!recipe.hasProperty(ComputationProperty.getInstance())) { + int recipeCWUt = recipe.getProperty(ComputationProperty.getInstance(), 0); + if (recipeCWUt == 0) { return true; } + IOpticalComputationProvider provider = getComputationProvider(); - int recipeCWUt = recipe.getProperty(ComputationProperty.getInstance(), 0); return provider.requestCWUt(recipeCWUt, true) >= recipeCWUt; } @Override - protected void setupRecipe(Recipe recipe) { + protected void setupRecipe(@NotNull Recipe recipe) { super.setupRecipe(recipe); this.recipeCWUt = recipe.getProperty(ComputationProperty.getInstance(), 0); this.isDurationTotalCWU = recipe.hasProperty(TotalComputationProperty.getInstance()); diff --git a/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java b/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java new file mode 100644 index 00000000000..e674db66763 --- /dev/null +++ b/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java @@ -0,0 +1,199 @@ +package gregtech.api.capability.impl; + +import gregtech.api.capability.IDistillationTower; +import gregtech.api.capability.IMultipleTankHandler; +import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.pattern.BlockPattern; +import gregtech.api.util.GTLog; +import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockPart; + +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.FluidTankProperties; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.IFluidTankProperties; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * Allows hatchscan behavior to be used on fluid outputs. Not a child of {@link AbstractRecipeLogic} + * for compatibility with other children. + */ +public class DistillationTowerLogicHandler { + + protected final IDistillationTower tower; + + private int layerCount; + private List orderedFluidOutputs; + private IMultipleTankHandler fluidTanks; + + public DistillationTowerLogicHandler(IDistillationTower tower) { + this.tower = tower; + } + + /** + * Applies fluids to outputs on a sorted one fluid -> one hatch basis + * + * @param fluids the fluids to output. Will be automatically trimmed if there are not enough output hatches. + * @param doFill whether the application should be simulated or not. + * @return whether the fluids were successfully applied to the outputs or not. + */ + public boolean applyFluidToOutputs(List fluids, boolean doFill) { + boolean valid = true; + for (int i = 0; i < Math.min(fluids.size(), this.getOrderedFluidOutputs().size()); i++) { + IFluidHandler handler = this.getOrderedFluidOutputs().get(i); + int accepted = handler.fill(fluids.get(i), doFill); + if (accepted != fluids.get(i).amount) valid = false; + if (!doFill && !valid) break; + } + return valid; + } + + /** + * Called on structure formation to determine the number of layers in the distillation tower.
+ *
+ * Needs to be overriden for multiblocks that have different assemblies than the standard distillation tower. + * + * @param structurePattern the structure pattern + */ + public void determineLayerCount(@NotNull BlockPattern structurePattern) { + this.setLayerCount(structurePattern.formedRepetitionCount[1] + 1); + } + + /** + * Called on structure formation to determine the ordered list of fluid handlers in the distillation tower.
+ *
+ * Needs to be overriden for multiblocks that have different assemblies than the standard distillation tower. + */ + public void determineOrderedFluidOutputs() { + // noinspection SimplifyStreamApiCallChains + List fluidExportParts = tower.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<>(); + List tankList = new ObjectArrayList<>(); + int firstY = tower.getPos().getY() + 1; + int exportIndex = 0; + for (int y = firstY; y < firstY + this.getLayerCount(); y++) { + if (fluidExportParts.size() <= exportIndex) { + orderedHandlerList.add(FakeTank.INSTANCE); + tankList.add(FakeTank.INSTANCE); + continue; + } + MetaTileEntityMultiblockPart part = fluidExportParts.get(exportIndex); + if (part.getPos().getY() == y) { + List hatchTanks = new ObjectArrayList<>(); + // noinspection unchecked + ((IMultiblockAbilityPart) part).registerAbilities(hatchTanks); + orderedHandlerList.add(new FluidTankList(false, hatchTanks)); + tankList.addAll(hatchTanks); + exportIndex++; + } else if (part.getPos().getY() > y) { + orderedHandlerList.add(FakeTank.INSTANCE); + tankList.add(FakeTank.INSTANCE); + } else { + GTLog.logger.error( + "The Distillation Tower at {} had a fluid export hatch with an unexpected Y position.", + tower.getPos()); + tower.invalidateStructure(); + this.setOrderedFluidOutputs(new ObjectArrayList<>()); + this.setFluidTanks(new FluidTankList(false)); + } + } + this.setOrderedFluidOutputs(orderedHandlerList); + this.setFluidTanks(new FluidTankList(tower.allowSameFluidFillForOutputs(), tankList)); + } + + /** + * Should be called on structure invalidation. + */ + public void invalidate() { + this.setLayerCount(0); + this.setOrderedFluidOutputs(null); + } + + protected void setLayerCount(int layerCount) { + this.layerCount = layerCount; + } + + public int getLayerCount() { + return layerCount; + } + + protected void setOrderedFluidOutputs(List orderedFluidOutputs) { + this.orderedFluidOutputs = orderedFluidOutputs; + } + + public List getOrderedFluidOutputs() { + return orderedFluidOutputs; + } + + protected void setFluidTanks(IMultipleTankHandler fluidTanks) { + this.fluidTanks = fluidTanks; + } + + public IMultipleTankHandler getFluidTanks() { + return fluidTanks; + } + + // an endless void devouring any fluid sent to it + protected static class FakeTank implements IFluidHandler, IFluidTank { + + protected static final FakeTank INSTANCE = new FakeTank(); + public static final FluidTankInfo FAKE_TANK_INFO = new FluidTankInfo(null, Integer.MAX_VALUE); + public static final IFluidTankProperties FAKE_TANK_PROPERTIES = new FluidTankProperties(null, Integer.MAX_VALUE, + true, false); + public static final IFluidTankProperties[] FAKE_TANK_PROPERTIES_ARRAY = new IFluidTankProperties[] { + FAKE_TANK_PROPERTIES }; + + @Override + public IFluidTankProperties[] getTankProperties() { + return FAKE_TANK_PROPERTIES_ARRAY; + } + + @Override + public FluidStack getFluid() { + return null; + } + + @Override + public int getFluidAmount() { + return 0; + } + + @Override + public int getCapacity() { + return Integer.MAX_VALUE; + } + + @Override + public FluidTankInfo getInfo() { + return FAKE_TANK_INFO; + } + + @Override + public int fill(FluidStack resource, boolean doFill) { + return resource.amount; + } + + @Override + public FluidStack drain(FluidStack resource, boolean doDrain) { + return null; + } + + @Override + public FluidStack drain(int maxDrain, boolean doDrain) { + return null; + } + } +} diff --git a/src/main/java/gregtech/api/capability/impl/EUToFEProvider.java b/src/main/java/gregtech/api/capability/impl/EUToFEProvider.java index 299e8f2af14..1f6f76c06be 100644 --- a/src/main/java/gregtech/api/capability/impl/EUToFEProvider.java +++ b/src/main/java/gregtech/api/capability/impl/EUToFEProvider.java @@ -15,6 +15,8 @@ import org.jetbrains.annotations.NotNull; +import static gregtech.api.util.GTUtility.safeCastLongToInt; + public class EUToFEProvider extends CapabilityCompatProvider { /** @@ -210,14 +212,4 @@ public boolean isOneProbeHidden() { return true; } } - - /** - * Safely cast a Long to an Int without overflow. - * - * @param v The Long value to cast to an Int. - * @return v, casted to Int, or Integer.MAX_VALUE if it would overflow. - */ - public static int safeCastLongToInt(long v) { - return v > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) v; - } } diff --git a/src/main/java/gregtech/api/capability/impl/FuelRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/FuelRecipeLogic.java index 64e305fb20a..26871a55d3c 100644 --- a/src/main/java/gregtech/api/capability/impl/FuelRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/FuelRecipeLogic.java @@ -4,12 +4,16 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.multiblock.ParallelLogicType; import gregtech.api.recipes.RecipeMap; -import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage; +import gregtech.api.recipes.logic.OCParams; +import gregtech.api.recipes.logic.OCResult; +import gregtech.api.recipes.properties.RecipePropertyStorage; import org.jetbrains.annotations.NotNull; import java.util.function.Supplier; +import static gregtech.api.recipes.logic.OverclockingLogic.standardOC; + public class FuelRecipeLogic extends RecipeLogicEnergy { public FuelRecipeLogic(MetaTileEntity tileEntity, RecipeMap recipeMap, @@ -29,16 +33,15 @@ public boolean consumesEnergy() { } @Override - protected boolean hasEnoughPower(@NotNull int[] resultOverclock) { + protected boolean hasEnoughPower(long eut, int duration) { // generators always have enough power to run recipes return true; } @Override - protected void modifyOverclockPost(int[] overclockResults, @NotNull IRecipePropertyStorage storage) { - super.modifyOverclockPost(overclockResults, storage); - // make EUt negative so it is consumed - overclockResults[0] = -overclockResults[0]; + protected void runOverclockingLogic(@NotNull OCParams ocParams, @NotNull OCResult ocResult, + @NotNull RecipePropertyStorage propertyStorage, long maxVoltage) { + standardOC(ocParams, ocResult, maxVoltage, getOverclockingDurationFactor(), getOverclockingVoltageFactor()); } @Override diff --git a/src/main/java/gregtech/api/capability/impl/HeatingCoilRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/HeatingCoilRecipeLogic.java index a19076ca0e8..fc9bd216d55 100644 --- a/src/main/java/gregtech/api/capability/impl/HeatingCoilRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/HeatingCoilRecipeLogic.java @@ -2,13 +2,15 @@ import gregtech.api.capability.IHeatingCoil; import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; +import gregtech.api.recipes.logic.OCParams; +import gregtech.api.recipes.logic.OCResult; import gregtech.api.recipes.logic.OverclockingLogic; -import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage; -import gregtech.api.recipes.recipeproperties.TemperatureProperty; +import gregtech.api.recipes.properties.RecipePropertyStorage; +import gregtech.api.recipes.properties.impl.TemperatureProperty; import org.jetbrains.annotations.NotNull; -import static gregtech.api.recipes.logic.OverclockingLogic.heatingCoilOverclockingLogic; +import static gregtech.api.recipes.logic.OverclockingLogic.heatingCoilOC; /** * RecipeLogic for multiblocks that use temperature for raising speed and lowering energy usage @@ -24,24 +26,18 @@ public HeatingCoilRecipeLogic(RecipeMapMultiblockController metaTileEntity) { } @Override - protected void modifyOverclockPre(@NotNull int[] values, @NotNull IRecipePropertyStorage storage) { - super.modifyOverclockPre(values, storage); + protected void modifyOverclockPre(@NotNull OCParams ocParams, @NotNull RecipePropertyStorage storage) { + super.modifyOverclockPre(ocParams, storage); // coil EU/t discount - values[0] = OverclockingLogic.applyCoilEUtDiscount(values[0], + ocParams.setEut(OverclockingLogic.applyCoilEUtDiscount(ocParams.eut(), ((IHeatingCoil) metaTileEntity).getCurrentTemperature(), - storage.getRecipePropertyValue(TemperatureProperty.getInstance(), 0)); + storage.get(TemperatureProperty.getInstance(), 0))); } - @NotNull @Override - protected int[] runOverclockingLogic(@NotNull IRecipePropertyStorage propertyStorage, int recipeEUt, - long maxVoltage, int duration, int amountOC) { - return heatingCoilOverclockingLogic( - Math.abs(recipeEUt), - maxVoltage, - duration, - amountOC, - ((IHeatingCoil) metaTileEntity).getCurrentTemperature(), - propertyStorage.getRecipePropertyValue(TemperatureProperty.getInstance(), 0)); + protected void runOverclockingLogic(@NotNull OCParams ocParams, @NotNull OCResult ocResult, + @NotNull RecipePropertyStorage propertyStorage, long maxVoltage) { + heatingCoilOC(ocParams, ocResult, maxVoltage, ((IHeatingCoil) metaTileEntity).getCurrentTemperature(), + propertyStorage.get(TemperatureProperty.getInstance(), 0)); } } diff --git a/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java index 9f93440025c..30c5e5410e3 100644 --- a/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/MultiblockFuelRecipeLogic.java @@ -6,7 +6,10 @@ import gregtech.api.metatileentity.multiblock.ParallelLogicType; import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; import gregtech.api.recipes.Recipe; -import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage; +import gregtech.api.recipes.logic.OCParams; +import gregtech.api.recipes.logic.OCResult; +import gregtech.api.recipes.properties.RecipePropertyStorage; +import gregtech.api.util.GTUtility; import gregtech.api.util.TextFormattingUtil; import net.minecraft.util.Tuple; @@ -26,28 +29,25 @@ public MultiblockFuelRecipeLogic(RecipeMapMultiblockController tileEntity) { } @Override - protected void modifyOverclockPre(@NotNull int[] values, @NotNull IRecipePropertyStorage storage) { + protected void modifyOverclockPre(@NotNull OCParams ocParams, @NotNull RecipePropertyStorage storage) { // apply maintenance bonuses Tuple maintenanceValues = getMaintenanceValues(); // duration bonus if (maintenanceValues.getSecond() != 1.0) { - values[1] = (int) Math.round(values[1] / maintenanceValues.getSecond()); + ocParams.setDuration((int) Math.round(ocParams.duration() / maintenanceValues.getSecond())); } } @Override - protected void modifyOverclockPost(int[] overclockResults, @NotNull IRecipePropertyStorage storage) { + protected void modifyOverclockPost(@NotNull OCResult ocResult, @NotNull RecipePropertyStorage storage) { // apply maintenance penalties Tuple maintenanceValues = getMaintenanceValues(); // duration penalty if (maintenanceValues.getFirst() > 0) { - overclockResults[1] = (int) (overclockResults[1] * (1 - 0.1 * maintenanceValues.getFirst())); + ocResult.setDuration((int) (ocResult.duration() * (1 - 0.1 * maintenanceValues.getFirst()))); } - - // make EUt negative so it is consumed - overclockResults[0] = -overclockResults[0]; } @NotNull @@ -57,7 +57,7 @@ public ParallelLogicType getParallelLogicType() { } @Override - protected boolean hasEnoughPower(@NotNull int[] resultOverclock) { + protected boolean hasEnoughPower(long eut, int duration) { // generators always have enough power to run recipes return true; } @@ -78,6 +78,11 @@ public int getParallelLimit() { return Integer.MAX_VALUE; } + @Override + protected long getMaxParallelVoltage() { + return getMaxVoltage(); + } + /** * Boost the energy production. * Should not change the state of the workable logic. Only read current values. @@ -90,18 +95,19 @@ protected long boostProduction(long production) { } @Override - protected boolean drawEnergy(int recipeEUt, boolean simulate) { + protected boolean drawEnergy(long recipeEUt, boolean simulate) { long euToDraw = boostProduction(recipeEUt); long resultEnergy = getEnergyStored() - euToDraw; if (resultEnergy >= 0L && resultEnergy <= getEnergyCapacity()) { if (!simulate) getEnergyContainer().changeEnergy(-euToDraw); return true; - } else return false; + } + return false; } @Override - public int getInfoProviderEUt() { - return (int) boostProduction(super.getInfoProviderEUt()); + public long getInfoProviderEUt() { + return boostProduction(super.getInfoProviderEUt()); } @Override @@ -133,10 +139,10 @@ public String getRecipeFluidInputInfo() { } FluidStack requiredFluidInput = recipe.getFluidInputs().get(0).getInputFluidStack(); - int ocAmount = (int) (getMaxVoltage() / recipe.getEUt()); + int ocAmount = GTUtility.safeCastLongToInt(getMaxVoltage() / recipe.getEUt()); int neededAmount = ocAmount * requiredFluidInput.amount; if (rotorHolder != null && rotorHolder.hasRotor()) { - neededAmount /= (rotorHolder.getTotalEfficiency() / 100f); + neededAmount /= (rotorHolder.getTotalEfficiency() / 100.0); } else if (rotorHolder != null && !rotorHolder.hasRotor()) { return null; } diff --git a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java index 1ebb3e73c82..ff95f0fbb0c 100644 --- a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java @@ -10,7 +10,9 @@ import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMap; -import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage; +import gregtech.api.recipes.logic.OCParams; +import gregtech.api.recipes.logic.OCResult; +import gregtech.api.recipes.properties.RecipePropertyStorage; import gregtech.api.util.GTUtility; import gregtech.common.ConfigHolder; @@ -25,6 +27,8 @@ import java.util.Iterator; import java.util.List; +import static gregtech.api.recipes.logic.OverclockingLogic.subTickParallelOC; + public class MultiblockRecipeLogic extends AbstractRecipeLogic { // Used for distinct mode @@ -55,19 +59,11 @@ protected boolean canProgressRecipe() { /** * Used to reset cached values in the Recipe Logic on structure deform */ + @Override public void invalidate() { - previousRecipe = null; - progressTime = 0; - maxProgressTime = 0; - recipeEUt = 0; - fluidOutputs = null; - itemOutputs = null; + super.invalidate(); lastRecipeIndex = 0; - parallelRecipesPerformed = 0; - isOutputsFull = false; - invalidInputsForRecipes = false; invalidatedInputList.clear(); - setActive(false); // this marks dirty for us } public void onDistinctChanged() { @@ -273,37 +269,47 @@ protected boolean prepareRecipeDistinct(Recipe recipe) { getMaxParallelVoltage(), getParallelLimit()); - if (recipe != null && setupAndConsumeRecipeInputs(recipe, currentDistinctInputBus)) { - setupRecipe(recipe); - return true; + if (recipe != null) { + recipe = setupAndConsumeRecipeInputs(recipe, currentDistinctInputBus); + if (recipe != null) { + setupRecipe(recipe); + return true; + } } return false; } @Override - protected void modifyOverclockPre(int @NotNull [] values, @NotNull IRecipePropertyStorage storage) { - super.modifyOverclockPre(values, storage); + protected void modifyOverclockPre(@NotNull OCParams ocParams, @NotNull RecipePropertyStorage storage) { + super.modifyOverclockPre(ocParams, storage); // apply maintenance bonuses Tuple maintenanceValues = getMaintenanceValues(); // duration bonus if (maintenanceValues.getSecond() != 1.0) { - values[1] = (int) Math.round(values[1] * maintenanceValues.getSecond()); + ocParams.setDuration((int) Math.round(ocParams.duration() * maintenanceValues.getSecond())); } } @Override - protected void modifyOverclockPost(int[] overclockResults, @NotNull IRecipePropertyStorage storage) { - super.modifyOverclockPost(overclockResults, storage); + protected void runOverclockingLogic(@NotNull OCParams ocParams, @NotNull OCResult ocResult, + @NotNull RecipePropertyStorage propertyStorage, long maxVoltage) { + subTickParallelOC(ocParams, ocResult, maxVoltage, getOverclockingDurationFactor(), + getOverclockingVoltageFactor()); + } + + @Override + protected void modifyOverclockPost(@NotNull OCResult ocResult, @NotNull RecipePropertyStorage storage) { + super.modifyOverclockPost(ocResult, storage); // apply maintenance penalties Tuple maintenanceValues = getMaintenanceValues(); // duration penalty if (maintenanceValues.getFirst() > 0) { - overclockResults[1] = (int) (overclockResults[1] * (1 + 0.1 * maintenanceValues.getFirst())); + ocResult.setDuration((int) (ocResult.duration() * (1 + 0.1 * maintenanceValues.getFirst()))); } } @@ -325,7 +331,7 @@ public long getMaximumOverclockVoltage() { // amperage is 1 when the energy is not exactly on a tier // the voltage for recipe search is always on tier, so take the closest lower tier - return GTValues.V[GTUtility.getFloorTierByVoltage(voltage)]; + return GTValues.VOC[GTUtility.getFloorTierByVoltage(voltage)]; } else { // amperage != 1 means the voltage is exactly on a tier // ignore amperage, since only the voltage is relevant for recipe search @@ -394,7 +400,7 @@ protected long getEnergyCapacity() { } @Override - protected boolean drawEnergy(int recipeEUt, boolean simulate) { + protected boolean drawEnergy(long recipeEUt, boolean simulate) { long resultEnergy = getEnergyStored() - recipeEUt; if (resultEnergy >= 0L && resultEnergy <= getEnergyCapacity()) { if (!simulate) getEnergyContainer().changeEnergy(-recipeEUt); @@ -414,7 +420,7 @@ public long getMaxVoltage() { // The voltage for recipe search is always on tier, so take the closest lower tier. // List check is done because single hatches will always be a "clean voltage," no need // for any additional checks. - return GTValues.V[GTUtility.getFloorTierByVoltage(voltage)]; + return GTValues.VOC[GTUtility.getFloorTierByVoltage(voltage)]; } return voltage; } else { @@ -434,6 +440,11 @@ public long getMaxVoltage() { } } + @Override + protected long getMaxParallelVoltage() { + return getMaximumOverclockVoltage(); + } + @Nullable @Override public RecipeMap getRecipeMap() { diff --git a/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java index 182b900ae3b..40e4f13ca43 100644 --- a/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java @@ -3,12 +3,12 @@ import gregtech.api.GTValues; import gregtech.api.metatileentity.multiblock.RecipeMapPrimitiveMultiblockController; import gregtech.api.recipes.RecipeMap; -import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage; +import gregtech.api.recipes.logic.OCParams; +import gregtech.api.recipes.logic.OCResult; +import gregtech.api.recipes.properties.RecipePropertyStorage; import org.jetbrains.annotations.NotNull; -import static gregtech.api.recipes.logic.OverclockingLogic.standardOverclockingLogic; - /** * Recipe Logic for a Multiblock that does not require power. */ @@ -34,45 +34,29 @@ protected long getEnergyCapacity() { } @Override - protected boolean drawEnergy(int recipeEUt, boolean simulate) { + protected boolean drawEnergy(long recipeEUt, boolean simulate) { return true; // spoof energy being drawn } + @Override + protected boolean hasEnoughPower(long eut, int duration) { + return true; + } + @Override public long getMaxVoltage() { return GTValues.LV; } - @NotNull @Override - protected int[] runOverclockingLogic(@NotNull IRecipePropertyStorage propertyStorage, int recipeEUt, - long maxVoltage, int recipeDuration, int amountOC) { - return standardOverclockingLogic( - 1, - getMaxVoltage(), - recipeDuration, - amountOC, - getOverclockingDurationDivisor(), - getOverclockingVoltageMultiplier() - - ); + protected void runOverclockingLogic(@NotNull OCParams ocParams, @NotNull OCResult ocResult, + @NotNull RecipePropertyStorage propertyStorage, long maxVoltage) { + ocParams.setEut(1L); + super.runOverclockingLogic(ocParams, ocResult, propertyStorage, maxVoltage); } @Override public long getMaximumOverclockVoltage() { return GTValues.V[GTValues.LV]; } - - /** - * Used to reset cached values in the Recipe Logic on structure deform - */ - public void invalidate() { - previousRecipe = null; - progressTime = 0; - maxProgressTime = 0; - recipeEUt = 0; - fluidOutputs = null; - itemOutputs = null; - setActive(false); // this marks dirty for us - } } diff --git a/src/main/java/gregtech/api/capability/impl/RecipeLogicEnergy.java b/src/main/java/gregtech/api/capability/impl/RecipeLogicEnergy.java index f618b37e2be..8460b2a7aa7 100644 --- a/src/main/java/gregtech/api/capability/impl/RecipeLogicEnergy.java +++ b/src/main/java/gregtech/api/capability/impl/RecipeLogicEnergy.java @@ -3,9 +3,16 @@ import gregtech.api.capability.IEnergyContainer; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.recipes.RecipeMap; +import gregtech.api.recipes.logic.OCParams; +import gregtech.api.recipes.logic.OCResult; +import gregtech.api.recipes.properties.RecipePropertyStorage; + +import org.jetbrains.annotations.NotNull; import java.util.function.Supplier; +import static gregtech.api.recipes.logic.OverclockingLogic.subTickNonParallelOC; + public class RecipeLogicEnergy extends AbstractRecipeLogic { protected final Supplier energyContainer; @@ -33,17 +40,24 @@ protected long getEnergyCapacity() { } @Override - protected boolean drawEnergy(int recipeEUt, boolean simulate) { + protected boolean drawEnergy(long recipeEUt, boolean simulate) { long resultEnergy = getEnergyStored() - recipeEUt; if (resultEnergy >= 0L && resultEnergy <= getEnergyCapacity()) { if (!simulate) energyContainer.get().changeEnergy(-recipeEUt); return true; - } else return false; + } + return false; } @Override public long getMaxVoltage() { - return Math.max(energyContainer.get().getInputVoltage(), - energyContainer.get().getOutputVoltage()); + return Math.max(energyContainer.get().getInputVoltage(), energyContainer.get().getOutputVoltage()); + } + + @Override + protected void runOverclockingLogic(@NotNull OCParams ocParams, @NotNull OCResult ocResult, + @NotNull RecipePropertyStorage propertyStorage, long maxVoltage) { + subTickNonParallelOC(ocParams, ocResult, maxVoltage, getOverclockingDurationFactor(), + getOverclockingVoltageFactor()); } } diff --git a/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java b/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java index c5d7dcbb960..3336b022760 100644 --- a/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java +++ b/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java @@ -7,6 +7,8 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMap; +import gregtech.api.recipes.logic.OCParams; +import gregtech.api.recipes.logic.OCResult; import gregtech.api.util.GTUtility; import gregtech.common.ConfigHolder; import gregtech.core.advancement.AdvancementTriggers; @@ -188,16 +190,14 @@ protected void completeRecipe() { tryDoVenting(); } - @NotNull @Override - protected int[] calculateOverclock(@NotNull Recipe recipe) { - // EUt, Duration - int[] result = new int[2]; - - result[0] = isHighPressure ? recipe.getEUt() * 2 : recipe.getEUt(); - result[1] = isHighPressure ? recipe.getDuration() : recipe.getDuration() * 2; - - return result; + protected void performOverclocking(@NotNull Recipe recipe, @NotNull OCParams ocParams, + @NotNull OCResult ocResult) { + if (isHighPressure) { + ocResult.init(recipe.getEUt() * 2L, recipe.getDuration()); + } else { + ocResult.init(recipe.getEUt(), recipe.getDuration() * 2); + } } @Override @@ -216,8 +216,8 @@ protected long getEnergyCapacity() { } @Override - protected boolean drawEnergy(int recipeEUt, boolean simulate) { - int resultDraw = (int) Math.ceil(recipeEUt / conversionRate); + protected boolean drawEnergy(long recipeEUt, boolean simulate) { + int resultDraw = GTUtility.safeCastLongToInt((long) Math.ceil(recipeEUt / conversionRate)); return resultDraw >= 0 && steamFluidTank.getFluidAmount() >= resultDraw && steamFluidTank.drain(resultDraw, !simulate) != null; } @@ -227,6 +227,23 @@ public long getMaxVoltage() { return GTValues.V[GTValues.LV]; } + @Override + protected boolean hasEnoughPower(long eut, int duration) { + long totalSteam = (long) (eut * duration / conversionRate); + if (totalSteam > 0) { + long steamStored = getEnergyStored(); + long steamCapacity = getEnergyCapacity(); + // if the required steam is larger than the full buffer, just require the full buffer + if (steamCapacity < totalSteam) { + return steamCapacity == steamStored; + } + // otherwise require the full amount of steam for the recipe + return steamStored >= totalSteam; + } + // generation case unchanged + return super.hasEnoughPower(eut, duration); + } + @NotNull @Override public NBTTagCompound serializeNBT() { diff --git a/src/main/java/gregtech/api/capability/impl/SteamMultiWorkable.java b/src/main/java/gregtech/api/capability/impl/SteamMultiWorkable.java index 6db74825342..184c72b251c 100644 --- a/src/main/java/gregtech/api/capability/impl/SteamMultiWorkable.java +++ b/src/main/java/gregtech/api/capability/impl/SteamMultiWorkable.java @@ -26,9 +26,9 @@ public ParallelLogicType getParallelLogicType() { @Override public void applyParallelBonus(@NotNull RecipeBuilder builder) { - int currentRecipeEU = builder.getEUt(); + long currentRecipeEU = builder.getEUt(); int currentRecipeDuration = builder.getDuration() / getParallelLimit(); - builder.EUt((int) Math.min(32.0, Math.ceil(currentRecipeEU * 1.33))) + builder.EUt((long) Math.min(32, Math.ceil(currentRecipeEU * 1.33))) .duration((int) (currentRecipeDuration * 1.5)); } } diff --git a/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java index b227f3942c2..2c05b255d40 100644 --- a/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java @@ -5,6 +5,7 @@ import gregtech.api.metatileentity.multiblock.RecipeMapSteamMultiblockController; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMap; +import gregtech.api.util.GTUtility; import gregtech.common.ConfigHolder; import net.minecraft.block.Block; @@ -22,6 +23,7 @@ import net.minecraftforge.items.IItemHandlerModifiable; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class SteamMultiblockRecipeLogic extends AbstractRecipeLogic { @@ -104,9 +106,9 @@ protected long getEnergyCapacity() { } @Override - protected boolean drawEnergy(int recipeEUt, boolean simulate) { + protected boolean drawEnergy(long recipeEUt, boolean simulate) { combineSteamTanks(); - int resultDraw = (int) Math.ceil(recipeEUt / conversionRate); + int resultDraw = GTUtility.safeCastLongToInt((long) Math.ceil(recipeEUt / conversionRate)); return resultDraw >= 0 && steamFluidTankCombined.getFluidAmount() >= resultDraw && steamFluidTank.drain(resultDraw, !simulate) != null; } @@ -122,14 +124,17 @@ public boolean isAllowOverclocking() { } @Override - protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, - @NotNull IItemHandlerModifiable importInventory) { + protected @Nullable Recipe setupAndConsumeRecipeInputs(@NotNull Recipe recipe, + @NotNull IItemHandlerModifiable importInventory) { RecipeMapSteamMultiblockController controller = (RecipeMapSteamMultiblockController) metaTileEntity; - if (controller.checkRecipe(recipe, false) && - super.setupAndConsumeRecipeInputs(recipe, importInventory)) { - controller.checkRecipe(recipe, true); - return true; - } else return false; + if (controller.checkRecipe(recipe, false)) { + recipe = super.setupAndConsumeRecipeInputs(recipe, importInventory); + if (recipe != null) { + controller.checkRecipe(recipe, true); + return recipe; + } + } + return null; } @Override @@ -167,4 +172,21 @@ private void performVentingAnimation(BlockPos machinePos, EnumFacing ventingSide 1.0f); } } + + @Override + protected boolean hasEnoughPower(long eut, int duration) { + long totalSteam = (long) (eut * duration / conversionRate); + if (totalSteam > 0) { + long steamStored = getEnergyStored(); + long steamCapacity = getEnergyCapacity(); + // if the required steam is larger than the full buffer, just require the full buffer + if (steamCapacity < totalSteam) { + return steamCapacity == steamStored; + } + // otherwise require the full amount of steam for the recipe + return steamStored >= totalSteam; + } + // generation case unchanged + return super.hasEnoughPower(eut, duration); + } } diff --git a/src/main/java/gregtech/api/capability/impl/miner/MinerLogic.java b/src/main/java/gregtech/api/capability/impl/miner/MinerLogic.java index 5b1ca454f3d..2565c02a7a5 100644 --- a/src/main/java/gregtech/api/capability/impl/miner/MinerLogic.java +++ b/src/main/java/gregtech/api/capability/impl/miner/MinerLogic.java @@ -157,8 +157,10 @@ public void performMining() { // drill a hole beneath the miner and extend the pipe downwards by one WorldServer world = (WorldServer) metaTileEntity.getWorld(); if (mineY.get() < pipeY.get()) { - world.destroyBlock( - new BlockPos(metaTileEntity.getPos().getX(), pipeY.get(), metaTileEntity.getPos().getZ()), false); + var pipePos = new BlockPos(metaTileEntity.getPos().getX(), pipeY.get(), metaTileEntity.getPos().getZ()); + if (world.getTileEntity(pipePos) == null && + world.getBlockState(pipePos).getBlockHardness(world, pipePos) >= 0) + world.destroyBlock(pipePos, false); pipeY.decrementAndGet(); incrementPipeLength(); } @@ -178,7 +180,7 @@ public void performMining() { blockState = metaTileEntity.getWorld().getBlockState(blocksToMine.getFirst()); } // When we are here we have an ore to mine! I'm glad we aren't threaded - if (!blocksToMine.isEmpty() & GTUtility.isOre(GTUtility.toItem(blockState))) { + if (!blocksToMine.isEmpty() && GTUtility.isOre(GTUtility.toItem(blockState))) { // get the small ore drops, if a small ore getSmallOreBlockDrops(blockDrops, world, blocksToMine.getFirst(), blockState); // get the block's drops. @@ -278,7 +280,7 @@ protected void getRegularBlockDrops(NonNullList blockDrops, WorldServ * @param blockDrops the List of items to insert * @param world the {@link WorldServer} the miner is in */ - private void mineAndInsertItems(NonNullList blockDrops, WorldServer world) { + private void mineAndInsertItems(List blockDrops, WorldServer world) { // If the block's drops can fit in the inventory, move the previously mined position to the block // replace the ore block with cobblestone instead of breaking it to prevent mob spawning // remove the ore block's position from the mining queue diff --git a/src/main/java/gregtech/api/cover/Cover.java b/src/main/java/gregtech/api/cover/Cover.java index 8540d97fc1f..0257544c99a 100644 --- a/src/main/java/gregtech/api/cover/Cover.java +++ b/src/main/java/gregtech/api/cover/Cover.java @@ -113,10 +113,13 @@ default long getOffsetTimer() { /** * Called when the cover is first attached on the Server Side. - * Do NOT sync custom data to client here. It will overwrite the attach cover packet! + * Values set here will automatically be synced to the client, if you + * specify them in {@link #writeInitialSyncData}. + * + * @apiNote The CoverableView will not have your cover attached to it in this method. * - * @param coverableView the CoverableView this cover is attached to - * @param side the side this cover is attached to + * @param coverableView the CoverableView this cover will be attached to + * @param side the side this cover will be attached to * @param player the player attaching the cover * @param itemStack the item used to place the cover */ diff --git a/src/main/java/gregtech/api/cover/CoverBase.java b/src/main/java/gregtech/api/cover/CoverBase.java index 49a3429f842..8382a8a1d4b 100644 --- a/src/main/java/gregtech/api/cover/CoverBase.java +++ b/src/main/java/gregtech/api/cover/CoverBase.java @@ -10,7 +10,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; -import net.minecraft.util.NonNullList; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.IItemHandlerModifiable; @@ -21,6 +20,9 @@ import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.List; + public abstract class CoverBase implements Cover { private final CoverDefinition definition; @@ -55,7 +57,7 @@ public CoverBase(@NotNull CoverDefinition definition, @NotNull CoverableView cov * @param inventory the inventory to clear */ protected void dropInventoryContents(@NotNull IItemHandlerModifiable inventory) { - NonNullList drops = NonNullList.create(); + List drops = new ArrayList<>(); MetaTileEntity.clearInventory(drops, inventory); for (ItemStack itemStack : drops) { Block.spawnAsEntity(getWorld(), getPos(), itemStack); diff --git a/src/main/java/gregtech/api/cover/CoverWithUI.java b/src/main/java/gregtech/api/cover/CoverWithUI.java index 10ab6f243dd..d1c6fa0d0c8 100644 --- a/src/main/java/gregtech/api/cover/CoverWithUI.java +++ b/src/main/java/gregtech/api/cover/CoverWithUI.java @@ -2,20 +2,34 @@ import gregtech.api.gui.IUIHolder; import gregtech.api.gui.ModularUI; +import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuiTheme; import gregtech.api.mui.GregTechGuiScreen; import gregtech.api.mui.factory.CoverGuiFactory; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IStringSerializable; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import com.cleanroommc.modularui.api.IGuiHolder; +import com.cleanroommc.modularui.api.drawable.IDrawable; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.screen.ModularScreen; -import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.utils.MouseData; +import com.cleanroommc.modularui.value.BoolValue; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.IntSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.layout.Row; import org.jetbrains.annotations.ApiStatus; public interface CoverWithUI extends Cover, IUIHolder, IGuiHolder { @@ -46,11 +60,11 @@ default ModularScreen createScreen(SidedPosGuiData guiData, ModularPanel mainPan } default GTGuiTheme getUITheme() { - return GTGuiTheme.STANDARD; + return GTGuiTheme.COVER; } @Override - default ModularPanel buildUI(SidedPosGuiData guiData, GuiSyncManager guiSyncManager) { + default ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager) { return null; } @@ -68,4 +82,159 @@ default boolean isRemote() { default void markAsDirty() { getCoverableView().markDirty(); } + + /* Helper methods for UI creation with covers that are commonly used */ + + /** + * The color used for Cover UI titles, and used in {@link #createTitleRow}. + */ + int UI_TITLE_COLOR = 0xFF222222; + /** + * The color used for Cover UI text. Available for reference, but is + * handled automatically by the {@link GTGuiTheme#COVER} theme. + */ + int UI_TEXT_COLOR = 0xFF555555; + + /** + * Create the Title bar widget for a Cover. + */ + static Row createTitleRow(ItemStack stack) { + return new Row() + .pos(4, 4) + .height(16).coverChildrenWidth() + .child(new ItemDrawable(stack).asWidget().size(16).marginRight(4)) + .child(IKey.str(stack.getDisplayName()).color(UI_TITLE_COLOR).asWidget().heightRel(1.0f)); + } + + /** + * Create a new settings row for a Cover setting. + */ + default ParentWidget createSettingsRow() { + return new ParentWidget<>().height(16).widthRel(1.0f).marginBottom(2); + } + + default int getIncrementValue(MouseData data) { + int adjust = 1; + if (data.shift) adjust *= 4; + if (data.ctrl) adjust *= 16; + if (data.alt) adjust *= 64; + return adjust; + } + + default IKey createAdjustOverlay(boolean increment) { + final StringBuilder builder = new StringBuilder(); + builder.append(increment ? '+' : '-'); + builder.append(getIncrementValue(MouseData.create(-1))); + + float scale = 1f; + if (builder.length() == 3) { + scale = 0.8f; + } else if (builder.length() == 4) { + scale = 0.6f; + } else if (builder.length() > 4) { + scale = 0.5f; + } + return IKey.str(builder.toString()) + .scale(scale); + } + + /** + * Get a BoolValue for use with toggle buttons which are "linked together," + * meaning only one of them can be pressed at a time. + */ + default > BoolValue.Dynamic boolValueOf(EnumSyncValue syncValue, T value) { + return new BoolValue.Dynamic(() -> syncValue.getValue() == value, $ -> syncValue.setValue(value)); + } + + /** + * Get a BoolValue for use with toggle buttons which are "linked together," + * meaning only one of them can be pressed at a time. + */ + default BoolValue.Dynamic boolValueOf(IntSyncValue syncValue, int value) { + return new BoolValue.Dynamic(() -> syncValue.getValue() == value, $ -> syncValue.setValue(value)); + } + + class EnumRowBuilder> { + + private EnumSyncValue syncValue; + private final Class enumValue; + private String lang; + private IDrawable[] background; + private IDrawable selectedBackground; + private IDrawable[] overlay; + + public EnumRowBuilder(Class enumValue) { + this.enumValue = enumValue; + } + + public EnumRowBuilder value(EnumSyncValue syncValue) { + this.syncValue = syncValue; + return this; + } + + public EnumRowBuilder lang(String lang) { + this.lang = lang; + return this; + } + + public EnumRowBuilder background(IDrawable... background) { + this.background = background; + return this; + } + + public EnumRowBuilder selectedBackground(IDrawable selectedBackground) { + this.selectedBackground = selectedBackground; + return this; + } + + public EnumRowBuilder overlay(IDrawable... overlay) { + this.overlay = overlay; + return this; + } + + public EnumRowBuilder overlay(int size, IDrawable... overlay) { + this.overlay = new IDrawable[overlay.length]; + for (int i = 0; i < overlay.length; i++) { + this.overlay[i] = overlay[i].asIcon().size(size); + } + return this; + } + + private BoolValue.Dynamic boolValueOf(EnumSyncValue syncValue, T value) { + return new BoolValue.Dynamic(() -> syncValue.getValue() == value, $ -> syncValue.setValue(value)); + } + + public Row build() { + var row = new Row().marginBottom(2).coverChildrenHeight().widthRel(1f); + if (this.enumValue != null && this.syncValue != null) { + for (var enumVal : enumValue.getEnumConstants()) { + var button = new ToggleButton().size(18).marginRight(2) + .value(boolValueOf(this.syncValue, enumVal)); + + if (this.background != null && this.background.length > 0) + button.background(this.background); + else + button.background(GTGuiTextures.MC_BUTTON); + + if (this.selectedBackground != null) + button.selectedBackground(this.selectedBackground); + else + button.selectedBackground(GTGuiTextures.MC_BUTTON_DISABLED); + + if (this.overlay != null) + button.overlay(this.overlay[enumVal.ordinal()]); + + if (enumVal instanceof IStringSerializable serializable) { + button.addTooltipLine(IKey.lang(serializable.getName())); + } + row.child(button); + } + } + + if (this.lang != null && !this.lang.isEmpty()) + row.child(IKey.lang(this.lang).asWidget().align(Alignment.CenterRight).height(18)); + + return row; + } + } } diff --git a/src/main/java/gregtech/api/cover/CoverableView.java b/src/main/java/gregtech/api/cover/CoverableView.java index 0b7d6f33c68..8bebd97b26d 100644 --- a/src/main/java/gregtech/api/cover/CoverableView.java +++ b/src/main/java/gregtech/api/cover/CoverableView.java @@ -1,5 +1,6 @@ package gregtech.api.cover; +import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; @@ -87,4 +88,10 @@ default boolean hasCover(@NotNull EnumFacing side) { int getInputRedstoneSignal(@NotNull EnumFacing side, boolean ignoreCover); void writeCoverData(@NotNull Cover cover, int discriminator, @NotNull Consumer<@NotNull PacketBuffer> buf); + + /** + * @return an ItemStack representation of the CoverableView, or {@link ItemStack#EMPTY} if not possible. + */ + @NotNull + ItemStack getStackForm(); } diff --git a/src/main/java/gregtech/api/util/BaseCreativeTab.java b/src/main/java/gregtech/api/creativetab/BaseCreativeTab.java similarity index 78% rename from src/main/java/gregtech/api/util/BaseCreativeTab.java rename to src/main/java/gregtech/api/creativetab/BaseCreativeTab.java index 0b9fd926651..4607cf05d08 100644 --- a/src/main/java/gregtech/api/util/BaseCreativeTab.java +++ b/src/main/java/gregtech/api/creativetab/BaseCreativeTab.java @@ -1,4 +1,6 @@ -package gregtech.api.util; +package gregtech.api.creativetab; + +import gregtech.api.util.GTLog; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.init.Blocks; @@ -13,31 +15,32 @@ public class BaseCreativeTab extends CreativeTabs { private final boolean hasSearchBar; private final Supplier iconSupplier; - public BaseCreativeTab(String TabName, Supplier iconSupplier, boolean hasSearchBar) { - super(TabName); + public BaseCreativeTab(String tabName, Supplier iconSupplier, boolean hasSearchBar) { + super(tabName); this.iconSupplier = iconSupplier; this.hasSearchBar = hasSearchBar; - if (hasSearchBar) + if (hasSearchBar) { setBackgroundImageName("item_search.png"); + } } @NotNull @Override public ItemStack createIcon() { if (iconSupplier == null) { - GTLog.logger.error("Icon supplier was null for CreativeTab " + getTabLabel()); + GTLog.logger.error("Icon supplier was null for CreativeTab {}", getTabLabel()); return new ItemStack(Blocks.STONE); } ItemStack stack = iconSupplier.get(); if (stack == null) { - GTLog.logger.error("Icon supplier return null for CreativeTab " + getTabLabel()); + GTLog.logger.error("Icon supplier return null for CreativeTab {}", getTabLabel()); return new ItemStack(Blocks.STONE); } - if (stack == ItemStack.EMPTY) { - GTLog.logger.error("Icon built from iconSupplied is EMPTY for CreativeTab " + getTabLabel()); + if (stack.isEmpty()) { + GTLog.logger.error("Icon built from iconSupplied is EMPTY for CreativeTab {}", getTabLabel()); return new ItemStack(Blocks.STONE); } diff --git a/src/main/java/gregtech/api/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 f7a75111cc4..31c9caad896 100644 --- a/src/main/java/gregtech/api/fluids/FluidBuilder.java +++ b/src/main/java/gregtech/api/fluids/FluidBuilder.java @@ -1,6 +1,5 @@ package gregtech.api.fluids; -import gregtech.api.GTValues; import gregtech.api.fluids.attribute.AttributedFluid; import gregtech.api.fluids.attribute.FluidAttribute; import gregtech.api.fluids.store.FluidStorageKey; @@ -12,13 +11,13 @@ import gregtech.api.util.FluidTooltipUtil; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import net.minecraft.block.material.MaterialLiquid; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fluids.BlockFluidBase; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; -import net.minecraftforge.fml.common.Loader; import com.google.common.base.Preconditions; import io.github.drmanganese.topaddons.reference.Colors; @@ -380,7 +379,7 @@ private static int convertViscosity(double viscosity) { } // register cross mod compat for colors - if (Loader.isModLoaded(GTValues.MODID_TOP_ADDONS)) { + if (Mods.TOPAddons.isModLoaded()) { int displayColor = isColorEnabled || material == null ? color : material.getMaterialRGB(); Colors.FLUID_NAME_COLOR_MAP.put(name, displayColor); } @@ -391,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..088035e57c2 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.GAS) { return "gregtech.fluid.gas_generic"; } return "gregtech.fluid.generic"; @@ -32,8 +36,26 @@ 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() {} + + /** + * Used to create registry names for fluids that only have a prefix when not stored by the primary key. + * + * @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 + */ + public 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/gui/GuiTextures.java b/src/main/java/gregtech/api/gui/GuiTextures.java index e85bffcfe97..8c984b5d4ed 100644 --- a/src/main/java/gregtech/api/gui/GuiTextures.java +++ b/src/main/java/gregtech/api/gui/GuiTextures.java @@ -48,6 +48,9 @@ public class GuiTextures { public static final TextureArea FLUID_TANK_OVERLAY = TextureArea .fullImage("textures/gui/base/fluid_tank_overlay.png"); public static final TextureArea SLOT = AdoptableTextureArea.fullImage("textures/gui/base/slot.png", 18, 18, 1, 1); + public static final TextureArea SLOT_DARK = AdoptableTextureArea.fullImage("textures/gui/base/slot_dark.png", 18, + 18, 1, 1); + @Deprecated // idek what this texture is public static final TextureArea SLOT_DARKENED = TextureArea.fullImage("textures/gui/base/darkened_slot.png"); public static final SteamTexture SLOT_STEAM = SteamTexture.fullImage("textures/gui/base/slot_%s.png"); public static final TextureArea TOGGLE_BUTTON_BACK = TextureArea @@ -471,9 +474,6 @@ public class GuiTextures { .fullImage("textures/gui/terminal/icon/appearance_hover.png"); public final static TextureArea ICON_CALCULATOR = TextureArea .fullImage("textures/gui/terminal/icon/calculator_hover.png"); - public final static TextureArea UI_FRAME_SIDE_UP = TextureArea.fullImage("textures/gui/terminal/frame_side_up.png"); - public final static TextureArea UI_FRAME_SIDE_DOWN = TextureArea - .fullImage("textures/gui/terminal/frame_side_down.png"); // Texture Areas public static final TextureArea BUTTON_FLUID = TextureArea @@ -504,6 +504,9 @@ public class GuiTextures { public static final TextureArea CONFIG_ARROW_DARK = TextureArea .fullImage("textures/gui/widget/config_arrow_dark.png"); public static final TextureArea SELECT_BOX = TextureArea.fullImage("textures/gui/widget/select_box.png"); + public static final TextureArea BUTTON_AUTO_PULL = TextureArea + .fullImage("textures/gui/widget/button_me_auto_pull.png"); + public static final TextureArea ARROW_DOUBLE = TextureArea.fullImage("textures/gui/widget/arrow_double.png"); // Fusion Reactor custom images public static final TextureArea FUSION_REACTOR_MK1_TITLE = TextureArea diff --git a/src/main/java/gregtech/api/gui/impl/FakeModularGuiContainer.java b/src/main/java/gregtech/api/gui/impl/FakeModularGuiContainer.java index 150a28c245f..574b010e1f8 100644 --- a/src/main/java/gregtech/api/gui/impl/FakeModularGuiContainer.java +++ b/src/main/java/gregtech/api/gui/impl/FakeModularGuiContainer.java @@ -8,16 +8,14 @@ import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; -import net.minecraft.util.NonNullList; - -import com.google.common.collect.Lists; +import java.util.ArrayList; import java.util.List; public abstract class FakeModularGuiContainer implements WidgetUIAccess { - protected final NonNullList inventoryItemStacks = NonNullList.create(); - public final List inventorySlots = Lists.newArrayList(); + protected final List inventoryItemStacks = new ArrayList<>(); + public final List inventorySlots = new ArrayList<>(); public final ModularUI modularUI; protected int windowId; diff --git a/src/main/java/gregtech/api/gui/resources/TextTexture.java b/src/main/java/gregtech/api/gui/resources/TextTexture.java index 19928d07c8b..2750890d749 100644 --- a/src/main/java/gregtech/api/gui/resources/TextTexture.java +++ b/src/main/java/gregtech/api/gui/resources/TextTexture.java @@ -20,16 +20,26 @@ public class TextTexture implements IGuiTexture { public TextType type; @SideOnly(Side.CLIENT) private List texts; + private final boolean isClient = FMLCommonHandler.instance().getSide().isClient(); public TextTexture(String text, int color) { this.color = color; this.type = TextType.NORMAL; - if (FMLCommonHandler.instance().getSide().isClient()) { + if (isClient) { this.text = I18n.format(text); texts = Collections.singletonList(this.text); } } + public TextTexture() { + this.color = 0xFFFFFF; + this.type = TextType.NORMAL; + this.text = ""; + + if (isClient) + this.texts = Collections.singletonList(this.text); + } + public TextTexture setColor(int color) { this.color = color; return this; @@ -42,11 +52,18 @@ public TextTexture setDropShadow(boolean dropShadow) { public TextTexture setWidth(int width) { this.width = width; - if (FMLCommonHandler.instance().getSide().isClient()) { - if (this.width > 0) { - texts = Minecraft.getMinecraft().fontRenderer.listFormattedStringToWidth(text, width); - } else { - texts = Collections.singletonList(text); + return this; + } + + public TextTexture setText(String text) { + if (!this.text.equals(text)) { + this.text = text; + if (isClient) { + if (this.width > 0) { + texts = Minecraft.getMinecraft().fontRenderer.listFormattedStringToWidth(text, width); + } else { + texts = Collections.singletonList(text); + } } } return this; diff --git a/src/main/java/gregtech/api/gui/widgets/ClickButtonWidget.java b/src/main/java/gregtech/api/gui/widgets/ClickButtonWidget.java index a834867fd1e..d4e059d713a 100644 --- a/src/main/java/gregtech/api/gui/widgets/ClickButtonWidget.java +++ b/src/main/java/gregtech/api/gui/widgets/ClickButtonWidget.java @@ -15,7 +15,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; -import com.google.common.base.Preconditions; import org.lwjgl.input.Mouse; import java.util.Arrays; @@ -64,7 +63,6 @@ public ClickButtonWidget setDisplayFunction(Supplier displayFunction) { } public ClickButtonWidget setTooltipText(String tooltipText, Object... args) { - Preconditions.checkNotNull(tooltipText, "tooltipText"); this.tooltipText = tooltipText; this.tooltipArgs = args; return this; diff --git a/src/main/java/gregtech/api/gui/widgets/PhantomFluidWidget.java b/src/main/java/gregtech/api/gui/widgets/PhantomFluidWidget.java index f6d3f4857f7..7fed3591548 100644 --- a/src/main/java/gregtech/api/gui/widgets/PhantomFluidWidget.java +++ b/src/main/java/gregtech/api/gui/widgets/PhantomFluidWidget.java @@ -6,7 +6,11 @@ import gregtech.api.gui.ingredient.IGhostIngredientTarget; import gregtech.api.gui.ingredient.IIngredientSlot; import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.util.*; +import gregtech.api.util.GTLog; +import gregtech.api.util.LocalizationUtils; +import gregtech.api.util.Position; +import gregtech.api.util.Size; +import gregtech.api.util.TextFormattingUtil; import gregtech.client.utils.RenderUtil; import gregtech.client.utils.TooltipHelper; diff --git a/src/main/java/gregtech/api/gui/widgets/SortingButtonWidget.java b/src/main/java/gregtech/api/gui/widgets/SortingButtonWidget.java index d053c49e7d1..2c491d18ecc 100644 --- a/src/main/java/gregtech/api/gui/widgets/SortingButtonWidget.java +++ b/src/main/java/gregtech/api/gui/widgets/SortingButtonWidget.java @@ -1,14 +1,13 @@ package gregtech.api.gui.widgets; +import gregtech.api.util.Mods; + import net.minecraft.client.settings.KeyBinding; -import net.minecraftforge.fml.common.Loader; import java.util.function.Consumer; public class SortingButtonWidget extends ClickButtonWidget { - private static boolean inventoryTweaksChecked; - private static boolean inventoryTweaksPresent; private static KeyBinding sortKeyBinding; public SortingButtonWidget(int xPosition, int yPosition, int width, int height, String displayText, @@ -43,13 +42,10 @@ public boolean keyTyped(char charTyped, int keyCode) { } private static int getInvTweaksSortCode() { - if (!inventoryTweaksChecked) { - inventoryTweaksChecked = true; - inventoryTweaksPresent = Loader.isModLoaded("inventorytweaks"); - } - if (!inventoryTweaksPresent) { + if (!Mods.InventoryTweaks.isModLoaded()) { return 0; } + try { if (sortKeyBinding == null) { Class proxyClass = Class.forName("invtweaks.forge.ClientProxy"); diff --git a/src/main/java/gregtech/api/items/armor/ArmorMetaItem.java b/src/main/java/gregtech/api/items/armor/ArmorMetaItem.java index e7e663377d0..a972b669c95 100644 --- a/src/main/java/gregtech/api/items/armor/ArmorMetaItem.java +++ b/src/main/java/gregtech/api/items/armor/ArmorMetaItem.java @@ -1,9 +1,9 @@ package gregtech.api.items.armor; -import gregtech.api.GregTechAPI; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.metaitem.stats.IEnchantabilityHelper; import gregtech.api.items.metaitem.stats.IItemComponent; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.model.ModelBiped; @@ -33,7 +33,7 @@ public class ArmorMetaItem.ArmorMetaValueItem> extend public ArmorMetaItem() { super((short) 0); - setCreativeTab(GregTechAPI.TAB_GREGTECH_TOOLS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS); } @SuppressWarnings("unchecked") diff --git a/src/main/java/gregtech/api/items/behavior/CoverItemBehavior.java b/src/main/java/gregtech/api/items/behavior/CoverItemBehavior.java index 5feda5eac58..826e85d961d 100644 --- a/src/main/java/gregtech/api/items/behavior/CoverItemBehavior.java +++ b/src/main/java/gregtech/api/items/behavior/CoverItemBehavior.java @@ -56,8 +56,10 @@ public EnumActionResult onItemUseFirst(EntityPlayer player, @NotNull World world ItemStack itemStack = player.getHeldItem(hand); - coverHolder.addCover(coverSide, cover); + // Call onAttachment first so that the cover can set up any + // necessary variables needed for the S2C cover sync packet. cover.onAttachment(coverHolder, coverSide, player, itemStack); + coverHolder.addCover(coverSide, cover); AdvancementTriggers.FIRST_COVER_PLACE.trigger((EntityPlayerMP) player); diff --git a/src/main/java/gregtech/api/items/gui/ItemUIFactory.java b/src/main/java/gregtech/api/items/gui/ItemUIFactory.java index abff0448370..6633e96bb8b 100644 --- a/src/main/java/gregtech/api/items/gui/ItemUIFactory.java +++ b/src/main/java/gregtech/api/items/gui/ItemUIFactory.java @@ -13,7 +13,7 @@ import com.cleanroommc.modularui.factory.HandGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.screen.ModularScreen; -import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; import org.jetbrains.annotations.ApiStatus; public interface ItemUIFactory extends IItemComponent, IGuiHolder { @@ -39,7 +39,7 @@ default GTGuiTheme getUITheme() { } @Override - default ModularPanel buildUI(HandGuiData guiData, GuiSyncManager guiSyncManager) { + default ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager) { return null; } } diff --git a/src/main/java/gregtech/api/items/itemhandlers/GTItemStackHandler.java b/src/main/java/gregtech/api/items/itemhandlers/GTItemStackHandler.java index b983862e399..eab9612c747 100644 --- a/src/main/java/gregtech/api/items/itemhandlers/GTItemStackHandler.java +++ b/src/main/java/gregtech/api/items/itemhandlers/GTItemStackHandler.java @@ -26,7 +26,7 @@ public GTItemStackHandler(MetaTileEntity metaTileEntity, NonNullList } @Override - protected void onContentsChanged(int slot) { + public void onContentsChanged(int slot) { super.onContentsChanged(slot); metaTileEntity.markDirty(); } diff --git a/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java b/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java index 35172727add..f84e0264ad2 100644 --- a/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java +++ b/src/main/java/gregtech/api/items/materialitem/MetaPrefixItem.java @@ -1,7 +1,6 @@ package gregtech.api.items.materialitem; import gregtech.api.GTValues; -import gregtech.api.GregTechAPI; import gregtech.api.damagesources.DamageSources; import gregtech.api.items.armor.ArmorMetaItem; import gregtech.api.items.metaitem.StandardMetaItem; @@ -15,6 +14,7 @@ import gregtech.api.unification.material.registry.MaterialRegistry; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.UnificationEntry; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.BlockCauldron; import net.minecraft.block.state.IBlockState; @@ -58,7 +58,7 @@ public MetaPrefixItem(@NotNull MaterialRegistry registry, @NotNull OrePrefix ore super(); this.registry = registry; this.prefix = orePrefix; - this.setCreativeTab(GregTechAPI.TAB_GREGTECH_MATERIALS); + this.setCreativeTab(GTCreativeTabs.TAB_GREGTECH_MATERIALS); } @Override @@ -85,11 +85,7 @@ private static void registerSpecialOreDict(ItemStack item, Material material, Or OreDictUnifier.registerOre(item, prefix.getAlternativeOreName(), material); } - if (material == Materials.Plutonium239) { - OreDictUnifier.registerOre(item, prefix.name() + material.toCamelCaseString() + "239"); - } else if (material == Materials.Uranium238) { - OreDictUnifier.registerOre(item, prefix.name() + material.toCamelCaseString() + "238"); - } else if (material == Materials.Saltpeter) { + if (material == Materials.Saltpeter) { OreDictUnifier.registerOre(item, prefix.name() + material.toCamelCaseString()); } } diff --git a/src/main/java/gregtech/api/items/metaitem/ElectricStats.java b/src/main/java/gregtech/api/items/metaitem/ElectricStats.java index 91bd1b739da..bf336ec4676 100644 --- a/src/main/java/gregtech/api/items/metaitem/ElectricStats.java +++ b/src/main/java/gregtech/api/items/metaitem/ElectricStats.java @@ -6,6 +6,7 @@ import gregtech.api.capability.IElectricItem; import gregtech.api.capability.impl.ElectricItem; import gregtech.api.items.metaitem.stats.*; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import gregtech.integration.baubles.BaublesModule; @@ -25,7 +26,6 @@ import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.energy.CapabilityEnergy; import net.minecraftforge.energy.IEnergyStorage; -import net.minecraftforge.fml.common.Loader; import java.time.Duration; import java.time.Instant; @@ -75,7 +75,7 @@ public void onUpdate(ItemStack itemStack, Entity entity) { IInventory inventoryPlayer = entityPlayer.inventory; long transferLimit = electricItem.getTransferLimit(); - if (Loader.isModLoaded(GTValues.MODID_BAUBLES)) { + if (Mods.Baubles.isModLoaded()) { inventoryPlayer = BaublesModule.getBaublesWrappedInventory(entityPlayer); } diff --git a/src/main/java/gregtech/api/items/metaitem/MetaItem.java b/src/main/java/gregtech/api/items/metaitem/MetaItem.java index ba1f713f010..a17559b05b2 100644 --- a/src/main/java/gregtech/api/items/metaitem/MetaItem.java +++ b/src/main/java/gregtech/api/items/metaitem/MetaItem.java @@ -1,7 +1,6 @@ package gregtech.api.items.metaitem; import gregtech.api.GTValues; -import gregtech.api.GregTechAPI; import gregtech.api.capability.GregtechCapabilities; import gregtech.api.capability.IElectricItem; import gregtech.api.capability.IFilteredFluidContainer; @@ -12,7 +11,18 @@ import gregtech.api.items.OreDictNames; import gregtech.api.items.gui.ItemUIFactory; import gregtech.api.items.gui.PlayerInventoryHolder; -import gregtech.api.items.metaitem.stats.*; +import gregtech.api.items.metaitem.stats.IEnchantabilityHelper; +import gregtech.api.items.metaitem.stats.IFoodBehavior; +import gregtech.api.items.metaitem.stats.IItemBehaviour; +import gregtech.api.items.metaitem.stats.IItemCapabilityProvider; +import gregtech.api.items.metaitem.stats.IItemColorProvider; +import gregtech.api.items.metaitem.stats.IItemComponent; +import gregtech.api.items.metaitem.stats.IItemContainerItemProvider; +import gregtech.api.items.metaitem.stats.IItemDurabilityManager; +import gregtech.api.items.metaitem.stats.IItemMaxStackSizeProvider; +import gregtech.api.items.metaitem.stats.IItemNameProvider; +import gregtech.api.items.metaitem.stats.IItemUseManager; +import gregtech.api.items.metaitem.stats.ISubItemHandler; import gregtech.api.recipes.ingredients.IntCircuitIngredient; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Material; @@ -20,8 +30,11 @@ import gregtech.api.unification.stack.ItemMaterialInfo; import gregtech.api.util.GTUtility; import gregtech.api.util.LocalizationUtils; +import gregtech.api.util.Mods; import gregtech.client.utils.ToolChargeBarRenderer; import gregtech.common.ConfigHolder; +import gregtech.common.covers.filter.IFilter; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.block.model.ModelBakery; @@ -40,7 +53,12 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.*; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.client.model.ModelLoader; @@ -72,23 +90,31 @@ import java.time.Duration; import java.time.Instant; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; /** - * MetaItem is item that can have up to Short.MAX_VALUE items inside one id. - * These items even can be edible, have custom behaviours, be electric or act like fluid containers! - * They can also have different burn time, plus be handheld, oredicted or invisible! - * They also can be reactor components. + * MetaItem is item that can have up to Short.MAX_VALUE items inside one id. These items even can be edible, have custom + * behaviours, be electric or act like fluid containers! They can also have different burn time, plus be handheld, + * oredicted or invisible! They also can be reactor components. *

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

* Items are added in MetaItem via {@link #addItem(int, String)}. You will get {@link MetaValueItem} instance, which you * can configure in builder-alike pattern: - * {@code addItem(0, "test_item").addStats(new ElectricStats(10000, 1, false)) } - * This will add single-use (not rechargeable) LV battery with initial capacity 10000 EU + * {@code addItem(0, "test_item").addStats(new ElectricStats(10000, 1, false)) } This will add single-use (not + * rechargeable) LV battery with initial capacity 10000 EU */ -@Optional.Interface(modid = GTValues.MODID_ECORE, iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") +@Optional.Interface( + modid = Mods.Names.ENDER_CORE, + iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") public abstract class MetaItem.MetaValueItem> extends Item implements ItemUIFactory, IOverlayRenderAware { @@ -107,11 +133,12 @@ public static List> getMetaItems() { protected final short metaItemOffset; - private CreativeTabs[] defaultCreativeTabs = new CreativeTabs[] { GregTechAPI.TAB_GREGTECH }; + private CreativeTabs[] defaultCreativeTabs = new CreativeTabs[] { GTCreativeTabs.TAB_GREGTECH }; private final Set additionalCreativeTabs = new ObjectArraySet<>(); + private String translationKey = "metaitem"; + public MetaItem(short metaItemOffset) { - setTranslationKey("meta_item"); setHasSubtypes(true); this.metaItemOffset = metaItemOffset; META_ITEMS.add(this); @@ -354,6 +381,7 @@ public void onPlayerStoppedUsing(@NotNull ItemStack stack, @NotNull World world, } } + @NotNull @Override public ItemStack onItemUseFinish(@NotNull ItemStack stack, @NotNull World world, @NotNull EntityLivingBase player) { if (player instanceof EntityPlayer) { @@ -527,10 +555,28 @@ public boolean shouldCauseReequipAnimation(@NotNull ItemStack oldStack, @NotNull return !ItemStack.areItemStacksEqual(oldStack, newStack); } + @NotNull + @Override + public MetaItem setTranslationKey(@NotNull String key) { + this.translationKey = Objects.requireNonNull(key, "key == null"); + return this; + } + + @NotNull @Override - public String getTranslationKey(ItemStack stack) { - T metaItem = getItem(stack); - return metaItem == null ? getTranslationKey() : getTranslationKey() + "." + metaItem.unlocalizedName; + public String getTranslationKey() { + return getTranslationKey((T) null); + } + + @NotNull + @Override + public String getTranslationKey(@NotNull ItemStack stack) { + return getTranslationKey(getItem(stack)); + } + + @NotNull + protected String getTranslationKey(@Nullable T metaValueItem) { + return metaValueItem == null ? this.translationKey : this.translationKey + "." + metaValueItem.unlocalizedName; } @NotNull @@ -541,7 +587,7 @@ public String getItemStackDisplayName(ItemStack stack) { if (item == null) { return "invalid item"; } - String unlocalizedName = String.format("metaitem.%s.name", item.unlocalizedName); + String unlocalizedName = getTranslationKey(item) + ".name"; if (item.getNameProvider() != null) { return item.getNameProvider().getItemStackDisplayName(stack, unlocalizedName); } @@ -564,7 +610,7 @@ public void addInformation(@NotNull ItemStack itemStack, @Nullable World worldIn @NotNull ITooltipFlag tooltipFlag) { T item = getItem(itemStack); if (item == null) return; - String unlocalizedTooltip = "metaitem." + item.unlocalizedName + ".tooltip"; + String unlocalizedTooltip = getTranslationKey(item) + ".tooltip"; if (I18n.hasKey(unlocalizedTooltip)) { Collections.addAll(lines, LocalizationUtils.formatLines(unlocalizedTooltip)); } @@ -660,25 +706,27 @@ public ItemStack getContainerItem(@NotNull ItemStack itemStack) { @NotNull @Override - public CreativeTabs[] getCreativeTabs() { + public CreativeTabs @NotNull [] getCreativeTabs() { if (additionalCreativeTabs.isEmpty()) return defaultCreativeTabs; // short circuit Set tabs = new ObjectArraySet<>(additionalCreativeTabs); tabs.addAll(Arrays.asList(defaultCreativeTabs)); return tabs.toArray(new CreativeTabs[0]); } + @NotNull @Override - public MetaItem setCreativeTab(CreativeTabs tab) { + public MetaItem setCreativeTab(@NotNull CreativeTabs tab) { this.defaultCreativeTabs = new CreativeTabs[] { tab }; return this; } - public MetaItem setCreativeTabs(CreativeTabs... tabs) { + @NotNull + public MetaItem setCreativeTabs(@NotNull CreativeTabs @NotNull... tabs) { this.defaultCreativeTabs = tabs; return this; } - public void addAdditionalCreativeTabs(CreativeTabs... tabs) { + public void addAdditionalCreativeTabs(@NotNull CreativeTabs @NotNull... tabs) { for (CreativeTabs tab : tabs) { if (!ArrayUtils.contains(defaultCreativeTabs, tab) && tab != CreativeTabs.SEARCH) { additionalCreativeTabs.add(tab); @@ -687,7 +735,7 @@ public void addAdditionalCreativeTabs(CreativeTabs... tabs) { } @Override - protected boolean isInCreativeTab(CreativeTabs tab) { + protected boolean isInCreativeTab(@NotNull CreativeTabs tab) { return tab == CreativeTabs.SEARCH || ArrayUtils.contains(defaultCreativeTabs, tab) || additionalCreativeTabs.contains(tab); @@ -734,6 +782,7 @@ public MetaItem getMetaItem() { private final List behaviours = new ArrayList<>(); private IItemUseManager useManager; private ItemUIFactory uiManager; + private IFilter.Factory filterBehavior; private IItemColorProvider colorProvider; private IItemDurabilityManager durabilityManager; private IEnchantabilityHelper enchantabilityHelper; @@ -861,9 +910,12 @@ protected void addItemComponentsInternal(IItemComponent... stats) { if (itemComponent instanceof IFoodBehavior) { this.useManager = new FoodUseManager((IFoodBehavior) itemComponent); } - if (itemComponent instanceof ItemUIFactory) + if (itemComponent instanceof ItemUIFactory) { this.uiManager = (ItemUIFactory) itemComponent; - + } + if (itemComponent instanceof IFilter.Factory) { + this.filterBehavior = (IFilter.Factory) itemComponent; + } if (itemComponent instanceof IItemColorProvider) { this.colorProvider = (IItemColorProvider) itemComponent; } @@ -909,6 +961,11 @@ public ItemUIFactory getUIManager() { return uiManager; } + @Nullable + public IFilter.Factory getFilterFactory() { + return filterBehavior; + } + @Nullable public IItemColorProvider getColorProvider() { return colorProvider; diff --git a/src/main/java/gregtech/api/items/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/items/toolitem/IGTTool.java b/src/main/java/gregtech/api/items/toolitem/IGTTool.java index 4c3ba369341..94ae45effb9 100644 --- a/src/main/java/gregtech/api/items/toolitem/IGTTool.java +++ b/src/main/java/gregtech/api/items/toolitem/IGTTool.java @@ -24,6 +24,7 @@ import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.api.util.TextFormattingUtil; import gregtech.client.utils.ToolChargeBarRenderer; import gregtech.client.utils.TooltipHelper; @@ -89,14 +90,21 @@ * Backing of every variation of a GT Tool */ @Optional.InterfaceList({ - @Optional.Interface(modid = GTValues.MODID_APPENG, iface = "appeng.api.implementations.items.IAEWrench"), - @Optional.Interface(modid = GTValues.MODID_BC, iface = "buildcraft.api.tools.IToolWrench"), - @Optional.Interface(modid = GTValues.MODID_COFH, iface = "cofh.api.item.IToolHammer"), - @Optional.Interface(modid = GTValues.MODID_EIO, iface = "crazypants.enderio.api.tool.ITool"), - @Optional.Interface(modid = GTValues.MODID_FR, iface = "forestry.api.arboriculture.IToolGrafter"), - @Optional.Interface(modid = GTValues.MODID_PROJRED_CORE, iface = "mrtjp.projectred.api.IScrewdriver"), - @Optional.Interface(modid = GTValues.MODID_RC, iface = "mods.railcraft.api.items.IToolCrowbar"), - @Optional.Interface(modid = GTValues.MODID_ECORE, + @Optional.Interface(modid = Mods.Names.APPLIED_ENERGISTICS2, + iface = "appeng.api.implementations.items.IAEWrench"), + @Optional.Interface(modid = Mods.Names.BUILD_CRAFT_CORE, + iface = "buildcraft.api.tools.IToolWrench"), + @Optional.Interface(modid = Mods.Names.COFH_CORE, + iface = "cofh.api.item.IToolHammer"), + @Optional.Interface(modid = Mods.Names.ENDER_IO, + iface = "crazypants.enderio.api.tool.ITool"), + @Optional.Interface(modid = Mods.Names.FORESTRY, + iface = "forestry.api.arboriculture.IToolGrafter"), + @Optional.Interface(modid = Mods.Names.PROJECT_RED_CORE, + iface = "mrtjp.projectred.api.IScrewdriver"), + @Optional.Interface(modid = Mods.Names.RAILCRAFT, + iface = "mods.railcraft.api.items.IToolCrowbar"), + @Optional.Interface(modid = Mods.Names.ENDER_CORE, iface = "com.enderio.core.common.interfaces.IOverlayRenderAware") }) public interface IGTTool extends ItemUIFactory, IAEWrench, IToolWrench, IToolHammer, ITool, IToolGrafter, IOverlayRenderAware, IScrewdriver, IToolCrowbar { diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTAxe.java b/src/main/java/gregtech/api/items/toolitem/ItemGTAxe.java index 5acd7f41780..2537884399a 100644 --- a/src/main/java/gregtech/api/items/toolitem/ItemGTAxe.java +++ b/src/main/java/gregtech/api/items/toolitem/ItemGTAxe.java @@ -1,7 +1,7 @@ package gregtech.api.items.toolitem; -import gregtech.api.GregTechAPI; import gregtech.api.util.LocalizationUtils; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.state.IBlockState; import net.minecraft.client.util.ITooltipFlag; @@ -14,7 +14,12 @@ import net.minecraft.item.ItemAxe; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.*; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; @@ -59,7 +64,7 @@ protected ItemGTAxe(String domain, String id, int tier, IGTToolDefinition toolSt this.secondaryOreDicts = secondaryOreDicts; this.markerItem = markerItem; setMaxStackSize(1); - setCreativeTab(GregTechAPI.TAB_GREGTECH_TOOLS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS); setTranslationKey("gt.tool." + id + ".name"); setRegistryName(domain, id); } diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTHoe.java b/src/main/java/gregtech/api/items/toolitem/ItemGTHoe.java index 7f52587be7c..13e14e8e574 100644 --- a/src/main/java/gregtech/api/items/toolitem/ItemGTHoe.java +++ b/src/main/java/gregtech/api/items/toolitem/ItemGTHoe.java @@ -1,7 +1,7 @@ package gregtech.api.items.toolitem; -import gregtech.api.GregTechAPI; import gregtech.api.util.LocalizationUtils; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.state.IBlockState; import net.minecraft.client.util.ITooltipFlag; @@ -14,7 +14,12 @@ import net.minecraft.item.ItemHoe; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.*; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; @@ -59,7 +64,7 @@ protected ItemGTHoe(String domain, String id, int tier, IGTToolDefinition toolSt this.secondaryOreDicts = secondaryOreDicts; this.markerItem = markerItem; setMaxStackSize(1); - setCreativeTab(GregTechAPI.TAB_GREGTECH_TOOLS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS); setTranslationKey("gt.tool." + id + ".name"); setRegistryName(domain, id); } diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTSword.java b/src/main/java/gregtech/api/items/toolitem/ItemGTSword.java index 5b95f6f3718..2786f91d558 100644 --- a/src/main/java/gregtech/api/items/toolitem/ItemGTSword.java +++ b/src/main/java/gregtech/api/items/toolitem/ItemGTSword.java @@ -1,7 +1,7 @@ package gregtech.api.items.toolitem; -import gregtech.api.GregTechAPI; import gregtech.api.util.LocalizationUtils; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.state.IBlockState; import net.minecraft.client.util.ITooltipFlag; @@ -14,7 +14,12 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.*; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; @@ -61,7 +66,7 @@ protected ItemGTSword(String domain, String id, int tier, IGTToolDefinition tool this.secondaryOreDicts = secondaryOreDicts; this.markerItem = markerItem; setMaxStackSize(1); - setCreativeTab(GregTechAPI.TAB_GREGTECH_TOOLS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS); setTranslationKey("gt.tool." + id + ".name"); setRegistryName(domain, id); } diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTTool.java b/src/main/java/gregtech/api/items/toolitem/ItemGTTool.java index edcfa83126d..375aadb845c 100644 --- a/src/main/java/gregtech/api/items/toolitem/ItemGTTool.java +++ b/src/main/java/gregtech/api/items/toolitem/ItemGTTool.java @@ -1,7 +1,7 @@ package gregtech.api.items.toolitem; -import gregtech.api.GregTechAPI; import gregtech.api.util.LocalizationUtils; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.state.IBlockState; import net.minecraft.client.util.ITooltipFlag; @@ -14,7 +14,12 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.ItemTool; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.*; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; @@ -65,7 +70,7 @@ protected ItemGTTool(String domain, String id, int tier, IGTToolDefinition toolS this.secondaryOreDicts = secondaryOreDicts; this.markerItem = markerItem; setMaxStackSize(1); - setCreativeTab(GregTechAPI.TAB_GREGTECH_TOOLS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS); setTranslationKey("gt.tool." + id + ".name"); setRegistryName(domain, id); } diff --git a/src/main/java/gregtech/api/items/toolitem/ToolHelper.java b/src/main/java/gregtech/api/items/toolitem/ToolHelper.java index 2e0a3335df0..8b1a8ef147a 100644 --- a/src/main/java/gregtech/api/items/toolitem/ToolHelper.java +++ b/src/main/java/gregtech/api/items/toolitem/ToolHelper.java @@ -18,7 +18,13 @@ import gregtech.tools.enchants.EnchantmentHardHammer; import net.minecraft.advancements.CriteriaTriggers; -import net.minecraft.block.*; +import net.minecraft.block.Block; +import net.minecraft.block.BlockCommandBlock; +import net.minecraft.block.BlockLiquid; +import net.minecraft.block.BlockPane; +import net.minecraft.block.BlockRailBase; +import net.minecraft.block.BlockStructure; +import net.minecraft.block.BlockWeb; import net.minecraft.block.state.IBlockState; import net.minecraft.enchantment.EnchantmentDurability; import net.minecraft.enchantment.EnchantmentHelper; @@ -57,7 +63,11 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.reflect.Method; -import java.util.*; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import java.util.Set; import java.util.function.Supplier; import static gregtech.api.GTValues.LV; @@ -196,7 +206,7 @@ public static ItemStack getAndSetToolData(IGTTool tool, Material material, int m ItemStack stack = tool.getRaw(); GTUtility.getOrCreateNbtCompound(stack).setInteger(HIDE_FLAGS, 2); NBTTagCompound toolTag = getToolTag(stack); - toolTag.setString(MATERIAL_KEY, material.toString()); + toolTag.setString(MATERIAL_KEY, material.getRegistryName()); toolTag.setInteger(MAX_DURABILITY_KEY, maxDurability); toolTag.setInteger(HARVEST_LEVEL_KEY, harvestLevel); toolTag.setFloat(TOOL_SPEED_KEY, toolSpeed); @@ -270,7 +280,7 @@ public static void damageItem(@NotNull ItemStack stack, @Nullable EntityLivingBa if (electricItem != null) { electricItem.discharge(electricDamage, tool.getElectricTier(), true, false, false); if (electricItem.getCharge() > 0 && - random.nextInt(100) > ConfigHolder.tools.rngDamageElectricTools) { + random.nextInt(100) >= ConfigHolder.tools.rngDamageElectricTools) { return; } } else { diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index 659460902b0..b0648610103 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -6,15 +6,25 @@ import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IControllable; +import gregtech.api.capability.IDataStickIntractable; import gregtech.api.capability.IEnergyContainer; -import gregtech.api.capability.impl.*; -import gregtech.api.cover.*; +import gregtech.api.capability.impl.AbstractRecipeLogic; +import gregtech.api.capability.impl.FluidHandlerProxy; +import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.ItemHandlerProxy; +import gregtech.api.capability.impl.NotifiableFluidTank; +import gregtech.api.cover.Cover; +import gregtech.api.cover.CoverHolder; +import gregtech.api.cover.CoverRayTracer; +import gregtech.api.cover.CoverSaveHandler; +import gregtech.api.cover.CoverUtil; import gregtech.api.gui.ModularUI; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.items.toolitem.ToolClasses; 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; @@ -22,9 +32,14 @@ import gregtech.api.util.GTLog; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.BloomEffectUtil; +import gregtech.client.utils.RenderUtil; +import gregtech.client.utils.TooltipHelper; import gregtech.common.ConfigHolder; +import gregtech.common.creativetab.GTCreativeTabs; +import gregtech.common.items.MetaItems; import net.minecraft.block.Block; import net.minecraft.block.state.BlockFaceShape; @@ -32,6 +47,7 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.I18n; import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; @@ -40,7 +56,13 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.*; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; @@ -51,6 +73,7 @@ import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.Optional.Method; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -66,14 +89,13 @@ import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.ColourMultiplier; import codechicken.lib.render.pipeline.IVertexOperation; -import codechicken.lib.texture.TextureUtils; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.IGuiHolder; import com.cleanroommc.modularui.factory.PosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.screen.ModularScreen; -import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.google.common.base.Preconditions; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; @@ -84,7 +106,12 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -97,6 +124,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; @@ -132,9 +161,14 @@ public abstract class MetaTileEntity implements ISyncedTileEntity, CoverHolder, protected boolean muffled = false; private int playSoundCooldown = 0; + private int lastTick = 0; + + @Nullable + private UUID owner = null; - public MetaTileEntity(ResourceLocation metaTileEntityId) { + protected MetaTileEntity(@NotNull ResourceLocation metaTileEntityId) { this.metaTileEntityId = metaTileEntityId; + this.registry = GregTechAPI.mteManager.getRegistry(metaTileEntityId.getNamespace()); initializeInventory(); } @@ -236,7 +270,7 @@ public boolean showToolUsages() { @SideOnly(Side.CLIENT) public Pair getParticleTexture() { - return Pair.of(TextureUtils.getMissingSprite(), 0xFFFFFF); + return Pair.of(RenderUtil.getMissingSprite(), 0xFFFFFF); } /** @@ -262,7 +296,7 @@ public void setRenderContextStack(ItemStack itemStack) { */ @SideOnly(Side.CLIENT) public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { - TextureAtlasSprite atlasSprite = TextureUtils.getMissingSprite(); + TextureAtlasSprite atlasSprite = RenderUtil.getMissingSprite(); IVertexOperation[] renderPipeline = ArrayUtils.add(pipeline, new ColourMultiplier(GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))); for (EnumFacing face : EnumFacing.VALUES) { @@ -328,7 +362,7 @@ public void getSubItems(CreativeTabs creativeTab, NonNullList subItem * MachineItemBlock#addCreativeTab(CreativeTabs) */ public boolean isInCreativeTab(CreativeTabs creativeTab) { - return creativeTab == CreativeTabs.SEARCH || creativeTab == GregTechAPI.TAB_GREGTECH_MACHINES; + return creativeTab == CreativeTabs.SEARCH || creativeTab == GTCreativeTabs.TAB_GREGTECH_MACHINES; } public String getItemSubTypeId(ItemStack itemStack) { @@ -446,7 +480,7 @@ public GTGuiTheme getUITheme() { } @Override - public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { return null; } @@ -465,6 +499,12 @@ public final void onCoverLeftClick(EntityPlayer playerIn, CuboidRayTraceResult r public boolean onRightClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, CuboidRayTraceResult hitResult) { ItemStack heldStack = playerIn.getHeldItem(hand); + if (this instanceof IDataStickIntractable dsi) { + if (MetaItems.TOOL_DATA_STICK.isItemEqual(heldStack) && dsi.onDataStickRightClick(playerIn, heldStack)) { + return true; + } + } + if (!playerIn.isSneaking() && openGUIOnRightClick()) { if (getWorld() != null && !getWorld().isRemote) { if (usesMui2()) { @@ -472,6 +512,10 @@ public boolean onRightClick(EntityPlayer playerIn, EnumHand hand, EnumFacing fac } else { MetaTileEntityUIFactory.INSTANCE.openUI(getHolder(), (EntityPlayerMP) playerIn); } + + if (getOwner() == null) { + this.owner = playerIn.getUniqueID(); + } } return true; } else { @@ -540,6 +584,9 @@ public final boolean onToolClick(EntityPlayer playerIn, @NotNull Set too if (toolClasses.contains(ToolClasses.HARD_HAMMER)) { return onHardHammerClick(playerIn, hand, gridSideHit, hitResult); } + if (toolClasses.contains(ToolClasses.WIRE_CUTTER)) { + return onWireCutterClick(playerIn, hand, gridSideHit, hitResult); + } return false; } @@ -620,7 +667,24 @@ public boolean onHardHammerClick(EntityPlayer playerIn, EnumHand hand, EnumFacin return true; } - public void onLeftClick(EntityPlayer player, EnumFacing facing, CuboidRayTraceResult hitResult) {} + /** + * Called when player clicks a wire cutter on specific side of this meta tile entity + * + * @return true if something happened, so the tool will get damaged and animation will be played + */ + public boolean onWireCutterClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, + CuboidRayTraceResult hitResult) { + return false; + } + + public void onLeftClick(EntityPlayer player, EnumFacing facing, CuboidRayTraceResult hitResult) { + if (this instanceof IDataStickIntractable dsi) { + ItemStack stack = player.getHeldItemMainhand(); + if (MetaItems.TOOL_DATA_STICK.isItemEqual(stack)) { + dsi.onDataStickLeftClick(player, stack); + } + } + } /** * @return true if the player must sneak to rotate this metatileentity, otherwise false @@ -789,11 +853,20 @@ private void updateLightValue() { } public void update() { + if (!getWorld().isRemote && !allowTickAcceleration()) { + int currentTick = FMLCommonHandler.instance().getMinecraftServerInstance().getTickCounter(); + if (currentTick == lastTick) { + return; + } + lastTick = currentTick; + } + for (MTETrait mteTrait : this.mteTraits.values()) { if (shouldUpdate(mteTrait)) { mteTrait.update(); } } + if (!getWorld().isRemote) { updateCovers(); } else { @@ -804,6 +877,15 @@ public void update() { } } + /** + * @return Whether this machine is allowed to be tick accelerated by external means. This does NOT + * apply to World Accelerators from GT, those will never work on machines. This refers to effects + * like Time in a Bottle, or Torcherino, or similar. + */ + public boolean allowTickAcceleration() { + return ConfigHolder.machines.allowTickAcceleration; + } + protected boolean shouldUpdate(MTETrait trait) { return true; } @@ -829,15 +911,24 @@ 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); } - public final ItemStack getStackForm() { + @Override + public final @NotNull ItemStack getStackForm() { 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 @@ -847,17 +938,18 @@ public final ItemStack getStackForm() { * @param dropsList list of meta tile entity drops * @param harvester harvester of this meta tile entity, or null */ - public void getDrops(NonNullList dropsList, @Nullable EntityPlayer harvester) {} + public void getDrops(@NotNull List<@NotNull ItemStack> dropsList, @Nullable EntityPlayer harvester) {} public final ItemStack getPickItem(CuboidRayTraceResult result, EntityPlayer player) { IndexedCuboid6 hitCuboid = result.cuboid6; + final boolean isCreativePickBlock = player.isCreative() && TooltipHelper.isCtrlDown(); if (hitCuboid.data instanceof CoverRayTracer.CoverSideData coverSideData) { Cover cover = getCoverAtSide(coverSideData.side); - return cover == null ? ItemStack.EMPTY : cover.getPickItem(); + return cover == null || isCreativePickBlock ? ItemStack.EMPTY : cover.getPickItem(); } else if (hitCuboid.data == null || hitCuboid.data instanceof CoverRayTracer.PrimaryBoxData) { // data is null -> MetaTileEntity hull hit Cover cover = getCoverAtSide(result.sideHit); - if (cover != null) { + if (cover != null && !isCreativePickBlock) { return cover.getPickItem(); } return getPickItem(player); @@ -1225,6 +1317,10 @@ public NBTTagCompound writeToNBT(NBTTagCompound data) { CoverSaveHandler.writeCoverNBT(data, this); data.setBoolean(TAG_KEY_MUFFLED, muffled); + + if (owner != null) + data.setUniqueId("Owner", owner); + return data; } @@ -1250,6 +1346,9 @@ public void readFromNBT(NBTTagCompound data) { CoverSaveHandler.readCoverNBT(data, this, covers::put); this.muffled = data.getBoolean(TAG_KEY_MUFFLED); + + if (data.hasKey("Owner")) + this.owner = data.getUniqueId("Owner"); } @Override @@ -1257,12 +1356,13 @@ public boolean isValid() { return getHolder() != null && getHolder().isValid(); } - public void clearMachineInventory(NonNullList itemBuffer) { + public void clearMachineInventory(@NotNull List<@NotNull ItemStack> itemBuffer) { clearInventory(itemBuffer, importItems); clearInventory(itemBuffer, exportItems); } - public static void clearInventory(NonNullList itemBuffer, IItemHandlerModifiable inventory) { + public static void clearInventory(@NotNull List<@NotNull ItemStack> itemBuffer, + @NotNull IItemHandlerModifiable inventory) { for (int i = 0; i < inventory.getSlots(); i++) { ItemStack stackInSlot = inventory.getStackInSlot(i); if (!stackInSlot.isEmpty()) { @@ -1277,12 +1377,28 @@ public int getItemStackLimit(ItemStack stack) { } /** - * Called whenever a MetaTileEntity is placed in world by {@link Block#onBlockPlacedBy} + * Called whenever a MetaTileEntity is placed in world by {@link Block#onBlockPlacedBy}, + * gives the MetaTileEntity an Owner by UUID *

* If placing an MTE with methods such as {@link World#setBlockState(BlockPos, IBlockState)}, * this should be manually called immediately afterwards */ - public void onPlacement() {} + public void onPlacement(@Nullable EntityLivingBase placer) { + if (placer instanceof EntityPlayer player) { + this.owner = player.getUniqueID(); + } + } + + /** + * Called whenever a MetaTileEntity is placed in world by {@link Block#onBlockPlacedBy}, + * gives the MetaTileEntity an Owner of Null + *

+ * If placing an MTE with methods such as {@link World#setBlockState(BlockPos, IBlockState)}, + * this should be manually called immediately afterwards + */ + public final void onPlacement() { + onPlacement(null); + } /** * Called from breakBlock right before meta tile entity destruction @@ -1382,6 +1498,11 @@ public boolean getWitherProof() { return false; } + @Nullable + public UUID getOwner() { + return owner; + } + public final void toggleMuffled() { muffled = !muffled; if (!getWorld().isRemote) { @@ -1527,17 +1648,17 @@ public boolean canVoidRecipeFluidOutputs() { } @NotNull - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AECableType getCableConnectionType(@NotNull AEPartLocation part) { return AECableType.NONE; } @Nullable - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AENetworkProxy getProxy() { return null; } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void gridChanged() {} } diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java index 9d5662a1153..6884f33ac38 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntityHolder.java @@ -1,13 +1,14 @@ package gregtech.api.metatileentity; -import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.block.machines.BlockMachine; import gregtech.api.capability.GregtechDataCodes; 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; import gregtech.client.particle.GTNameTagParticle; import gregtech.client.particle.GTParticleManager; @@ -24,12 +25,15 @@ 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; import net.minecraftforge.common.util.Constants.NBT; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional.Interface; import net.minecraftforge.fml.common.Optional.InterfaceList; import net.minecraftforge.fml.common.Optional.Method; @@ -54,10 +58,11 @@ @InterfaceList(value = { @Interface(iface = "appeng.api.networking.security.IActionHost", - modid = GTValues.MODID_APPENG, + modid = Mods.Names.APPLIED_ENERGISTICS2, striprefs = true), - @Interface(iface = "appeng.me.helpers.IGridProxyable", modid = GTValues.MODID_APPENG, striprefs = true), -}) + @Interface(iface = "appeng.me.helpers.IGridProxyable", + modid = Mods.Names.APPLIED_ENERGISTICS2, + striprefs = true) }) public class MetaTileEntityHolder extends TickableTileEntityBase implements IGregTechTileEntity, IUIHolder, IWorldNameable, IActionHost, IGridProxyable { @@ -84,13 +89,18 @@ public MetaTileEntity getMetaTileEntity() { * Also can use certain data to preinit the block before data is synced */ @Override - public MetaTileEntity setMetaTileEntity(MetaTileEntity sampleMetaTileEntity) { + public MetaTileEntity setMetaTileEntity(@NotNull MetaTileEntity sampleMetaTileEntity, + @Nullable NBTTagCompound tagCompound) { Preconditions.checkNotNull(sampleMetaTileEntity, "metaTileEntity"); setRawMetaTileEntity(sampleMetaTileEntity.createMetaTileEntity(this)); + if (tagCompound != null && !tagCompound.isEmpty()) + getMetaTileEntity().readFromNBT(tagCompound); 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 +136,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,9 +147,9 @@ 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 (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { readFromNBT_AENetwork(compound); } } @@ -154,7 +165,7 @@ public NBTTagCompound writeToNBT(@NotNull NBTTagCompound compound) { NBTTagCompound metaTileEntityData = new NBTTagCompound(); metaTileEntity.writeToNBT(metaTileEntityData); compound.setTag("MetaTileEntity", metaTileEntityData); - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { writeToNBT_AENetwork(compound); } } @@ -167,7 +178,7 @@ public void invalidate() { metaTileEntity.invalidate(); } super.invalidate(); - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { invalidateAE(); } } @@ -297,7 +308,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 +337,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(); @@ -375,7 +389,7 @@ public void onChunkUnload() { if (metaTileEntity != null) { metaTileEntity.onUnload(); } - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { onChunkUnloadAE(); } } @@ -384,7 +398,7 @@ public void onChunkUnload() { public boolean shouldRefresh(@NotNull World world, @NotNull BlockPos pos, IBlockState oldState, IBlockState newState) { return oldState.getBlock() != newState.getBlock(); // MetaTileEntityHolder should never refresh (until block - // changes) + // changes) } @Override @@ -505,7 +519,7 @@ public ITextComponent getDisplayName() { @Nullable @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public IGridNode getGridNode(@NotNull AEPartLocation part) { // Forbid it connects the faces it shouldn't connect. if (this.getCableConnectionType(part) == AECableType.NONE) { @@ -517,44 +531,44 @@ public IGridNode getGridNode(@NotNull AEPartLocation part) { @NotNull @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AECableType getCableConnectionType(@NotNull AEPartLocation part) { return metaTileEntity == null ? AECableType.NONE : metaTileEntity.getCableConnectionType(part); } @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void securityBreak() {} @NotNull @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public IGridNode getActionableNode() { AENetworkProxy proxy = getProxy(); return proxy == null ? null : proxy.getNode(); } @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AENetworkProxy getProxy() { return metaTileEntity == null ? null : metaTileEntity.getProxy(); } @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public DimensionalCoord getLocation() { return new DimensionalCoord(this); } @Override - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void gridChanged() { if (metaTileEntity != null) { metaTileEntity.gridChanged(); } } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void readFromNBT_AENetwork(NBTTagCompound data) { AENetworkProxy proxy = getProxy(); if (proxy != null) { @@ -562,7 +576,7 @@ public void readFromNBT_AENetwork(NBTTagCompound data) { } } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void writeToNBT_AENetwork(NBTTagCompound data) { AENetworkProxy proxy = getProxy(); if (proxy != null) { @@ -570,7 +584,7 @@ public void writeToNBT_AENetwork(NBTTagCompound data) { } } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) void onChunkUnloadAE() { AENetworkProxy proxy = getProxy(); if (proxy != null) { @@ -578,7 +592,7 @@ void onChunkUnloadAE() { } } - @Method(modid = GTValues.MODID_APPENG) + @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) void invalidateAE() { AENetworkProxy proxy = getProxy(); if (proxy != null) { diff --git a/src/main/java/gregtech/api/metatileentity/SimpleMachineMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/SimpleMachineMetaTileEntity.java index 4547f5eaac0..64b8d3c86eb 100644 --- a/src/main/java/gregtech/api/metatileentity/SimpleMachineMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/SimpleMachineMetaTileEntity.java @@ -37,7 +37,6 @@ import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; -import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; @@ -475,7 +474,7 @@ public boolean isAllowInputFromOutputSideFluids() { } @Override - public void clearMachineInventory(NonNullList itemBuffer) { + public void clearMachineInventory(@NotNull List<@NotNull ItemStack> itemBuffer) { super.clearMachineInventory(itemBuffer); clearInventory(itemBuffer, chargerInventory); } @@ -524,8 +523,7 @@ protected ModularUI.Builder createGuiTemplate(EntityPlayer player) { if (exportItems.getSlots() + exportFluids.getTanks() <= 9) { ImageWidget logo = new ImageWidget(152, 63 + yOffset, 17, 17, - GTValues.XMAS.get() ? GuiTextures.GREGTECH_LOGO_XMAS : GuiTextures.GREGTECH_LOGO) - .setIgnoreColor(true); + GTValues.XMAS.get() ? getXmasLogo() : getLogo()).setIgnoreColor(true); if (this.circuitInventory != null) { SlotWidget circuitSlot = new GhostCircuitSlotWidget(circuitInventory, 0, 124, 62 + yOffset) @@ -536,6 +534,14 @@ protected ModularUI.Builder createGuiTemplate(EntityPlayer player) { return builder; } + protected @NotNull TextureArea getLogo() { + return GuiTextures.GREGTECH_LOGO; + } + + protected @NotNull TextureArea getXmasLogo() { + return GuiTextures.GREGTECH_LOGO_XMAS; + } + @Override public boolean hasGhostCircuitInventory() { return true; diff --git a/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java index 69c42322da8..5e648be0f60 100644 --- a/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/WorkableTieredMetaTileEntity.java @@ -1,7 +1,12 @@ package gregtech.api.metatileentity; import gregtech.api.GTValues; -import gregtech.api.capability.impl.*; +import gregtech.api.capability.impl.AbstractRecipeLogic; +import gregtech.api.capability.impl.EnergyContainerHandler; +import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.NotifiableFluidTank; +import gregtech.api.capability.impl.NotifiableItemStackHandler; +import gregtech.api.capability.impl.RecipeLogicEnergy; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.multiblock.ICleanroomProvider; import gregtech.api.metatileentity.multiblock.ICleanroomReceiver; @@ -34,7 +39,7 @@ public abstract class WorkableTieredMetaTileEntity extends TieredMetaTileEntity implements IDataInfoProvider, ICleanroomReceiver { - protected final RecipeLogicEnergy workable; + protected final AbstractRecipeLogic workable; protected final RecipeMap recipeMap; protected final ICubeRenderer renderer; @@ -63,7 +68,7 @@ public WorkableTieredMetaTileEntity(ResourceLocation metaTileEntityId, RecipeMap reinitializeEnergyContainer(); } - protected RecipeLogicEnergy createWorkable(RecipeMap recipeMap) { + protected AbstractRecipeLogic createWorkable(RecipeMap recipeMap) { return new RecipeLogicEnergy(this, recipeMap, () -> energyContainer); } diff --git a/src/main/java/gregtech/api/metatileentity/interfaces/IGregTechTileEntity.java b/src/main/java/gregtech/api/metatileentity/interfaces/IGregTechTileEntity.java index 43446101414..df7ae0563fe 100644 --- a/src/main/java/gregtech/api/metatileentity/interfaces/IGregTechTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/interfaces/IGregTechTileEntity.java @@ -3,6 +3,11 @@ import gregtech.api.gui.IUIHolder; import gregtech.api.metatileentity.MetaTileEntity; +import net.minecraft.nbt.NBTTagCompound; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + /** * A simple compound Interface for all my TileEntities. *

@@ -13,7 +18,11 @@ public interface IGregTechTileEntity extends IHasWorldObjectAndCoords, INeighbor MetaTileEntity getMetaTileEntity(); - MetaTileEntity setMetaTileEntity(MetaTileEntity metaTileEntity); + default MetaTileEntity setMetaTileEntity(MetaTileEntity metaTileEntity) { + return setMetaTileEntity(metaTileEntity, null); + } + + MetaTileEntity setMetaTileEntity(@NotNull MetaTileEntity metaTileEntity, @Nullable NBTTagCompound tagCompound); long getOffsetTimer(); // todo might not keep this one diff --git a/src/main/java/gregtech/api/metatileentity/interfaces/ISyncedTileEntity.java b/src/main/java/gregtech/api/metatileentity/interfaces/ISyncedTileEntity.java index f08beb475b9..0222ffdbe47 100644 --- a/src/main/java/gregtech/api/metatileentity/interfaces/ISyncedTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/interfaces/ISyncedTileEntity.java @@ -11,6 +11,8 @@ */ public interface ISyncedTileEntity { + Consumer NO_OP = buf -> {}; + /** * Used to sync data from Server -> Client. * Called during initial loading of the chunk or when many blocks change at once. @@ -68,6 +70,27 @@ public interface ISyncedTileEntity { */ void writeCustomData(int discriminator, @NotNull Consumer<@NotNull PacketBuffer> dataWriter); + /** + * Used to send an empty anonymous Server -> Client packet. + *

+ * Data is received in {@link #receiveCustomData(int, PacketBuffer)}; + *

+ * Typically used to signal to the client that a rendering update is needed + * when sending a server-side state update. + *

+ * Should be called manually. + *

+ * This method is called Server-Side. + *

+ * Equivalent to {@link net.minecraft.tileentity.TileEntity#getUpdatePacket} + * + * @param discriminator the discriminator determining the packet sent. + * @see gregtech.api.capability.GregtechDataCodes + */ + default void writeCustomData(int discriminator) { + writeCustomData(discriminator, NO_OP); + } + /** * Used to receive an anonymous Server -> Client packet. * Called when receiving a packet for the location this TileEntity is currently in. diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/FuelMultiblockController.java b/src/main/java/gregtech/api/metatileentity/multiblock/FuelMultiblockController.java index faad3421dc1..790a150ec0c 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/FuelMultiblockController.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/FuelMultiblockController.java @@ -34,7 +34,10 @@ public FuelMultiblockController(ResourceLocation metaTileEntityId, RecipeMap @Override protected void initializeAbilities() { super.initializeAbilities(); - this.energyContainer = new EnergyContainerList(getAbilities(MultiblockAbility.OUTPUT_ENERGY)); + List outputEnergy = new ArrayList<>(getAbilities(MultiblockAbility.OUTPUT_ENERGY)); + outputEnergy.addAll(getAbilities(MultiblockAbility.SUBSTATION_OUTPUT_ENERGY)); + outputEnergy.addAll(getAbilities(MultiblockAbility.OUTPUT_LASER)); + this.energyContainer = new EnergyContainerList(outputEnergy); } @Override diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockPart.java b/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockPart.java index dc6cb0e5d28..520a36dcebb 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockPart.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockPart.java @@ -11,4 +11,7 @@ public interface IMultiblockPart { default boolean canPartShare() { return true; } + + /** Called when distinct mode is toggled on the controller that this part is attached to */ + default void onDistinctChange(boolean newValue) {} } diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/MultiMapMultiblockController.java b/src/main/java/gregtech/api/metatileentity/multiblock/MultiMapMultiblockController.java index 53d204a0d2b..f80337e10c8 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/MultiMapMultiblockController.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/MultiMapMultiblockController.java @@ -59,7 +59,6 @@ public boolean onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, EnumFaci index = (recipeMapIndex + 1) % recipeMaps.length; setRecipeMapIndex(index); - this.recipeMapWorkable.forceRecipeRecheck(); } else { playerIn.sendStatusMessage( new TextComponentTranslation("gregtech.multiblock.multiple_recipemaps.switch_message"), true); @@ -79,6 +78,7 @@ public void setRecipeMapIndex(int index) { this.recipeMapIndex = index; if (!getWorld().isRemote) { writeCustomData(GregtechDataCodes.RECIPE_MAP_INDEX, buf -> buf.writeByte(index)); + recipeMapWorkable.forceRecipeRecheck(); markDirty(); } } diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java index 933ec7b1259..ff3848b1557 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; @@ -26,6 +30,7 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.I18n; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -52,7 +57,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; @@ -76,8 +92,8 @@ public MultiblockControllerBase(ResourceLocation metaTileEntityId) { } @Override - public void onPlacement() { - super.onPlacement(); + public void onPlacement(EntityLivingBase placer) { + super.onPlacement(placer); reinitializeStructurePattern(); } @@ -206,7 +222,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); } @@ -343,9 +359,9 @@ public void checkStructurePattern() { abilityPart.registerAbilities(abilityInstancesList); } } - parts.forEach(part -> part.addToMultiBlock(this)); this.multiblockParts.addAll(parts); this.multiblockAbilities.putAll(abilities); + parts.forEach(part -> part.addToMultiBlock(this)); this.structureFormed = true; writeCustomData(STRUCTURE_FORMED, buf -> buf.writeBoolean(true)); formStructure(context); diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockDisplayText.java b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockDisplayText.java index 0802125bf07..9127d5ca68c 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockDisplayText.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockDisplayText.java @@ -93,7 +93,7 @@ public Builder addEnergyUsageLine(IEnergyContainer energyContainer) { String energyFormatted = TextFormattingUtil.formatNumbers(maxVoltage); // wrap in text component to keep it from being formatted ITextComponent voltageName = new TextComponentString( - GTValues.VNF[GTUtility.getFloorTierByVoltage(maxVoltage)]); + GTValues.VOCNF[GTUtility.getFloorTierByVoltage(maxVoltage)]); ITextComponent bodyText = TextComponentUtil.translationWithColor( TextFormatting.GRAY, @@ -138,7 +138,7 @@ public Builder addEnergyUsageExactLine(long energyUsage) { String energyFormatted = TextFormattingUtil.formatNumbers(energyUsage); // wrap in text component to keep it from being formatted ITextComponent voltageName = new TextComponentString( - GTValues.VNF[GTUtility.getTierByVoltage(energyUsage)]); + GTValues.VOCNF[GTUtility.getOCTierByVoltage(energyUsage)]); textList.add(TextComponentUtil.translationWithColor( TextFormatting.GRAY, @@ -159,7 +159,7 @@ public Builder addEnergyProductionLine(long maxVoltage, long recipeEUt) { String energyFormatted = TextFormattingUtil.formatNumbers(maxVoltage); // wrap in text component to keep it from being formatted ITextComponent voltageName = new TextComponentString( - GTValues.VNF[GTUtility.getFloorTierByVoltage(maxVoltage)]); + GTValues.VOCNF[GTUtility.getFloorTierByVoltage(maxVoltage)]); textList.add(TextComponentUtil.translationWithColor( TextFormatting.GRAY, @@ -182,7 +182,7 @@ public Builder addEnergyProductionAmpsLine(long maxVoltage, int amperage) { String energyFormatted = TextFormattingUtil.formatNumbers(maxVoltage); // wrap in text component to keep it from being formatted ITextComponent voltageName = new TextComponentString( - GTValues.VNF[GTUtility.getFloorTierByVoltage(maxVoltage)]); + GTValues.VOCNF[GTUtility.getFloorTierByVoltage(maxVoltage)]); textList.add(TextComponentUtil.translationWithColor( TextFormatting.GRAY, @@ -456,7 +456,7 @@ public Builder addMufflerObstructedLine(boolean isObstructed) { * Added if structure is formed, the machine is active, and the passed fuelName parameter is not null. */ public Builder addFuelNeededLine(String fuelName, int previousRecipeDuration) { - if (!isStructureFormed || !isActive) return this; + if (!isStructureFormed || !isActive || fuelName == null) return this; ITextComponent fuelNeeded = TextComponentUtil.stringWithColor(TextFormatting.RED, fuelName); ITextComponent numTicks = TextComponentUtil.stringWithColor(TextFormatting.AQUA, TextFormattingUtil.formatNumbers(previousRecipeDuration)); diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java index 4301adbacce..4949074c91a 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java @@ -124,7 +124,11 @@ protected void initializeAbilities() { this.outputInventory = new ItemHandlerList(getAbilities(MultiblockAbility.EXPORT_ITEMS)); this.outputFluidInventory = new FluidTankList(allowSameFluidFillForOutputs(), getAbilities(MultiblockAbility.EXPORT_FLUIDS)); - this.energyContainer = new EnergyContainerList(getAbilities(MultiblockAbility.INPUT_ENERGY)); + + List inputEnergy = new ArrayList<>(getAbilities(MultiblockAbility.INPUT_ENERGY)); + inputEnergy.addAll(getAbilities(MultiblockAbility.SUBSTATION_INPUT_ENERGY)); + inputEnergy.addAll(getAbilities(MultiblockAbility.INPUT_LASER)); + this.energyContainer = new EnergyContainerList(inputEnergy); } private void resetTileAbilities() { @@ -246,6 +250,7 @@ public boolean isDistinct() { public void setDistinct(boolean isDistinct) { this.isDistinct = isDistinct; recipeMapWorkable.onDistinctChanged(); + getMultiblockParts().forEach(part -> part.onDistinctChange(isDistinct)); // mark buses as changed on distinct toggle if (this.isDistinct) { this.notifiedItemInputList.addAll(this.getAbilities(MultiblockAbility.IMPORT_ITEMS)); diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapPrimitiveMultiblockController.java b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapPrimitiveMultiblockController.java index d5bd83b3413..da874e0bdb8 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapPrimitiveMultiblockController.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapPrimitiveMultiblockController.java @@ -1,12 +1,21 @@ package gregtech.api.metatileentity.multiblock; -import gregtech.api.capability.impl.*; +import gregtech.api.capability.impl.FluidHandlerProxy; +import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.ItemHandlerProxy; +import gregtech.api.capability.impl.NotifiableFluidTank; +import gregtech.api.capability.impl.NotifiableItemStackHandler; +import gregtech.api.capability.impl.PrimitiveRecipeLogic; import gregtech.api.metatileentity.MTETrait; import gregtech.api.recipes.RecipeMap; +import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundEvent; +import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fluids.FluidTank; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.items.CapabilityItemHandler; import java.util.ArrayList; import java.util.List; @@ -44,6 +53,15 @@ private List makeFluidTanks(int length, boolean isExport) { return fluidTankList; } + @Override + public T getCapability(Capability capability, EnumFacing side) { + if ((capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || + capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) && side != null) { + return null; + } + return super.getCapability(capability, side); + } + @Override protected void updateFormedValid() { recipeMapWorkable.update(); 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 d1f432c6c07..4f0345f49fc 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTextures.java +++ b/src/main/java/gregtech/api/mui/GTGuiTextures.java @@ -12,6 +12,7 @@ * while MUI port is still ongoing. When MUI port is done, this annotation will be removed. */ // TODO ^ +@SuppressWarnings("unused") @ApiStatus.Experimental public class GTGuiTextures { @@ -19,6 +20,7 @@ public class GTGuiTextures { public static class IDs { public static final String STANDARD_BACKGROUND = "gregtech_standard_bg"; + public static final String COVER_BACKGROUND = "gregtech_cover_bg"; public static final String BRONZE_BACKGROUND = "gregtech_bronze_bg"; public static final String STEEL_BACKGROUND = "gregtech_steel_bg"; public static final String PRIMITIVE_BACKGROUND = "gregtech_primitive_bg"; @@ -34,9 +36,9 @@ public static class IDs { } // ICONS - /** @apiNote You may want {@link GTGuiTextures#getLogo()} instead. */ + /** @apiNote You may want {@link GTGuiTextures#getLogo} instead. */ public static final UITexture GREGTECH_LOGO = fullImage("textures/gui/icon/gregtech_logo.png"); - /** @apiNote You may want {@link GTGuiTextures#getLogo()} instead. */ + /** @apiNote You may want {@link GTGuiTextures#getLogo} instead. */ public static final UITexture GREGTECH_LOGO_XMAS = fullImage("textures/gui/icon/gregtech_logo_xmas.png"); public static final UITexture GREGTECH_LOGO_DARK = fullImage("textures/gui/icon/gregtech_logo_dark.png"); // todo blinking GT logos @@ -61,6 +63,7 @@ public static class IDs { .location(GTValues.MODID, "textures/gui/base/background_popup.png") .imageSize(195, 136) .adaptable(4) + .name(IDs.COVER_BACKGROUND) .canApplyTheme() .build(); @@ -151,6 +154,60 @@ public static class IDs { .canApplyTheme() .build(); + public static final UITexture[] BUTTON_BLACKLIST = slice("textures/gui/widget/button_blacklist.png", + 16, 32, 16, 16, true); + public static final UITexture[] BUTTON_IGNORE_DAMAGE = slice("textures/gui/widget/button_filter_damage.png", + 16, 32, 16, 16, true); + public static final UITexture[] BUTTON_IGNORE_NBT = slice("textures/gui/widget/button_filter_nbt.png", + 16, 32, 16, 16, true); + + public static final UITexture[] BUTTON_CASE_SENSITIVE = slice( + "textures/gui/widget/ore_filter/button_case_sensitive.png", + 16, 32, 16, 16, true); + + public static final UITexture[] BUTTON_MATCH_ALL = slice("textures/gui/widget/ore_filter/button_match_all.png", + 16, 32, 16, 16, true); + + public static final UITexture OREDICT_ERROR = fullImage("textures/gui/widget/ore_filter/error.png"); + public static final UITexture OREDICT_INFO = fullImage("textures/gui/widget/ore_filter/info.png"); + public static final UITexture OREDICT_MATCH = fullImage("textures/gui/widget/ore_filter/match.png"); + public static final UITexture OREDICT_NO_MATCH = fullImage("textures/gui/widget/ore_filter/no_match.png"); + public static final UITexture OREDICT_SUCCESS = fullImage("textures/gui/widget/ore_filter/success.png"); + public static final UITexture OREDICT_WAITING = fullImage("textures/gui/widget/ore_filter/waiting.png"); + public static final UITexture OREDICT_WARN = fullImage("textures/gui/widget/ore_filter/warn.png"); + + public static final UITexture[] MANUAL_IO_OVERLAY_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); + + public static final UITexture[] TRANSFER_MODE_OVERLAY = slice("textures/gui/overlay/transfer_mode_overlay.png", + 18, 18 * 3, 18, 18, true); + + public static final UITexture[] FLUID_TRANSFER_MODE_OVERLAY = slice( + "textures/gui/overlay/fluid_transfer_mode_overlay.png", + 18, 18 * 3, 18, 18, true); + + public static final UITexture[] DISTRIBUTION_MODE_OVERLAY = slice( + "textures/gui/widget/button_distribution_mode.png", + 16, 48, 16, 16, true); + + public static final UITexture[] VOIDING_MODE_OVERLAY = slice( + "textures/gui/overlay/voiding_mode_overlay.png", + 16, 32, 16, 16, true); + + public static final UITexture[] FILTER_MODE_OVERLAY = slice( + "textures/gui/overlay/filter_mode_overlay.png", + 16, 48, 16, 16, true); + + public static final UITexture[] PRIVATE_MODE_BUTTON = slice( + "textures/gui/widget/button_public_private.png", + 18, 36, 18, 18, true); + + public static final UITexture MENU_OVERLAY = fullImage("textures/gui/overlay/menu_overlay.png"); + // todo bronze/steel/primitive fluid slots? // SLOT OVERLAYS @@ -203,6 +260,9 @@ public static class IDs { public static final UITexture EXTRACTOR_OVERLAY_STEEL = fullImage( "textures/gui/overlay/extractor_overlay_steel.png"); public static final UITexture FILTER_SLOT_OVERLAY = fullImage("textures/gui/overlay/filter_slot_overlay.png", true); + public static final UITexture FILTER_SETTINGS_OVERLAY = fullImage( + "textures/gui/overlay/filter_settings_overlay.png", + true); public static final UITexture FURNACE_OVERLAY_1 = fullImage("textures/gui/overlay/furnace_overlay_1.png", true); public static final UITexture FURNACE_OVERLAY_2 = fullImage("textures/gui/overlay/furnace_overlay_2.png", true); public static final UITexture FURNACE_OVERLAY_BRONZE = fullImage("textures/gui/overlay/furnace_overlay_bronze.png"); @@ -263,11 +323,24 @@ public static class IDs { public static final UITexture BUTTON = new UITexture.Builder() .location(GTValues.MODID, "textures/gui/widget/button.png") .imageSize(18, 18) - .adaptable(1) + .adaptable(2) .name(IDs.STANDARD_BUTTON) .canApplyTheme() .build(); + public static final UITexture MC_BUTTON = new UITexture.Builder() + .location("modularui", "gui/widgets/mc_button.png") // todo + .imageSize(16, 32) + .uv(0.0f, 0.0f, 1.0f, 0.5f) + .adaptable(2) + .build(); + + public static final UITexture MC_BUTTON_DISABLED = new UITexture.Builder() + .location("modularui", "gui/widgets/mc_button_disabled.png") // todo + .imageSize(16, 16) + .adaptable(2) + .build(); + // BUTTON OVERLAYS public static final UITexture BUTTON_ITEM_OUTPUT = fullImage("textures/gui/widget/button_item_output_overlay.png"); @@ -277,6 +350,10 @@ public static class IDs { "textures/gui/widget/button_auto_collapse_overlay.png"); public static final UITexture BUTTON_X = fullImage("textures/gui/widget/button_x_overlay.png", true); + public static final UITexture BUTTON_CROSS = fullImage("textures/gui/widget/button_cross.png"); + public static final UITexture BUTTON_REDSTONE_ON = fullImage("textures/gui/widget/button_redstone_on.png"); + public static final UITexture BUTTON_REDSTONE_OFF = fullImage("textures/gui/widget/button_redstone_off.png"); + // PROGRESS BARS public static final UITexture PROGRESS_BAR_ARC_FURNACE = progressBar( "textures/gui/progress_bar/progress_bar_arc_furnace.png", true); @@ -434,6 +511,29 @@ private static UITexture fullImage(String path, boolean canApplyTheme) { return UITexture.fullImage(GTValues.MODID, path, canApplyTheme); } + @SuppressWarnings("SameParameterValue") + private static UITexture[] slice(String path, int imageWidth, int imageHeight, int sliceWidth, int sliceHeight, + boolean canApplyTheme) { + if (imageWidth % sliceWidth != 0 || imageHeight % sliceHeight != 0) + throw new IllegalArgumentException("Slice height and slice width must divide the image evenly!"); + + int countX = imageWidth / sliceWidth; + int countY = imageHeight / sliceHeight; + UITexture[] slices = new UITexture[countX * countY]; + + for (int indexX = 0; indexX < countX; indexX++) { + for (int indexY = 0; indexY < countY; indexY++) { + slices[(indexX * countX) + indexY] = UITexture.builder() + .location(GTValues.MODID, path) + .canApplyTheme(canApplyTheme) + .imageSize(imageWidth, imageHeight) + .uv(indexX * sliceWidth, indexY * sliceHeight, sliceWidth, sliceHeight) + .build(); + } + } + return slices; + } + private static UITexture progressBar(String path) { return progressBar(path, 20, 40, false); } diff --git a/src/main/java/gregtech/api/mui/GTGuiTheme.java b/src/main/java/gregtech/api/mui/GTGuiTheme.java index c3f80b09943..3ed22931d18 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTheme.java +++ b/src/main/java/gregtech/api/mui/GTGuiTheme.java @@ -1,5 +1,6 @@ package gregtech.api.mui; +import gregtech.api.cover.CoverWithUI; import gregtech.common.ConfigHolder; import net.minecraftforge.common.MinecraftForge; @@ -33,7 +34,15 @@ public class GTGuiTheme { ConfigHolder.client.defaultUIColor) .build(); - // TODO Cover theme to utilize the GT5u-like button textures vs the standard ones + public static final GTGuiTheme COVER = templateBuilder("gregtech_cover") + .panel(GTGuiTextures.IDs.COVER_BACKGROUND) + .itemSlot(GTGuiTextures.IDs.STANDARD_SLOT) + .fluidSlot(GTGuiTextures.IDs.STANDARD_FLUID_SLOT) + .color(ConfigHolder.client.defaultUIColor) + .textColor(CoverWithUI.UI_TEXT_COLOR) + .build(); + + // TODO Multiblock theme for display texture, logo changes public static final GTGuiTheme BRONZE = templateBuilder("gregtech_bronze") .panel(GTGuiTextures.IDs.BRONZE_BACKGROUND) @@ -220,7 +229,9 @@ public Builder button(String buttonId, String hoverId, int textColor, boolean te .add("background", new JsonBuilder() .add("type", "texture") .add("id", buttonId)) - .add("hoverBackground", hoverId) + .add("hoverBackground", new JsonBuilder() + .add("type", "texture") + .add("id", hoverId)) .add("textColor", textColor) .add("textShadow", textShadow))); return this; diff --git a/src/main/java/gregtech/api/mui/GTGuis.java b/src/main/java/gregtech/api/mui/GTGuis.java index d60b66088c7..614f6a08f1b 100644 --- a/src/main/java/gregtech/api/mui/GTGuis.java +++ b/src/main/java/gregtech/api/mui/GTGuis.java @@ -9,6 +9,7 @@ import net.minecraft.item.ItemStack; +import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.factory.GuiManager; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Alignment; @@ -60,11 +61,17 @@ private static class PopupPanel extends ModularPanel { public PopupPanel(@NotNull String name, int width, int height, boolean disableBelow, boolean closeOnOutsideClick) { super(name); - flex().startDefaultMode(); - flex().size(width, height).align(Alignment.Center); - flex().endDefaultMode(); + size(width, height).align(Alignment.Center); background(GTGuiTextures.BACKGROUND_POPUP); - child(ButtonWidget.panelCloseButton().top(5).right(5)); + child(ButtonWidget.panelCloseButton().top(5).right(5) + .onMousePressed(mouseButton -> { + if (mouseButton == 0 || mouseButton == 1) { + this.closeIfOpen(true); + Interactable.playButtonClickSound(); + return true; + } + return false; + })); this.disableBelow = disableBelow; this.closeOnOutsideClick = closeOnOutsideClick; } diff --git a/src/main/java/gregtech/api/mui/sync/FixedFluidSlotSH.java b/src/main/java/gregtech/api/mui/sync/FixedFluidSlotSH.java new file mode 100644 index 00000000000..bf3c6c581d7 --- /dev/null +++ b/src/main/java/gregtech/api/mui/sync/FixedFluidSlotSH.java @@ -0,0 +1,150 @@ +package gregtech.api.mui.sync; + +import gregtech.common.covers.filter.readers.SimpleFluidFilterReader; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandlerItem; + +import com.cleanroommc.modularui.utils.MouseData; +import com.cleanroommc.modularui.value.sync.FluidSlotSyncHandler; +import org.jetbrains.annotations.Nullable; + +public class FixedFluidSlotSH extends FluidSlotSyncHandler { + + @Nullable + private FluidStack lastStoredPhantomFluid; + + public FixedFluidSlotSH(IFluidTank fluidTank) { + super(fluidTank); + if (this.updateCacheFromSource(true) && fluidTank.getFluid() != null) { + this.lastStoredPhantomFluid = fluidTank.getFluid().copy(); + } + } + + @Override + public void readOnServer(int id, PacketBuffer buf) { + super.readOnServer(id, buf); + if (id == 0) { + var fluid = getFluidTank().getFluid(); + if (this.lastStoredPhantomFluid == null && fluid != null || + (this.lastStoredPhantomFluid != null && !this.lastStoredPhantomFluid.isFluidEqual(fluid))) { + this.lastStoredPhantomFluid = fluid; + } + } + } + + @Override + public void setValue(@Nullable FluidStack value, boolean setSource, boolean sync) { + super.setValue(value, setSource, sync); + if (setSource) { + this.getFluidTank().drain(Integer.MAX_VALUE, true); + if (!isFluidEmpty(value)) { + this.getFluidTank().fill(value.copy(), true); + } + } + } + + @Override + public void tryClickPhantom(MouseData mouseData) { + EntityPlayer player = getSyncManager().getPlayer(); + ItemStack currentStack = player.inventory.getItemStack(); + FluidStack currentFluid = this.getFluidTank().getFluid(); + IFluidHandlerItem fluidHandlerItem = currentStack + .getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null); + + if (mouseData.mouseButton == 0) { + if (currentStack.isEmpty() || fluidHandlerItem == null) { + if (this.canDrainSlot()) { + this.getFluidTank().drain(mouseData.shift ? Integer.MAX_VALUE : 1000, true); + } + } else { + FluidStack cellFluid = fluidHandlerItem.drain(Integer.MAX_VALUE, false); + if ((this.controlsAmount() || currentFluid == null) && cellFluid != null) { + if (this.canFillSlot()) { + if (!this.controlsAmount()) { + cellFluid.amount = 1; + } + if (this.getFluidTank().fill(cellFluid, true) > 0) { + this.lastStoredPhantomFluid = cellFluid.copy(); + } + } + } else { + if (this.canDrainSlot()) { + this.getFluidTank().drain(mouseData.shift ? Integer.MAX_VALUE : 1000, true); + } + } + } + } else if (mouseData.mouseButton == 1) { + if (this.canFillSlot()) { + if (currentFluid != null) { + if (this.controlsAmount()) { + FluidStack toFill = currentFluid.copy(); + toFill.amount = 1000; + this.getFluidTank().fill(toFill, true); + } + } else if (this.lastStoredPhantomFluid != null) { + FluidStack toFill = this.lastStoredPhantomFluid.copy(); + toFill.amount = this.controlsAmount() ? 1 : toFill.amount; + this.getFluidTank().fill(toFill, true); + } + } + } else if (mouseData.mouseButton == 2 && currentFluid != null && this.canDrainSlot()) { + this.getFluidTank().drain(mouseData.shift ? Integer.MAX_VALUE : 1000, true); + } + this.setValue(this.getFluidTank().getFluid(), false, true); + } + + @Override + public void tryScrollPhantom(MouseData mouseData) { + FluidStack currentFluid = this.getFluidTank().getFluid(); + int amount = mouseData.mouseButton; + if (!this.controlsAmount()) { + var fluid = getFluidTank().getFluid(); + int newAmt = amount == 1 ? 1 : 0; + if (fluid != null && fluid.amount != newAmt) { + fluid.amount = newAmt; + setValue(fluid, true, true); + return; + } + } + if (mouseData.shift) { + amount *= 10; + } + if (mouseData.ctrl) { + amount *= 100; + } + if (mouseData.alt) { + amount *= 1000; + } + if (currentFluid == null) { + if (amount > 0 && this.lastStoredPhantomFluid != null) { + FluidStack toFill = this.lastStoredPhantomFluid.copy(); + toFill.amount = this.controlsAmount() ? amount : 1; + this.getFluidTank().fill(toFill, true); + } + this.setValue(this.getFluidTank().getFluid(), false, true); + return; + } + if (amount > 0) { + FluidStack toFill = currentFluid.copy(); + toFill.amount = amount; + this.getFluidTank().fill(toFill, true); + } else if (amount < 0) { + this.getFluidTank().drain(-amount, true); + } + this.setValue(this.getFluidTank().getFluid(), false, true); + } + + @Override + public boolean controlsAmount() { + if (getFluidTank() instanceof SimpleFluidFilterReader.WritableFluidTank writableFluidTank) { + return writableFluidTank.showAmount(); + } + return super.controlsAmount(); + } +} diff --git a/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java b/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java new file mode 100644 index 00000000000..b5be013da18 --- /dev/null +++ b/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java @@ -0,0 +1,224 @@ +package gregtech.api.mui.sync; + +import gregtech.api.util.GTUtility; + +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvent; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandlerItem; + +import com.cleanroommc.modularui.network.NetworkUtils; +import com.cleanroommc.modularui.value.sync.SyncHandler; +import org.jetbrains.annotations.NotNull; + +public class GTFluidSyncHandler extends SyncHandler { + + private static final int TRY_CLICK_CONTAINER = 1; + + private final IFluidTank tank; + private boolean canDrainSlot = true; + private boolean canFillSlot = true; + + public GTFluidSyncHandler(IFluidTank tank) { + this.tank = tank; + } + + public FluidStack getFluid() { + return this.tank.getFluid(); + } + + public int getCapacity() { + return this.tank.getCapacity(); + } + + public GTFluidSyncHandler canDrainSlot(boolean canDrainSlot) { + this.canDrainSlot = canDrainSlot; + return this; + } + + public boolean canDrainSlot() { + return this.canDrainSlot; + } + + public GTFluidSyncHandler canFillSlot(boolean canFillSlot) { + this.canFillSlot = canFillSlot; + return this; + } + + public boolean canFillSlot() { + return this.canFillSlot; + } + + @Override + public void readOnClient(int id, PacketBuffer buf) { + if (id == TRY_CLICK_CONTAINER) { + replaceCursorItemStack(NetworkUtils.readItemStack(buf)); + } + } + + @Override + public void readOnServer(int id, PacketBuffer buf) { + if (id == TRY_CLICK_CONTAINER) { + var stack = tryClickContainer(buf.readBoolean()); + if (!stack.isEmpty()) + syncToClient(TRY_CLICK_CONTAINER, buffer -> NetworkUtils.writeItemStack(buffer, stack)); + } + } + + public ItemStack tryClickContainer(boolean tryFillAll) { + ItemStack playerHeldStack = getSyncManager().getCursorItem(); + if (playerHeldStack.isEmpty()) + return ItemStack.EMPTY; + + ItemStack useStack = GTUtility.copy(1, playerHeldStack); + IFluidHandlerItem fluidHandlerItem = useStack + .getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null); + if (fluidHandlerItem == null) return ItemStack.EMPTY; + + FluidStack tankFluid = tank.getFluid(); + FluidStack heldFluid = fluidHandlerItem.drain(Integer.MAX_VALUE, false); + + // nothing to do, return + if (tankFluid == null && heldFluid == null) + return ItemStack.EMPTY; + + // tank is empty, try to fill tank + if (canFillSlot && tankFluid == null) { + return fillTankFromStack(fluidHandlerItem, heldFluid, tryFillAll); + + // hand is empty, try to drain tank + } else if (canDrainSlot && heldFluid == null) { + return drainTankFromStack(fluidHandlerItem, tankFluid, tryFillAll); + + // neither is empty but tank is not full, try to fill tank + } else if (canFillSlot && tank.getFluidAmount() < tank.getCapacity() && heldFluid != null) { + return fillTankFromStack(fluidHandlerItem, heldFluid, tryFillAll); + } + + return ItemStack.EMPTY; + } + + private ItemStack fillTankFromStack(IFluidHandlerItem fluidHandler, @NotNull FluidStack heldFluid, + boolean tryFillAll) { + ItemStack heldItem = getSyncManager().getCursorItem(); + if (heldItem.isEmpty()) return ItemStack.EMPTY; + + FluidStack currentFluid = tank.getFluid(); + // Fluid type does not match + if (currentFluid != null && !currentFluid.isFluidEqual(heldFluid)) return ItemStack.EMPTY; + + int freeSpace = tank.getCapacity() - tank.getFluidAmount(); + if (freeSpace <= 0) return ItemStack.EMPTY; + + ItemStack itemStackEmptied = ItemStack.EMPTY; + int fluidAmountTaken = 0; + + FluidStack drained = fluidHandler.drain(freeSpace, true); + if (drained != null && drained.amount > 0) { + itemStackEmptied = fluidHandler.getContainer(); + fluidAmountTaken = drained.amount; + } + if (itemStackEmptied == ItemStack.EMPTY) { + return ItemStack.EMPTY; + } + + // find out how many fills we can do + // same round down behavior as drain + int additional = tryFillAll ? Math.min(freeSpace / fluidAmountTaken, heldItem.getCount()) : 1; + FluidStack copiedFluidStack = heldFluid.copy(); + copiedFluidStack.amount = fluidAmountTaken * additional; + tank.fill(copiedFluidStack, true); + + itemStackEmptied.setCount(additional); + replaceCursorItemStack(itemStackEmptied); + playSound(heldFluid, true); + return itemStackEmptied; + } + + private ItemStack drainTankFromStack(IFluidHandlerItem fluidHandler, FluidStack tankFluid, boolean tryFillAll) { + ItemStack heldItem = getSyncManager().getCursorItem(); + if (heldItem.isEmpty()) return ItemStack.EMPTY; + + ItemStack fluidContainer = fluidHandler.getContainer(); + int filled = fluidHandler.fill(tankFluid, false); + if (filled > 0) { + tank.drain(filled, true); + fluidHandler.fill(tankFluid, true); + if (tryFillAll) { + // Determine how many more items we can fill. One item is already filled. + // Integer division means it will round down, so it will only fill equivalent fluid amounts. + // For example: + // Click with 3 cells, with 2500L of fluid in the tank. + // 2 cells will be filled, and 500L will be left behind in the tank. + int additional = Math.min(heldItem.getCount(), tankFluid.amount / filled) - 1; + tank.drain(filled * additional, true); + fluidContainer.grow(additional); + } + replaceCursorItemStack(fluidContainer); + playSound(tankFluid, false); + return fluidContainer; + } + return ItemStack.EMPTY; + } + + /** + * Replace the ItemStack on the player's cursor with the passed stack. Use to replace empty cells with filled, or + * filled cells with empty. If it is not fully emptied/filled, it will place the new items into the player inventory + * instead, and shrink the held stack by the appropriate amount. + */ + private void replaceCursorItemStack(ItemStack resultStack) { + int resultStackSize = resultStack.getMaxStackSize(); + ItemStack playerStack = getSyncManager().getCursorItem(); + + if (!getSyncManager().isClient()) + syncToClient(TRY_CLICK_CONTAINER, buffer -> NetworkUtils.writeItemStack(buffer, resultStack)); + + while (resultStack.getCount() > resultStackSize) { + playerStack.shrink(resultStackSize); + addItemToPlayerInventory(resultStack.splitStack(resultStackSize)); + } + if (playerStack.getCount() == resultStack.getCount()) { + // every item on the cursor is mutated, so leave it there + getSyncManager().setCursorItem(resultStack); + } else { + // some items not mutated. Mutated items go into the inventory/world. + playerStack.shrink(resultStack.getCount()); + getSyncManager().setCursorItem(playerStack); + addItemToPlayerInventory(resultStack); + } + } + + /** Place an item into the player's inventory, or drop it in-world as an item entity if it cannot fit. */ + private void addItemToPlayerInventory(ItemStack stack) { + if (stack == null) return; + var player = getSyncManager().getPlayer(); + + if (!player.inventory.addItemStackToInventory(stack) && !player.world.isRemote) { + EntityItem dropItem = player.entityDropItem(stack, 0); + if (dropItem != null) dropItem.setPickupDelay(0); + } + } + + /** + * Play the appropriate fluid interaction sound for the fluid.
+ * Must be called on server to work correctly + **/ + private void playSound(FluidStack fluid, boolean fill) { + if (fluid == null) return; + SoundEvent soundEvent; + if (fill) { + soundEvent = fluid.getFluid().getFillSound(fluid); + } else { + soundEvent = fluid.getFluid().getEmptySound(fluid); + } + EntityPlayer player = getSyncManager().getPlayer(); + player.world.playSound(null, player.posX, player.posY + 0.5, player.posZ, + soundEvent, SoundCategory.PLAYERS, 1.0F, 1.0F); + } +} diff --git a/src/main/java/gregtech/api/mui/widget/GhostCircuitSlotWidget.java b/src/main/java/gregtech/api/mui/widget/GhostCircuitSlotWidget.java index bd848099117..448740e7147 100644 --- a/src/main/java/gregtech/api/mui/widget/GhostCircuitSlotWidget.java +++ b/src/main/java/gregtech/api/mui/widget/GhostCircuitSlotWidget.java @@ -11,6 +11,7 @@ import net.minecraft.util.text.TextComponentTranslation; import net.minecraftforge.items.IItemHandler; +import com.cleanroommc.modularui.api.IPanelHandler; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; import com.cleanroommc.modularui.drawable.ItemDrawable; @@ -123,7 +124,7 @@ private void createSelectorPanel() { } } - getPanel().getScreen().openPanel(GTGuis.createPopupPanel("circuit_selector", 176, 120) + IPanelHandler.simple(getPanel(), (mainPanel, player) -> GTGuis.createPopupPanel("circuit_selector", 176, 120) .child(IKey.lang("metaitem.circuit.integrated.gui").asWidget().pos(5, 5)) .child(circuitPreview.asIcon().size(16).asWidget() .size(18) @@ -133,7 +134,8 @@ private void createSelectorPanel() { .left(7).right(7).top(41).height(4 * 18) .matrix(options) .minColWidth(18).minRowHeight(18) - .minElementMargin(0, 0))); + .minElementMargin(0, 0))) + .openPanel(); } private static class GhostCircuitSyncHandler extends ItemSlotSH { diff --git a/src/main/java/gregtech/api/pattern/BlockPattern.java b/src/main/java/gregtech/api/pattern/BlockPattern.java index 667202c7404..8479368a3db 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; @@ -165,7 +165,8 @@ private PatternMatchContext checkPatternAt(World world, BlockPos centerPos, Enum for (int b = 0, y = -centerOffset[1]; b < this.thumbLength; b++, y++) { for (int a = 0, x = -centerOffset[0]; a < this.palmLength; a++, x++) { TraceabilityPredicate predicate = this.blockMatches[c][b][a]; - BlockPos pos = setActualRelativeOffset(x, y, z, frontFacing, upwardsFacing, isFlipped) + BlockPos pos = RelativeDirection.setActualRelativeOffset(x, y, z, frontFacing, upwardsFacing, + isFlipped, structureDir) .add(centerPos.getX(), centerPos.getY(), centerPos.getZ()); worldState.update(world, pos, matchContext, globalCount, layerCount, predicate); TileEntity tileEntity = worldState.getTileEntity(); @@ -250,9 +251,10 @@ public void autoBuild(EntityPlayer player, MultiblockControllerBase controllerBa for (int b = 0, y = -centerOffset[1]; b < this.thumbLength; b++, y++) { for (int a = 0, x = -centerOffset[0]; a < this.palmLength; a++, x++) { TraceabilityPredicate predicate = this.blockMatches[c][b][a]; - BlockPos pos = setActualRelativeOffset(x, y, z, facing, controllerBase.getUpwardsFacing(), - controllerBase.isFlipped()) - .add(centerPos.getX(), centerPos.getY(), centerPos.getZ()); + BlockPos pos = RelativeDirection.setActualRelativeOffset(x, y, z, facing, + controllerBase.getUpwardsFacing(), + controllerBase.isFlipped(), structureDir) + .add(centerPos.getX(), centerPos.getY(), centerPos.getZ()); worldState.update(world, pos, matchContext, globalCount, layerCount, predicate); if (!world.getBlockState(pos).getMaterial().isReplaceable()) { blocks.put(pos, world.getBlockState(pos)); @@ -382,13 +384,13 @@ 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.onPlacement(); + MetaTileEntity metaTileEntity = igtte.setMetaTileEntity(sampleMetaTileEntity); + metaTileEntity.onPlacement(player); blocks.put(pos, metaTileEntity); if (found.getTagCompound() != null) { metaTileEntity.initFromItemStackData(found.getTagCompound()); @@ -571,13 +573,14 @@ public BlockInfo[][][] getPreview(int[] repetition) { } } BlockInfo info = infos == null || infos.length == 0 ? BlockInfo.EMPTY : infos[0]; - BlockPos pos = setActualRelativeOffset(z, y, x, EnumFacing.NORTH, EnumFacing.UP, false); + BlockPos pos = RelativeDirection.setActualRelativeOffset(z, y, x, EnumFacing.NORTH, + EnumFacing.UP, false, structureDir); // TODO if (info.getTileEntity() instanceof MetaTileEntityHolder) { MetaTileEntityHolder holder = new MetaTileEntityHolder(); 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); @@ -624,87 +627,4 @@ public BlockInfo[][][] getPreview(int[] repetition) { }); return result; } - - private BlockPos setActualRelativeOffset(int x, int y, int z, EnumFacing facing, EnumFacing upwardsFacing, - boolean isFlipped) { - int[] c0 = new int[] { x, y, z }, c1 = new int[3]; - if (facing == EnumFacing.UP || facing == EnumFacing.DOWN) { - EnumFacing of = facing == EnumFacing.DOWN ? upwardsFacing : upwardsFacing.getOpposite(); - for (int i = 0; i < 3; i++) { - switch (structureDir[i].getActualFacing(of)) { - case UP -> c1[1] = c0[i]; - case DOWN -> c1[1] = -c0[i]; - case WEST -> c1[0] = -c0[i]; - case EAST -> c1[0] = c0[i]; - case NORTH -> c1[2] = -c0[i]; - case SOUTH -> c1[2] = c0[i]; - } - } - int xOffset = upwardsFacing.getXOffset(); - int zOffset = upwardsFacing.getZOffset(); - int tmp; - if (xOffset == 0) { - tmp = c1[2]; - c1[2] = zOffset > 0 ? c1[1] : -c1[1]; - c1[1] = zOffset > 0 ? -tmp : tmp; - } else { - tmp = c1[0]; - c1[0] = xOffset > 0 ? c1[1] : -c1[1]; - c1[1] = xOffset > 0 ? -tmp : tmp; - } - if (isFlipped) { - if (upwardsFacing == EnumFacing.NORTH || upwardsFacing == EnumFacing.SOUTH) { - c1[0] = -c1[0]; // flip X-axis - } else { - c1[2] = -c1[2]; // flip Z-axis - } - } - } else { - for (int i = 0; i < 3; i++) { - switch (structureDir[i].getActualFacing(facing)) { - case UP -> c1[1] = c0[i]; - case DOWN -> c1[1] = -c0[i]; - case WEST -> c1[0] = -c0[i]; - case EAST -> c1[0] = c0[i]; - case NORTH -> c1[2] = -c0[i]; - case SOUTH -> c1[2] = c0[i]; - } - } - if (upwardsFacing == EnumFacing.WEST || upwardsFacing == EnumFacing.EAST) { - int xOffset = upwardsFacing == EnumFacing.WEST ? facing.rotateY().getXOffset() : - facing.rotateY().getOpposite().getXOffset(); - int zOffset = upwardsFacing == EnumFacing.WEST ? facing.rotateY().getZOffset() : - facing.rotateY().getOpposite().getZOffset(); - int tmp; - if (xOffset == 0) { - tmp = c1[2]; - c1[2] = zOffset > 0 ? -c1[1] : c1[1]; - c1[1] = zOffset > 0 ? tmp : -tmp; - } else { - tmp = c1[0]; - c1[0] = xOffset > 0 ? -c1[1] : c1[1]; - c1[1] = xOffset > 0 ? tmp : -tmp; - } - } else if (upwardsFacing == EnumFacing.SOUTH) { - c1[1] = -c1[1]; - if (facing.getXOffset() == 0) { - c1[0] = -c1[0]; - } else { - c1[2] = -c1[2]; - } - } - if (isFlipped) { - if (upwardsFacing == EnumFacing.NORTH || upwardsFacing == EnumFacing.SOUTH) { - if (facing == EnumFacing.NORTH || facing == EnumFacing.SOUTH) { - c1[0] = -c1[0]; // flip X-axis - } else { - c1[2] = -c1[2]; // flip Z-axis - } - } else { - c1[1] = -c1[1]; // flip Y-axis - } - } - } - return new BlockPos(c1[0], c1[1], c1[2]); - } } diff --git a/src/main/java/gregtech/api/pattern/FactoryBlockPattern.java b/src/main/java/gregtech/api/pattern/FactoryBlockPattern.java index e83c519186d..7b2e272f991 100644 --- a/src/main/java/gregtech/api/pattern/FactoryBlockPattern.java +++ b/src/main/java/gregtech/api/pattern/FactoryBlockPattern.java @@ -30,7 +30,7 @@ private FactoryBlockPattern(RelativeDirection charDir, RelativeDirection stringD structureDir[1] = stringDir; structureDir[2] = aisleDir; int flags = 0; - for (int i = 0; i < 3; i++) { + for (int i = 0; i < this.structureDir.length; i++) { switch (structureDir[i]) { case UP: case DOWN: @@ -127,6 +127,14 @@ public FactoryBlockPattern where(char symbol, TraceabilityPredicate blockMatcher return this; } + public FactoryBlockPattern where(String symbol, TraceabilityPredicate blockMatcher) { + if (symbol.length() == 1) { + return where(symbol.charAt(0), blockMatcher); + } + throw new IllegalArgumentException( + String.format("Symbol \"%s\" is invalid! It must be exactly one character!", symbol)); + } + public BlockPattern build() { return new BlockPattern(makePredicateArray(), structureDir, aisleRepetitions.toArray(new int[aisleRepetitions.size()][])); diff --git a/src/main/java/gregtech/api/pattern/MultiblockShapeInfo.java b/src/main/java/gregtech/api/pattern/MultiblockShapeInfo.java index a768aae5c68..f82b3dc8319 100644 --- a/src/main/java/gregtech/api/pattern/MultiblockShapeInfo.java +++ b/src/main/java/gregtech/api/pattern/MultiblockShapeInfo.java @@ -3,11 +3,12 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.util.BlockInfo; -import gregtech.common.blocks.MetaBlocks; +import gregtech.api.util.RelativeDirection; import net.minecraft.block.state.IBlockState; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; import org.jetbrains.annotations.NotNull; @@ -15,8 +16,11 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.function.Supplier; +import static gregtech.api.util.RelativeDirection.*; + public class MultiblockShapeInfo { /** {@code [x][y][z]} */ @@ -34,14 +38,48 @@ public BlockInfo[][][] getBlocks() { } public static Builder builder() { - return new Builder(); + return builder(RIGHT, DOWN, BACK); + } + + public static Builder builder(@NotNull RelativeDirection... structureDir) { + if (structureDir.length != 3) throw new IllegalArgumentException("Must have exactly 3 directions!"); + return new Builder(structureDir[0], structureDir[1], structureDir[2]); } public static class Builder { + private final RelativeDirection[] structureDir = new RelativeDirection[3]; + private List shape = new ArrayList<>(); private Map symbolMap = new HashMap<>(); + /** + * Use {@link #builder(RelativeDirection...)} + * + * @param structureDir The directions that the provided block pattern is based upon (character, string, row). + */ + @Deprecated + public Builder(@NotNull RelativeDirection... structureDir) { + this(structureDir[0], structureDir[1], structureDir[2]); + } + + @Deprecated + public Builder(@NotNull RelativeDirection one, @NotNull RelativeDirection two, + @NotNull RelativeDirection three) { + this.structureDir[0] = Objects.requireNonNull(one); + this.structureDir[1] = Objects.requireNonNull(two); + this.structureDir[2] = Objects.requireNonNull(three); + int flags = 0; + for (int i = 0; i < this.structureDir.length; i++) { + switch (structureDir[i]) { + case UP, DOWN -> flags |= 0x1; + case LEFT, RIGHT -> flags |= 0x2; + case FRONT, BACK -> flags |= 0x4; + } + } + if (flags != 0x7) throw new IllegalArgumentException("The directions must be on different axes!"); + } + public Builder aisle(String... data) { this.shape.add(data); return this; @@ -65,7 +103,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)); } /** @@ -86,7 +124,13 @@ private BlockInfo[][][] bakeArray() { final int maxZ = shape.size(); final int maxY = shape.get(0).length; final int maxX = shape.get(0)[0].length(); - BlockInfo[][][] blockInfos = new BlockInfo[maxX][maxY][maxZ]; + + BlockPos end = RelativeDirection.setActualRelativeOffset(maxX, maxY, maxZ, EnumFacing.SOUTH, EnumFacing.UP, + true, structureDir); + BlockPos addition = new BlockPos(end.getX() < 0 ? -end.getX() - 1 : 0, end.getY() < 0 ? -end.getY() - 1 : 0, + end.getZ() < 0 ? -end.getZ() - 1 : 0); + BlockPos bound = new BlockPos(Math.abs(end.getX()), Math.abs(end.getY()), Math.abs(end.getZ())); + BlockInfo[][][] blockInfos = new BlockInfo[bound.getX()][bound.getY()][bound.getZ()]; for (int z = 0; z < maxZ; z++) { String[] aisleEntry = shape.get(z); for (int y = 0; y < maxY; y++) { @@ -104,7 +148,9 @@ private BlockInfo[][][] bakeArray() { } else if (tileEntity != null) { info = new BlockInfo(info.getBlockState(), tileEntity); } - blockInfos[x][y][z] = info; + BlockPos pos = RelativeDirection.setActualRelativeOffset(x, y, z, EnumFacing.SOUTH, + EnumFacing.UP, true, structureDir).add(addition); + blockInfos[pos.getX()][pos.getY()][pos.getZ()] = info; } } } @@ -112,7 +158,7 @@ private BlockInfo[][][] bakeArray() { } public Builder shallowCopy() { - Builder builder = new Builder(); + Builder builder = new Builder(this.structureDir); builder.shape = new ArrayList<>(this.shape); builder.symbolMap = new HashMap<>(this.symbolMap); return builder; diff --git a/src/main/java/gregtech/api/persistence/PersistentData.java b/src/main/java/gregtech/api/persistence/PersistentData.java new file mode 100644 index 00000000000..dc88872d9a3 --- /dev/null +++ b/src/main/java/gregtech/api/persistence/PersistentData.java @@ -0,0 +1,108 @@ +package gregtech.api.persistence; + +import gregtech.api.GTValues; +import gregtech.api.util.GTLog; + +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fml.common.Loader; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; + +public final class PersistentData { + + private static final PersistentData INSTANCE = new PersistentData(); + + private @Nullable Path path; + private @Nullable NBTTagCompound tag; + + public static @NotNull PersistentData instance() { + return INSTANCE; + } + + private PersistentData() {} + + @ApiStatus.Internal + public void init() { + this.path = Loader.instance().getConfigDir().toPath() + .resolve(GTValues.MODID) + .resolve("persistent_data.dat"); + } + + /** + * @return the stored persistent data + */ + public synchronized @NotNull NBTTagCompound getTag() { + if (this.tag == null) { + this.tag = read(); + } + return this.tag; + } + + /** + * @return the read NBTTagCompound from disk + */ + private @NotNull NBTTagCompound read() { + GTLog.logger.debug("Reading persistent data from path {}", path); + if (this.path == null) { + throw new IllegalStateException("Persistent data path cannot be null"); + } + + if (!Files.exists(path)) { + return new NBTTagCompound(); + } + + try (InputStream inputStream = Files.newInputStream(this.path)) { + return CompressedStreamTools.readCompressed(inputStream); + } catch (IOException e) { + GTLog.logger.error("Failed to read persistent data", e); + return new NBTTagCompound(); + } + } + + /** + * Save the GT Persistent data to disk + */ + public synchronized void save() { + if (this.tag != null) { + write(this.tag); + } + } + + /** + * @param tagCompound the tag compound to save to disk + */ + private void write(@NotNull NBTTagCompound tagCompound) { + GTLog.logger.debug("Writing persistent data to path {}", path); + if (tagCompound.isEmpty()) { + return; + } + + if (this.path == null) { + throw new IllegalStateException("Persistent data path cannot be null"); + } + + if (!Files.exists(path)) { + try { + Files.createDirectories(path.getParent()); + } catch (IOException e) { + GTLog.logger.error("Could not create persistent data dir", e); + return; + } + } + + try (OutputStream outputStream = Files.newOutputStream(path)) { + CompressedStreamTools.writeCompressed(tagCompound, outputStream); + } catch (IOException e) { + GTLog.logger.error("Failed to write persistent data", e); + } + } +} diff --git a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java index 5468aae38dd..667b67fcf52 100644 --- a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java +++ b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java @@ -34,7 +34,12 @@ import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.*; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.SoundCategory; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; @@ -485,7 +490,7 @@ public void harvestBlock(@NotNull World worldIn, @NotNull EntityPlayer player, @ @NotNull IBlockState state, @Nullable TileEntity te, @NotNull ItemStack stack) { tileEntities.set(te == null ? tileEntities.get() : (IPipeTile) te); super.harvestBlock(worldIn, player, pos, state, te, stack); - tileEntities.set(null); + tileEntities.remove(); } @Override diff --git a/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java b/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java index cb3a9a5abbb..2372a9792c8 100644 --- a/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java +++ b/src/main/java/gregtech/api/pipenet/longdist/BlockLongDistancePipe.java @@ -1,7 +1,7 @@ package gregtech.api.pipenet.longdist; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.Block; import net.minecraft.block.material.Material; @@ -33,8 +33,10 @@ public BlockLongDistancePipe(LongDistancePipeType pipeType) { super(Material.IRON); this.pipeType = pipeType; setTranslationKey("long_distance_" + pipeType.getName() + "_pipeline"); - setCreativeTab(GregTechAPI.TAB_GREGTECH); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH); setHarvestLevel(ToolClasses.WRENCH, 1); + setHardness(2f); + setResistance(10f); } @Override @@ -101,7 +103,7 @@ public void breakBlock(@NotNull World worldIn, @NotNull BlockPos pos, @NotNull I @Override public void getSubBlocks(@NotNull CreativeTabs itemIn, @NotNull NonNullList items) { - if (itemIn == GregTechAPI.TAB_GREGTECH) { + if (itemIn == GTCreativeTabs.TAB_GREGTECH) { items.add(new ItemStack(this)); } } diff --git a/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java b/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java index 6be552bfc95..df20bd54bfb 100644 --- a/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java +++ b/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java @@ -85,7 +85,8 @@ public final void removeCover(@NotNull EnumFacing side) { } @SuppressWarnings("unchecked") - public ItemStack getStackForm() { + @Override + public @NotNull ItemStack getStackForm() { BlockPipe pipeBlock = holder.getPipeBlock(); return pipeBlock.getDropItem(holder); } diff --git a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java index 84897a022e8..3756849a3e7 100644 --- a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java +++ b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java @@ -67,7 +67,7 @@ public void transferDataFrom(IPipeTile tileEntity) { if (tileEntity instanceof SyncedTileEntityBase pipeBase) { addPacketsFrom(pipeBase); } - coverableImplementation.transferDataTo(tileEntity.getCoverableImplementation()); + tileEntity.getCoverableImplementation().transferDataTo(coverableImplementation); setFrameMaterial(tileEntity.getFrameMaterial()); } @@ -335,24 +335,28 @@ public T getCapabilityInternal(Capability capability, @Nullable EnumFacin @Nullable @Override public final T getCapability(@NotNull Capability capability, @Nullable EnumFacing facing) { - boolean isCoverable = capability == GregtechTileCapabilities.CAPABILITY_COVER_HOLDER; - Cover cover = facing == null ? null : coverableImplementation.getCoverAtSide(facing); - T defaultValue; - if (getPipeBlock() == null) - defaultValue = null; - else - defaultValue = getCapabilityInternal(capability, facing); + T pipeCapability = getPipeBlock() == null ? null : getCapabilityInternal(capability, facing); - if (isCoverable) { - return defaultValue; + if (capability == GregtechTileCapabilities.CAPABILITY_COVER_HOLDER) { + return pipeCapability; } - if (cover == null && facing != null) { - return isConnected(facing) ? defaultValue : null; + + Cover cover = facing == null ? null : coverableImplementation.getCoverAtSide(facing); + if (cover == null) { + if (facing == null || isConnected(facing)) { + return pipeCapability; + } + return null; } - if (cover != null) { - return cover.getCapability(capability, defaultValue); + + T coverCapability = cover.getCapability(capability, pipeCapability); + if (coverCapability == pipeCapability) { + if (isConnected(facing)) { + return pipeCapability; + } + return null; } - return defaultValue; + return coverCapability; } @Override diff --git a/src/main/java/gregtech/api/recipes/GTRecipeInputCache.java b/src/main/java/gregtech/api/recipes/GTRecipeInputCache.java index f72fb572f6e..4e9a68fdf03 100644 --- a/src/main/java/gregtech/api/recipes/GTRecipeInputCache.java +++ b/src/main/java/gregtech/api/recipes/GTRecipeInputCache.java @@ -1,11 +1,18 @@ package gregtech.api.recipes; import gregtech.api.GTValues; +import gregtech.api.persistence.PersistentData; import gregtech.api.recipes.ingredients.GTRecipeInput; import gregtech.api.util.GTLog; import gregtech.common.ConfigHolder; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.math.MathHelper; + +import it.unimi.dsi.fastutil.Hash; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Collections; @@ -14,54 +21,77 @@ /** * Cache of GTRecipeInput instances for deduplication. *

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

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

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

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

    + *
  1. Pick a Load Factor to test: i.e. {@code 0.75f} (default).
  2. + *
  3. Pick a Size to test: i.e. {@code 8192}.
  4. + *
  5. Internal array's size: next highest power of 2 for {@code size / loadFactor}, + * {@code nextHighestPowerOf2(8192 / 0.75) = 16384}.
  6. + *
  7. The maximum amount of stored values before a rehash is required {@code arraySize * loadFactor}, + * {@code 16384 * 0.75 = 12288}.
  8. + *
  9. Compare with the known amount of values stored: {@code 12288 >= 11774}.
  10. + *
  11. If larger or equal, the initial capacity and load factor will not induce a rehash/resize.
  12. + *
+ * + * @return the optimal expected input cache size + */ + private static int calculateOptimalExpectedSize() { + int min = Math.max(getExpectedInstanceAmount(PersistentData.instance().getTag()), MINIMUM_CACHE_SIZE); + for (int i = 13; i < 31; i++) { + int sizeToTest = 1 << i; + int arraySize = nextHighestPowerOf2((int) (sizeToTest / Hash.DEFAULT_LOAD_FACTOR)); + int maxStoredBeforeRehash = (int) (arraySize * Hash.DEFAULT_LOAD_FACTOR); + + if (maxStoredBeforeRehash >= min) { + return sizeToTest; + } + } + return MINIMUM_CACHE_SIZE; + } + + /** + * Algorithm source. + * + * @param x the number to use + * @return the next highest power of 2 relative to the number + */ + private static int nextHighestPowerOf2(int x) { + x--; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x++; + return x; + } } diff --git a/src/main/java/gregtech/api/recipes/ModHandler.java b/src/main/java/gregtech/api/recipes/ModHandler.java index 010d1c22346..10e55ea68b1 100644 --- a/src/main/java/gregtech/api/recipes/ModHandler.java +++ b/src/main/java/gregtech/api/recipes/ModHandler.java @@ -16,6 +16,7 @@ import gregtech.api.util.DummyContainer; import gregtech.api.util.GTLog; import gregtech.api.util.LocalizationUtils; +import gregtech.api.util.Mods; import gregtech.api.util.world.DummyWorld; import gregtech.common.ConfigHolder; import gregtech.common.crafting.FluidReplaceRecipe; @@ -48,7 +49,12 @@ import org.jetbrains.annotations.Nullable; import java.lang.reflect.Field; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Objects; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -679,8 +685,6 @@ public static Pair getRecipeOutput(@Nullable World world, @N * disable the config and remove the recipes manually */ public static void removeSmeltingEBFMetals() { - boolean isCTLoaded = Loader.isModLoaded(GTValues.MODID_CT); - Field actionAddFurnaceRecipe$output = null; Map furnaceList = FurnaceRecipes.instance().getSmeltingList(); @@ -702,7 +706,7 @@ public static void removeSmeltingEBFMetals() { ItemStack ingot = OreDictUnifier.get(OrePrefix.ingot, material); // Check if the inputs are actually dust -> ingot if (ingot.isItemEqual(output) && dust.isItemEqual(input)) { - if (isCTLoaded) { + if (Mods.CraftTweaker.isModLoaded()) { if (actionAddFurnaceRecipe$output == null) { try { actionAddFurnaceRecipe$output = ActionAddFurnaceRecipe.class @@ -753,6 +757,6 @@ public static boolean setErroredInvalidRecipe(@NotNull String message) throws Il } public static void logInvalidRecipe(@NotNull String message) { - GTLog.logger.warn("Invalid Recipe Found", new IllegalArgumentException(message)); + GTLog.logger.warn("Invalid Recipe Found: {}", message, new Throwable()); } } diff --git a/src/main/java/gregtech/api/recipes/Recipe.java b/src/main/java/gregtech/api/recipes/Recipe.java index b291f994301..ff495651ac5 100644 --- a/src/main/java/gregtech/api/recipes/Recipe.java +++ b/src/main/java/gregtech/api/recipes/Recipe.java @@ -8,15 +8,14 @@ import gregtech.api.recipes.chance.output.impl.ChancedFluidOutput; import gregtech.api.recipes.chance.output.impl.ChancedItemOutput; import gregtech.api.recipes.ingredients.GTRecipeInput; -import gregtech.api.recipes.recipeproperties.EmptyRecipePropertyStorage; -import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage; -import gregtech.api.recipes.recipeproperties.RecipeProperty; +import gregtech.api.recipes.properties.RecipeProperty; +import gregtech.api.recipes.properties.RecipePropertyStorage; +import gregtech.api.recipes.properties.RecipePropertyStorageImpl; import gregtech.api.util.GTUtility; import gregtech.api.util.ItemStackHashStrategy; import gregtech.integration.groovy.GroovyScriptModule; import net.minecraft.item.ItemStack; -import net.minecraft.util.NonNullList; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemHandlerHelper; @@ -27,9 +26,15 @@ import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; /** * Class that represent machine recipe. @@ -53,8 +58,6 @@ */ public class Recipe { - private static final NonNullList EMPTY = NonNullList.create(); - /** * This method was deprecated in 2.8 and will be removed in 2.9 * @@ -67,7 +70,7 @@ public static int getMaxChancedValue() { } private final List inputs; - private final NonNullList outputs; + private final List outputs; /** * A chance of 10000 equals 100% @@ -82,7 +85,7 @@ public static int getMaxChancedValue() { /** * if > 0 means EU/t consumed, if < 0 - produced */ - private final int EUt; + private final long EUt; /** * If this Recipe is hidden from JEI @@ -96,7 +99,7 @@ public static int getMaxChancedValue() { // TODO YEET private final boolean isCTRecipe; private final boolean groovyRecipe; - private final IRecipePropertyStorage recipePropertyStorage; + private final RecipePropertyStorage recipePropertyStorage; private final int hashCode; @@ -107,19 +110,17 @@ public Recipe(@NotNull List inputs, List fluidOutputs, @NotNull ChancedOutputList chancedFluidOutputs, int duration, - int EUt, + long EUt, boolean hidden, boolean isCTRecipe, - IRecipePropertyStorage recipePropertyStorage, + @NotNull RecipePropertyStorage recipePropertyStorage, @NotNull GTRecipeCategory recipeCategory) { - this.recipePropertyStorage = recipePropertyStorage == null ? EmptyRecipePropertyStorage.INSTANCE : - recipePropertyStorage; + this.recipePropertyStorage = recipePropertyStorage; this.inputs = GTRecipeInputCache.deduplicateInputs(inputs); if (outputs.isEmpty()) { - this.outputs = EMPTY; + this.outputs = Collections.emptyList(); } else { - this.outputs = NonNullList.create(); - this.outputs.addAll(outputs); + this.outputs = new ArrayList<>(outputs); } this.chancedOutputs = chancedOutputs; this.chancedFluidOutputs = chancedFluidOutputs; @@ -185,8 +186,54 @@ public static Recipe trimRecipeOutputs(Recipe currentRecipe, RecipeMap recipe public final boolean matches(boolean consumeIfSuccessful, IItemHandlerModifiable inputs, IMultipleTankHandler fluidInputs) { - return matches(consumeIfSuccessful, GTUtility.itemHandlerToList(inputs), - GTUtility.fluidHandlerToList(fluidInputs)); + Pair fluids = null; + Pair items = null; + + if (fluidInputs.getFluidTanks().size() > 0) { + fluids = matchesFluid(GTUtility.fluidHandlerToList(fluidInputs)); + if (!fluids.getKey()) { + return false; + } + } + + if (inputs.getSlots() > 0) { + items = matchesItems(GTUtility.itemHandlerToList(inputs)); + if (!items.getKey()) { + return false; + } + } + + if (consumeIfSuccessful) { + if (fluids != null) { + int[] fluidAmountInTank = fluids.getValue(); + var backedList = fluidInputs.getFluidTanks(); + + for (int i = 0; i < fluidAmountInTank.length; i++) { + var tank = backedList.get(i); + FluidStack fluidStack = tank.getFluid(); + int fluidAmount = fluidAmountInTank[i]; + + if (fluidStack == null || fluidStack.amount == fluidAmount) { + continue; + } + tank.drain(Math.abs(fluidAmount - fluidStack.amount), true); + } + } + if (items != null) { + int[] itemAmountInSlot = items.getValue(); + for (int i = 0; i < itemAmountInSlot.length; i++) { + ItemStack itemInSlot = inputs.getStackInSlot(i); + int itemAmount = itemAmountInSlot[i]; + + if (itemInSlot.isEmpty() || itemInSlot.getCount() == itemAmount) { + continue; + } + inputs.extractItem(i, Math.abs(itemAmount - itemInSlot.getCount()), false); + } + } + } + + return true; } /** @@ -405,7 +452,7 @@ public List getInputs() { return inputs; } - public NonNullList getOutputs() { + public List getOutputs() { return outputs; } @@ -423,7 +470,7 @@ public NonNullList getOutputs() { * @return A list of all resulting ItemStacks from the recipe, after chance has been applied to any chanced outputs */ public List getResultItemOutputs(int recipeTier, int machineTier, RecipeMap recipeMap) { - List outputs = new ArrayList<>(GTUtility.copyStackList(getOutputs())); + List outputs = new ArrayList<>(getOutputs()); ChanceBoostFunction function = recipeMap.getChanceFunction(); List chancedOutputsList = getChancedOutputs().roll(function, recipeTier, machineTier); @@ -650,7 +697,7 @@ public int getDuration() { return duration; } - public int getEUt() { + public long getEUt() { return EUt; } @@ -673,8 +720,9 @@ public boolean hasValidInputsForDisplay() { .anyMatch(s -> !s.isEmpty())) { return true; } + } else if (Arrays.stream(ingredient.getInputStacks()).anyMatch(s -> !s.isEmpty())) { + return true; } - return Arrays.stream(ingredient.getInputStacks()).anyMatch(s -> !s.isEmpty()); } for (GTRecipeInput fluidInput : fluidInputs) { FluidStack fluidIngredient = fluidInput.getInputFluidStack(); @@ -693,40 +741,26 @@ public GTRecipeCategory getRecipeCategory() { /////////////////////////////////////////////////////////// // Property Helper Methods // /////////////////////////////////////////////////////////// - public T getProperty(RecipeProperty property, T defaultValue) { - return recipePropertyStorage.getRecipePropertyValue(property, defaultValue); - } - public Object getPropertyRaw(String key) { - return recipePropertyStorage.getRawRecipePropertyValue(key); - } - - public Set, Object>> getPropertyValues() { - return recipePropertyStorage.getRecipeProperties(); - } - - public Set getPropertyKeys() { - return recipePropertyStorage.getRecipePropertyKeys(); - } - - public Set> getPropertyTypes() { - return recipePropertyStorage.getPropertyTypes(); - } - - public boolean hasProperty(RecipeProperty property) { - return recipePropertyStorage.hasRecipeProperty(property); - } - - public int getPropertyCount() { - return recipePropertyStorage.getSize(); + /** + * @see RecipePropertyStorageImpl#get(RecipeProperty, Object) + */ + @Contract("_, !null -> !null") + public @Nullable T getProperty(@NotNull RecipeProperty property, @Nullable T defaultValue) { + return recipePropertyStorage.get(property, defaultValue); } - public int getUnhiddenPropertyCount() { - return (int) recipePropertyStorage.getRecipeProperties().stream() - .filter((property) -> !property.getKey().isHidden()).count(); + /** + * @see RecipePropertyStorageImpl#contains(RecipeProperty) + */ + public boolean hasProperty(@NotNull RecipeProperty property) { + return recipePropertyStorage.contains(property); } - public IRecipePropertyStorage getRecipePropertyStorage() { + /** + * @return the property storage + */ + public @NotNull RecipePropertyStorage propertyStorage() { return recipePropertyStorage; } } diff --git a/src/main/java/gregtech/api/recipes/RecipeBuildAction.java b/src/main/java/gregtech/api/recipes/RecipeBuildAction.java new file mode 100644 index 00000000000..f7310129276 --- /dev/null +++ b/src/main/java/gregtech/api/recipes/RecipeBuildAction.java @@ -0,0 +1,17 @@ +package gregtech.api.recipes; + +import org.jetbrains.annotations.NotNull; + +@FunctionalInterface +public interface RecipeBuildAction> { + + /** + * Process a RecipeBuilder to perform an action with. + *

+ * Do not call {@link RecipeBuilder#buildAndRegister()} on the passed builder. + * It is safe to do so only on other builders, i.e. created through {@link RecipeBuilder#copy()}. + * + * @param builder the builder to utilize + */ + void accept(@NotNull R builder); +} diff --git a/src/main/java/gregtech/api/recipes/RecipeBuilder.java b/src/main/java/gregtech/api/recipes/RecipeBuilder.java index dd5fee598df..d7d8884daa7 100644 --- a/src/main/java/gregtech/api/recipes/RecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/RecipeBuilder.java @@ -9,19 +9,25 @@ import gregtech.api.recipes.chance.output.ChancedOutputLogic; import gregtech.api.recipes.chance.output.impl.ChancedFluidOutput; import gregtech.api.recipes.chance.output.impl.ChancedItemOutput; -import gregtech.api.recipes.ingredients.*; +import gregtech.api.recipes.ingredients.GTRecipeFluidInput; +import gregtech.api.recipes.ingredients.GTRecipeInput; +import gregtech.api.recipes.ingredients.GTRecipeItemInput; +import gregtech.api.recipes.ingredients.GTRecipeOreInput; +import gregtech.api.recipes.ingredients.IntCircuitIngredient; import gregtech.api.recipes.ingredients.nbtmatch.NBTCondition; import gregtech.api.recipes.ingredients.nbtmatch.NBTMatcher; -import gregtech.api.recipes.recipeproperties.CleanroomProperty; -import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage; -import gregtech.api.recipes.recipeproperties.RecipeProperty; -import gregtech.api.recipes.recipeproperties.RecipePropertyStorage; +import gregtech.api.recipes.properties.RecipeProperty; +import gregtech.api.recipes.properties.RecipePropertyStorage; +import gregtech.api.recipes.properties.RecipePropertyStorageImpl; +import gregtech.api.recipes.properties.impl.CleanroomProperty; +import gregtech.api.recipes.properties.impl.DimensionProperty; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Material; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.util.EnumValidationResult; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.api.util.ValidationResult; import gregtech.common.ConfigHolder; import gregtech.integration.groovy.GroovyScriptModule; @@ -29,7 +35,7 @@ import net.minecraft.block.Block; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.NonNullList; +import net.minecraft.util.ResourceLocation; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.common.Optional; @@ -38,12 +44,20 @@ import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.helper.ingredient.OreDictIngredient; import crafttweaker.CraftTweakerAPI; +import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.apache.commons.lang3.builder.ToStringBuilder; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.MustBeInvokedByOverriders; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; -import java.util.function.Consumer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; /** * @see Recipe @@ -65,19 +79,22 @@ public class RecipeBuilder> { protected ChancedOutputLogic chancedOutputLogic = ChancedOutputLogic.OR; protected ChancedOutputLogic chancedFluidOutputLogic = ChancedOutputLogic.OR; - protected int duration, EUt; + protected int duration; + protected long EUt; protected boolean hidden = false; protected GTRecipeCategory category; protected boolean isCTRecipe = false; protected int parallel = 0; - protected Consumer onBuildAction = null; protected EnumValidationResult recipeStatus = EnumValidationResult.VALID; - protected IRecipePropertyStorage recipePropertyStorage = null; + protected RecipePropertyStorage recipePropertyStorage = RecipePropertyStorage.EMPTY; protected boolean recipePropertyStorageErrored = false; + protected boolean ignoreAllBuildActions = false; + protected Map> ignoredBuildActions; + protected RecipeBuilder() { - this.inputs = NonNullList.create(); - this.outputs = NonNullList.create(); + this.inputs = new ArrayList<>(); + this.outputs = new ArrayList<>(); this.chancedOutputs = new ArrayList<>(); this.fluidInputs = new ArrayList<>(); this.fluidOutputs = new ArrayList<>(); @@ -86,10 +103,8 @@ protected RecipeBuilder() { public RecipeBuilder(Recipe recipe, RecipeMap recipeMap) { this.recipeMap = recipeMap; - this.inputs = NonNullList.create(); - this.inputs.addAll(recipe.getInputs()); - this.outputs = NonNullList.create(); - this.outputs.addAll(GTUtility.copyStackList(recipe.getOutputs())); + this.inputs = new ArrayList<>(recipe.getInputs()); + this.outputs = new ArrayList<>(recipe.getOutputs()); this.chancedOutputs = new ArrayList<>(recipe.getChancedOutputs().getChancedEntries()); this.fluidInputs = new ArrayList<>(recipe.getFluidInputs()); this.fluidOutputs = GTUtility.copyFluidList(recipe.getFluidOutputs()); @@ -98,19 +113,14 @@ public RecipeBuilder(Recipe recipe, RecipeMap recipeMap) { this.EUt = recipe.getEUt(); this.hidden = recipe.isHidden(); this.category = recipe.getRecipeCategory(); - this.recipePropertyStorage = recipe.getRecipePropertyStorage().copy(); - if (this.recipePropertyStorage != null) { - this.recipePropertyStorage.freeze(false); - } + this.recipePropertyStorage = recipe.propertyStorage().copy(); } @SuppressWarnings("CopyConstructorMissesField") protected RecipeBuilder(RecipeBuilder recipeBuilder) { this.recipeMap = recipeBuilder.recipeMap; - this.inputs = NonNullList.create(); - this.inputs.addAll(recipeBuilder.getInputs()); - this.outputs = NonNullList.create(); - this.outputs.addAll(GTUtility.copyStackList(recipeBuilder.getOutputs())); + this.inputs = new ArrayList<>(recipeBuilder.getInputs()); + this.outputs = new ArrayList<>(recipeBuilder.getOutputs()); this.chancedOutputs = new ArrayList<>(recipeBuilder.chancedOutputs); this.fluidInputs = new ArrayList<>(recipeBuilder.getFluidInputs()); this.fluidOutputs = GTUtility.copyFluidList(recipeBuilder.getFluidOutputs()); @@ -121,23 +131,62 @@ protected RecipeBuilder(RecipeBuilder recipeBuilder) { this.EUt = recipeBuilder.EUt; this.hidden = recipeBuilder.hidden; this.category = recipeBuilder.category; - this.onBuildAction = recipeBuilder.onBuildAction; - this.recipePropertyStorage = recipeBuilder.recipePropertyStorage; - if (this.recipePropertyStorage != null) { - this.recipePropertyStorage = this.recipePropertyStorage.copy(); + this.recipePropertyStorage = recipeBuilder.recipePropertyStorage.copy(); + this.ignoreAllBuildActions = recipeBuilder.ignoreAllBuildActions; + if (recipeBuilder.ignoredBuildActions != null) { + this.ignoredBuildActions = new Object2ObjectOpenHashMap<>(recipeBuilder.ignoredBuildActions); } } public R cleanroom(@Nullable CleanroomType cleanroom) { - if (!ConfigHolder.machines.enableCleanroom) { - return (R) this; + if (ConfigHolder.machines.enableCleanroom && cleanroom != null) { + this.applyProperty(CleanroomProperty.getInstance(), cleanroom); + } + return (R) this; + } + + public R dimension(int dimensionID) { + return dimension(dimensionID, false); + } + + public R dimension(int dimensionID, boolean toBlackList) { + DimensionProperty.DimensionPropertyList dimensionIDs = getCompleteDimensionIDs(); + if (dimensionIDs == null) { + dimensionIDs = new DimensionProperty.DimensionPropertyList(); + this.applyProperty(DimensionProperty.getInstance(), dimensionIDs); } - this.applyProperty(CleanroomProperty.getInstance(), cleanroom); + dimensionIDs.add(dimensionID, toBlackList); return (R) this; } - public boolean applyProperty(@NotNull String key, @Nullable Object value) { - if (key.equals(CleanroomProperty.KEY)) { + public @Nullable DimensionProperty.DimensionPropertyList getCompleteDimensionIDs() { + return this.recipePropertyStorage.get(DimensionProperty.getInstance(), null); + } + + public @NotNull IntList getDimensionIDs() { + return this.recipePropertyStorage.get(DimensionProperty.getInstance(), + DimensionProperty.DimensionPropertyList.EMPTY_LIST).whiteListDimensions; + } + + public @NotNull IntList getBlockedDimensionIDs() { + return this.recipePropertyStorage.get(DimensionProperty.getInstance(), + DimensionProperty.DimensionPropertyList.EMPTY_LIST).blackListDimensions; + } + + @MustBeInvokedByOverriders + public boolean applyPropertyCT(@NotNull String key, @NotNull Object value) { + if (key.equals(DimensionProperty.KEY)) { + if (value instanceof DimensionProperty.DimensionPropertyList list) { + DimensionProperty.DimensionPropertyList dimensionIDs = getCompleteDimensionIDs(); + if (dimensionIDs == null) { + dimensionIDs = new DimensionProperty.DimensionPropertyList(); + this.applyProperty(DimensionProperty.getInstance(), dimensionIDs); + } + dimensionIDs.merge(list); + return true; + } + return false; + } else if (key.equals(CleanroomProperty.KEY)) { if (value instanceof CleanroomType) { this.cleanroom((CleanroomType) value); } else if (value instanceof String) { @@ -150,28 +199,21 @@ public boolean applyProperty(@NotNull String key, @Nullable Object value) { return false; } - public boolean applyProperty(@NotNull RecipeProperty property, @Nullable Object value) { - if (value == null) { - if (this.recipePropertyStorage != null) { - return this.recipePropertyStorage.remove(property); - } - } else { - if (this.recipePropertyStorage == null) { - this.recipePropertyStorage = new RecipePropertyStorage(); - } - boolean stored = this.recipePropertyStorage.store(property, value); - if (!stored) { - this.recipePropertyStorageErrored = true; - } - return stored; + public final boolean applyProperty(@NotNull RecipeProperty property, @NotNull Object value) { + if (this.recipePropertyStorage == RecipePropertyStorage.EMPTY) { + this.recipePropertyStorage = new RecipePropertyStorageImpl(); + } + + boolean stored = this.recipePropertyStorage.store(property, value); + if (!stored) { + this.recipePropertyStorageErrored = true; } - return true; + return stored; } public R input(GTRecipeInput input) { if (input.getAmount() < 0) { - GTLog.logger.error("Count cannot be less than 0. Actual: {}.", input.getAmount()); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("Count cannot be less than 0. Actual: {}.", input.getAmount(), new Throwable()); } else { this.inputs.add(input); } @@ -240,18 +282,15 @@ public R input(MetaTileEntity mte, int amount) { public R inputNBT(GTRecipeInput input, NBTMatcher matcher, NBTCondition condition) { if (input.getAmount() < 0) { - GTLog.logger.error("Count cannot be less than 0. Actual: {}.", input.getAmount()); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("Count cannot be less than 0. Actual: {}.", input.getAmount(), new Throwable()); return (R) this; } if (matcher == null) { - GTLog.logger.error("NBTMatcher must not be null"); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("NBTMatcher must not be null", new Throwable()); return (R) this; } if (condition == null) { - GTLog.logger.error("NBTCondition must not be null"); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("NBTCondition must not be null", new Throwable()); return (R) this; } this.inputs.add(input.setNBTMatchingCondition(matcher, condition)); @@ -275,20 +314,20 @@ public R inputNBT(OrePrefix orePrefix, Material material, int count, NBTMatcher } public R inputNBT(Item item, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(item)), matcher, condition); + return inputNBT(new ItemStack(item), matcher, condition); } public R inputNBT(Item item, int count, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(item), count), matcher, condition); + return inputNBT(new ItemStack(item, count), matcher, condition); } public R inputNBT(Item item, int count, int meta, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(item, count, meta)), matcher, condition); + return inputNBT(new ItemStack(item, count, meta), matcher, condition); } public R inputNBT(Item item, int count, @SuppressWarnings("unused") boolean wild, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(item, count, GTValues.W)), matcher, condition); + return inputNBT(new ItemStack(item, count, GTValues.W), matcher, condition); } public R inputNBT(Block block, NBTMatcher matcher, NBTCondition condition) { @@ -296,35 +335,57 @@ public R inputNBT(Block block, NBTMatcher matcher, NBTCondition condition) { } public R inputNBT(Block block, int count, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(block, count)), matcher, condition); + return inputNBT(new ItemStack(block, count), matcher, condition); } public R inputNBT(Block block, int count, @SuppressWarnings("unused") boolean wild, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(new ItemStack(block, count, GTValues.W)), matcher, condition); + return inputNBT(new ItemStack(block, count, GTValues.W), matcher, condition); } public R inputNBT(MetaItem.MetaValueItem item, int count, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(item.getStackForm(count)), matcher, condition); + return inputNBT(item.getStackForm(count), matcher, condition); } public R inputNBT(MetaItem.MetaValueItem item, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(item.getStackForm()), matcher, condition); + return inputNBT(item.getStackForm(), matcher, condition); } public R inputNBT(MetaTileEntity mte, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(mte.getStackForm()), matcher, condition); + return inputNBT(mte.getStackForm(), matcher, condition); } public R inputNBT(MetaTileEntity mte, int amount, NBTMatcher matcher, NBTCondition condition) { - return inputNBT(new GTRecipeItemInput(mte.getStackForm(amount)), matcher, condition); + return inputNBT(mte.getStackForm(amount), matcher, condition); + } + + /** + * NBT tags are stripped from the input stack and are not automatically checked. + * + * @param stack the itemstack to input. + * @param matcher the matcher for the stack's nbt + * @param condition the condition for the stack's nbt + * @return this + */ + public R inputNBT(@NotNull ItemStack stack, NBTMatcher matcher, NBTCondition condition) { + return inputNBT(new GTRecipeItemInput(stack), matcher, condition); + } + + public R inputs(ItemStack input) { + if (input == null || input.isEmpty()) { + GTLog.logger.error("Input cannot be null or empty. Input: {}", input, new Throwable()); + recipeStatus = EnumValidationResult.INVALID; + } else { + this.inputs.add(new GTRecipeItemInput(input)); + } + return (R) this; } public R inputs(ItemStack... inputs) { for (ItemStack input : inputs) { if (input == null || input.isEmpty()) { - GTLog.logger.error("Input cannot contain null or empty ItemStacks. Inputs: {}", input); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("Inputs cannot contain null or empty ItemStacks. Inputs: {}", input, + new Throwable()); recipeStatus = EnumValidationResult.INVALID; continue; } @@ -336,8 +397,7 @@ public R inputs(ItemStack... inputs) { public R inputStacks(Collection inputs) { for (ItemStack input : inputs) { if (input == null || input.isEmpty()) { - GTLog.logger.error("Input cannot contain null or empty ItemStacks. Inputs: {}", input); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("Input cannot contain null or empty ItemStacks. Inputs: {}", input, new Throwable()); recipeStatus = EnumValidationResult.INVALID; continue; } @@ -346,11 +406,21 @@ public R inputStacks(Collection inputs) { return (R) this; } + public R inputs(GTRecipeInput input) { + if (input.getAmount() < 0) { + GTLog.logger.error("Input count cannot be less than 0. Actual: {}.", input.getAmount(), new Throwable()); + recipeStatus = EnumValidationResult.INVALID; + } else { + this.inputs.add(input); + } + return (R) this; + } + public R inputs(GTRecipeInput... inputs) { for (GTRecipeInput input : inputs) { if (input.getAmount() < 0) { - GTLog.logger.error("Count cannot be less than 0. Actual: {}.", input.getAmount()); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("Input count cannot be less than 0. Actual: {}.", input.getAmount(), + new Throwable()); recipeStatus = EnumValidationResult.INVALID; continue; } @@ -362,8 +432,7 @@ public R inputs(GTRecipeInput... inputs) { public R inputIngredients(Collection inputs) { for (GTRecipeInput input : inputs) { if (input.getAmount() < 0) { - GTLog.logger.error("Count cannot be less than 0. Actual: {}.", input.getAmount()); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("Count cannot be less than 0. Actual: {}.", input.getAmount(), new Throwable()); recipeStatus = EnumValidationResult.INVALID; continue; } @@ -412,8 +481,7 @@ public R notConsumable(FluidStack fluidStack) { public R circuitMeta(int circuitNumber) { if (IntCircuitIngredient.CIRCUIT_MIN > circuitNumber || circuitNumber > IntCircuitIngredient.CIRCUIT_MAX) { GTLog.logger.error("Integrated Circuit Number cannot be less than {} and more than {}", - IntCircuitIngredient.CIRCUIT_MIN, IntCircuitIngredient.CIRCUIT_MAX); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException("Invalid Integrated Circuit Number")); + IntCircuitIngredient.CIRCUIT_MIN, IntCircuitIngredient.CIRCUIT_MAX, new Throwable()); recipeStatus = EnumValidationResult.INVALID; return (R) this; } @@ -464,6 +532,13 @@ public R output(MetaTileEntity mte, int amount) { return outputs(mte.getStackForm(amount)); } + public R outputs(ItemStack output) { + if (output != null && !output.isEmpty()) { + this.outputs.add(output); + } + return (R) this; + } + public R outputs(ItemStack... outputs) { return outputs(Arrays.asList(outputs)); } @@ -490,14 +565,25 @@ public R fluidInputs(GTRecipeInput fluidIngredient) { return (R) this; } + public R fluidInputs(FluidStack input) { + if (input != null && input.amount > 0) { + this.fluidInputs.add(new GTRecipeFluidInput(input)); + } else if (input != null) { + GTLog.logger.error("Fluid Input count cannot be less than 0. Actual: {}.", input.amount, new Throwable()); + } else { + GTLog.logger.error("FluidStack cannot be null."); + } + return (R) this; + } + public R fluidInputs(FluidStack... fluidStacks) { ArrayList fluidIngredients = new ArrayList<>(); for (FluidStack fluidStack : fluidStacks) { if (fluidStack != null && fluidStack.amount > 0) { fluidIngredients.add(new GTRecipeFluidInput(fluidStack)); } else if (fluidStack != null) { - GTLog.logger.error("Count cannot be less than 0. Actual: {}.", fluidStack.amount); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("Fluid Input count cannot be less than 0. Actual: {}.", fluidStack.amount, + new Throwable()); } else { GTLog.logger.error("FluidStack cannot be null."); } @@ -511,13 +597,20 @@ public R clearFluidInputs() { return (R) this; } + public R fluidOutputs(FluidStack output) { + if (output != null && output.amount > 0) { + this.fluidOutputs.add(output); + } + return (R) this; + } + public R fluidOutputs(FluidStack... outputs) { return fluidOutputs(Arrays.asList(outputs)); } public R fluidOutputs(Collection outputs) { outputs = new ArrayList<>(outputs); - outputs.removeIf(Objects::isNull); + outputs.removeIf(o -> o == null || o.amount <= 0); this.fluidOutputs.addAll(outputs); return (R) this; } @@ -533,8 +626,7 @@ public R chancedOutput(ItemStack stack, int chance, int tierChanceBoost) { } if (0 >= chance || chance > ChancedOutputLogic.getMaxChancedValue()) { GTLog.logger.error("Chance cannot be less or equal to 0 or more than {}. Actual: {}.", - ChancedOutputLogic.getMaxChancedValue(), chance); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + ChancedOutputLogic.getMaxChancedValue(), chance, new Throwable()); recipeStatus = EnumValidationResult.INVALID; return (R) this; } @@ -581,8 +673,7 @@ public R chancedFluidOutput(FluidStack stack, int chance, int tierChanceBoost) { } if (0 >= chance || chance > ChancedOutputLogic.getMaxChancedValue()) { GTLog.logger.error("Chance cannot be less or equal to 0 or more than {}. Actual: {}.", - ChancedOutputLogic.getMaxChancedValue(), chance); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + ChancedOutputLogic.getMaxChancedValue(), chance, new Throwable()); recipeStatus = EnumValidationResult.INVALID; return (R) this; } @@ -607,12 +698,12 @@ public R chancedFluidOutputLogic(@NotNull ChancedOutputLogic logic) { return (R) this; } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public R inputs(IIngredient ingredient) { return input(ofGroovyIngredient(ingredient)); } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public R inputs(IIngredient... ingredients) { for (IIngredient ingredient : ingredients) { inputs(ingredient); @@ -620,7 +711,7 @@ public R inputs(IIngredient... ingredients) { return (R) this; } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public R inputs(Collection ingredients) { for (IIngredient ingredient : ingredients) { inputs(ingredient); @@ -628,12 +719,12 @@ public R inputs(Collection ingredients) { return (R) this; } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public R notConsumable(IIngredient ingredient) { return notConsumable(ofGroovyIngredient(ingredient)); } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) private static GTRecipeInput ofGroovyIngredient(IIngredient ingredient) { if (ingredient instanceof OreDictIngredient) { return new GTRecipeOreInput(((OreDictIngredient) ingredient).getOreDict(), ingredient.getAmount()); @@ -692,8 +783,8 @@ public void chancedOutputsMultiply(Recipe chancedOutputsFrom, int numberOfOperat */ public R append(Recipe recipe, int multiplier, boolean multiplyDuration) { - for (Map.Entry, Object> property : recipe.getPropertyValues()) { - this.applyProperty(property.getKey().getKey(), property.getValue()); + for (Map.Entry, Object> property : recipe.propertyStorage().entrySet()) { + this.applyPropertyCT(property.getKey().getKey(), property.getValue()); } // Create holders for the various parts of the new multiplied Recipe @@ -716,7 +807,13 @@ public R append(Recipe recipe, int multiplier, boolean multiplyDuration) { this.EUt(multiplyDuration ? recipe.getEUt() : this.EUt + recipe.getEUt() * multiplier); this.duration(multiplyDuration ? this.duration + recipe.getDuration() * multiplier : recipe.getDuration()); - this.parallel += multiplier; + if (this.parallel == 0) { + this.parallel = multiplier; + } else if (multiplyDuration) { + this.parallel += multiplier; + } else { + this.parallel *= multiplier; + } return (R) this; } @@ -731,7 +828,7 @@ protected static void multiplyInputsAndOutputs(List newRecipeInpu if (ri.isNonConsumable()) { newRecipeInputs.add(ri); } else { - newRecipeInputs.add(ri.withAmount(ri.getAmount() * numberOfOperations)); + newRecipeInputs.add(ri.copyWithAmount(ri.getAmount() * numberOfOperations)); } }); @@ -739,7 +836,7 @@ protected static void multiplyInputsAndOutputs(List newRecipeInpu if (fi.isNonConsumable()) { newFluidInputs.add(fi); } else { - newFluidInputs.add(fi.withAmount(fi.getAmount() * numberOfOperations)); + newFluidInputs.add(fi.copyWithAmount(fi.getAmount() * numberOfOperations)); } }); @@ -771,7 +868,7 @@ public R duration(int duration) { return (R) this; } - public R EUt(int EUt) { + public R EUt(long EUt) { this.EUt = EUt; return (R) this; } @@ -800,12 +897,34 @@ public R copy() { return (R) new RecipeBuilder<>(this); } - protected EnumValidationResult finalizeAndValidate() { - return recipePropertyStorageErrored ? EnumValidationResult.INVALID : validate(); + /** + * Only use if you absolutely don't want the recipe to be run through any build actions. + * Instead, you should blacklist specific actions with {@link #ignoreBuildAction(ResourceLocation)} + */ + public R ignoreAllBuildActions() { + this.ignoreAllBuildActions = true; + return (R) this; + } + + public R ignoreBuildAction(ResourceLocation buildActionName) { + if (ignoredBuildActions == null) { + ignoredBuildActions = new Object2ObjectOpenHashMap<>(); + } else if (!recipeMap.getBuildActions().containsKey(buildActionName)) { + GTLog.logger.error("Recipe map {} does not contain build action {}!", recipeMap, buildActionName, + new Throwable()); + return (R) this; + } else if (ignoredBuildActions.containsKey(buildActionName)) { + return (R) this; + } + + ignoredBuildActions.put(buildActionName, recipeMap.getBuildActions().get(buildActionName)); + + return (R) this; } public ValidationResult build() { - return ValidationResult.newResult(finalizeAndValidate(), new Recipe(inputs, outputs, + EnumValidationResult result = recipePropertyStorageErrored ? EnumValidationResult.INVALID : validate(); + return ValidationResult.newResult(result, new Recipe(inputs, outputs, new ChancedOutputList<>(this.chancedOutputLogic, chancedOutputs), fluidInputs, fluidOutputs, new ChancedOutputList<>(this.chancedFluidOutputLogic, chancedFluidOutputs), @@ -819,31 +938,31 @@ protected EnumValidationResult validate() { return msg.postIfNotEmpty() ? EnumValidationResult.SKIP : EnumValidationResult.VALID; } if (EUt == 0) { - GTLog.logger.error("EU/t cannot be equal to 0", new IllegalArgumentException()); + GTLog.logger.error("EU/t cannot be equal to 0", new Throwable()); if (isCTRecipe) { - CraftTweakerAPI.logError("EU/t cannot be equal to 0", new IllegalArgumentException()); + CraftTweakerAPI.logError("EU/t cannot be equal to 0", new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } if (duration <= 0) { - GTLog.logger.error("Duration cannot be less or equal to 0", new IllegalArgumentException()); + GTLog.logger.error("Duration cannot be less or equal to 0", new Throwable()); if (isCTRecipe) { - CraftTweakerAPI.logError("Duration cannot be less or equal to 0", new IllegalArgumentException()); + CraftTweakerAPI.logError("Duration cannot be less or equal to 0", new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } if (recipeMap != null) { // recipeMap can be null in tests if (category == null) { - GTLog.logger.error("Recipes must have a category", new IllegalArgumentException()); + GTLog.logger.error("Recipes must have a category", new Throwable()); if (isCTRecipe) { - CraftTweakerAPI.logError("Recipes must have a category", new IllegalArgumentException()); + CraftTweakerAPI.logError("Recipes must have a category", new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } else if (category.getRecipeMap() != this.recipeMap) { - GTLog.logger.error("Cannot apply Category with incompatible RecipeMap", new IllegalArgumentException()); + GTLog.logger.error("Cannot apply Category with incompatible RecipeMap", new Throwable()); if (isCTRecipe) { CraftTweakerAPI.logError("Cannot apply Category with incompatible RecipeMap", - new IllegalArgumentException()); + new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } @@ -851,13 +970,10 @@ protected EnumValidationResult validate() { if (recipeStatus == EnumValidationResult.INVALID) { GTLog.logger.error("Invalid recipe, read the errors above: {}", this); } - if (recipePropertyStorage != null) { - recipePropertyStorage.freeze(true); - } return recipeStatus; } - @Optional.Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) protected void validateGroovy(GroovyLog.Msg errorMsg) { errorMsg.add(EUt == 0, () -> "EU/t must not be to 0"); errorMsg.add(duration <= 0, () -> "Duration must not be less or equal to 0"); @@ -886,19 +1002,32 @@ protected static String getRequiredString(int max, int actual, @NotNull String t return out; } - protected R onBuild(Consumer consumer) { - this.onBuildAction = consumer; - return (R) this; - } - + /** + * @deprecated Obsolete. Does not need calling. + */ + @ApiStatus.Obsolete + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") + @Deprecated protected R invalidateOnBuildAction() { - this.onBuildAction = null; return (R) this; } + /** + * Build and register the recipe, if valid. + * Do not call outside of the + * {@link net.minecraftforge.event.RegistryEvent.Register} event for recipes. + * + */ + @MustBeInvokedByOverriders public void buildAndRegister() { - if (onBuildAction != null) { - onBuildAction.accept((R) this); + if (!ignoreAllBuildActions) { + for (Map.Entry> buildAction : recipeMap.getBuildActions() + .entrySet()) { + if (ignoredBuildActions != null && ignoredBuildActions.containsKey(buildAction.getKey())) { + continue; + } + buildAction.getValue().accept((R) this); + } } ValidationResult validationResult = build(); recipeMap.addRecipe(validationResult); @@ -947,7 +1076,7 @@ public List getFluidOutputs() { return fluidOutputs; } - public int getEUt() { + public long getEUt() { return EUt; } @@ -955,10 +1084,29 @@ public int getDuration() { return duration; } - @Nullable - public CleanroomType getCleanroom() { - return this.recipePropertyStorage == null ? null : - this.recipePropertyStorage.getRecipePropertyValue(CleanroomProperty.getInstance(), null); + public @Nullable CleanroomType getCleanroom() { + return this.recipePropertyStorage.get(CleanroomProperty.getInstance(), null); + } + + public boolean ignoresAllBuildActions() { + return ignoreAllBuildActions; + } + + /** + * Get all ignored build actions for the recipe map. + * + * @return A map of ignored build actions. + */ + public @NotNull Map> getIgnoredBuildActions() { + if (ignoreAllBuildActions) { + return recipeMap.getBuildActions(); + } + + if (ignoredBuildActions == null) { + return Collections.emptyMap(); + } + + return ignoredBuildActions; } @Override @@ -975,7 +1123,11 @@ public String toString() { .append("EUt", EUt) .append("hidden", hidden) .append("cleanroom", getCleanroom()) + .append("dimensions", getDimensionIDs().toString()) + .append("dimensions_blocked", getBlockedDimensionIDs().toString()) .append("recipeStatus", recipeStatus) + .append("ignoresBuildActions", ignoresAllBuildActions()) + .append("ignoredBuildActions", getIgnoredBuildActions()) .toString(); } } diff --git a/src/main/java/gregtech/api/recipes/RecipeMap.java b/src/main/java/gregtech/api/recipes/RecipeMap.java index 2f9417afe27..a2c2ef7b1f4 100644 --- a/src/main/java/gregtech/api/recipes/RecipeMap.java +++ b/src/main/java/gregtech/api/recipes/RecipeMap.java @@ -27,6 +27,7 @@ import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; import gregtech.api.util.LocalizationUtils; +import gregtech.api.util.Mods; import gregtech.api.util.ValidationResult; import gregtech.common.ConfigHolder; import gregtech.integration.crafttweaker.CTRecipeHelper; @@ -38,6 +39,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundEvent; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.common.Optional.Method; @@ -58,6 +60,7 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.UnmodifiableView; import stanhebben.zenscript.annotations.Optional; import stanhebben.zenscript.annotations.ZenClass; import stanhebben.zenscript.annotations.ZenGetter; @@ -74,9 +77,7 @@ import java.util.Map; import java.util.Set; import java.util.WeakHashMap; -import java.util.function.Consumer; import java.util.function.DoubleSupplier; -import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -87,7 +88,7 @@ public class RecipeMap> { private static final Map> RECIPE_MAP_REGISTRY = new Object2ReferenceOpenHashMap<>(); private static final Comparator RECIPE_DURATION_THEN_EU = Comparator.comparingInt(Recipe::getDuration) - .thenComparingInt(Recipe::getEUt) + .thenComparingLong(Recipe::getEUt) .thenComparing(Recipe::hashCode); private static boolean foundInvalidRecipe = false; @@ -123,9 +124,9 @@ public class RecipeMap> { private final Map> recipeByCategory = new Object2ObjectOpenHashMap<>(); - private Consumer onRecipeBuildAction; - protected SoundEvent sound; - private RecipeMap smallRecipeMap; + private final Map> recipeBuildActions = new Object2ObjectOpenHashMap<>(); + protected @Nullable SoundEvent sound; + private @Nullable RecipeMap smallRecipeMap; /** * Create and register new instance of RecipeMap with specified properties. All @@ -139,7 +140,7 @@ public class RecipeMap> { * @param defaultRecipeBuilder the default RecipeBuilder for the RecipeMap * @param isHidden if the RecipeMap should have a category in JEI * - * @deprecated {@link #RecipeMap(String, RecipeBuilder, Function, int, int, int, int)} + * @deprecated {@link RecipeMap#RecipeMap(String, R, RecipeMapUIFunction, int, int, int, int)} */ @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @Deprecated @@ -168,7 +169,7 @@ public RecipeMap(@NotNull String unlocalizedName, * @param defaultRecipeBuilder the default RecipeBuilder for the RecipeMap * @param isHidden if the RecipeMap should have a category in JEI * - * @deprecated {@link #RecipeMap(String, RecipeBuilder, Function, int, int, int, int)} + * @deprecated {@link RecipeMap#RecipeMap(String, R, RecipeMapUIFunction, int, int, int, int)} */ @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @Deprecated @@ -192,7 +193,7 @@ public RecipeMap(@NotNull String unlocalizedName, this.recipeBuilderSample = defaultRecipeBuilder; this.recipeMapUI = new RecipeMapUI<>(this, modifyItemInputs, modifyItemOutputs, modifyFluidInputs, - modifyFluidOutputs); + modifyFluidOutputs, false); this.recipeMapUI.setJEIVisible(!isHidden); RECIPE_MAP_REGISTRY.put(unlocalizedName, this); @@ -310,11 +311,46 @@ public RecipeMap setChanceFunction(@NotNull ChanceBoostFunction function) { return this; } - public RecipeMap onRecipeBuild(Consumer consumer) { - onRecipeBuildAction = consumer; + /** + * Add a recipe build action to be performed upon this RecipeMap's builder's recipe registration. + * + * @param name the unique name of the action + * @param action the action to perform + * @return this + */ + public RecipeMap onRecipeBuild(@NotNull ResourceLocation name, @NotNull RecipeBuildAction action) { + if (recipeBuildActions.containsKey(name)) { + throw new IllegalArgumentException("Cannot register RecipeBuildAction with duplicate name: " + name); + } + recipeBuildActions.put(name, action); return this; } + /** + * @param name the name of the build action to remove + */ + public void removeBuildAction(@NotNull ResourceLocation name) { + recipeBuildActions.remove(name); + } + + /** + * Add a recipe build action to be performed upon this RecipeMap's builder's recipe registration. + * + * @param actions the actions to perform + */ + @ApiStatus.Internal + protected void onRecipeBuild(@NotNull Map> actions) { + recipeBuildActions.putAll(actions); + } + + /** + * @return the build actions for this RecipeMap's default RecipeBuilder + */ + @ApiStatus.Internal + protected @UnmodifiableView @NotNull Map> getBuildActions() { + return this.recipeBuildActions; + } + public RecipeMap allowEmptyOutput() { this.allowEmptyOutput = true; return this; @@ -401,7 +437,7 @@ public boolean removeRecipe(@NotNull Recipe recipe) { * @see GTRecipeHandler#removeAllRecipes(RecipeMap) */ @ApiStatus.Internal - void removeAllRecipes() { + protected void removeAllRecipes() { if (GroovyScriptModule.isCurrentlyRunning()) { this.lookup.getRecipes(false).forEach(this.getGroovyScriptRecipeMap()::addBackup); } @@ -426,11 +462,9 @@ protected ValidationResult postValidateRecipe(@NotNull ValidationResult< boolean emptyInputs = recipe.getInputs().isEmpty() && recipe.getFluidInputs().isEmpty(); if (emptyInputs) { - GTLog.logger.error("Invalid amount of recipe inputs. Recipe inputs are empty."); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException("Invalid number of Inputs")); + GTLog.logger.error("Invalid amount of recipe inputs. Recipe inputs are empty.", new Throwable()); if (recipe.getIsCTRecipe()) { - CraftTweakerAPI.logError("Invalid amount of recipe inputs. Recipe inputs are empty."); - CraftTweakerAPI.logError("Stacktrace:", new IllegalArgumentException("Invalid number of Inputs")); + CraftTweakerAPI.logError("Invalid amount of recipe inputs. Recipe inputs are empty.", new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } @@ -438,11 +472,10 @@ protected ValidationResult postValidateRecipe(@NotNull ValidationResult< recipe.getFluidOutputs().isEmpty() && recipe.getChancedOutputs().getChancedEntries().isEmpty() && recipe.getChancedFluidOutputs().getChancedEntries().isEmpty(); if (emptyOutputs) { - GTLog.logger.error("Invalid amount of recipe outputs. Recipe outputs are empty."); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException("Invalid number of Outputs")); + GTLog.logger.error("Invalid amount of recipe outputs. Recipe outputs are empty.", new Throwable()); if (recipe.getIsCTRecipe()) { - CraftTweakerAPI.logError("Invalid amount of outputs inputs. Recipe outputs are empty."); - CraftTweakerAPI.logError("Stacktrace:", new IllegalArgumentException("Invalid number of Outputs")); + CraftTweakerAPI.logError("Invalid amount of outputs inputs. Recipe outputs are empty.", + new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } @@ -450,12 +483,11 @@ protected ValidationResult postValidateRecipe(@NotNull ValidationResult< int amount = recipe.getInputs().size(); if (amount > getMaxInputs()) { GTLog.logger.error("Invalid amount of recipe inputs. Actual: {}. Should be at most {}.", amount, - getMaxInputs()); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException("Invalid number of Inputs")); + getMaxInputs(), new Throwable()); if (recipe.getIsCTRecipe()) { CraftTweakerAPI.logError(String.format( - "Invalid amount of recipe inputs. Actual: %s. Should be at most %s.", amount, getMaxInputs())); - CraftTweakerAPI.logError("Stacktrace:", new IllegalArgumentException("Invalid number of Inputs")); + "Invalid amount of recipe inputs. Actual: %s. Should be at most %s.", amount, getMaxInputs()), + new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } @@ -463,13 +495,11 @@ protected ValidationResult postValidateRecipe(@NotNull ValidationResult< amount = recipe.getOutputs().size() + recipe.getChancedOutputs().getChancedEntries().size(); if (amount > getMaxOutputs()) { GTLog.logger.error("Invalid amount of recipe outputs. Actual: {}. Should be at most {}.", amount, - getMaxOutputs()); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException("Invalid number of Outputs")); + getMaxOutputs(), new Throwable()); if (recipe.getIsCTRecipe()) { CraftTweakerAPI .logError(String.format("Invalid amount of recipe outputs. Actual: %s. Should be at most %s.", - amount, getMaxOutputs())); - CraftTweakerAPI.logError("Stacktrace:", new IllegalArgumentException("Invalid number of Outputs")); + amount, getMaxOutputs()), new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } @@ -477,13 +507,12 @@ protected ValidationResult postValidateRecipe(@NotNull ValidationResult< amount = recipe.getFluidInputs().size(); if (amount > getMaxFluidInputs()) { GTLog.logger.error("Invalid amount of recipe fluid inputs. Actual: {}. Should be at most {}.", amount, - getMaxFluidInputs()); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException("Invalid number of Fluid Inputs")); + getMaxFluidInputs(), new Throwable()); if (recipe.getIsCTRecipe()) { CraftTweakerAPI.logError( String.format("Invalid amount of recipe fluid inputs. Actual: %s. Should be at most %s.", - amount, getMaxFluidInputs())); - CraftTweakerAPI.logError("Stacktrace:", new IllegalArgumentException("Invalid number of Fluid Inputs")); + amount, getMaxFluidInputs()), + new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } @@ -491,14 +520,12 @@ protected ValidationResult postValidateRecipe(@NotNull ValidationResult< amount = recipe.getFluidOutputs().size() + recipe.getChancedFluidOutputs().getChancedEntries().size(); if (amount > getMaxFluidOutputs()) { GTLog.logger.error("Invalid amount of recipe fluid outputs. Actual: {}. Should be at most {}.", amount, - getMaxFluidOutputs()); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException("Invalid number of Fluid Outputs")); + getMaxFluidOutputs(), new Throwable()); if (recipe.getIsCTRecipe()) { CraftTweakerAPI.logError( String.format("Invalid amount of recipe fluid outputs. Actual: %s. Should be at most %s.", - amount, getMaxFluidOutputs())); - CraftTweakerAPI.logError("Stacktrace:", - new IllegalArgumentException("Invalid number of Fluid Outputs")); + amount, getMaxFluidOutputs()), + new Throwable()); } recipeStatus = EnumValidationResult.INVALID; } @@ -942,7 +969,7 @@ private boolean shouldShiftWidgets() { return false; } - @Method(modid = GTValues.MODID_GROOVYSCRIPT) + @Method(modid = Mods.Names.GROOVY_SCRIPT) private VirtualizedRecipeMap getGroovyScriptRecipeMap() { return ((VirtualizedRecipeMap) grsVirtualizedRecipeMap); } @@ -972,7 +999,7 @@ private boolean recurseIngredientTreeAdd(@NotNull Recipe recipe, @NotNull Branch branchMap, int index, int count) { if (count >= ingredients.size()) return true; if (index >= ingredients.size()) { - throw new RuntimeException("Index out of bounds for recurseItemTreeAdd, should not happen"); + throw new IllegalStateException("Index out of bounds for recurseItemTreeAdd, should not happen"); } // Loop through NUMBER_OF_INGREDIENTS times. @@ -1291,7 +1318,7 @@ public Collection getRecipeList() { } @ZenMethod("findRecipe") - @Method(modid = GTValues.MODID_CT) + @Method(modid = Mods.Names.CRAFT_TWEAKER) @Nullable public CTRecipe ctFindRecipe(long maxVoltage, IItemStack[] itemInputs, ILiquidStack[] fluidInputs, @Optional(valueLong = Integer.MAX_VALUE) int outputFluidTankCapacity) { @@ -1304,7 +1331,7 @@ public CTRecipe ctFindRecipe(long maxVoltage, IItemStack[] itemInputs, ILiquidSt } @ZenGetter("recipes") - @Method(modid = GTValues.MODID_CT) + @Method(modid = Mods.Names.CRAFT_TWEAKER) public List ctGetRecipeList() { return getRecipeList().stream().map(recipe -> new CTRecipe(this, recipe)).collect(Collectors.toList()); } @@ -1325,7 +1352,7 @@ public String getUnlocalizedName() { } public R recipeBuilder() { - return recipeBuilderSample.copy().onBuild(onRecipeBuildAction); + return recipeBuilderSample.copy(); } /** @@ -1393,7 +1420,7 @@ public R recipeBuilder() { } @ZenMethod("recipeBuilder") - @Method(modid = GTValues.MODID_CT) + @Method(modid = Mods.Names.CRAFT_TWEAKER) public CTRecipeBuilder ctRecipeBuilder() { return new CTRecipeBuilder(recipeBuilder()); } diff --git a/src/main/java/gregtech/api/recipes/RecipeMapBuilder.java b/src/main/java/gregtech/api/recipes/RecipeMapBuilder.java index 2d6e810cac8..24e52ad07ce 100644 --- a/src/main/java/gregtech/api/recipes/RecipeMapBuilder.java +++ b/src/main/java/gregtech/api/recipes/RecipeMapBuilder.java @@ -5,13 +5,17 @@ import gregtech.api.recipes.ui.RecipeMapUI; import gregtech.api.recipes.ui.RecipeMapUIFunction; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundEvent; import it.unimi.dsi.fastutil.bytes.Byte2ObjectArrayMap; import it.unimi.dsi.fastutil.bytes.Byte2ObjectMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Map; + import static gregtech.api.recipes.ui.RecipeMapUI.computeOverlayKey; public class RecipeMapBuilder> { @@ -30,6 +34,8 @@ public class RecipeMapBuilder> { private int fluidOutputs; private boolean modifyFluidOutputs = true; + private boolean isGenerator; + private @Nullable TextureArea progressBar; private @Nullable ProgressWidget.MoveType moveType; @@ -41,6 +47,8 @@ public class RecipeMapBuilder> { private SoundEvent sound; private boolean allowEmptyOutputs; + private @Nullable Map> buildActions; + /** * @param unlocalizedName the name of the recipemap * @param defaultRecipeBuilder the default recipe builder of the recipemap @@ -122,6 +130,16 @@ public RecipeMapBuilder(@NotNull String unlocalizedName, @NotNull B defaultRecip return this; } + /** + * Mark this recipemap is generating energy + * + * @return this + */ + public @NotNull RecipeMapBuilder generator() { + this.isGenerator = true; + return this; + } + /** * @param progressBar the progress bar texture to use * @return this @@ -211,7 +229,7 @@ public RecipeMapBuilder(@NotNull String unlocalizedName, @NotNull B defaultRecip */ private @NotNull RecipeMapUI buildUI(@NotNull RecipeMap recipeMap) { RecipeMapUI ui = new RecipeMapUI<>(recipeMap, modifyItemInputs, modifyItemOutputs, modifyFluidInputs, - modifyFluidOutputs); + modifyFluidOutputs, isGenerator); if (progressBar != null) { ui.setProgressBarTexture(progressBar); } @@ -247,6 +265,23 @@ public RecipeMapBuilder(@NotNull String unlocalizedName, @NotNull B defaultRecip return this; } + /** + * Add a recipe build action to be performed upon this RecipeMap's builder's recipe registration. + * + * @param name the unique name of the action + * @param action the action to perform + * @return this + */ + public @NotNull RecipeMapBuilder onBuild(@NotNull ResourceLocation name, @NotNull RecipeBuildAction action) { + if (buildActions == null) { + buildActions = new Object2ObjectOpenHashMap<>(); + } else if (buildActions.containsKey(name)) { + throw new IllegalArgumentException("Cannot register RecipeBuildAction with duplicate name: " + name); + } + buildActions.put(name, action); + return this; + } + /** * Do not call this twice. RecipeMapBuilders are not re-usable. * @@ -254,12 +289,14 @@ public RecipeMapBuilder(@NotNull String unlocalizedName, @NotNull B defaultRecip */ public @NotNull RecipeMap build() { RecipeMap recipeMap = new RecipeMap<>(unlocalizedName, defaultRecipeBuilder, this.recipeMapUIFunction, - itemInputs, - itemOutputs, fluidInputs, fluidOutputs); + itemInputs, itemOutputs, fluidInputs, fluidOutputs); recipeMap.setSound(sound); if (allowEmptyOutputs) { recipeMap.allowEmptyOutput(); } + if (buildActions != null) { + recipeMap.onRecipeBuild(buildActions); + } return recipeMap; } } diff --git a/src/main/java/gregtech/api/recipes/RecipeMaps.java b/src/main/java/gregtech/api/recipes/RecipeMaps.java index e61261ddd09..414ead42aba 100644 --- a/src/main/java/gregtech/api/recipes/RecipeMaps.java +++ b/src/main/java/gregtech/api/recipes/RecipeMaps.java @@ -11,7 +11,6 @@ import gregtech.api.recipes.builders.ComputationRecipeBuilder; import gregtech.api.recipes.builders.FuelRecipeBuilder; import gregtech.api.recipes.builders.FusionRecipeBuilder; -import gregtech.api.recipes.builders.GasCollectorRecipeBuilder; import gregtech.api.recipes.builders.ImplosionRecipeBuilder; import gregtech.api.recipes.builders.PrimitiveRecipeBuilder; import gregtech.api.recipes.builders.SimpleRecipeBuilder; @@ -34,6 +33,7 @@ import gregtech.api.unification.material.Materials; import gregtech.api.unification.stack.ItemMaterialInfo; import gregtech.api.util.AssemblyLineManager; +import gregtech.api.util.GTUtility; import gregtech.core.sound.GTSoundEvents; import net.minecraft.init.SoundEvents; @@ -44,6 +44,7 @@ import stanhebben.zenscript.annotations.ZenProperty; import static gregtech.api.GTValues.*; +import static gregtech.api.util.GTUtility.gregtechId; /** * Notes: @@ -123,13 +124,12 @@ public final class RecipeMaps { .fluidOutputs(1) .progressBar(GuiTextures.PROGRESS_BAR_ARC_FURNACE) .sound(GTSoundEvents.ARC) - .build() - .onRecipeBuild(recipeBuilder -> { - recipeBuilder.invalidateOnBuildAction(); + .onBuild(gregtechId("arc_furnace_oxygen"), recipeBuilder -> { if (recipeBuilder.getFluidInputs().isEmpty()) { recipeBuilder.fluidInputs(Materials.Oxygen.getFluid(recipeBuilder.getDuration())); } - }); + }) + .build(); /** * Example: @@ -152,9 +152,7 @@ public final class RecipeMaps { .itemSlotOverlay(GuiTextures.CIRCUIT_OVERLAY, false) .progressBar(GuiTextures.PROGRESS_BAR_CIRCUIT) .sound(GTSoundEvents.ASSEMBLER) - .build() - .onRecipeBuild(recipeBuilder -> { - recipeBuilder.invalidateOnBuildAction(); + .onBuild(gregtechId("assembler_solder"), recipeBuilder -> { var fluidInputs = recipeBuilder.getFluidInputs(); if (fluidInputs.size() == 1 && fluidInputs.get(0).getInputFluidStack().getFluid() == Materials.SolderingAlloy.getFluid()) { @@ -163,7 +161,8 @@ public final class RecipeMaps { recipeBuilder.copy().clearFluidInputs().fluidInputs(Materials.Tin.getFluid(amount * 2)) .buildAndRegister(); } - + }) + .onBuild(gregtechId("assembler_recycling"), recipeBuilder -> { if (recipeBuilder.isWithRecycling()) { // ignore input fluids for recycling ItemStack outputStack = recipeBuilder.getOutputs().get(0); @@ -173,7 +172,8 @@ public final class RecipeMaps { OreDictUnifier.registerOre(outputStack, info); } } - }); + }) + .build(); /** * Example: @@ -192,12 +192,14 @@ public final class RecipeMaps { * .duration(600).EUt(6000).buildAndRegister(); * * - * The Assembly Line Recipe Builder has no special properties/build actions yet, but will in the future + * The Assembly Line Recipe Builder creates additional Research Recipes for its outputs in the Scanner or Research + * Station when specified. */ @ZenProperty public static final RecipeMap ASSEMBLY_LINE_RECIPES = new RecipeMapAssemblyLine<>( "assembly_line", new AssemblyLineRecipeBuilder(), AssemblyLineUI::new) - .onRecipeBuild(AssemblyLineManager::createDefaultResearchRecipe); + .onRecipeBuild(gregtechId("default_research_recipe"), + AssemblyLineManager::createDefaultResearchRecipe); /** * Example: @@ -331,7 +333,7 @@ public final class RecipeMaps { public static final RecipeMap CANNER_RECIPES = new RecipeMapFluidCanner("canner", new SimpleRecipeBuilder(), recipeMap -> { - RecipeMapUI ui = new RecipeMapUI<>(recipeMap, true, true, true, true); + RecipeMapUI ui = new RecipeMapUI<>(recipeMap, true, true, true, true, false); ui.setItemSlotOverlay(GuiTextures.CANNER_OVERLAY, false, false); ui.setItemSlotOverlay(GuiTextures.CANISTER_OVERLAY, false, true); ui.setItemSlotOverlay(GuiTextures.CANISTER_OVERLAY, true); @@ -437,21 +439,18 @@ public final class RecipeMaps { .fluidSlotOverlay(GuiTextures.VIAL_OVERLAY_2, true) .progressBar(GuiTextures.PROGRESS_BAR_ARROW_MULTIPLE) .sound(GTValues.FOOLS.get() ? GTSoundEvents.SCIENCE : GTSoundEvents.CHEMICAL_REACTOR) - .build() - .onRecipeBuild(recipeBuilder -> { - recipeBuilder.invalidateOnBuildAction(); - RecipeMaps.LARGE_CHEMICAL_RECIPES.recipeBuilder() - .inputs(recipeBuilder.getInputs().toArray(new GTRecipeInput[0])) - .fluidInputs(recipeBuilder.getFluidInputs()) - .outputs(recipeBuilder.getOutputs()) - .chancedOutputs(recipeBuilder.getChancedOutputs()) - .fluidOutputs(recipeBuilder.getFluidOutputs()) - .chancedFluidOutputs(recipeBuilder.getChancedFluidOutputs()) - .cleanroom(recipeBuilder.getCleanroom()) - .duration(recipeBuilder.getDuration()) - .EUt(recipeBuilder.getEUt()) - .buildAndRegister(); - }); + .onBuild(gregtechId("lcr_copy"), recipeBuilder -> RecipeMaps.LARGE_CHEMICAL_RECIPES.recipeBuilder() + .inputs(recipeBuilder.getInputs().toArray(new GTRecipeInput[0])) + .fluidInputs(recipeBuilder.getFluidInputs()) + .outputs(recipeBuilder.getOutputs()) + .chancedOutputs(recipeBuilder.getChancedOutputs()) + .fluidOutputs(recipeBuilder.getFluidOutputs()) + .chancedFluidOutputs(recipeBuilder.getChancedFluidOutputs()) + .cleanroom(recipeBuilder.getCleanroom()) + .duration(recipeBuilder.getDuration()) + .EUt(recipeBuilder.getEUt()) + .buildAndRegister()) + .build(); /** * Example: @@ -489,9 +488,7 @@ public final class RecipeMaps { .itemSlotOverlay(GuiTextures.CIRCUIT_OVERLAY, false) .progressBar(GuiTextures.PROGRESS_BAR_CIRCUIT_ASSEMBLER) .sound(GTSoundEvents.ASSEMBLER) - .build() - .onRecipeBuild(recipeBuilder -> { - recipeBuilder.invalidateOnBuildAction(); + .onBuild(gregtechId("circuit_assembler_solder"), recipeBuilder -> { if (recipeBuilder.getFluidInputs().isEmpty()) { recipeBuilder.copy() .fluidInputs(Materials.SolderingAlloy.getFluid(Math.max(1, @@ -504,7 +501,8 @@ public final class RecipeMaps { recipeBuilder.fluidInputs(Materials.Tin.getFluid(Math.max(1, GTValues.L * recipeBuilder.getSolderMultiplier()))); } - }); + }) + .build(); /** * Example: @@ -612,24 +610,22 @@ public final class RecipeMaps { .itemSlotOverlay(GuiTextures.DUST_OVERLAY, true, true) .progressBar(GuiTextures.PROGRESS_BAR_SLICE) .sound(GTSoundEvents.CUT) - .build() - .onRecipeBuild(recipeBuilder -> { - recipeBuilder.invalidateOnBuildAction(); + .onBuild(gregtechId("cutter_fluid"), recipeBuilder -> { if (recipeBuilder.getFluidInputs().isEmpty()) { - int duration = recipeBuilder.getDuration(); - int eut = recipeBuilder.getEUt(); + long eut = recipeBuilder.getEUt(); recipeBuilder .copy() - .fluidInputs(Materials.Water.getFluid(Math.max(4, - Math.min(1000, duration * eut / 320)))) + .fluidInputs(Materials.Water.getFluid(GTUtility.safeCastLongToInt(Math.max(4, + Math.min(1000, duration * eut / 320))))) .duration(duration * 2) .buildAndRegister(); recipeBuilder .copy() - .fluidInputs(Materials.DistilledWater.getFluid(Math.max(3, - Math.min(750, duration * eut / 426)))) + .fluidInputs( + Materials.DistilledWater.getFluid(GTUtility.safeCastLongToInt(Math.max(3, + Math.min(750, duration * eut / 426))))) .duration((int) (duration * 1.5)) .buildAndRegister(); @@ -637,12 +633,13 @@ public final class RecipeMaps { // middle of a buildAndRegister call. // Adding a second call will result in duplicate recipe generation attempts recipeBuilder - .fluidInputs(Materials.Lubricant.getFluid(Math.max(1, - Math.min(250, duration * eut / 1280)))) + .fluidInputs(Materials.Lubricant.getFluid(GTUtility.safeCastLongToInt(Math.max(1, + Math.min(250, duration * eut / 1280))))) .duration(Math.max(1, duration)); } - }); + }) + .build(); /** * Examples: @@ -754,7 +751,7 @@ public final class RecipeMaps { public static final RecipeMap ELECTROMAGNETIC_SEPARATOR_RECIPES = new RecipeMapBuilder<>( "electromagnetic_separator", new SimpleRecipeBuilder()) .itemInputs(1) - .itemOutputs(3) + .itemOutputs(4) .itemSlotOverlay(GuiTextures.CRUSHED_ORE_OVERLAY, false) .itemSlotOverlay(GuiTextures.DUST_OVERLAY, true) .progressBar(GuiTextures.PROGRESS_BAR_MAGNET) @@ -944,7 +941,7 @@ public final class RecipeMaps { @ZenProperty public static final RecipeMap FURNACE_RECIPES = new RecipeMapFurnace("electric_furnace", new SimpleRecipeBuilder(), recipeMap -> { - RecipeMapUI ui = new RecipeMapUI<>(recipeMap, true, true, true, true); + RecipeMapUI ui = new RecipeMapUI<>(recipeMap, true, true, true, true, false); ui.setItemSlotOverlay(GuiTextures.FURNACE_OVERLAY_1, false); ui.setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, ProgressWidget.MoveType.HORIZONTAL); return ui; @@ -982,8 +979,8 @@ public final class RecipeMaps { .build(); @ZenProperty - public static final RecipeMap GAS_COLLECTOR_RECIPES = new RecipeMapBuilder<>( - "gas_collector", new GasCollectorRecipeBuilder()) + public static final RecipeMap GAS_COLLECTOR_RECIPES = new RecipeMapBuilder<>( + "gas_collector", new SimpleRecipeBuilder()) .itemInputs(1) .fluidOutputs(1) .itemSlotOverlay(GuiTextures.INT_CIRCUIT_OVERLAY, false, true) @@ -1370,7 +1367,7 @@ public final class RecipeMaps { @ZenProperty public static final RecipeMap SCANNER_RECIPES = new RecipeMapScanner("scanner", new SimpleRecipeBuilder(), recipeMap -> { - RecipeMapUI ui = new RecipeMapUI<>(recipeMap, true, true, true, true); + RecipeMapUI ui = new RecipeMapUI<>(recipeMap, true, true, true, true, false); ui.setItemSlotOverlay(GuiTextures.DATA_ORB_OVERLAY, false, false); ui.setItemSlotOverlay(GuiTextures.SCANNER_OVERLAY, false, true); ui.setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, ProgressWidget.MoveType.HORIZONTAL); @@ -1488,6 +1485,7 @@ public final class RecipeMaps { .progressBar(GuiTextures.PROGRESS_BAR_ARROW_MULTIPLE) .sound(GTSoundEvents.COMBUSTION) .allowEmptyOutputs() + .generator() .build(); @ZenProperty @@ -1498,6 +1496,7 @@ public final class RecipeMaps { .progressBar(GuiTextures.PROGRESS_BAR_GAS_COLLECTOR) .sound(GTSoundEvents.TURBINE) .allowEmptyOutputs() + .generator() .build(); @ZenProperty @@ -1509,6 +1508,7 @@ public final class RecipeMaps { .progressBar(GuiTextures.PROGRESS_BAR_GAS_COLLECTOR) .sound(GTSoundEvents.TURBINE) .allowEmptyOutputs() + .generator() .build(); @ZenProperty @@ -1519,6 +1519,7 @@ public final class RecipeMaps { .progressBar(GuiTextures.PROGRESS_BAR_ARROW_MULTIPLE) .sound(GTSoundEvents.COMBUSTION) .allowEmptyOutputs() + .generator() .build(); @ZenProperty @@ -1530,6 +1531,7 @@ public final class RecipeMaps { .progressBar(GuiTextures.PROGRESS_BAR_GAS_COLLECTOR) .sound(GTSoundEvents.TURBINE) .allowEmptyOutputs() + .generator() .build(); private RecipeMaps() {} diff --git a/src/main/java/gregtech/api/recipes/builders/AssemblyLineRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/AssemblyLineRecipeBuilder.java index 9ddc9d6851b..dc711dd0a0a 100644 --- a/src/main/java/gregtech/api/recipes/builders/AssemblyLineRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/AssemblyLineRecipeBuilder.java @@ -4,8 +4,8 @@ import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; -import gregtech.api.recipes.recipeproperties.ResearchProperty; -import gregtech.api.recipes.recipeproperties.ResearchPropertyData; +import gregtech.api.recipes.properties.impl.ResearchProperty; +import gregtech.api.recipes.properties.impl.ResearchPropertyData; import gregtech.api.util.AssemblyLineManager; import gregtech.api.util.EnumValidationResult; import gregtech.api.util.GTLog; @@ -14,7 +14,6 @@ import net.minecraft.item.ItemStack; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collection; @@ -45,40 +44,39 @@ public AssemblyLineRecipeBuilder copy() { } @Override - public boolean applyProperty(@NotNull String key, @Nullable Object value) { + public boolean applyPropertyCT(@NotNull String key, @NotNull Object value) { if (key.equals(ResearchProperty.KEY)) { if (value instanceof ItemStack itemStack) { scannerResearch(itemStack); return true; } + return false; } - return super.applyProperty(key, value); + return super.applyPropertyCT(key, value); } private boolean applyResearchProperty(ResearchPropertyData.ResearchEntry researchEntry) { if (!ConfigHolder.machines.enableResearch) return false; if (researchEntry == null) { - GTLog.logger.error("Assembly Line Research Entry cannot be empty.", new IllegalArgumentException()); + GTLog.logger.error("Assembly Line Research Entry cannot be empty.", new Throwable()); recipeStatus = EnumValidationResult.INVALID; return false; } if (!generatingRecipes) { GTLog.logger.error("Cannot generate recipes when using researchWithoutRecipe()", - new IllegalArgumentException()); + new Throwable()); recipeStatus = EnumValidationResult.INVALID; return false; } - if (recipePropertyStorage != null && recipePropertyStorage.hasRecipeProperty(ResearchProperty.getInstance())) { - ResearchPropertyData property = recipePropertyStorage.getRecipePropertyValue(ResearchProperty.getInstance(), - null); - if (property == null) throw new IllegalStateException("Property storage has a null property"); + ResearchPropertyData property = recipePropertyStorage.get(ResearchProperty.getInstance(), null); + if (property != null) { property.add(researchEntry); return true; } - ResearchPropertyData property = new ResearchPropertyData(); + property = new ResearchPropertyData(); if (applyProperty(ResearchProperty.getInstance(), property)) { property.add(researchEntry); return true; diff --git a/src/main/java/gregtech/api/recipes/builders/BlastRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/BlastRecipeBuilder.java index 3e309d76d4b..c5bf92c5e16 100644 --- a/src/main/java/gregtech/api/recipes/builders/BlastRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/BlastRecipeBuilder.java @@ -3,7 +3,7 @@ import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; -import gregtech.api.recipes.recipeproperties.TemperatureProperty; +import gregtech.api.recipes.properties.impl.TemperatureProperty; import gregtech.api.util.EnumValidationResult; import gregtech.api.util.GTLog; @@ -28,18 +28,18 @@ public BlastRecipeBuilder copy() { } @Override - public boolean applyProperty(@NotNull String key, Object value) { + public boolean applyPropertyCT(@NotNull String key, @NotNull Object value) { if (key.equals(TemperatureProperty.KEY)) { this.blastFurnaceTemp(((Number) value).intValue()); return true; } - return super.applyProperty(key, value); + return super.applyPropertyCT(key, value); } public BlastRecipeBuilder blastFurnaceTemp(int blastFurnaceTemp) { if (blastFurnaceTemp <= 0) { GTLog.logger.error("Blast Furnace Temperature cannot be less than or equal to 0", - new IllegalArgumentException()); + new Throwable()); recipeStatus = EnumValidationResult.INVALID; } this.applyProperty(TemperatureProperty.getInstance(), blastFurnaceTemp); @@ -47,8 +47,7 @@ public BlastRecipeBuilder blastFurnaceTemp(int blastFurnaceTemp) { } public int getBlastFurnaceTemp() { - return this.recipePropertyStorage == null ? 0 : - this.recipePropertyStorage.getRecipePropertyValue(TemperatureProperty.getInstance(), 0); + return this.recipePropertyStorage.get(TemperatureProperty.getInstance(), 0); } @Override diff --git a/src/main/java/gregtech/api/recipes/builders/CircuitAssemblerRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/CircuitAssemblerRecipeBuilder.java index a6a4cda94d0..20d4652ddb9 100644 --- a/src/main/java/gregtech/api/recipes/builders/CircuitAssemblerRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/CircuitAssemblerRecipeBuilder.java @@ -31,8 +31,8 @@ public CircuitAssemblerRecipeBuilder copy() { public CircuitAssemblerRecipeBuilder solderMultiplier(int multiplier) { if (1 > GTValues.L * multiplier || GTValues.L * multiplier > 64000) { - GTLog.logger.error("Fluid multiplier cannot exceed 64000mb total. Multiplier: {}", multiplier); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("Fluid multiplier cannot exceed 64000mb total. Multiplier: {}", multiplier, + new Throwable()); recipeStatus = EnumValidationResult.INVALID; } this.solderMultiplier = multiplier; diff --git a/src/main/java/gregtech/api/recipes/builders/ComputationRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/ComputationRecipeBuilder.java index d6cadabc988..1d6c49a75d8 100644 --- a/src/main/java/gregtech/api/recipes/builders/ComputationRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/ComputationRecipeBuilder.java @@ -3,8 +3,8 @@ import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; -import gregtech.api.recipes.recipeproperties.ComputationProperty; -import gregtech.api.recipes.recipeproperties.TotalComputationProperty; +import gregtech.api.recipes.properties.impl.ComputationProperty; +import gregtech.api.recipes.properties.impl.TotalComputationProperty; import gregtech.api.util.EnumValidationResult; import gregtech.api.util.GTLog; @@ -28,7 +28,7 @@ public ComputationRecipeBuilder copy() { } @Override - public boolean applyProperty(@NotNull String key, Object value) { + public boolean applyPropertyCT(@NotNull String key, @NotNull Object value) { if (key.equals(ComputationProperty.KEY)) { this.CWUt(((Number) value).intValue()); return true; @@ -37,12 +37,12 @@ public boolean applyProperty(@NotNull String key, Object value) { this.totalCWU(((Number) value).intValue()); return true; } - return super.applyProperty(key, value); + return super.applyPropertyCT(key, value); } public ComputationRecipeBuilder CWUt(int cwut) { if (cwut < 0) { - GTLog.logger.error("CWU/t cannot be less than 0", new IllegalArgumentException()); + GTLog.logger.error("CWU/t cannot be less than 0", new Throwable()); recipeStatus = EnumValidationResult.INVALID; } this.applyProperty(ComputationProperty.getInstance(), cwut); @@ -54,7 +54,7 @@ public ComputationRecipeBuilder CWUt(int cwut) { */ public ComputationRecipeBuilder totalCWU(int totalCWU) { if (totalCWU < 0) { - GTLog.logger.error("Total CWU cannot be less than 0", new IllegalArgumentException()); + GTLog.logger.error("Total CWU cannot be less than 0", new Throwable()); recipeStatus = EnumValidationResult.INVALID; } this.applyProperty(TotalComputationProperty.getInstance(), totalCWU); diff --git a/src/main/java/gregtech/api/recipes/builders/FusionRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/FusionRecipeBuilder.java index e3da67a3114..91622a9950c 100644 --- a/src/main/java/gregtech/api/recipes/builders/FusionRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/FusionRecipeBuilder.java @@ -3,7 +3,7 @@ import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; -import gregtech.api.recipes.recipeproperties.FusionEUToStartProperty; +import gregtech.api.recipes.properties.impl.FusionEUToStartProperty; import gregtech.api.util.EnumValidationResult; import gregtech.api.util.GTLog; @@ -28,17 +28,17 @@ public FusionRecipeBuilder copy() { } @Override - public boolean applyProperty(@NotNull String key, Object value) { + public boolean applyPropertyCT(@NotNull String key, @NotNull Object value) { if (key.equals(FusionEUToStartProperty.KEY)) { this.EUToStart(((Number) value).longValue()); return true; } - return super.applyProperty(key, value); + return super.applyPropertyCT(key, value); } public FusionRecipeBuilder EUToStart(long EUToStart) { if (EUToStart <= 0) { - GTLog.logger.error("EU to start cannot be less than or equal to 0", new IllegalArgumentException()); + GTLog.logger.error("EU to start cannot be less than or equal to 0", new Throwable()); recipeStatus = EnumValidationResult.INVALID; } this.applyProperty(FusionEUToStartProperty.getInstance(), EUToStart); @@ -46,8 +46,7 @@ public FusionRecipeBuilder EUToStart(long EUToStart) { } public long getEUToStart() { - return this.recipePropertyStorage == null ? 0L : - this.recipePropertyStorage.getRecipePropertyValue(FusionEUToStartProperty.getInstance(), 0L); + return this.recipePropertyStorage.get(FusionEUToStartProperty.getInstance(), 0L); } @Override diff --git a/src/main/java/gregtech/api/recipes/builders/GasCollectorRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/GasCollectorRecipeBuilder.java deleted file mode 100644 index fe3bb345305..00000000000 --- a/src/main/java/gregtech/api/recipes/builders/GasCollectorRecipeBuilder.java +++ /dev/null @@ -1,82 +0,0 @@ -package gregtech.api.recipes.builders; - -import gregtech.api.recipes.Recipe; -import gregtech.api.recipes.RecipeBuilder; -import gregtech.api.recipes.RecipeMap; -import gregtech.api.recipes.recipeproperties.GasCollectorDimensionProperty; - -import crafttweaker.CraftTweakerAPI; -import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntList; -import it.unimi.dsi.fastutil.ints.IntLists; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -public class GasCollectorRecipeBuilder extends RecipeBuilder { - - public GasCollectorRecipeBuilder() {} - - public GasCollectorRecipeBuilder(Recipe recipe, RecipeMap recipeMap) { - super(recipe, recipeMap); - } - - public GasCollectorRecipeBuilder(RecipeBuilder recipeBuilder) { - super(recipeBuilder); - } - - @Override - public GasCollectorRecipeBuilder copy() { - return new GasCollectorRecipeBuilder(this); - } - - @Override - public boolean applyProperty(@NotNull String key, Object value) { - if (key.equals(GasCollectorDimensionProperty.KEY)) { - if (value instanceof Integer) { - this.dimension((Integer) value); - } else if (value instanceof List && !((List) value).isEmpty() && - ((List) value).get(0) instanceof Integer) { - IntList dimensionIDs = getDimensionIDs(); - if (dimensionIDs == IntLists.EMPTY_LIST) { - dimensionIDs = new IntArrayList(); - this.applyProperty(GasCollectorDimensionProperty.getInstance(), dimensionIDs); - } - dimensionIDs.addAll((List) value); - } else { - if (isCTRecipe) { - CraftTweakerAPI.logError("Dimension for Gas Collector needs to be a Integer"); - return false; - } - throw new IllegalArgumentException("Invalid Dimension Property Type!"); - } - return true; - } - return super.applyProperty(key, value); - } - - public GasCollectorRecipeBuilder dimension(int dimensionID) { - IntList dimensionIDs = getDimensionIDs(); - if (dimensionIDs == IntLists.EMPTY_LIST) { - dimensionIDs = new IntArrayList(); - this.applyProperty(GasCollectorDimensionProperty.getInstance(), dimensionIDs); - } - dimensionIDs.add(dimensionID); - return this; - } - - public IntList getDimensionIDs() { - return this.recipePropertyStorage == null ? IntLists.EMPTY_LIST : - this.recipePropertyStorage.getRecipePropertyValue(GasCollectorDimensionProperty.getInstance(), - IntLists.EMPTY_LIST); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .appendSuper(super.toString()) - .append(GasCollectorDimensionProperty.getInstance().getKey(), getDimensionIDs().toString()) - .toString(); - } -} diff --git a/src/main/java/gregtech/api/recipes/builders/ImplosionRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/ImplosionRecipeBuilder.java index b44771e8a31..ce078b9751b 100644 --- a/src/main/java/gregtech/api/recipes/builders/ImplosionRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/ImplosionRecipeBuilder.java @@ -4,10 +4,9 @@ import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.ingredients.GTRecipeItemInput; -import gregtech.api.recipes.recipeproperties.ImplosionExplosiveProperty; +import gregtech.api.recipes.properties.impl.ImplosionExplosiveProperty; import gregtech.api.util.EnumValidationResult; import gregtech.api.util.GTLog; -import gregtech.api.util.ValidationResult; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; @@ -34,61 +33,52 @@ public ImplosionRecipeBuilder copy() { } @Override - public boolean applyProperty(@NotNull String key, Object value) { + public boolean applyPropertyCT(@NotNull String key, @NotNull Object value) { if (key.equals(ImplosionExplosiveProperty.KEY)) { - if (value instanceof ItemStack) { - this.applyProperty(ImplosionExplosiveProperty.getInstance(), value); - } else { - this.applyProperty(ImplosionExplosiveProperty.getInstance(), new ItemStack(Blocks.TNT, (int) value)); + if (value instanceof ItemStack stack) { + return this.applyProperty(ImplosionExplosiveProperty.getInstance(), stack); + } else if (value instanceof Number number) { + return this.applyProperty(ImplosionExplosiveProperty.getInstance(), number.intValue()); } - return true; + return false; } - return super.applyProperty(key, value); + return super.applyPropertyCT(key, value); } @ZenMethod - public ImplosionRecipeBuilder explosivesAmount(int explosivesAmount) { - if (1 > explosivesAmount || explosivesAmount > 64) { - GTLog.logger.error("Amount of explosives should be from 1 to 64 inclusive", new IllegalArgumentException()); - recipeStatus = EnumValidationResult.INVALID; - } - this.applyProperty(ImplosionExplosiveProperty.getInstance(), new ItemStack(Blocks.TNT, explosivesAmount)); - return this; + public ImplosionRecipeBuilder explosives(int amount) { + return explosives(new ItemStack(Blocks.TNT, amount)); } @ZenMethod - public ImplosionRecipeBuilder explosivesType(ItemStack explosivesType) { - if (1 > explosivesType.getCount() || explosivesType.getCount() > 64) { - GTLog.logger.error("Amount of explosives should be from 1 to 64 inclusive", new IllegalArgumentException()); - recipeStatus = EnumValidationResult.INVALID; + public ImplosionRecipeBuilder explosives(@NotNull ItemStack explosive) { + if (explosive.isEmpty()) { + GTLog.logger.error("Cannot use empty explosives", new Throwable()); + this.recipeStatus = EnumValidationResult.INVALID; + return this; } - this.applyProperty(ImplosionExplosiveProperty.getInstance(), explosivesType); - return this; - } - public ItemStack getExplosivesType() { - if (this.recipePropertyStorage == null) { - return ItemStack.EMPTY; + int count = explosive.getCount(); + if (count < 1 || count > 64) { + GTLog.logger.error("Amount of explosives should be from 1 to 64 inclusive", new Throwable()); + recipeStatus = EnumValidationResult.INVALID; + return this; + } + if (this.applyProperty(ImplosionExplosiveProperty.getInstance(), explosive)) { + this.inputs.add(new GTRecipeItemInput(explosive)); } - return this.recipePropertyStorage.getRecipePropertyValue(ImplosionExplosiveProperty.getInstance(), - ItemStack.EMPTY); + return this; } - public ValidationResult build() { - ItemStack explosivesType = getExplosivesType(); - if (!explosivesType.isEmpty()) { - this.inputs.add(new GTRecipeItemInput(explosivesType)); - } else { - this.recipePropertyStorageErrored = true; - } - return super.build(); + public @NotNull ItemStack getExplosives() { + return this.recipePropertyStorage.get(ImplosionExplosiveProperty.getInstance(), ItemStack.EMPTY); } @Override public String toString() { return new ToStringBuilder(this) .appendSuper(super.toString()) - .append(ImplosionExplosiveProperty.getInstance().getKey(), getExplosivesType()) + .append(ImplosionExplosiveProperty.getInstance().getKey(), getExplosives()) .toString(); } } diff --git a/src/main/java/gregtech/api/recipes/builders/PrimitiveRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/PrimitiveRecipeBuilder.java index 858a94d1177..ec0e8cf2202 100644 --- a/src/main/java/gregtech/api/recipes/builders/PrimitiveRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/PrimitiveRecipeBuilder.java @@ -3,7 +3,7 @@ import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; -import gregtech.api.recipes.recipeproperties.PrimitiveProperty; +import gregtech.api.recipes.properties.impl.PrimitiveProperty; import gregtech.api.util.ValidationResult; public class PrimitiveRecipeBuilder extends RecipeBuilder { diff --git a/src/main/java/gregtech/api/recipes/builders/UniversalDistillationRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/UniversalDistillationRecipeBuilder.java index 36008717735..d5a204f5527 100644 --- a/src/main/java/gregtech/api/recipes/builders/UniversalDistillationRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/UniversalDistillationRecipeBuilder.java @@ -10,7 +10,7 @@ import org.jetbrains.annotations.Nullable; -import static gregtech.api.recipes.logic.OverclockingLogic.STANDARD_OVERCLOCK_DURATION_DIVISOR; +import static gregtech.api.recipes.logic.OverclockingLogic.STD_DURATION_FACTOR_INV; public class UniversalDistillationRecipeBuilder extends RecipeBuilder { @@ -45,7 +45,7 @@ public void buildAndRegister() { int ratio = getRatioForDistillery(this.fluidInputs.get(0).getInputFluidStack(), this.fluidOutputs.get(i), !this.outputs.isEmpty() ? this.outputs.get(0) : null); - int recipeDuration = (int) (this.duration * STANDARD_OVERCLOCK_DURATION_DIVISOR); + int recipeDuration = (int) (this.duration * STD_DURATION_FACTOR_INV); boolean shouldDivide = ratio != 1; 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/recipes/ingredients/nbtmatch/ListNBTCondition.java b/src/main/java/gregtech/api/recipes/ingredients/nbtmatch/ListNBTCondition.java index ee8b61833a8..e7d3d744ffa 100644 --- a/src/main/java/gregtech/api/recipes/ingredients/nbtmatch/ListNBTCondition.java +++ b/src/main/java/gregtech/api/recipes/ingredients/nbtmatch/ListNBTCondition.java @@ -19,8 +19,7 @@ protected ListNBTCondition(NBTTagType listTagType, String nbtKey, Object value) super(NBTTagType.LIST, nbtKey, value); this.listTagType = listTagType; if (listTagType == null) { - GTLog.logger.error("ListNBTCondition must not have null parameters."); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("ListNBTCondition must not have null parameters.", new Throwable()); } } diff --git a/src/main/java/gregtech/api/recipes/ingredients/nbtmatch/NBTCondition.java b/src/main/java/gregtech/api/recipes/ingredients/nbtmatch/NBTCondition.java index 06298ae22ad..ebf380d753b 100644 --- a/src/main/java/gregtech/api/recipes/ingredients/nbtmatch/NBTCondition.java +++ b/src/main/java/gregtech/api/recipes/ingredients/nbtmatch/NBTCondition.java @@ -37,8 +37,7 @@ protected NBTCondition(NBTTagType tagType, String nbtKey, Object value) { this.nbtKey = nbtKey; this.value = value; if (tagType == null || nbtKey == null || value == null) { - GTLog.logger.error("NBTCondition must not have null parameters."); - GTLog.logger.error("Stacktrace:", new IllegalArgumentException()); + GTLog.logger.error("NBTCondition must not have null parameters.", new Throwable()); } } diff --git a/src/main/java/gregtech/api/recipes/logic/OCParams.java b/src/main/java/gregtech/api/recipes/logic/OCParams.java new file mode 100644 index 00000000000..39d300b1519 --- /dev/null +++ b/src/main/java/gregtech/api/recipes/logic/OCParams.java @@ -0,0 +1,44 @@ +package gregtech.api.recipes.logic; + +public final class OCParams { + + private long eut; + private int duration; + private int ocAmount; + + public void initialize(long eut, int duration, int ocAmount) { + this.eut = eut; + this.duration = duration; + this.ocAmount = ocAmount; + } + + public void reset() { + this.eut = 0L; + this.duration = 0; + this.ocAmount = 0; + } + + public long eut() { + return eut; + } + + public void setEut(long eut) { + this.eut = eut; + } + + public int duration() { + return duration; + } + + public void setDuration(int duration) { + this.duration = duration; + } + + public int ocAmount() { + return ocAmount; + } + + public void setOcAmount(int ocAmount) { + this.ocAmount = ocAmount; + } +} diff --git a/src/main/java/gregtech/api/recipes/logic/OCResult.java b/src/main/java/gregtech/api/recipes/logic/OCResult.java new file mode 100644 index 00000000000..c0688f4f30d --- /dev/null +++ b/src/main/java/gregtech/api/recipes/logic/OCResult.java @@ -0,0 +1,74 @@ +package gregtech.api.recipes.logic; + +import org.jetbrains.annotations.NotNull; + +public final class OCResult { + + private long eut; + private long parallelEUt; + private int duration; + private int parallel; + + public void init(long eut, int duration) { + init(eut, duration, 0); + } + + public void init(long eut, int duration, int parallel) { + init(eut, duration, parallel, parallel == 0 ? eut : eut * parallel); + } + + public void init(long eut, int duration, int parallel, long parallelEUt) { + this.eut = eut; + this.duration = duration; + this.parallel = parallel; + this.parallelEUt = parallelEUt; + } + + public void reset() { + this.eut = 0L; + this.parallelEUt = 0L; + this.duration = 0; + this.parallel = 0; + } + + public long eut() { + return eut; + } + + public void setEut(long eut) { + this.eut = eut; + } + + public long parallelEUt() { + return parallelEUt; + } + + public void setParallelEUt(long parallelEUt) { + this.parallelEUt = parallelEUt; + } + + public int duration() { + return duration; + } + + public void setDuration(int duration) { + this.duration = duration; + } + + public int parallel() { + return parallel; + } + + public void setParallel(int parallel) { + this.parallel = parallel; + } + + @Override + public @NotNull String toString() { + return "OCResult[" + + "EUt=" + eut + ", " + + "duration=" + duration + ", " + + "parallel=" + parallel + ", " + + "parallelEUt=" + parallelEUt + ']'; + } +} diff --git a/src/main/java/gregtech/api/recipes/logic/OverclockingLogic.java b/src/main/java/gregtech/api/recipes/logic/OverclockingLogic.java index 824d69b8c5f..63c6d359344 100644 --- a/src/main/java/gregtech/api/recipes/logic/OverclockingLogic.java +++ b/src/main/java/gregtech/api/recipes/logic/OverclockingLogic.java @@ -5,54 +5,287 @@ /** * A class for holding all the various Overclocking logics */ -public class OverclockingLogic { +public final class OverclockingLogic { - public static final double STANDARD_OVERCLOCK_VOLTAGE_MULTIPLIER = 4.0; - public static final double STANDARD_OVERCLOCK_DURATION_DIVISOR = 2.0; - public static final double PERFECT_OVERCLOCK_DURATION_DIVISOR = 4.0; + public static final double STD_VOLTAGE_FACTOR = 4.0; + public static final double PERFECT_HALF_VOLTAGE_FACTOR = 2.0; + + public static final double STD_DURATION_FACTOR = 0.5; + public static final double STD_DURATION_FACTOR_INV = 2.0; + public static final double PERFECT_DURATION_FACTOR = 0.25; + public static final double PERFECT_DURATION_FACTOR_INV = 4.0; + public static final double PERFECT_HALF_DURATION_FACTOR = 0.5; + public static final double PERFECT_HALF_DURATION_FACTOR_INV = 2.0; public static final int COIL_EUT_DISCOUNT_TEMPERATURE = 900; + private OverclockingLogic() {} + + /** + * Standard overclocking algorithm with no sub-tick behavior. + *

+ * While there are overclocks remaining: + *

    + *
  1. Multiplies {@code EUt} by {@code voltageFactor} + *
  2. Multiplies {@code duration} by {@code durationFactor} + *
  3. Limit {@code duration} to {@code 1} tick, and stop overclocking early if needed + * + * @param params the overclocking parameters + * @param result the result of the overclock + * @param maxVoltage the maximum voltage allowed to be overclocked to + * @param durationFactor the factor to multiply duration by + * @param voltageFactor the factor to multiply voltage by + */ + public static void standardOC(@NotNull OCParams params, @NotNull OCResult result, long maxVoltage, + double durationFactor, double voltageFactor) { + double duration = params.duration(); + double eut = params.eut(); + int ocAmount = params.ocAmount(); + + while (ocAmount-- > 0) { + double potentialEUt = eut * voltageFactor; + if (potentialEUt > maxVoltage) { + break; + } + + double potentialDuration = duration * durationFactor; + if (potentialDuration < 1) { + break; + } + + // only update EUt if duration is also valid + eut = potentialEUt; + duration = potentialDuration; + } + + result.init((long) eut, (int) duration); + } + + /** + * Overclocking algorithm with sub-tick logic, which improves energy efficiency without parallelization. + *

    + * While there are overclocks remaining: + *

      + *
    1. Multiplies {@code EUt} by {@code voltageFactor} + *
    2. Multiplies {@code duration} by {@code durationFactor} + *
    3. Limit {@code duration} to {@code 1} tick + *
    4. Multiply {@code EUt} by {@code durationFactor} and maintain {@code duration} at {@code 1} tick for + * overclocks that would have {@code duration < 1} + * + * @param params the overclocking parameters + * @param result the result of the overclock + * @param maxVoltage the maximum voltage allowed to be overclocked to + * @param durationFactor the factor to multiply duration by + * @param voltageFactor the factor to multiply voltage by + */ + public static void subTickNonParallelOC(@NotNull OCParams params, @NotNull OCResult result, long maxVoltage, + double durationFactor, double voltageFactor) { + double duration = params.duration(); + double eut = params.eut(); + int ocAmount = params.ocAmount(); + + while (ocAmount-- > 0) { + double potentialEUt = eut * voltageFactor; + if (potentialEUt > maxVoltage || potentialEUt < 1) { + break; + } + + double potentialDuration = duration * durationFactor; + if (potentialDuration < 1) { + potentialEUt = eut * durationFactor; + if (potentialEUt > maxVoltage || potentialEUt < 1) { + break; + } + } else { + duration = potentialDuration; + } + + eut = potentialEUt; + } + + result.init((long) eut, (int) duration); + } + /** - * applies standard logic for overclocking, where each overclock modifies energy and duration + * Overclocking algorithm with sub-tick parallelization. + *

      + * While there are overclocks remaining: + *

        + *
      1. Multiplies {@code EUt} by {@code voltageFactor} + *
      2. Multiplies {@code duration} by {@code durationFactor} + *
      3. Limit {@code duration} to {@code 1} tick + *
      4. Parallelize {@code EUt} with {@code voltageFactor} and maintain {@code duration} at {@code 1} tick for + * overclocks that would have {@code duration < 1} + *
      5. Parallel amount per overclock is {@code 1 / durationFactor} * - * @param recipeEUt the EU/t of the recipe to overclock - * @param maxVoltage the maximum voltage the recipe is allowed to be run at - * @param recipeDuration the duration of the recipe to overclock - * @param durationDivisor the value to divide the duration by for each overclock - * @param voltageMultiplier the value to multiply the voltage by for each overclock - * @param numberOfOCs the maximum amount of overclocks allowed - * @return an int array of {OverclockedEUt, OverclockedDuration} + * @param params the overclocking parameters + * @param result the result of the overclock + * @param maxVoltage the maximum voltage allowed to be overclocked to + * @param durationFactor the factor to multiply duration by + * @param voltageFactor the factor to multiply voltage by */ - public static int @NotNull [] standardOverclockingLogic(int recipeEUt, long maxVoltage, int recipeDuration, - int numberOfOCs, - double durationDivisor, double voltageMultiplier) { - double resultDuration = recipeDuration; - double resultVoltage = recipeEUt; - - for (; numberOfOCs > 0; numberOfOCs--) { - // make sure that duration is not already as low as it can do - if (resultDuration == 1) break; - - // it is important to do voltage first, - // so overclocking voltage does not go above the limit before changing duration - - double potentialVoltage = resultVoltage * voltageMultiplier; - // do not allow voltage to go above maximum - if (potentialVoltage > maxVoltage) break; - - double potentialDuration = resultDuration / durationDivisor; - // do not allow duration to go below one tick - if (potentialDuration < 1) potentialDuration = 1; - // update the duration for the next iteration - resultDuration = potentialDuration; - - // update the voltage for the next iteration after everything else - // in case duration overclocking would waste energy - resultVoltage = potentialVoltage; + public static void subTickParallelOC(@NotNull OCParams params, @NotNull OCResult result, long maxVoltage, + double durationFactor, double voltageFactor) { + double duration = params.duration(); + double eut = params.eut(); + int ocAmount = params.ocAmount(); + double parallel = 1; + int parallelIterAmount = 0; + boolean shouldParallel = false; + + while (ocAmount-- > 0) { + double potentialEUt = eut * voltageFactor; + if (potentialEUt > maxVoltage) { + break; + } + eut = potentialEUt; + + if (shouldParallel) { + parallel /= durationFactor; + parallelIterAmount++; + } else { + double potentialDuration = duration * durationFactor; + if (potentialDuration < 1) { + parallel /= durationFactor; + parallelIterAmount++; + shouldParallel = true; + } else { + duration = potentialDuration; + } + } } - return new int[] { (int) resultVoltage, (int) resultDuration }; + result.init((long) (eut / Math.pow(voltageFactor, parallelIterAmount)), (int) duration, (int) parallel, + (long) eut); + } + + /** + * Heating Coil overclocking algorithm with sub-tick parallelization. + *

        + * While there are overclocks remaining: + *

          + *
        1. Multiplies {@code EUt} by {@link #STD_VOLTAGE_FACTOR} + *
        2. Multiplies {@code duration} by {@link #PERFECT_DURATION_FACTOR} if there are perfect OCs remaining, + * otherwise multiplies by {@link #STD_DURATION_FACTOR} + *
        3. Limit {@code duration} to {@code 1} tick + *
        4. Parallelize {@code EUt} with {@link #STD_VOLTAGE_FACTOR} and maintain {@code duration} at {@code 1} tick for + * overclocks that would have {@code duration < 1} + *
        5. Parallelization amount per overclock is {@link #PERFECT_DURATION_FACTOR_INV} if there are perfect OCs + * remaining, otherwise uses {@link #STD_DURATION_FACTOR_INV} + *
        6. The maximum amount of perfect OCs is determined by {@link #calculateAmountCoilEUtDiscount(int, int)}, divided + * by 2. + * + * @param params the overclocking parameters + * @param result the result of the overclock + * @param maxVoltage the maximum voltage allowed to be overclocked to + * @param providedTemp the provided temperature + * @param requiredTemp the temperature required by the recipe + */ + public static void heatingCoilOC(@NotNull OCParams params, @NotNull OCResult result, long maxVoltage, + int providedTemp, int requiredTemp) { + int perfectOCAmount = calculateAmountCoilEUtDiscount(providedTemp, requiredTemp) / 2; + double duration = params.duration(); + double eut = params.eut(); + int ocAmount = params.ocAmount(); + double parallel = 1; + int parallelIterAmount = 0; + boolean shouldParallel = false; + + while (ocAmount-- > 0) { + boolean perfect = perfectOCAmount-- > 0; + + double potentialEUt = eut * STD_VOLTAGE_FACTOR; + if (potentialEUt > maxVoltage) { + break; + } + eut = potentialEUt; + + if (shouldParallel) { + if (perfect) { + parallel *= PERFECT_DURATION_FACTOR_INV; + } else { + parallel *= STD_DURATION_FACTOR_INV; + } + parallelIterAmount++; + } else { + double potentialDuration; + if (perfect) { + potentialDuration = duration * PERFECT_DURATION_FACTOR; + } else { + potentialDuration = duration * STD_DURATION_FACTOR; + } + + if (potentialDuration < 1) { + if (perfect) { + parallel *= PERFECT_DURATION_FACTOR_INV; + } else { + parallel *= STD_DURATION_FACTOR_INV; + } + + parallelIterAmount++; + shouldParallel = true; + } else { + duration = potentialDuration; + } + } + } + + result.init((long) (eut / Math.pow(STD_VOLTAGE_FACTOR, parallelIterAmount)), (int) duration, (int) parallel, + (long) eut); + } + + /** + * Heating Coil overclocking algorithm with sub-tick parallelization. + *

          + * While there are overclocks remaining: + *

            + *
          1. Multiplies {@code EUt} by {@link #STD_VOLTAGE_FACTOR} + *
          2. Multiplies {@code duration} by {@link #PERFECT_DURATION_FACTOR} if there are perfect OCs remaining, + * otherwise multiplies by {@link #STD_DURATION_FACTOR} + *
          3. Limit {@code duration} to {@code 1} tick + *
          4. Parallelize {@code EUt} with {@link #STD_VOLTAGE_FACTOR} and maintain {@code duration} at {@code 1} tick for + * overclocks that would have {@code duration < 1} + *
          5. Parallelization amount per overclock is {@link #PERFECT_DURATION_FACTOR_INV} if there are perfect OCs + * remaining, otherwise uses {@link #STD_DURATION_FACTOR_INV} + *
          6. The maximum amount of perfect OCs is determined by {@link #calculateAmountCoilEUtDiscount(int, int)}, divided + * by 2. + * + * @param params the overclocking parameters + * @param result the result of the overclock + * @param maxVoltage the maximum voltage allowed to be overclocked to + * @param providedTemp the provided temperature + * @param requiredTemp the temperature required by the recipe + */ + public static void heatingCoilNonSubTickOC(@NotNull OCParams params, @NotNull OCResult result, long maxVoltage, + int providedTemp, int requiredTemp) { + int perfectOCAmount = calculateAmountCoilEUtDiscount(providedTemp, requiredTemp) / 2; + double duration = params.duration(); + double eut = params.eut(); + int ocAmount = params.ocAmount(); + + while (ocAmount-- > 0) { + boolean perfect = perfectOCAmount-- > 0; + + double potentialEUt = eut * STD_VOLTAGE_FACTOR; + if (potentialEUt > maxVoltage) { + break; + } + eut = potentialEUt; + + double potentialDuration; + if (perfect) { + potentialDuration = duration * PERFECT_DURATION_FACTOR; + } else { + potentialDuration = duration * STD_DURATION_FACTOR; + } + + if (potentialDuration < 1) { + break; + } + duration = potentialDuration; + } + + result.init((long) eut, (int) duration); } /** @@ -72,32 +305,10 @@ private static int calculateAmountCoilEUtDiscount(int providedTemp, int required * @param requiredTemp the required temperature of the recipe * @return the discounted EU/t */ - public static int applyCoilEUtDiscount(int recipeEUt, int providedTemp, int requiredTemp) { + public static long applyCoilEUtDiscount(long recipeEUt, int providedTemp, int requiredTemp) { if (requiredTemp < COIL_EUT_DISCOUNT_TEMPERATURE) return recipeEUt; int amountEUtDiscount = calculateAmountCoilEUtDiscount(providedTemp, requiredTemp); if (amountEUtDiscount < 1) return recipeEUt; - return (int) (recipeEUt * Math.min(1, Math.pow(0.95, amountEUtDiscount))); - } - - public static int @NotNull [] heatingCoilOverclockingLogic(int recipeEUt, long maximumVoltage, int recipeDuration, - int maxOverclocks, int currentTemp, - int recipeRequiredTemp) { - int amountPerfectOC = calculateAmountCoilEUtDiscount(currentTemp, recipeRequiredTemp) / 2; - - // perfect overclock for every 1800k over recipe temperature - if (amountPerfectOC > 0) { - // use the normal overclock logic to do perfect OCs up to as many times as calculated - int[] overclock = standardOverclockingLogic(recipeEUt, maximumVoltage, recipeDuration, amountPerfectOC, - PERFECT_OVERCLOCK_DURATION_DIVISOR, STANDARD_OVERCLOCK_VOLTAGE_MULTIPLIER); - - // overclock normally as much as possible after perfects are exhausted - return standardOverclockingLogic(overclock[0], maximumVoltage, overclock[1], - maxOverclocks - amountPerfectOC, STANDARD_OVERCLOCK_DURATION_DIVISOR, - STANDARD_OVERCLOCK_VOLTAGE_MULTIPLIER); - } - - // no perfects are performed, do normal overclocking - return standardOverclockingLogic(recipeEUt, maximumVoltage, recipeDuration, maxOverclocks, - STANDARD_OVERCLOCK_DURATION_DIVISOR, STANDARD_OVERCLOCK_VOLTAGE_MULTIPLIER); + return (long) (recipeEUt * Math.min(1, Math.pow(0.95, amountEUtDiscount))); } } diff --git a/src/main/java/gregtech/api/recipes/logic/ParallelLogic.java b/src/main/java/gregtech/api/recipes/logic/ParallelLogic.java index c9b688b6653..c056890d086 100644 --- a/src/main/java/gregtech/api/recipes/logic/ParallelLogic.java +++ b/src/main/java/gregtech/api/recipes/logic/ParallelLogic.java @@ -8,6 +8,7 @@ import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.ingredients.GTRecipeInput; import gregtech.api.util.GTHashMaps; +import gregtech.api.util.GTUtility; import gregtech.api.util.ItemStackHashStrategy; import gregtech.api.util.OverlayedFluidHandler; import gregtech.api.util.OverlayedItemHandler; @@ -23,7 +24,11 @@ import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; public abstract class ParallelLogic { @@ -496,9 +501,9 @@ public static RecipeBuilder doParallelRecipes(@NotNull Recipe currentRecipe, limitByOutput = ParallelLogic.limitByOutputMerging(currentRecipe, exportInventory, exportFluids, multiplierByInputs, voidItems, voidFluids); - int recipeEUt = currentRecipe.getEUt(); + long recipeEUt = currentRecipe.getEUt(); if (recipeEUt != 0) { - int limitByVoltage = Math.abs((int) (maxVoltage / recipeEUt)); + int limitByVoltage = GTUtility.safeCastLongToInt(Math.abs(maxVoltage / recipeEUt)); int parallelizable = Math.min(limitByVoltage, limitByOutput); if (parallelizable != 0) // Use the minimum between the amount of recipes we can run with available inputs and amount of recipe diff --git a/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java b/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java index 28cd542d11d..d1d8301a3c7 100644 --- a/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java +++ b/src/main/java/gregtech/api/recipes/machines/RecipeMapAssemblyLine.java @@ -3,8 +3,8 @@ import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; -import gregtech.api.recipes.recipeproperties.ResearchProperty; -import gregtech.api.recipes.recipeproperties.ResearchPropertyData; +import gregtech.api.recipes.properties.impl.ResearchProperty; +import gregtech.api.recipes.properties.impl.ResearchPropertyData; import gregtech.api.recipes.ui.RecipeMapUIFunction; import gregtech.core.sound.GTSoundEvents; @@ -32,15 +32,11 @@ public RecipeMapAssemblyLine(@NotNull String unlocalizedName, @NotNull R default @Override public boolean compileRecipe(Recipe recipe) { if (!super.compileRecipe(recipe)) return false; - if (recipe.hasProperty(ResearchProperty.getInstance())) { - ResearchPropertyData data = recipe.getProperty(ResearchProperty.getInstance(), null); - if (data != null) { - for (ResearchPropertyData.ResearchEntry entry : data) { - addDataStickEntry(entry.getResearchId(), recipe); - } - return true; + ResearchPropertyData data = recipe.getProperty(ResearchProperty.getInstance(), null); + if (data != null) { + for (ResearchPropertyData.ResearchEntry entry : data) { + addDataStickEntry(entry.researchId(), recipe); } - return false; } return true; } @@ -48,21 +44,27 @@ public boolean compileRecipe(Recipe recipe) { @Override public boolean removeRecipe(@NotNull Recipe recipe) { if (!super.removeRecipe(recipe)) return false; - if (recipe.hasProperty(ResearchProperty.getInstance())) { - ResearchPropertyData data = recipe.getProperty(ResearchProperty.getInstance(), null); - if (data != null) { - for (ResearchPropertyData.ResearchEntry entry : data) { - removeDataStickEntry(entry.getResearchId(), recipe); - } - return true; + ResearchPropertyData data = recipe.getProperty(ResearchProperty.getInstance(), null); + if (data != null) { + for (ResearchPropertyData.ResearchEntry entry : data) { + removeDataStickEntry(entry.researchId(), recipe); } - return false; } return true; } + @Override + protected void removeAllRecipes() { + super.removeAllRecipes(); + researchEntries.clear(); + } + @Override public void addDataStickEntry(@NotNull String researchId, @NotNull Recipe recipe) { + if (researchId.contains("xmetaitem.")) { + // save compatibility with an issue in 2.8.6, causing research IDs to change + addDataStickEntry(researchId.replace("xmetaitem.", "xitem.meta_item."), recipe); + } Collection collection = researchEntries.computeIfAbsent(researchId, (k) -> new ObjectOpenHashSet<>()); collection.add(recipe); } diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/RecipeProperty.java b/src/main/java/gregtech/api/recipes/properties/RecipeProperty.java similarity index 62% rename from src/main/java/gregtech/api/recipes/recipeproperties/RecipeProperty.java rename to src/main/java/gregtech/api/recipes/properties/RecipeProperty.java index 9dde81bb195..bb54c07603f 100644 --- a/src/main/java/gregtech/api/recipes/recipeproperties/RecipeProperty.java +++ b/src/main/java/gregtech/api/recipes/properties/RecipeProperty.java @@ -1,11 +1,13 @@ -package gregtech.api.recipes.recipeproperties; +package gregtech.api.recipes.properties; import net.minecraft.client.Minecraft; +import net.minecraft.nbt.NBTBase; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import org.jetbrains.annotations.NotNull; + import java.util.List; -import java.util.Objects; public abstract class RecipeProperty { @@ -17,6 +19,18 @@ protected RecipeProperty(String key, Class type) { this.type = type; } + /** + * @param value the value to serialize + * @return the serialized form of the value + */ + public abstract @NotNull NBTBase serialize(@NotNull Object value); + + /** + * @param nbt the nbt to deserialize + * @return the deserialized property value + */ + public abstract @NotNull Object deserialize(@NotNull NBTBase nbt); + @SideOnly(Side.CLIENT) public abstract void drawInfo(Minecraft minecraft, int x, int y, int color, Object value); @@ -28,19 +42,15 @@ public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value, @SideOnly(Side.CLIENT) public void getTooltipStrings(List tooltip, int mouseX, int mouseY, Object value) {} - public int getInfoHeight(Object value) { + public int getInfoHeight(@NotNull Object value) { return 10; // GTRecipeWrapper#LINE_HEIGHT } - public boolean isOfType(Class otherType) { - return this.type == otherType; - } - - public String getKey() { + public final @NotNull String getKey() { return key; } - public T castValue(Object value) { + protected final T castValue(@NotNull Object value) { return this.type.cast(value); } @@ -75,15 +85,20 @@ public boolean hideDuration() { } @Override - public boolean equals(Object o) { + public final boolean equals(Object o) { if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - RecipeProperty that = (RecipeProperty) o; - return Objects.equals(type, that.type) && Objects.equals(key, that.key); + if (!(o instanceof RecipePropertythat)) return false; + + return type.equals(that.type) && getKey().equals(that.getKey()); + } + + @Override + public final int hashCode() { + return 31 * type.hashCode() + getKey().hashCode(); } @Override - public int hashCode() { - return Objects.hash(type, key); + public String toString() { + return "RecipeProperty{" + "key='" + key + "'}"; } } diff --git a/src/main/java/gregtech/api/recipes/properties/RecipePropertyRegistry.java b/src/main/java/gregtech/api/recipes/properties/RecipePropertyRegistry.java new file mode 100644 index 00000000000..13defc9f723 --- /dev/null +++ b/src/main/java/gregtech/api/recipes/properties/RecipePropertyRegistry.java @@ -0,0 +1,29 @@ +package gregtech.api.recipes.properties; + +import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; + +public final class RecipePropertyRegistry { + + private final Map> map = new Object2ReferenceOpenHashMap<>(); + + /** + * @param key the RecipeProperty's key + * @param property the property's instance + */ + public void register(@NotNull String key, @NotNull RecipeProperty property) { + if (map.containsKey(key)) { + throw new IllegalArgumentException("RecipeProperty is already registered: " + key); + } + map.put(key, property); + } + + @ApiStatus.Internal + public @Nullable RecipeProperty get(@NotNull String key) { + return map.get(key); + } +} diff --git a/src/main/java/gregtech/api/recipes/properties/RecipePropertyStorage.java b/src/main/java/gregtech/api/recipes/properties/RecipePropertyStorage.java new file mode 100644 index 00000000000..790143293dd --- /dev/null +++ b/src/main/java/gregtech/api/recipes/properties/RecipePropertyStorage.java @@ -0,0 +1,119 @@ +package gregtech.api.recipes.properties; + +import gregtech.api.util.GTLog; + +import net.minecraft.nbt.NBTTagCompound; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.UnmodifiableView; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +public interface RecipePropertyStorage { + + /** + * @param recipeProperty the property to store + * @param value the value to store + * @return if the store succeeds + */ + boolean store(@NotNull RecipeProperty recipeProperty, @NotNull Object value); + + /** + * @return a copy of this property storage + */ + @NotNull + RecipePropertyStorage copy(); + + /** + * @return number of stored properties + */ + int size(); + + /** + * @return all stored properties and values + */ + @NotNull + Set, Object>> entrySet(); + + /** + * @param recipeProperty the property to retrieve + * @param defaultValue default value if the property is not found + * @param the type of returned value + * @return value associated with the provided recipeProperty, otherwise the default + */ + @Contract("_, !null -> !null") + @Nullable T get(@NotNull RecipeProperty recipeProperty, @Nullable T defaultValue); + + /** + * @param recipeProperty the property to check + * @return if the property is in this storage + */ + boolean contains(@NotNull RecipeProperty recipeProperty); + + /** + * @return the recipe property values + */ + @UnmodifiableView + @NotNull + Set<@NotNull RecipeProperty> values(); + + @NotNull + NBTTagCompound serializeNBT(); + + void deserializeNBT(@NotNull NBTTagCompound nbt); + + RecipePropertyStorage EMPTY = new RecipePropertyStorage() { + + @Override + public boolean store(@NotNull RecipeProperty recipeProperty, @NotNull Object value) { + throw new UnsupportedOperationException("empty"); + } + + @Override + public @NotNull RecipePropertyStorage copy() { + return this; + } + + @Override + public int size() { + return 0; + } + + @Override + public @NotNull Set, Object>> entrySet() { + return Collections.emptySet(); + } + + @Override + public @Nullable T get(@NotNull RecipeProperty recipeProperty, @Nullable T defaultValue) { + return defaultValue; + } + + @Override + public boolean contains(@NotNull RecipeProperty recipeProperty) { + return false; + } + + @Override + public @UnmodifiableView @NotNull Set<@NotNull RecipeProperty> values() { + return Collections.emptySet(); + } + + @Override + public @NotNull NBTTagCompound serializeNBT() { + return new NBTTagCompound(); + } + + @Override + public void deserializeNBT(@NotNull NBTTagCompound nbt) { + if (!nbt.isEmpty()) { + GTLog.logger.warn("Tried to deserialize non-empty tag in RecipePropertyStorage.EMPTY: {}", nbt, + new Throwable()); + } + } + }; +} diff --git a/src/main/java/gregtech/api/recipes/properties/RecipePropertyStorageImpl.java b/src/main/java/gregtech/api/recipes/properties/RecipePropertyStorageImpl.java new file mode 100644 index 00000000000..ffc7ea21227 --- /dev/null +++ b/src/main/java/gregtech/api/recipes/properties/RecipePropertyStorageImpl.java @@ -0,0 +1,111 @@ +package gregtech.api.recipes.properties; + +import gregtech.api.GregTechAPI; +import gregtech.api.util.GTLog; + +import net.minecraft.nbt.NBTTagCompound; + +import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.UnmodifiableView; + +import java.util.Map; +import java.util.Set; + +public final class RecipePropertyStorageImpl implements RecipePropertyStorage { + + private final Map, Object> map; + + public RecipePropertyStorageImpl() { + this(new Object2ObjectArrayMap<>(1)); + } + + private RecipePropertyStorageImpl(@NotNull Map, Object> map) { + this.map = map; + } + + @Override + public boolean store(@NotNull RecipeProperty recipeProperty, @NotNull Object value) { + String key = recipeProperty.getKey(); + if (map.containsKey(recipeProperty)) { + GTLog.logger.warn("Duplicate recipe property added: {} -> {}", key, value, new Throwable()); + return false; + } + + try { + recipeProperty.castValue(value); + } catch (ClassCastException e) { + GTLog.logger.error("Provided incorrect value for RecipeProperty with key {}", key, e); + return false; + } + + map.put(recipeProperty, value); + return true; + } + + @Override + public @NotNull RecipePropertyStorage copy() { + return new RecipePropertyStorageImpl(new Object2ObjectArrayMap<>(this.map)); + } + + @Override + public int size() { + return map.size(); + } + + @Override + public @NotNull Set, Object>> entrySet() { + return this.map.entrySet(); + } + + @Override + @Contract("_, !null -> !null") + public @Nullable T get(@NotNull RecipeProperty recipeProperty, @Nullable T defaultValue) { + var value = map.get(recipeProperty); + if (value == null) { + return defaultValue; + } + + return recipeProperty.castValue(value); + } + + @Override + public boolean contains(@NotNull RecipeProperty recipeProperty) { + return map.containsKey(recipeProperty); + } + + @Override + @UnmodifiableView + public @NotNull Set<@NotNull RecipeProperty> values() { + return map.keySet(); + } + + @Override + public @NotNull String toString() { + return "RecipePropertyStorage{" + map + '}'; + } + + @Override + public @NotNull NBTTagCompound serializeNBT() { + NBTTagCompound tag = new NBTTagCompound(); + for (var entry : map.entrySet()) { + var property = entry.getKey(); + tag.setTag(property.getKey(), property.serialize(entry.getValue())); + } + return tag; + } + + @Override + public void deserializeNBT(@NotNull NBTTagCompound nbt) { + for (var entry : nbt.tagMap.entrySet()) { + var property = GregTechAPI.RECIPE_PROPERTIES.get(entry.getKey()); + if (property == null) { + GTLog.logger.warn("Failed to read property with key {}", entry.getKey()); + continue; + } + map.put(property, property.deserialize(entry.getValue())); + } + } +} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/CleanroomProperty.java b/src/main/java/gregtech/api/recipes/properties/impl/CleanroomProperty.java similarity index 56% rename from src/main/java/gregtech/api/recipes/recipeproperties/CleanroomProperty.java rename to src/main/java/gregtech/api/recipes/properties/impl/CleanroomProperty.java index ccbe97bdc17..5329b868c04 100644 --- a/src/main/java/gregtech/api/recipes/recipeproperties/CleanroomProperty.java +++ b/src/main/java/gregtech/api/recipes/properties/impl/CleanroomProperty.java @@ -1,13 +1,21 @@ -package gregtech.api.recipes.recipeproperties; +package gregtech.api.recipes.properties.impl; +import gregtech.api.GregTechAPI; import gregtech.api.metatileentity.multiblock.CleanroomType; +import gregtech.api.recipes.properties.RecipeProperty; import net.minecraft.client.Minecraft; import net.minecraft.client.resources.I18n; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagString; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import org.jetbrains.annotations.NotNull; -public class CleanroomProperty extends RecipeProperty { +import java.util.Objects; + +public final class CleanroomProperty extends RecipeProperty { public static final String KEY = "cleanroom"; @@ -20,14 +28,25 @@ private CleanroomProperty() { public static CleanroomProperty getInstance() { if (INSTANCE == null) { INSTANCE = new CleanroomProperty(); + GregTechAPI.RECIPE_PROPERTIES.register(KEY, INSTANCE); } return INSTANCE; } @Override + public @NotNull NBTBase serialize(@NotNull Object value) { + return new NBTTagString(castValue(value).getName()); + } + + @Override + public @NotNull Object deserialize(@NotNull NBTBase nbt) { + return Objects.requireNonNull(CleanroomType.getByName(((NBTTagString) nbt).getString())); + } + + @Override + @SideOnly(Side.CLIENT) public void drawInfo(@NotNull Minecraft minecraft, int x, int y, int color, Object value) { CleanroomType type = castValue(value); - if (type == null) return; minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.cleanroom", getName(type)), x, y, color); } diff --git a/src/main/java/gregtech/api/recipes/properties/impl/ComputationProperty.java b/src/main/java/gregtech/api/recipes/properties/impl/ComputationProperty.java new file mode 100644 index 00000000000..f57a6ed2ea7 --- /dev/null +++ b/src/main/java/gregtech/api/recipes/properties/impl/ComputationProperty.java @@ -0,0 +1,49 @@ +package gregtech.api.recipes.properties.impl; + +import gregtech.api.GregTechAPI; +import gregtech.api.recipes.properties.RecipeProperty; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.I18n; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagInt; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; + +public final class ComputationProperty extends RecipeProperty { + + public static final String KEY = "computation_per_tick"; + + private static ComputationProperty INSTANCE; + + private ComputationProperty() { + super(KEY, Integer.class); + } + + public static ComputationProperty getInstance() { + if (INSTANCE == null) { + INSTANCE = new ComputationProperty(); + GregTechAPI.RECIPE_PROPERTIES.register(KEY, INSTANCE); + } + return INSTANCE; + } + + @Override + public @NotNull NBTBase serialize(@NotNull Object value) { + return new NBTTagInt(castValue(value)); + } + + @Override + public @NotNull Object deserialize(@NotNull NBTBase nbt) { + return ((NBTTagInt) nbt).getInt(); + } + + @Override + @SideOnly(Side.CLIENT) + public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { + minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.computation_per_tick", castValue(value)), x, y, + color); + } +} diff --git a/src/main/java/gregtech/api/recipes/properties/impl/DimensionProperty.java b/src/main/java/gregtech/api/recipes/properties/impl/DimensionProperty.java new file mode 100644 index 00000000000..721300af5d4 --- /dev/null +++ b/src/main/java/gregtech/api/recipes/properties/impl/DimensionProperty.java @@ -0,0 +1,117 @@ +package gregtech.api.recipes.properties.impl; + +import gregtech.api.GregTechAPI; +import gregtech.api.recipes.properties.RecipeProperty; +import gregtech.api.worldgen.config.WorldGenRegistry; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.I18n; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import org.jetbrains.annotations.NotNull; + +public final class DimensionProperty extends RecipeProperty { + + public static final String KEY = "dimension"; + + private static DimensionProperty INSTANCE; + + private DimensionProperty() { + super(KEY, DimensionPropertyList.class); + } + + public static DimensionProperty getInstance() { + if (INSTANCE == null) { + INSTANCE = new DimensionProperty(); + GregTechAPI.RECIPE_PROPERTIES.register(KEY, INSTANCE); + } + return INSTANCE; + } + + @Override + public @NotNull NBTBase serialize(@NotNull Object value) { + DimensionPropertyList list = castValue(value); + NBTTagCompound tag = new NBTTagCompound(); + tag.setIntArray("whiteListDimensions", list.whiteListDimensions.toArray(new int[0])); + tag.setIntArray("blackListDimensions", list.blackListDimensions.toArray(new int[0])); + return tag; + } + + @Override + public @NotNull Object deserialize(@NotNull NBTBase nbt) { + NBTTagCompound tag = (NBTTagCompound) nbt; + DimensionPropertyList list = new DimensionPropertyList(); + for (int i : tag.getIntArray("whiteListDimensions")) { + list.add(i, false); + } + + for (int i : tag.getIntArray("blackListDimensions")) { + list.add(i, true); + } + return tag; + } + + @Override + @SideOnly(Side.CLIENT) + public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { + DimensionPropertyList list = castValue(value); + + if (list.whiteListDimensions.size() > 0) + minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.dimensions", + getDimensionsForRecipe(castValue(value).whiteListDimensions)), x, y, color); + if (list.blackListDimensions.size() > 0) + minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.dimensions_blocked", + getDimensionsForRecipe(castValue(value).blackListDimensions)), x, y, color); + } + + private static String getDimensionsForRecipe(IntList value) { + Int2ObjectMap dimNames = WorldGenRegistry.getNamedDimensions(); + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < value.size(); i++) { + builder.append(dimNames.getOrDefault(value.getInt(i), String.valueOf(value.getInt(i)))); + if (i != value.size() - 1) + builder.append(", "); + } + String str = builder.toString(); + + if (str.length() >= 13) { + str = str.substring(0, 10) + ".."; + } + return str; + } + + // It would've been better to have one list and swap between blacklist and whitelist, but that would've been + // a bit awkward to apply to the property in practice. + public static class DimensionPropertyList { + + public static DimensionPropertyList EMPTY_LIST = new DimensionPropertyList(); + + public final IntList whiteListDimensions = new IntArrayList(); + public final IntList blackListDimensions = new IntArrayList(); + + public void add(int key, boolean toBlacklist) { + if (toBlacklist) { + blackListDimensions.add(key); + whiteListDimensions.rem(key); + } else { + whiteListDimensions.add(key); + blackListDimensions.rem(key); + } + } + + public void merge(@NotNull DimensionPropertyList list) { + this.whiteListDimensions.addAll(list.whiteListDimensions); + this.blackListDimensions.addAll(list.blackListDimensions); + } + + public boolean checkDimension(int dim) { + return !blackListDimensions.contains(dim) && whiteListDimensions.contains(dim); + } + } +} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/FusionEUToStartProperty.java b/src/main/java/gregtech/api/recipes/properties/impl/FusionEUToStartProperty.java similarity index 70% rename from src/main/java/gregtech/api/recipes/recipeproperties/FusionEUToStartProperty.java rename to src/main/java/gregtech/api/recipes/properties/impl/FusionEUToStartProperty.java index 60188d8cd5f..13446abe8d1 100644 --- a/src/main/java/gregtech/api/recipes/recipeproperties/FusionEUToStartProperty.java +++ b/src/main/java/gregtech/api/recipes/properties/impl/FusionEUToStartProperty.java @@ -1,17 +1,24 @@ -package gregtech.api.recipes.recipeproperties; +package gregtech.api.recipes.properties.impl; +import gregtech.api.GregTechAPI; +import gregtech.api.recipes.properties.RecipeProperty; import gregtech.api.util.TextFormattingUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.resources.I18n; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagLong; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; import java.util.Map; import java.util.TreeMap; -public class FusionEUToStartProperty extends RecipeProperty { +public final class FusionEUToStartProperty extends RecipeProperty { public static final String KEY = "eu_to_start"; @@ -19,19 +26,31 @@ public class FusionEUToStartProperty extends RecipeProperty { private static FusionEUToStartProperty INSTANCE; - protected FusionEUToStartProperty() { + private FusionEUToStartProperty() { super(KEY, Long.class); } public static FusionEUToStartProperty getInstance() { if (INSTANCE == null) { INSTANCE = new FusionEUToStartProperty(); + GregTechAPI.RECIPE_PROPERTIES.register(KEY, INSTANCE); } return INSTANCE; } @Override + public @NotNull NBTBase serialize(@NotNull Object value) { + return new NBTTagLong(castValue(value)); + } + + @Override + public @NotNull Object deserialize(@NotNull NBTBase nbt) { + return ((NBTTagLong) nbt).getLong(); + } + + @Override + @SideOnly(Side.CLIENT) public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.eu_to_start", TextFormattingUtil.formatLongToCompactString(castValue(value))) + getFusionTierName(castValue(value)), diff --git a/src/main/java/gregtech/api/recipes/properties/impl/ImplosionExplosiveProperty.java b/src/main/java/gregtech/api/recipes/properties/impl/ImplosionExplosiveProperty.java new file mode 100644 index 00000000000..915fc5aa4e3 --- /dev/null +++ b/src/main/java/gregtech/api/recipes/properties/impl/ImplosionExplosiveProperty.java @@ -0,0 +1,56 @@ +package gregtech.api.recipes.properties.impl; + +import gregtech.api.GregTechAPI; +import gregtech.api.recipes.properties.RecipeProperty; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.I18n; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; + +public final class ImplosionExplosiveProperty extends RecipeProperty { + + public static final String KEY = "explosives"; + + private static ImplosionExplosiveProperty INSTANCE; + + private ImplosionExplosiveProperty() { + super(KEY, ItemStack.class); + } + + public static ImplosionExplosiveProperty getInstance() { + if (INSTANCE == null) { + INSTANCE = new ImplosionExplosiveProperty(); + GregTechAPI.RECIPE_PROPERTIES.register(KEY, INSTANCE); + } + + return INSTANCE; + } + + @Override + public @NotNull NBTBase serialize(@NotNull Object value) { + return castValue(value).serializeNBT(); + } + + @Override + public @NotNull Object deserialize(@NotNull NBTBase nbt) { + return new ItemStack((NBTTagCompound) nbt); + } + + @Override + @SideOnly(Side.CLIENT) + public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { + minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.explosive", + castValue(value).getDisplayName()), x, y, color); + } + + @Override + public boolean isHidden() { + return true; + } +} diff --git a/src/main/java/gregtech/api/recipes/properties/impl/PrimitiveProperty.java b/src/main/java/gregtech/api/recipes/properties/impl/PrimitiveProperty.java new file mode 100644 index 00000000000..22b49f00bb8 --- /dev/null +++ b/src/main/java/gregtech/api/recipes/properties/impl/PrimitiveProperty.java @@ -0,0 +1,62 @@ +package gregtech.api.recipes.properties.impl; + +import gregtech.api.GregTechAPI; +import gregtech.api.recipes.properties.RecipeProperty; + +import net.minecraft.client.Minecraft; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagByte; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; + +/** + * Simple Marker Property to tell JEI to not display Total EU and EU/t. + */ +public final class PrimitiveProperty extends RecipeProperty { + + public static final String KEY = "primitive_property"; + private static PrimitiveProperty INSTANCE; + + private PrimitiveProperty() { + super(KEY, Boolean.class); + } + + public static PrimitiveProperty getInstance() { + if (INSTANCE == null) { + INSTANCE = new PrimitiveProperty(); + GregTechAPI.RECIPE_PROPERTIES.register(KEY, INSTANCE); + } + return INSTANCE; + } + + @Override + public @NotNull NBTBase serialize(@NotNull Object value) { + return new NBTTagByte((byte) (castValue(value) ? 1 : 0)); + } + + @Override + public @NotNull Object deserialize(@NotNull NBTBase nbt) { + return ((NBTTagByte) nbt).getByte() == 1; + } + + @Override + @SideOnly(Side.CLIENT) + public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) {} + + @Override + public int getInfoHeight(@NotNull Object value) { + return 0; + } + + @Override + public boolean hideTotalEU() { + return true; + } + + @Override + public boolean hideEUt() { + return true; + } +} diff --git a/src/main/java/gregtech/api/recipes/properties/impl/ResearchProperty.java b/src/main/java/gregtech/api/recipes/properties/impl/ResearchProperty.java new file mode 100644 index 00000000000..15b538fa5d6 --- /dev/null +++ b/src/main/java/gregtech/api/recipes/properties/impl/ResearchProperty.java @@ -0,0 +1,59 @@ +package gregtech.api.recipes.properties.impl; + +import gregtech.api.GregTechAPI; +import gregtech.api.recipes.properties.RecipeProperty; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.I18n; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagList; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; + +public final class ResearchProperty extends RecipeProperty { + + public static final String KEY = "research"; + + private static ResearchProperty INSTANCE; + + private ResearchProperty() { + super(KEY, ResearchPropertyData.class); + } + + @NotNull + public static ResearchProperty getInstance() { + if (INSTANCE == null) { + INSTANCE = new ResearchProperty(); + GregTechAPI.RECIPE_PROPERTIES.register(KEY, INSTANCE); + } + return INSTANCE; + } + + @Override + public @NotNull NBTBase serialize(@NotNull Object value) { + NBTTagList list = new NBTTagList(); + for (var entry : castValue(value)) { + list.appendTag(entry.serializeNBT()); + } + return list; + } + + @Override + public @NotNull Object deserialize(@NotNull NBTBase nbt) { + NBTTagList list = (NBTTagList) nbt; + ResearchPropertyData data = new ResearchPropertyData(); + for (int i = 0; i < list.tagCount(); i++) { + data.add(ResearchPropertyData.ResearchEntry.deserializeFromNBT(list.getCompoundTagAt(i))); + } + + return data; + } + + @Override + @SideOnly(Side.CLIENT) + public void drawInfo(@NotNull Minecraft minecraft, int x, int y, int color, Object value) { + minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.research"), x, y, color); + } +} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/ResearchPropertyData.java b/src/main/java/gregtech/api/recipes/properties/impl/ResearchPropertyData.java similarity index 66% rename from src/main/java/gregtech/api/recipes/recipeproperties/ResearchPropertyData.java rename to src/main/java/gregtech/api/recipes/properties/impl/ResearchPropertyData.java index 4b199221d6c..95a5159aac0 100644 --- a/src/main/java/gregtech/api/recipes/recipeproperties/ResearchPropertyData.java +++ b/src/main/java/gregtech/api/recipes/properties/impl/ResearchPropertyData.java @@ -1,6 +1,7 @@ -package gregtech.api.recipes.recipeproperties; +package gregtech.api.recipes.properties.impl; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; import org.jetbrains.annotations.NotNull; @@ -12,8 +13,6 @@ public final class ResearchPropertyData implements Iterable entries = new ArrayList<>(); - public ResearchPropertyData() {} - /** * @param entry the entry to add */ @@ -46,14 +45,23 @@ public ResearchEntry(@NotNull String researchId, @NotNull ItemStack dataItem) { this.dataItem = dataItem; } - @NotNull - public String getResearchId() { + public @NotNull String researchId() { return researchId; } - @NotNull - public ItemStack getDataItem() { + public @NotNull ItemStack dataItem() { return dataItem; } + + public @NotNull NBTTagCompound serializeNBT() { + NBTTagCompound tag = new NBTTagCompound(); + tag.setString("researchId", researchId); + tag.setTag("dataItem", dataItem.serializeNBT()); + return tag; + } + + public static @NotNull ResearchEntry deserializeFromNBT(@NotNull NBTTagCompound tag) { + return new ResearchEntry(tag.getString("researchId"), new ItemStack(tag.getCompoundTag("dataItem"))); + } } } diff --git a/src/main/java/gregtech/api/recipes/properties/impl/ScanProperty.java b/src/main/java/gregtech/api/recipes/properties/impl/ScanProperty.java new file mode 100644 index 00000000000..4e80ca61c20 --- /dev/null +++ b/src/main/java/gregtech/api/recipes/properties/impl/ScanProperty.java @@ -0,0 +1,49 @@ +package gregtech.api.recipes.properties.impl; + +import gregtech.api.GregTechAPI; +import gregtech.api.recipes.properties.RecipeProperty; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.I18n; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagByte; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; + +public final class ScanProperty extends RecipeProperty { + + public static final String KEY = "scan"; + + private static ScanProperty INSTANCE; + + private ScanProperty() { + super(KEY, Boolean.class); + } + + @NotNull + public static ScanProperty getInstance() { + if (INSTANCE == null) { + INSTANCE = new ScanProperty(); + GregTechAPI.RECIPE_PROPERTIES.register(KEY, INSTANCE); + } + return INSTANCE; + } + + @Override + public @NotNull NBTBase serialize(@NotNull Object value) { + return new NBTTagByte((byte) (castValue(value) ? 1 : 0)); + } + + @Override + public @NotNull Object deserialize(@NotNull NBTBase nbt) { + return ((NBTTagByte) nbt).getByte() == 1; + } + + @Override + @SideOnly(Side.CLIENT) + public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { + minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.scan_for_research"), x, y, color); + } +} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/TemperatureProperty.java b/src/main/java/gregtech/api/recipes/properties/impl/TemperatureProperty.java similarity index 75% rename from src/main/java/gregtech/api/recipes/recipeproperties/TemperatureProperty.java rename to src/main/java/gregtech/api/recipes/properties/impl/TemperatureProperty.java index 0b647d69523..3764158baed 100644 --- a/src/main/java/gregtech/api/recipes/recipeproperties/TemperatureProperty.java +++ b/src/main/java/gregtech/api/recipes/properties/impl/TemperatureProperty.java @@ -1,9 +1,15 @@ -package gregtech.api.recipes.recipeproperties; +package gregtech.api.recipes.properties.impl; +import gregtech.api.GregTechAPI; +import gregtech.api.recipes.properties.RecipeProperty; import gregtech.api.unification.material.Material; import net.minecraft.client.Minecraft; import net.minecraft.client.resources.I18n; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagInt; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import org.apache.commons.lang3.Validate; import org.jetbrains.annotations.NotNull; @@ -11,7 +17,7 @@ import java.util.Map; import java.util.TreeMap; -public class TemperatureProperty extends RecipeProperty { +public final class TemperatureProperty extends RecipeProperty { public static final String KEY = "temperature"; @@ -26,11 +32,23 @@ private TemperatureProperty() { public static TemperatureProperty getInstance() { if (INSTANCE == null) { INSTANCE = new TemperatureProperty(); + GregTechAPI.RECIPE_PROPERTIES.register(KEY, INSTANCE); } return INSTANCE; } @Override + public @NotNull NBTBase serialize(@NotNull Object value) { + return new NBTTagInt(castValue(value)); + } + + @Override + public @NotNull Object deserialize(@NotNull NBTBase nbt) { + return ((NBTTagInt) nbt).getInt(); + } + + @Override + @SideOnly(Side.CLIENT) public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.temperature", value, getMinTierForTemperature(castValue(value))), x, y, color); diff --git a/src/main/java/gregtech/api/recipes/properties/impl/TotalComputationProperty.java b/src/main/java/gregtech/api/recipes/properties/impl/TotalComputationProperty.java new file mode 100644 index 00000000000..0704e44cb46 --- /dev/null +++ b/src/main/java/gregtech/api/recipes/properties/impl/TotalComputationProperty.java @@ -0,0 +1,54 @@ +package gregtech.api.recipes.properties.impl; + +import gregtech.api.GregTechAPI; +import gregtech.api.recipes.properties.RecipeProperty; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.I18n; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagInt; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; + +public final class TotalComputationProperty extends RecipeProperty { + + public static final String KEY = "total_computation"; + + private static TotalComputationProperty INSTANCE; + + private TotalComputationProperty() { + super(KEY, Integer.class); + } + + public static TotalComputationProperty getInstance() { + if (INSTANCE == null) { + INSTANCE = new TotalComputationProperty(); + GregTechAPI.RECIPE_PROPERTIES.register(KEY, INSTANCE); + } + return INSTANCE; + } + + @Override + public @NotNull NBTBase serialize(@NotNull Object value) { + return new NBTTagInt(castValue(value)); + } + + @Override + public @NotNull Object deserialize(@NotNull NBTBase nbt) { + return ((NBTTagInt) nbt).getInt(); + } + + @Override + @SideOnly(Side.CLIENT) + public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { + minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.total_computation", castValue(value)), x, y, + color); + } + + @Override + public boolean hideDuration() { + return true; + } +} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/ComputationProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/ComputationProperty.java deleted file mode 100644 index 20fa33c1a05..00000000000 --- a/src/main/java/gregtech/api/recipes/recipeproperties/ComputationProperty.java +++ /dev/null @@ -1,28 +0,0 @@ -package gregtech.api.recipes.recipeproperties; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.I18n; - -public class ComputationProperty extends RecipeProperty { - - public static final String KEY = "computation_per_tick"; - - private static ComputationProperty INSTANCE; - - protected ComputationProperty() { - super(KEY, Integer.class); - } - - public static ComputationProperty getInstance() { - if (INSTANCE == null) { - INSTANCE = new ComputationProperty(); - } - return INSTANCE; - } - - @Override - public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { - minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.computation_per_tick", castValue(value)), x, y, - color); - } -} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/DefaultProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/DefaultProperty.java deleted file mode 100644 index 9620d1b6a22..00000000000 --- a/src/main/java/gregtech/api/recipes/recipeproperties/DefaultProperty.java +++ /dev/null @@ -1,16 +0,0 @@ -package gregtech.api.recipes.recipeproperties; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.I18n; - -public class DefaultProperty extends RecipeProperty { - - public DefaultProperty(String key, Class type) { - super(key, type); - } - - public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { - minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe." + getKey(), - castValue(value)), x, y, color); - } -} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/EmptyRecipePropertyStorage.java b/src/main/java/gregtech/api/recipes/recipeproperties/EmptyRecipePropertyStorage.java deleted file mode 100644 index 89f6bb201d6..00000000000 --- a/src/main/java/gregtech/api/recipes/recipeproperties/EmptyRecipePropertyStorage.java +++ /dev/null @@ -1,65 +0,0 @@ -package gregtech.api.recipes.recipeproperties; - -import java.util.Collections; -import java.util.Map; -import java.util.Set; - -public final class EmptyRecipePropertyStorage implements IRecipePropertyStorage { - - public static final EmptyRecipePropertyStorage INSTANCE = new EmptyRecipePropertyStorage(); - - private EmptyRecipePropertyStorage() {} - - @Override - public boolean store(RecipeProperty recipeProperty, Object value) { - return false; - } - - @Override - public boolean remove(RecipeProperty recipeProperty) { - return false; - } - - @Override - public void freeze(boolean frozen) {} - - @Override - public IRecipePropertyStorage copy() { - return null; // Fresh for RecipeBuilder to handle - } - - @Override - public int getSize() { - return 0; - } - - @Override - public Set, Object>> getRecipeProperties() { - return Collections.emptySet(); - } - - @Override - public T getRecipePropertyValue(RecipeProperty recipeProperty, T defaultValue) { - return defaultValue; - } - - @Override - public boolean hasRecipeProperty(RecipeProperty recipeProperty) { - return false; - } - - @Override - public Set getRecipePropertyKeys() { - return Collections.emptySet(); - } - - @Override - public Set> getPropertyTypes() { - return Collections.emptySet(); - } - - @Override - public Object getRawRecipePropertyValue(String key) { - return null; - } -} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/GasCollectorDimensionProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/GasCollectorDimensionProperty.java deleted file mode 100644 index 94bb810e3b1..00000000000 --- a/src/main/java/gregtech/api/recipes/recipeproperties/GasCollectorDimensionProperty.java +++ /dev/null @@ -1,48 +0,0 @@ -package gregtech.api.recipes.recipeproperties; - -import gregtech.api.worldgen.config.WorldGenRegistry; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.I18n; - -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.IntList; - -public class GasCollectorDimensionProperty extends RecipeProperty { - - public static final String KEY = "dimension"; - - private static GasCollectorDimensionProperty INSTANCE; - - private GasCollectorDimensionProperty() { - super(KEY, IntList.class); - } - - public static GasCollectorDimensionProperty getInstance() { - if (INSTANCE == null) - INSTANCE = new GasCollectorDimensionProperty(); - return INSTANCE; - } - - @Override - public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { - minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.dimensions", - getDimensionsForRecipe(castValue(value))), x, y, color); - } - - private static String getDimensionsForRecipe(IntList value) { - Int2ObjectMap dimNames = WorldGenRegistry.getNamedDimensions(); - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < value.size(); i++) { - builder.append(dimNames.getOrDefault(value.getInt(i), String.valueOf(value.getInt(i)))); - if (i != value.size() - 1) - builder.append(", "); - } - String str = builder.toString(); - - if (str.length() >= 13) { - str = str.substring(0, 10) + ".."; - } - return str; - } -} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/IRecipePropertyStorage.java b/src/main/java/gregtech/api/recipes/recipeproperties/IRecipePropertyStorage.java deleted file mode 100644 index 234434bf003..00000000000 --- a/src/main/java/gregtech/api/recipes/recipeproperties/IRecipePropertyStorage.java +++ /dev/null @@ -1,62 +0,0 @@ -package gregtech.api.recipes.recipeproperties; - -import java.util.Map; -import java.util.Set; - -public interface IRecipePropertyStorage { - - String STACKTRACE = "Stacktrace:"; - - /** - * Stores new {@link RecipeProperty} with value - * - * @param recipeProperty {@link RecipeProperty} - * @param value value - * @return {@code true} if store succeeds; otherwise {@code false} - */ - boolean store(RecipeProperty recipeProperty, Object value); - - boolean remove(RecipeProperty recipeProperty); - - void freeze(boolean frozen); - - IRecipePropertyStorage copy(); - - /** - * Provides information how many {@link RecipeProperty} are stored - * - * @return number of stored {@link RecipeProperty} - */ - int getSize(); - - /** - * Provides all stored {@link RecipeProperty} - * - * @return all stored {@link RecipeProperty} and values - */ - Set, Object>> getRecipeProperties(); - - /** - * Provides casted value for one specific {@link RecipeProperty} if is stored or defaultValue - * - * @param recipeProperty {@link RecipeProperty} - * @param defaultValue Default value if recipeProperty is not found - * @param Type of returned value - * @return value tied with provided recipeProperty on success; otherwise defaultValue - */ - T getRecipePropertyValue(RecipeProperty recipeProperty, T defaultValue); - - boolean hasRecipeProperty(RecipeProperty recipeProperty); - - Set getRecipePropertyKeys(); - - Set> getPropertyTypes(); - - /** - * Provides un-casted value for one specific {@link RecipeProperty} searched by key - * - * @param key Key of stored {@link RecipeProperty} - * @return {@link Object} value on success; otherwise {@code null} - */ - Object getRawRecipePropertyValue(String key); -} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/ImplosionExplosiveProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/ImplosionExplosiveProperty.java deleted file mode 100644 index 725129e8843..00000000000 --- a/src/main/java/gregtech/api/recipes/recipeproperties/ImplosionExplosiveProperty.java +++ /dev/null @@ -1,35 +0,0 @@ -package gregtech.api.recipes.recipeproperties; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.I18n; -import net.minecraft.item.ItemStack; - -public class ImplosionExplosiveProperty extends RecipeProperty { - - public static final String KEY = "explosives"; - - private static ImplosionExplosiveProperty INSTANCE; - - private ImplosionExplosiveProperty() { - super(KEY, ItemStack.class); - } - - public static ImplosionExplosiveProperty getInstance() { - if (INSTANCE == null) { - INSTANCE = new ImplosionExplosiveProperty(); - } - - return INSTANCE; - } - - @Override - public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { - minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.explosive", - ((ItemStack) value).getDisplayName()), x, y, color); - } - - @Override - public boolean isHidden() { - return true; - } -} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/PrimitiveProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/PrimitiveProperty.java deleted file mode 100644 index 524fd7180fe..00000000000 --- a/src/main/java/gregtech/api/recipes/recipeproperties/PrimitiveProperty.java +++ /dev/null @@ -1,36 +0,0 @@ -package gregtech.api.recipes.recipeproperties; - -import net.minecraft.client.Minecraft; - -/** - * Simple Marker Property to tell JEI to not display Total EU and EU/t. - */ -public class PrimitiveProperty extends RecipeProperty { - - public static final String KEY = "primitive_property"; - private static PrimitiveProperty INSTANCE; - - private PrimitiveProperty() { - super(KEY, Boolean.class); - } - - public static PrimitiveProperty getInstance() { - if (INSTANCE == null) { - INSTANCE = new PrimitiveProperty(); - } - return INSTANCE; - } - - @Override - public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) {} - - @Override - public boolean hideTotalEU() { - return true; - } - - @Override - public boolean hideEUt() { - return true; - } -} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/RecipePropertyStorage.java b/src/main/java/gregtech/api/recipes/recipeproperties/RecipePropertyStorage.java deleted file mode 100644 index a74ba78da6d..00000000000 --- a/src/main/java/gregtech/api/recipes/recipeproperties/RecipePropertyStorage.java +++ /dev/null @@ -1,135 +0,0 @@ -package gregtech.api.recipes.recipeproperties; - -import gregtech.api.util.GTLog; - -import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; - -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -public class RecipePropertyStorage implements IRecipePropertyStorage { - - private final Map, Object> recipeProperties; - - private boolean frozen = false; - - public RecipePropertyStorage() { - recipeProperties = new Object2ObjectArrayMap<>(1); - } - - private RecipePropertyStorage(Map, Object> recipeProperties) { - this(); - this.recipeProperties.putAll(recipeProperties); - } - - @Override - public boolean store(RecipeProperty recipeProperty, Object value) { - boolean success = true; - String key = recipeProperty.getKey(); - if (frozen) { - GTLog.logger.warn("Unable to add RecipeProperty with key {} as the storage is frozen", key); - success = false; - } - for (RecipeProperty existingRecipeProperty : recipeProperties.keySet()) { - if (existingRecipeProperty.getKey().equals(key)) { - GTLog.logger.warn("Unable to add RecipeProperty with key {} as it already exists", key); - success = false; - } - } - - if (value == null) { - GTLog.logger.warn("Provided value is null for RecipeProperty with key {}", key); - success = false; - } - - try { - recipeProperty.castValue(value); - } catch (ClassCastException ex) { - GTLog.logger.warn("Provided incorrect value for RecipeProperty with key {}", key); - GTLog.logger.warn("Full exception:", ex); - success = false; - } - - if (success) { - recipeProperties.put(recipeProperty, value); - } else { - GTLog.logger.warn(STACKTRACE, new IllegalArgumentException()); - } - - return success; - } - - @Override - public boolean remove(RecipeProperty recipeProperty) { - return this.recipeProperties.remove(recipeProperty) != null; - } - - @Override - public void freeze(boolean frozen) { - this.frozen = frozen; - } - - @Override - public IRecipePropertyStorage copy() { - return new RecipePropertyStorage(this.recipeProperties); - } - - @Override - public int getSize() { - return recipeProperties.size(); - } - - @Override - public Set, Object>> getRecipeProperties() { - return this.recipeProperties.entrySet(); - } - - @Override - public T getRecipePropertyValue(RecipeProperty recipeProperty, T defaultValue) { - Object value = recipeProperties.get(recipeProperty); - - if (value == null) { - return defaultValue; - } - - return recipeProperty.castValue(value); - } - - public boolean hasRecipeProperty(RecipeProperty recipeProperty) { - return recipeProperties.containsKey(recipeProperty); - } - - @Override - public Set getRecipePropertyKeys() { - HashSet keys = new HashSet<>(); - - recipeProperties.keySet().forEach(recipeProperty -> keys.add(recipeProperty.getKey())); - - return keys; - } - - @Override - public Set> getPropertyTypes() { - return recipeProperties.keySet(); - } - - @Override - public Object getRawRecipePropertyValue(String key) { - RecipeProperty recipeProperty = getRecipePropertyValue(key); - if (recipeProperty != null) { - return recipeProperties.get(recipeProperty); - } - - return null; - } - - private RecipeProperty getRecipePropertyValue(String key) { - for (RecipeProperty recipeProperty : recipeProperties.keySet()) { - if (recipeProperty.getKey().equals(key)) - return recipeProperty; - } - - return null; - } -} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/ResearchProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/ResearchProperty.java deleted file mode 100644 index 510ed5eaa71..00000000000 --- a/src/main/java/gregtech/api/recipes/recipeproperties/ResearchProperty.java +++ /dev/null @@ -1,30 +0,0 @@ -package gregtech.api.recipes.recipeproperties; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.I18n; - -import org.jetbrains.annotations.NotNull; - -public final class ResearchProperty extends RecipeProperty { - - public static final String KEY = "research"; - - private static ResearchProperty INSTANCE; - - private ResearchProperty() { - super(KEY, ResearchPropertyData.class); - } - - @NotNull - public static ResearchProperty getInstance() { - if (INSTANCE == null) { - INSTANCE = new ResearchProperty(); - } - return INSTANCE; - } - - @Override - public void drawInfo(@NotNull Minecraft minecraft, int x, int y, int color, Object value) { - minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.research"), x, y, color); - } -} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/ScanProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/ScanProperty.java deleted file mode 100644 index 3548c982fa8..00000000000 --- a/src/main/java/gregtech/api/recipes/recipeproperties/ScanProperty.java +++ /dev/null @@ -1,30 +0,0 @@ -package gregtech.api.recipes.recipeproperties; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.I18n; - -import org.jetbrains.annotations.NotNull; - -public class ScanProperty extends RecipeProperty { - - public static final String KEY = "scan"; - - private static ScanProperty INSTANCE; - - private ScanProperty() { - super(KEY, Boolean.class); - } - - @NotNull - public static ScanProperty getInstance() { - if (INSTANCE == null) { - INSTANCE = new ScanProperty(); - } - return INSTANCE; - } - - @Override - public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { - minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.scan_for_research"), x, y, color); - } -} diff --git a/src/main/java/gregtech/api/recipes/recipeproperties/TotalComputationProperty.java b/src/main/java/gregtech/api/recipes/recipeproperties/TotalComputationProperty.java deleted file mode 100644 index 3557539d1ee..00000000000 --- a/src/main/java/gregtech/api/recipes/recipeproperties/TotalComputationProperty.java +++ /dev/null @@ -1,33 +0,0 @@ -package gregtech.api.recipes.recipeproperties; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.I18n; - -public class TotalComputationProperty extends RecipeProperty { - - public static final String KEY = "total_computation"; - - private static TotalComputationProperty INSTANCE; - - protected TotalComputationProperty() { - super(KEY, Integer.class); - } - - public static TotalComputationProperty getInstance() { - if (INSTANCE == null) { - INSTANCE = new TotalComputationProperty(); - } - return INSTANCE; - } - - @Override - public void drawInfo(Minecraft minecraft, int x, int y, int color, Object value) { - minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.total_computation", castValue(value)), x, y, - color); - } - - @Override - public boolean hideDuration() { - return true; - } -} diff --git a/src/main/java/gregtech/api/recipes/ui/RecipeMapUI.java b/src/main/java/gregtech/api/recipes/ui/RecipeMapUI.java index 569efa103b6..a6d66d3e62e 100644 --- a/src/main/java/gregtech/api/recipes/ui/RecipeMapUI.java +++ b/src/main/java/gregtech/api/recipes/ui/RecipeMapUI.java @@ -34,6 +34,8 @@ public class RecipeMapUI> { private final boolean modifyFluidInputs; private final boolean modifyFluidOutputs; + private final boolean isGenerator; + private TextureArea progressBarTexture = GuiTextures.PROGRESS_BAR_ARROW; private ProgressWidget.MoveType moveType = ProgressWidget.MoveType.HORIZONTAL; private @Nullable TextureArea specialTexture; @@ -49,12 +51,13 @@ public class RecipeMapUI> { * @param modifyFluidOutputs if fluid output amounts can be modified */ public RecipeMapUI(@NotNull R recipeMap, boolean modifyItemInputs, boolean modifyItemOutputs, - boolean modifyFluidInputs, boolean modifyFluidOutputs) { + boolean modifyFluidInputs, boolean modifyFluidOutputs, boolean isGenerator) { this.recipeMap = recipeMap; this.modifyItemInputs = modifyItemInputs; this.modifyItemOutputs = modifyItemOutputs; this.modifyFluidInputs = modifyFluidInputs; this.modifyFluidOutputs = modifyFluidOutputs; + this.isGenerator = isGenerator; } /** @@ -280,8 +283,10 @@ public int getPropertyHeightShift() { int maxPropertyCount = 0; if (shouldShiftWidgets()) { for (Recipe recipe : recipeMap.getRecipeList()) { - if (recipe.getPropertyCount() > maxPropertyCount) - maxPropertyCount = recipe.getPropertyCount(); + int count = recipe.propertyStorage().size(); + if (count > maxPropertyCount) { + maxPropertyCount = count; + } } } return maxPropertyCount * 10; // GTRecipeWrapper#LINE_HEIGHT @@ -423,6 +428,13 @@ public boolean canModifyFluidOutputs() { return modifyFluidOutputs; } + /** + * @return if this UI represents an energy generating recipemap + */ + public boolean isGenerator() { + return isGenerator; + } + /** * @param texture the texture to set * @param isOutput if the slot is an output slot diff --git a/src/main/java/gregtech/api/recipes/ui/impl/AssemblyLineUI.java b/src/main/java/gregtech/api/recipes/ui/impl/AssemblyLineUI.java index 244bba47b35..adc2e1ff50b 100644 --- a/src/main/java/gregtech/api/recipes/ui/impl/AssemblyLineUI.java +++ b/src/main/java/gregtech/api/recipes/ui/impl/AssemblyLineUI.java @@ -20,7 +20,7 @@ public final class AssemblyLineUI> extends RecipeMapUI * @param recipeMap the recipemap corresponding to this ui */ public AssemblyLineUI(@NotNull R recipeMap) { - super(recipeMap, false, false, false, false); + super(recipeMap, false, false, false, false, false); setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, ProgressWidget.MoveType.HORIZONTAL); } diff --git a/src/main/java/gregtech/api/recipes/ui/impl/CokeOvenUI.java b/src/main/java/gregtech/api/recipes/ui/impl/CokeOvenUI.java index 910d4e4908b..3d453bfe012 100644 --- a/src/main/java/gregtech/api/recipes/ui/impl/CokeOvenUI.java +++ b/src/main/java/gregtech/api/recipes/ui/impl/CokeOvenUI.java @@ -19,7 +19,7 @@ public class CokeOvenUI> extends RecipeMapUI { * @param recipeMap the recipemap corresponding to this ui */ public CokeOvenUI(@NotNull R recipeMap) { - super(recipeMap, false, false, false, false); + super(recipeMap, false, false, false, false, false); } @Override diff --git a/src/main/java/gregtech/api/recipes/ui/impl/CrackerUnitUI.java b/src/main/java/gregtech/api/recipes/ui/impl/CrackerUnitUI.java index fb4a6698e40..9544113498d 100644 --- a/src/main/java/gregtech/api/recipes/ui/impl/CrackerUnitUI.java +++ b/src/main/java/gregtech/api/recipes/ui/impl/CrackerUnitUI.java @@ -21,7 +21,7 @@ public class CrackerUnitUI> extends RecipeMapUI { public CrackerUnitUI(@NotNull R recipeMap) { - super(recipeMap, true, true, false, true); + super(recipeMap, true, true, false, true, false); setFluidSlotOverlay(GuiTextures.CRACKING_OVERLAY_1, false); setFluidSlotOverlay(GuiTextures.CRACKING_OVERLAY_2, true); setItemSlotOverlay(GuiTextures.CIRCUIT_OVERLAY, false); diff --git a/src/main/java/gregtech/api/recipes/ui/impl/DistillationTowerUI.java b/src/main/java/gregtech/api/recipes/ui/impl/DistillationTowerUI.java index f87d1767ac1..e11f636fe6a 100644 --- a/src/main/java/gregtech/api/recipes/ui/impl/DistillationTowerUI.java +++ b/src/main/java/gregtech/api/recipes/ui/impl/DistillationTowerUI.java @@ -17,7 +17,7 @@ public class DistillationTowerUI> extends RecipeMapUI { public DistillationTowerUI(@NotNull R recipeMap) { - super(recipeMap, true, true, true, false); + super(recipeMap, true, true, true, false, false); } @Override diff --git a/src/main/java/gregtech/api/recipes/ui/impl/FormingPressUI.java b/src/main/java/gregtech/api/recipes/ui/impl/FormingPressUI.java index 7d63ff00da7..1ef4fbdcc31 100644 --- a/src/main/java/gregtech/api/recipes/ui/impl/FormingPressUI.java +++ b/src/main/java/gregtech/api/recipes/ui/impl/FormingPressUI.java @@ -18,7 +18,7 @@ public class FormingPressUI> extends RecipeMapUI { public FormingPressUI(@NotNull R recipeMap) { - super(recipeMap, true, true, true, true); + super(recipeMap, true, true, true, true, false); setProgressBar(GuiTextures.PROGRESS_BAR_COMPRESS, ProgressWidget.MoveType.HORIZONTAL); } diff --git a/src/main/java/gregtech/api/recipes/ui/impl/ResearchStationUI.java b/src/main/java/gregtech/api/recipes/ui/impl/ResearchStationUI.java index 917fc953dab..6ba9dc82e48 100644 --- a/src/main/java/gregtech/api/recipes/ui/impl/ResearchStationUI.java +++ b/src/main/java/gregtech/api/recipes/ui/impl/ResearchStationUI.java @@ -22,7 +22,7 @@ public class ResearchStationUI> extends RecipeMapUI { public ResearchStationUI(@NotNull R recipeMap) { - super(recipeMap, true, true, true, true); + super(recipeMap, true, true, true, true, false); setItemSlotOverlay(GuiTextures.SCANNER_OVERLAY, false); setItemSlotOverlay(GuiTextures.RESEARCH_STATION_OVERLAY, true); setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, ProgressWidget.MoveType.HORIZONTAL); @@ -39,11 +39,11 @@ public ModularUI.Builder createJeiUITemplate(IItemHandlerModifiable importItems, GuiTextures.PROGRESS_BAR_RESEARCH_STATION_1, ProgressWidget.MoveType.HORIZONTAL)) .widget(new ProgressWidget(pairedSuppliers.getRight(), 119, 32, 10, 18, GuiTextures.PROGRESS_BAR_RESEARCH_STATION_2, ProgressWidget.MoveType.VERTICAL_DOWNWARDS)) - .widget(new SlotWidget(importItems, 0, 115, 50, true, true) + .widget(new SlotWidget(exportItems, 0, 115, 50, true, true) .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.DATA_ORB_OVERLAY)) .widget(new SlotWidget(importItems, 1, 43, 21, true, true) .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.SCANNER_OVERLAY)) - .widget(new SlotWidget(exportItems, 0, 97, 21, true, true) + .widget(new SlotWidget(importItems, 0, 97, 21, true, true) .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.RESEARCH_STATION_OVERLAY)); } } diff --git a/src/main/java/gregtech/api/terminal/TerminalRegistry.java b/src/main/java/gregtech/api/terminal/TerminalRegistry.java deleted file mode 100644 index 6da73912e23..00000000000 --- a/src/main/java/gregtech/api/terminal/TerminalRegistry.java +++ /dev/null @@ -1,346 +0,0 @@ -package gregtech.api.terminal; - -import gregtech.api.GTValues; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.hardware.Hardware; -import gregtech.api.util.FileUtility; -import gregtech.api.util.GTLog; -import gregtech.common.ConfigHolder; -import gregtech.common.items.MetaItems; -import gregtech.common.terminal.app.VirtualTankApp; -import gregtech.common.terminal.app.appstore.AppStoreApp; -import gregtech.common.terminal.app.batterymanager.BatteryManagerApp; -import gregtech.common.terminal.app.capeselector.CapeSelectorApp; -import gregtech.common.terminal.app.console.ConsoleApp; -import gregtech.common.terminal.app.game.maze.MazeApp; -import gregtech.common.terminal.app.game.minesweeper.MinesweeperApp; -import gregtech.common.terminal.app.game.pong.PongApp; -import gregtech.common.terminal.app.guide.ItemGuideApp; -import gregtech.common.terminal.app.guide.MultiBlockGuideApp; -import gregtech.common.terminal.app.guide.SimpleMachineGuideApp; -import gregtech.common.terminal.app.guide.TutorialGuideApp; -import gregtech.common.terminal.app.guideeditor.GuideEditorApp; -import gregtech.common.terminal.app.hardwaremanager.HardwareManagerApp; -import gregtech.common.terminal.app.multiblockhelper.MultiBlockPreviewARApp; -import gregtech.common.terminal.app.prospector.ProspectorApp; -import gregtech.common.terminal.app.prospector.ProspectorMode; -import gregtech.common.terminal.app.recipechart.RecipeChartApp; -import gregtech.common.terminal.app.settings.SettingsApp; -import gregtech.common.terminal.app.teleport.TeleportApp; -import gregtech.common.terminal.app.worldprospector.WorldProspectorARApp; -import gregtech.common.terminal.hardware.BatteryHardware; -import gregtech.common.terminal.hardware.DeviceHardware; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.IResourceManager; -import net.minecraft.client.resources.SimpleReloadableResourceManager; -import net.minecraft.init.Items; -import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.util.*; -import java.util.stream.Collectors; - -public class TerminalRegistry { - - public static final Map APP_REGISTER = new LinkedHashMap<>(); - public static final Map HW_REGISTER = new LinkedHashMap<>(); - public static final Map[]> APP_HW_DEMAND = new HashMap<>(); - public static final Map[]> APP_UPGRADE_CONDITIONS = new HashMap<>(); - public static final List DEFAULT_APPS = new ArrayList<>(); - @SideOnly(Side.CLIENT) - public static File TERMINAL_PATH; - - static { - if (FMLCommonHandler.instance().getSide().isClient()) { - TERMINAL_PATH = new File(Loader.instance().getConfigDir(), ConfigHolder.client.terminalRootPath); - } - } - - public static void init() { - // register hardware - registerHardware(new BatteryHardware()); - int deviceSize = DeviceHardware.DEVICE.values().length; - for (int i = 1; i < deviceSize; i++) { - registerHardware(new DeviceHardware(i)); - } - // register applications - AppRegistryBuilder.create(new SimpleMachineGuideApp()).defaultApp().build(); - AppRegistryBuilder.create(new MultiBlockGuideApp()).defaultApp().build(); - AppRegistryBuilder.create(new ItemGuideApp()).defaultApp().build(); - AppRegistryBuilder.create(new TutorialGuideApp()).defaultApp().build(); - AppRegistryBuilder.create(new GuideEditorApp()).defaultApp().build(); - AppRegistryBuilder.create(new SettingsApp()).defaultApp().build(); - AppRegistryBuilder.create(new CapeSelectorApp()).defaultApp().build(); - - AppRegistryBuilder.create(new TeleportApp()) - .battery(GTValues.ZPM, 10000) - .device(DeviceHardware.DEVICE.FIELD_GENERATOR_UV) - .build(); - - AppRegistryBuilder.create(new PongApp()) - .battery(GTValues.LV, 75) - .build(); - AppRegistryBuilder.create(new MazeApp()) - .battery(GTValues.LV, 150) - .build(); - AppRegistryBuilder.create(new MinesweeperApp()) - .battery(GTValues.LV, 150) - .build(); - - AppRegistryBuilder.create(new ProspectorApp(ProspectorMode.ORE)) - .battery(0, GTValues.LV, 640) - .battery(1, GTValues.LV, 640) - .battery(2, GTValues.MV, 1000) - .battery(3, GTValues.HV, 1500) - .battery(4, GTValues.HV, 1500) - .upgrade(0, MetaItems.SENSOR_LV.getStackForm(1)) - .upgrade(1, MetaItems.SENSOR_HV.getStackForm(1)) - .upgrade(2, MetaItems.SENSOR_EV.getStackForm(1)) - .upgrade(3, MetaItems.SENSOR_IV.getStackForm(1)) - .upgrade(4, MetaItems.SENSOR_LuV.getStackForm(1)) - .device(0, DeviceHardware.DEVICE.PROSPECTOR_LV) - .device(1, DeviceHardware.DEVICE.PROSPECTOR_LV) - .device(2, DeviceHardware.DEVICE.PROSPECTOR_LV) - .device(3, DeviceHardware.DEVICE.PROSPECTOR_HV) - .device(4, DeviceHardware.DEVICE.PROSPECTOR_HV) - .build(); - - AppRegistryBuilder.create(new ProspectorApp(ProspectorMode.FLUID)) - .battery(0, GTValues.MV, 1000) - .battery(1, GTValues.MV, 1000) - .battery(2, GTValues.HV, 1500) - .battery(3, GTValues.HV, 1500) - .battery(4, GTValues.HV, 1500) - .upgrade(0, MetaItems.SENSOR_HV.getStackForm(1)) - .upgrade(1, MetaItems.SENSOR_HV.getStackForm(3)) - .upgrade(2, MetaItems.SENSOR_EV.getStackForm(1)) - .upgrade(3, MetaItems.SENSOR_IV.getStackForm(1)) - .upgrade(4, MetaItems.SENSOR_LuV.getStackForm(1)) - .device(DeviceHardware.DEVICE.PROSPECTOR_HV) - .build(); - AppRegistryBuilder.create(new MultiBlockPreviewARApp()) - .battery(GTValues.LV, 128) - .device(DeviceHardware.DEVICE.CAMERA) - .upgrade(1, MetaItems.EMITTER_HV.getStackForm(4), MetaItems.WORKSTATION_EV.getStackForm(2)) - .defaultApp() - .build(); - if (Loader.isModLoaded(GTValues.MODID_JEI)) { - AppRegistryBuilder.create(new RecipeChartApp()) - .battery(GTValues.LV, 160) - .upgrade(0, new ItemStack(Items.PAPER, 32)) - .upgrade(1, new ItemStack(Items.PAPER, 64)) - .upgrade(2, MetaItems.RANDOM_ACCESS_MEMORY.getStackForm(16)) - .upgrade(3, MetaItems.RANDOM_ACCESS_MEMORY.getStackForm(32)) - .build(); - } - AppRegistryBuilder.create(new ConsoleApp()) - .battery(GTValues.LV, 500) - .device(DeviceHardware.DEVICE.WIRELESS) - .build(); - AppRegistryBuilder.create(new BatteryManagerApp()).defaultApp() - .battery(GTValues.ULV, 0) - .build(); - AppRegistryBuilder.create(new HardwareManagerApp()).defaultApp().build(); - AppRegistryBuilder.create(new AppStoreApp()).defaultApp().build(); - AppRegistryBuilder.create(new WorldProspectorARApp()) - .battery(GTValues.LV, 320) - .upgrade(0, MetaItems.EMITTER_LV.getStackForm(2)) - .upgrade(1, MetaItems.EMITTER_MV.getStackForm(2)) - .upgrade(2, MetaItems.EMITTER_HV.getStackForm(2)) - .device(DeviceHardware.DEVICE.CAMERA) - .build(); - AppRegistryBuilder.create(new VirtualTankApp()) - .battery(GTValues.MV, 500) - .device(DeviceHardware.DEVICE.WIRELESS) - .build(); - } - - @SideOnly(Side.CLIENT) - public static void initTerminalFiles() { - ((SimpleReloadableResourceManager) Minecraft.getMinecraft().getResourceManager()) - .registerReloadListener(TerminalRegistry::onResourceManagerReload); - } - - @SideOnly(Side.CLIENT) - public static void onResourceManagerReload(IResourceManager resourceManager) { - FileUtility.extractJarFiles(String.format("/assets/%s/%s", GTValues.MODID, "terminal"), TERMINAL_PATH, false); - } - - public static void registerApp(AbstractApplication application) { - String name = application.getRegistryName(); - if (APP_REGISTER.containsKey(name)) { - GTLog.logger.warn("Duplicate APP registry names exist: {}", name); - return; - } - APP_REGISTER.put(name, application); - } - - public static void registerHardware(Hardware hardware) { - String name = hardware.getRegistryName(); - if (APP_REGISTER.containsKey(name)) { - GTLog.logger.warn("Duplicate APP registry names exist: {}", name); - return; - } - HW_REGISTER.put(name, hardware); - } - - public static void registerHardwareDemand(String name, boolean isDefaultApp, @NotNull List[] hardware, - @NotNull List[] upgrade) { - if (name != null && APP_REGISTER.containsKey(name)) { - if (isDefaultApp) { - DEFAULT_APPS.add(name); - } - APP_HW_DEMAND.put(name, hardware); - APP_UPGRADE_CONDITIONS.put(name, upgrade); - } else { - GTLog.logger.error("Not found the app {}", name); - } - } - - public static List getDefaultApps() { - return DEFAULT_APPS.stream().map(APP_REGISTER::get).collect(Collectors.toList()); - } - - public static Collection getAllApps() { - return APP_REGISTER.values(); - } - - public static AbstractApplication getApplication(String name) { - return APP_REGISTER.get(name); - } - - public static Collection getAllHardware() { - return HW_REGISTER.values(); - } - - public static Hardware getHardware(String name) { - return HW_REGISTER.get(name); - } - - public static List getAppHardwareDemand(String name, int tier) { - return APP_HW_DEMAND.get(name)[tier] != null ? APP_HW_DEMAND.get(name)[tier] : Collections.emptyList(); - } - - public static List getAppHardwareUpgradeConditions(String name, int tier) { - return APP_UPGRADE_CONDITIONS.get(name)[tier] != null ? APP_UPGRADE_CONDITIONS.get(name)[tier] : - Collections.emptyList(); - } - - private static class AppRegistryBuilder { - - AbstractApplication app; - boolean isDefaultApp; - BatteryHardware[] battery; - List[] hardware; - List[] upgrade; - - public static AppRegistryBuilder create(AbstractApplication app) { - AppRegistryBuilder builder = new AppRegistryBuilder(); - builder.app = app; - builder.battery = new BatteryHardware[app.getMaxTier() + 1]; - builder.hardware = new List[app.getMaxTier() + 1]; - builder.upgrade = new List[app.getMaxTier() + 1]; - return builder; - } - - public AppRegistryBuilder defaultApp() { - this.isDefaultApp = true; - return this; - } - - public AppRegistryBuilder battery(int batteryTier, long cost) { - BatteryHardware hw = new BatteryHardware.BatteryDemand(batteryTier, cost); - for (int i = 0; i <= app.getMaxTier(); i++) { - battery[i] = hw; - } - return this; - } - - public AppRegistryBuilder battery(int tier, int batteryTier, long cost) { - if (tier < battery.length) { - battery[tier] = new BatteryHardware.BatteryDemand(batteryTier, cost); - } - return this; - } - - public AppRegistryBuilder device(DeviceHardware.DEVICE... device) { - Hardware[] hw = Arrays.stream(device).map(DeviceHardware.DeviceDemand::new).toArray(Hardware[]::new); - for (int i = 0; i <= app.getMaxTier(); i++) { - this.hardware(i, hw); - } - return this; - } - - public AppRegistryBuilder device(int tier, DeviceHardware.DEVICE... device) { - this.hardware(tier, Arrays.stream(device).map(DeviceHardware.DeviceDemand::new).toArray(Hardware[]::new)); - return this; - } - - public AppRegistryBuilder hardware(Hardware... hardware) { - for (int i = 0; i <= app.getMaxTier(); i++) { - this.hardware(i, hardware); - } - return this; - } - - public AppRegistryBuilder hardware(int tier, Hardware... hardware) { - if (tier < this.hardware.length) { - this.hardware[tier] = new LinkedList<>(); - for (Hardware hw : hardware) { - this.hardware[tier].add(hw); - } - } - return this; - } - - public AppRegistryBuilder appendHardware(int tier, Hardware... hardware) { - if (tier < this.hardware.length) { - if (this.hardware[tier] == null) { - this.hardware[tier] = new LinkedList<>(); - } - for (Hardware hw : hardware) { - this.hardware[tier].add(hw); - } - } - return this; - } - - public AppRegistryBuilder upgrade(ItemStack... upgrade) { - ItemStack[] up = Arrays.stream(upgrade).toArray(ItemStack[]::new); - for (int i = 0; i <= app.getMaxTier(); i++) { - this.upgrade(i, up); - } - return this; - } - - public AppRegistryBuilder upgrade(int tier, ItemStack... upgrade) { - if (tier < this.upgrade.length) { - this.upgrade[tier] = new LinkedList<>(); - for (ItemStack up : upgrade) { - this.upgrade[tier].add(up); - } - } - return this; - } - - public void build() { - TerminalRegistry.registerApp(app); - for (int i = 0; i < hardware.length; i++) { - if (battery[i] != null) { - if (hardware[i] == null) { - hardware[i] = new LinkedList<>(); - } - hardware[i].add(battery[i]); - } - } - TerminalRegistry.registerHardwareDemand(app.getRegistryName(), isDefaultApp, hardware, upgrade); - } - } -} diff --git a/src/main/java/gregtech/api/terminal/app/ARApplication.java b/src/main/java/gregtech/api/terminal/app/ARApplication.java deleted file mode 100644 index c5bd9a4e564..00000000000 --- a/src/main/java/gregtech/api/terminal/app/ARApplication.java +++ /dev/null @@ -1,104 +0,0 @@ -package gregtech.api.terminal.app; - -import gregtech.api.terminal.os.SystemCall; -import gregtech.common.items.behaviors.TerminalBehaviour; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraftforge.client.event.RenderWorldLastEvent; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -/** - * Created with IntelliJ IDEA. - * - * @Author: KilaBash - * @Date: 2021/09/13 - * @Description: Application for AR. - * When AR is running, {@link #tickAR(EntityPlayer)} and {@link #drawARScreen(RenderWorldLastEvent)} will - * be called when you hold the terminal in one of your hands. - * Therefore, at most one AR app is active on the terminal at any one time. And when you open the terminal - * GUI it automatically closes the currently running AR. - * You have access to the app's NBT of the handheld terminal when the AR is active, to load configs, init - * and so on. - * Don't try to write NBT, you should always be aware that the AR is running on the client side. - * if you really want to do something on the server side when AR is running, plz send packets. Because - * it's always running on the client side!!!!!!!!!! - * (If you need data from NBT, dont forget to write nbt when closeApp {@link #closeApp()}) - */ -public abstract class ARApplication extends AbstractApplication { - - protected ItemStack heldStack; - - public ARApplication(String name) { - super(name); - } - - @Override - public int getAppTier() { - if (nbt != null) { - if (os != null) { - return super.getAppTier(); - } else if (TerminalBehaviour.isCreative(heldStack)) { - return getMaxTier(); - } - return Math.min(nbt.getInteger("_tier"), getMaxTier()); - } - return 0; - } - - @SideOnly(Side.CLIENT) - public final void setAROpened(ItemStack heldStack) { - this.heldStack = heldStack; - this.nbt = heldStack.getOrCreateSubCompound("terminal").getCompoundTag(getRegistryName()); - } - - @Override - public AbstractApplication initApp() { - openAR(); - return this; - } - - /** - * open Camera for this AR and shutdown. - * then, this AR will be in active and running on the client side. - * It is best to call it on both sides. - */ - protected final void openAR() { - os.tabletNBT.setString("_ar", getRegistryName()); - if (isClient) { - SystemCall.SHUT_DOWN.call(getOs(), true); - } - } - - /** - * this will be fired every time you first switch selected slot to the held terminal. - */ - @SideOnly(Side.CLIENT) - public void onAROpened() {} - - /** - * this will be fired when switch the current slot (terminal) to other slots or open this terminal. - */ - @SideOnly(Side.CLIENT) - public void onARClosed() { - nbt = null; - heldStack = null; - } - - /** - * Be careful! do not try to use non-static field or call a non-static function here. - * This method is called with the registered instance. - * {@link gregtech.api.terminal.TerminalRegistry#registerApp(AbstractApplication)} - */ - @SideOnly(Side.CLIENT) - public void tickAR(EntityPlayer player) {} - - /** - * Be careful! do not try to use non-static field or call a non-static function here. - * This method is called with the registered instance. - * {@link gregtech.api.terminal.TerminalRegistry#registerApp(AbstractApplication)} - */ - @SideOnly(Side.CLIENT) - public abstract void drawARScreen(RenderWorldLastEvent event); -} diff --git a/src/main/java/gregtech/api/terminal/app/AbstractApplication.java b/src/main/java/gregtech/api/terminal/app/AbstractApplication.java deleted file mode 100644 index 30f5878f829..00000000000 --- a/src/main/java/gregtech/api/terminal/app/AbstractApplication.java +++ /dev/null @@ -1,268 +0,0 @@ -package gregtech.api.terminal.app; - -import gregtech.api.gui.INativeWidget; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.resources.ResourceHelper; -import gregtech.api.gui.resources.TextureArea; -import gregtech.api.terminal.TerminalRegistry; -import gregtech.api.terminal.gui.widgets.AnimaWidgetGroup; -import gregtech.api.terminal.os.TerminalOSWidget; -import gregtech.api.terminal.os.menu.IMenuComponent; -import gregtech.api.util.GTLog; -import gregtech.api.util.Position; -import gregtech.api.util.Size; -import gregtech.common.items.behaviors.TerminalBehaviour; - -import net.minecraft.client.resources.I18n; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.nbt.CompressedStreamTools; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.PacketBuffer; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import java.io.File; -import java.io.IOException; -import java.util.Collections; -import java.util.List; -import java.util.function.Consumer; -import java.util.regex.Pattern; - -public abstract class AbstractApplication extends AnimaWidgetGroup { - - private static final Pattern NEW_LINE_PATTERN = Pattern.compile("\\\\n"); - - protected final String name; - protected TerminalOSWidget os; - protected boolean isClient; - protected NBTTagCompound nbt; - - public AbstractApplication(String name) { - super(Position.ORIGIN, new Size(TerminalOSWidget.DEFAULT_WIDTH, TerminalOSWidget.DEFAULT_HEIGHT)); - this.name = name; - } - - public AbstractApplication setOs(TerminalOSWidget os) { - this.os = os; - return this; - } - - public boolean canOpenMenuOnEdge() { - return true; - } - - /** - * App theme color - */ - public int getThemeColor() { - return name.hashCode() | 0xff000000; - } - - /** - * App Name - */ - public String getRegistryName() { - return name; - } - - public String getUnlocalizedName() { - return "gregtech.terminal.app_name." + name; - } - - /** - * App Icon - */ - public IGuiTexture getIcon() { - return TextureArea.fullImage("textures/gui/terminal/" + name + "/icon.png"); - } - - /** - * App Description - */ - @SideOnly(Side.CLIENT) - public String getDescription() { - if (I18n.hasKey("terminal." + getRegistryName() + ".description")) { - return NEW_LINE_PATTERN.matcher(I18n.format("terminal." + getRegistryName() + ".description")) - .replaceAll("\n"); - } - return I18n.format("terminal.app_name.description"); - } - - /** - * App Profile - */ - @SideOnly(Side.CLIENT) - public IGuiTexture getProfile() { - if (ResourceHelper.isResourceExist("textures/gui/terminal/" + name + "/profile.png")) { - return TextureArea.fullImage("textures/gui/terminal/" + name + "/profile.png"); - } - return getIcon(); - } - - /** - * App Banner - */ - @SideOnly(Side.CLIENT) - public IGuiTexture getBanner() { - if (ResourceHelper.isResourceExist("textures/gui/terminal/" + name + "/banner.png")) { - return TextureArea.fullImage("textures/gui/terminal/" + name + "/banner.png"); - } - return null; - } - - /** - * App Information for each tier - */ - @SideOnly(Side.CLIENT) - public String getTierInformation(int tier) { - if (I18n.hasKey("terminal." + name + ".tier." + tier)) { - return I18n.format("terminal." + name + ".tier." + tier); - } - return I18n.format("terminal.app_name.tier", tier); - } - - /** - * Will be called when try to open this app. you should return an instance here. - * Due to INative's poor synchronization, do not add the INativeWidget {@link INativeWidget} here. - * Instead, It's probably best not to initialize your app here. initialize should in initApp {@link #initApp()} - */ - public AbstractApplication createAppInstance(TerminalOSWidget os, boolean isClient, NBTTagCompound nbt) { - try { - AbstractApplication app = this.getClass().newInstance(); - app.isClient = isClient; - app.nbt = nbt; - return app; - } catch (InstantiationException | IllegalAccessException e) { - GTLog.logger.error("Error while create default app. {}", this.getClass(), e); - } - return null; - } - - /** - * init app here. you have access to os, isClient, nbt. - */ - public AbstractApplication initApp() { - return this; - } - - /** - * you should store the persistent data for both side here. - * - * @return nbt data. if its a clientSideApp and the nbt not null, this nbt should be synced to the server side. - */ - public NBTTagCompound closeApp() { - return null; - } - - /** - * Whether the app can run in the background when minimized. - */ - public boolean isBackgroundApp() { - return false; - } - - /** - * If it is a client side app, will block all action packets sent from client. - * If the app doesn't require server execution, it better be a client side app. - * For details about data synchronization, see {@link #closeApp()} - */ - public boolean isClientSideApp() { - return false; - } - - public TerminalOSWidget getOs() { - return os; - } - - /** - * Add components to menu bar. - * - * @see IMenuComponent - */ - public List getMenuComponents() { - return Collections.emptyList(); - } - - /** - * Whether the player can open this app. - */ - public boolean canPlayerUse(EntityPlayer player) { - return true; - } - - /** - * App Current Tier. Creative Terminal(return max tier) - */ - public int getAppTier() { - if (nbt != null) { - if (TerminalBehaviour.isCreative(getOs().itemStack)) { - return getMaxTier(); - } - return Math.min(nbt.getInteger("_tier"), getMaxTier()); - } - return 0; - } - - /** - * App Max Tier - */ - public int getMaxTier() { - return 0; - } - - @Override - protected void writeClientAction(int id, Consumer packetBufferWriter) { - if (!isClientSideApp()) { - super.writeClientAction(id, packetBufferWriter); - } - } - - /** - * read NBT from the local config folder. - */ - protected void loadLocalConfig(Consumer reader) { - if (isClient && reader != null) { - NBTTagCompound nbt = null; - try { - nbt = CompressedStreamTools.read( - new File(TerminalRegistry.TERMINAL_PATH, String.format("config/%S.nbt", getRegistryName()))); - } catch (IOException e) { - GTLog.logger.error("error while loading local nbt for {}", getRegistryName(), e); - } - if (nbt == null) { - nbt = new NBTTagCompound(); - } - reader.accept(nbt); - } - } - - /** - * Write NBT to the local config folder. - */ - protected void saveLocalConfig(Consumer writer) { - if (isClient && writer != null) { - NBTTagCompound nbt = new NBTTagCompound(); - try { - writer.accept(nbt); - if (!nbt.isEmpty()) { - CompressedStreamTools.safeWrite(nbt, new File(TerminalRegistry.TERMINAL_PATH, - String.format("config/%S.nbt", getRegistryName()))); - } - } catch (IOException e) { - GTLog.logger.error("error while saving local nbt for {}", getRegistryName(), e); - } - } - } - - /** - * Fired when you open this app or terminal's size updated. (maximize) - */ - public void onOSSizeUpdate(int width, int height) { - setSelfPosition( - Position.ORIGIN.add(new Position((width - getSize().width) / 2, (height - getSize().height) / 2))); - } - - public boolean canLaunchConcurrently(AbstractApplication application) { - return true; - } -} diff --git a/src/main/java/gregtech/api/terminal/gui/CustomTabListRenderer.java b/src/main/java/gregtech/api/terminal/gui/CustomTabListRenderer.java deleted file mode 100644 index c3cf0733e93..00000000000 --- a/src/main/java/gregtech/api/terminal/gui/CustomTabListRenderer.java +++ /dev/null @@ -1,51 +0,0 @@ -package gregtech.api.terminal.gui; - -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.widgets.tab.ITabInfo; -import gregtech.api.gui.widgets.tab.TabListRenderer; -import gregtech.api.util.Position; - -import net.minecraft.client.renderer.GlStateManager; - -import java.util.List; - -public class CustomTabListRenderer extends TabListRenderer { - - private final IGuiTexture unSelected; - private final IGuiTexture selected; - private final int width; - private final int height; - - public CustomTabListRenderer(IGuiTexture unSelected, IGuiTexture selected, int width, int height) { - this.unSelected = unSelected; - this.selected = selected; - this.width = width; - this.height = height; - } - - @Override - public void renderTabs(ModularUI gui, Position offset, List tabInfos, int guiWidth, int guiHeight, - int selectedTabIndex) { - int y = offset.y - height; - GlStateManager.color(gui.getRColorForOverlay(), gui.getGColorForOverlay(), gui.getBColorForOverlay(), 1.0F); - for (int i = 0; i < tabInfos.size(); i++) { - int x = offset.x + i * width; - if (selectedTabIndex == i && selected != null) { - tabInfos.get(i).renderTab(selected, x, y, width, height, true); - GlStateManager.color(gui.getRColorForOverlay(), gui.getGColorForOverlay(), gui.getBColorForOverlay(), - 1.0F); - } - if (selectedTabIndex != i && unSelected != null) { - tabInfos.get(i).renderTab(unSelected, x, y, width, height, false); - GlStateManager.color(gui.getRColorForOverlay(), gui.getGColorForOverlay(), gui.getBColorForOverlay(), - 1.0F); - } - } - } - - @Override - public int[] getTabPos(int guiWidth, int guiHeight, int tabIndex) { - return new int[] { width * guiWidth, -height, width, height }; - } -} diff --git a/src/main/java/gregtech/api/terminal/gui/widgets/AnimaWidgetGroup.java b/src/main/java/gregtech/api/terminal/gui/widgets/AnimaWidgetGroup.java deleted file mode 100644 index acd2a58bed4..00000000000 --- a/src/main/java/gregtech/api/terminal/gui/widgets/AnimaWidgetGroup.java +++ /dev/null @@ -1,111 +0,0 @@ -package gregtech.api.terminal.gui.widgets; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.util.Position; -import gregtech.api.util.Size; -import gregtech.api.util.interpolate.Eases; -import gregtech.api.util.interpolate.Interpolator; - -import net.minecraft.client.renderer.GlStateManager; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import java.util.function.Consumer; - -public abstract class AnimaWidgetGroup extends WidgetGroup { - - @SideOnly(Side.CLIENT) - protected Interpolator interpolator; - protected float scale = 1; - - public AnimaWidgetGroup(Position position, Size size) { - super(position, size); - } - - public AnimaWidgetGroup(int x, int y, int width, int height) { - super(new Position(x, y), new Size(width, height)); - } - - @Override - public void updateScreenOnFrame() { - if (interpolator != null) { - interpolator.update(); - } - super.updateScreenOnFrame(); - } - - @SideOnly(Side.CLIENT) - public final void maximizeWidget(Consumer callback) { - this.scale = 0; - setVisible(true); - interpolator = new Interpolator(0, 1, 10, Eases.LINEAR, - value -> scale = value.floatValue(), - value -> { - interpolator = null; - if (callback != null) { - callback.accept(this); - } - }); - interpolator.start(); - } - - @SideOnly(Side.CLIENT) - public final void minimizeWidget(Consumer callback) { - this.scale = 1; - interpolator = new Interpolator(1, 0, 10, Eases.LINEAR, - value -> scale = value.floatValue(), - value -> { - setVisible(false); - interpolator = null; - if (callback != null) { - callback.accept(this); - } - }); - interpolator.start(); - } - - @SideOnly(Side.CLIENT) - protected void hookDrawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - super.drawInBackground(mouseX, mouseY, partialTicks, context); - } - - @SideOnly(Side.CLIENT) - protected void hookDrawInForeground(int mouseX, int mouseY) { - super.drawInForeground(mouseX, mouseY); - } - - @Override - public final void drawInForeground(int mouseX, int mouseY) { - if (scale == 0) { - return; - } - if (scale != 1) { - GlStateManager.pushMatrix(); - GlStateManager.translate((this.gui.getScreenWidth() - this.gui.getScreenWidth() * scale) / 2, - (this.gui.getScreenHeight() - this.gui.getScreenHeight() * scale) / 2, 0); - GlStateManager.scale(scale, scale, 1); - hookDrawInForeground(0, 0); - GlStateManager.popMatrix(); - } else { - hookDrawInForeground(mouseX, mouseY); - } - } - - @Override - public final void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - if (scale == 0) { - return; - } - if (scale != 1) { - GlStateManager.pushMatrix(); - GlStateManager.translate((this.gui.getScreenWidth() - this.gui.getScreenWidth() * scale) / 2, - (this.gui.getScreenHeight() - this.gui.getScreenHeight() * scale) / 2, 0); - GlStateManager.scale(scale, scale, 1); - hookDrawInBackground(0, 0, partialTicks, context); - GlStateManager.popMatrix(); - } else { - hookDrawInBackground(mouseX, mouseY, partialTicks, context); - } - } -} diff --git a/src/main/java/gregtech/api/terminal/gui/widgets/ColorWidget.java b/src/main/java/gregtech/api/terminal/gui/widgets/ColorWidget.java deleted file mode 100644 index 673c049b5f6..00000000000 --- a/src/main/java/gregtech/api/terminal/gui/widgets/ColorWidget.java +++ /dev/null @@ -1,305 +0,0 @@ -package gregtech.api.terminal.gui.widgets; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.widgets.TextFieldWidget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.util.Position; -import gregtech.api.util.Size; - -import net.minecraft.network.PacketBuffer; -import net.minecraft.util.math.MathHelper; - -import java.util.function.Consumer; -import java.util.function.Supplier; - -public class ColorWidget extends WidgetGroup { - - private int red = 255; - private int green = 255; - private int blue = 255; - private int alpha = 255; - private Consumer onColorChanged; - private final int barWidth; - private final int barHeight; - private final CircleButtonWidget redButton; - private final CircleButtonWidget greenButton; - private final CircleButtonWidget blueButton; - private final CircleButtonWidget alphaButton; - private int lastMouseX; - private CircleButtonWidget dragged; - private Supplier colorSupplier; - private boolean isClient; - - public ColorWidget(int x, int y, int barWidth, int barHeight) { - super(new Position(x, y), new Size(barWidth + 35, 3 * (barHeight + 5) + 10)); - this.barWidth = barWidth; - this.barHeight = barHeight; - IGuiTexture textFieldBackground = new ColorRectTexture(0x9f000000); - TextFieldWidget redField = new TextFieldWidget(barWidth + 5, 0, 30, barHeight, textFieldBackground, null, null) - .setTextResponder((t) -> { - setRed(t.isEmpty() ? 0 : Integer.parseInt(t)); - if (onColorChanged != null) { - onColorChanged.accept(getColor()); - } - writeClientAction(2, buffer -> buffer.writeInt(getColor())); - }, true) - .setTextSupplier(() -> Integer.toString(red), true) - .setValidator(ColorWidget::checkValid); - TextFieldWidget greenField = new TextFieldWidget(barWidth + 5, barHeight + 5, 30, barHeight, - textFieldBackground, null, null) - .setTextResponder((t) -> { - setGreen(t.isEmpty() ? 0 : Integer.parseInt(t)); - if (onColorChanged != null) { - onColorChanged.accept(getColor()); - } - writeClientAction(2, buffer -> buffer.writeInt(getColor())); - }, true) - .setTextSupplier(() -> Integer.toString(green), true) - .setValidator(ColorWidget::checkValid); - TextFieldWidget blueField = new TextFieldWidget(barWidth + 5, (barHeight + 5) * 2, 30, barHeight, - textFieldBackground, null, null) - .setTextResponder((t) -> { - setBlue(t.isEmpty() ? 0 : Integer.parseInt(t)); - if (onColorChanged != null) { - onColorChanged.accept(getColor()); - } - writeClientAction(2, buffer -> buffer.writeInt(getColor())); - }, true) - .setTextSupplier(() -> Integer.toString(blue), true) - .setValidator(ColorWidget::checkValid); - TextFieldWidget alphaField = new TextFieldWidget(barWidth + 5, (barHeight + 5) * 3, 30, barHeight, - textFieldBackground, null, null) - .setTextResponder((t) -> { - setAlpha(t.isEmpty() ? 0 : Integer.parseInt(t)); - if (onColorChanged != null) { - onColorChanged.accept(getColor()); - } - writeClientAction(2, buffer -> buffer.writeInt(getColor())); - }, true) - .setTextSupplier(() -> Integer.toString(alpha), true) - .setValidator(ColorWidget::checkValid); - this.addWidget(redField); - this.addWidget(greenField); - this.addWidget(blueField); - this.addWidget(alphaField); - redButton = new CircleButtonWidget(barWidth, barHeight / 2, 4, 1, 0).setFill(0xffff0000).setStrokeAnima(-1); - greenButton = new CircleButtonWidget(barWidth, barHeight / 2 + barHeight + 5, 4, 1, 0).setFill(0xff00ff00) - .setStrokeAnima(-1); - blueButton = new CircleButtonWidget(barWidth, barHeight / 2 + 2 * (barHeight + 5), 4, 1, 0).setFill(0xff0000ff) - .setStrokeAnima(-1); - alphaButton = new CircleButtonWidget(barWidth, barHeight / 2 + 3 * (barHeight + 5), 4, 1, 0).setFill(-1) - .setStrokeAnima(-1); - this.addWidget(redButton); - this.addWidget(greenButton); - this.addWidget(blueButton); - this.addWidget(alphaButton); - } - - public ColorWidget setOnColorChanged(Consumer onColorChanged) { - this.onColorChanged = onColorChanged; - return this; - } - - public ColorWidget setColorSupplier(Supplier colorSupplier, boolean isClient) { - this.colorSupplier = colorSupplier; - this.isClient = isClient; - return this; - } - - public ColorWidget setStartColor(int color) { - setRed((color >> 16) & 0xFF); - setGreen((color >> 8) & 0xFF); - setBlue(color & 0xFF); - setAlpha((color >> 24) & 0xFF); - return this; - } - - public int getColor() { - return (alpha << 24) | (red << 16) | (green << 8) | (blue); - } - - @Override - public void detectAndSendChanges() { - super.detectAndSendChanges(); - if (!isClient && colorSupplier != null) { - int c = colorSupplier.get(); - int r = (c & 0x00ff0000) >>> 16; - int g = (c & 0x0000ff00) >>> 8; - int b = (c & 0x000000ff); - int a = (c & 0xff000000) >>> 24; - if (r != red || g != green || b != blue || a != alpha) { - setRed(r); - setGreen(g); - setBlue(b); - setAlpha(a); - writeUpdateInfo(2, buffer -> buffer.writeInt(c)); - } - } - } - - @Override - public void updateScreen() { - super.updateScreen(); - if (isClient && colorSupplier != null) { - int c = colorSupplier.get(); - int r = (c & 0x00ff0000) >>> 16; - int g = (c & 0x0000ff00) >>> 8; - int b = (c & 0x000000ff); - int a = (c & 0xff000000) >>> 24; - if (r != red || g != green || b != blue || a != alpha) { - setRed(r); - setGreen(g); - setBlue(b); - setAlpha(a); - writeClientAction(2, buffer -> buffer.writeInt(c)); - } - } - } - - @Override - public void readUpdateInfo(int id, PacketBuffer buffer) { - handleColor(id, buffer); - } - - private void handleColor(int id, PacketBuffer buffer) { - if (id == 2) { - int c = buffer.readInt(); - int r = (c & 0x00ff0000) >>> 16; - int g = (c & 0x0000ff00) >>> 8; - int b = (c & 0x000000ff); - int a = (c & 0xff000000) >>> 24; - if (r != red || g != green || b != blue || a != alpha) { - setRed(r); - setGreen(g); - setBlue(b); - setAlpha(a); - if (onColorChanged != null) { - onColorChanged.accept(getColor()); - } - } - } - } - - @Override - public void handleClientAction(int id, PacketBuffer buffer) { - handleColor(id, buffer); - } - - private void setRed(int red) { - if (this.red != red) { - this.red = red; - redButton.setSelfPosition(new Position(red * barWidth / 255 - 4, redButton.getSelfPosition().y)); - } - } - - private void setGreen(int green) { - if (this.green != green) { - this.green = green; - greenButton.setSelfPosition(new Position(green * barWidth / 255 - 4, greenButton.getSelfPosition().y)); - } - } - - private void setBlue(int blue) { - if (this.blue != blue) { - this.blue = blue; - blueButton.setSelfPosition(new Position(blue * barWidth / 255 - 4, blueButton.getSelfPosition().y)); - } - } - - private void setAlpha(int alpha) { - if (this.alpha != alpha) { - this.alpha = alpha; - alphaButton.setSelfPosition(new Position(alpha * barWidth / 255 - 4, alphaButton.getSelfPosition().y)); - } - } - - private static boolean checkValid(String input) { - if (input.length() > 3) return false; - if (input.isEmpty()) return true; - try { - int value = Integer.parseInt(input); - if (value >= 0 && value <= 255) { - return true; - } - } catch (Exception e) { - return false; - } - return false; - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - int x = getPosition().x; - int y = getPosition().y; - drawGradientRect(x, y + 2, barWidth, 5, (255 << 24) | (0) | (green << 8) | (blue), - (255 << 24) | (255 << 16) | (green << 8) | (blue), true); - drawGradientRect(x, y + barHeight + 5 + 2, barWidth, 5, (255 << 24) | (red << 16) | (0) | (blue), - (255 << 24) | (red << 16) | (255 << 8) | (blue), true); - drawGradientRect(x, y + 2 * (barHeight + 5) + 2, barWidth, 5, (255 << 24) | (red << 16) | (green << 8) | (0), - (255 << 24) | (red << 16) | (green << 8) | (255), true); - drawGradientRect(x, y + 3 * (barHeight + 5) + 2, barWidth, 5, (0) | (red << 16) | (green << 8) | (blue), - (255 << 24) | (red << 16) | (green << 8) | (blue), true); - super.drawInBackground(mouseX, mouseY, partialTicks, context); - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - lastMouseX = mouseX; - dragged = null; - if (redButton.isMouseOverElement(mouseX, mouseY)) { - dragged = redButton; - return true; - } else if (greenButton.isMouseOverElement(mouseX, mouseY)) { - dragged = greenButton; - return true; - } else if (blueButton.isMouseOverElement(mouseX, mouseY)) { - dragged = blueButton; - return true; - } else if (alphaButton.isMouseOverElement(mouseX, mouseY)) { - dragged = alphaButton; - return true; - } - boolean flag = false; - for (int i = widgets.size() - 1; i >= 0; i--) { - Widget widget = widgets.get(i); - if (widget.isVisible() && widget.mouseClicked(mouseX, mouseY, button)) { - flag = true; - } - } - return flag; - } - - @Override - public boolean mouseDragged(int mouseX, int mouseY, int button, long timeDragged) { - int xDelta = mouseX - lastMouseX; - lastMouseX = mouseX; - if (dragged != null) { - int newX = MathHelper.clamp(dragged.getSelfPosition().x + 4 + xDelta, 0, barWidth); - if (dragged == redButton) { - setRed(newX * 255 / barWidth); - } else if (dragged == greenButton) { - setGreen(newX * 255 / barWidth); - } else if (dragged == blueButton) { - setBlue(newX * 255 / barWidth); - } else if (dragged == alphaButton) { - setAlpha(newX * 255 / barWidth); - } - if (onColorChanged != null) { - onColorChanged.accept(getColor()); - } - writeClientAction(2, buffer -> buffer.writeInt(getColor())); - dragged.setSelfPosition(new Position(newX - 4, dragged.getSelfPosition().y)); - return true; - } - return super.mouseDragged(mouseX, mouseY, button, timeDragged); - } - - @Override - public boolean mouseReleased(int mouseX, int mouseY, int button) { - dragged = null; - return super.mouseReleased(mouseX, mouseY, button); - } -} diff --git a/src/main/java/gregtech/api/terminal/gui/widgets/CustomPositionSizeWidget.java b/src/main/java/gregtech/api/terminal/gui/widgets/CustomPositionSizeWidget.java deleted file mode 100644 index a499d12ebb0..00000000000 --- a/src/main/java/gregtech/api/terminal/gui/widgets/CustomPositionSizeWidget.java +++ /dev/null @@ -1,217 +0,0 @@ -package gregtech.api.terminal.gui.widgets; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.terminal.gui.IDraggable; -import gregtech.api.util.Position; -import gregtech.api.util.Size; - -import java.util.function.BiConsumer; - -public class CustomPositionSizeWidget extends Widget implements IDraggable { - - private Widget controlled; - private final int borderColor; - private final int hoverColor; - private final int border; - private boolean dragUp; - private boolean dragDown; - private boolean dragLeft; - private boolean dragRight; - private boolean dragPos; - - private BiConsumer onUpdated; - - public CustomPositionSizeWidget(Widget controlled, int borderColor, int hoverColor, int border) { - super(controlled.getSelfPosition(), controlled.getSize()); - this.controlled = controlled; - this.borderColor = borderColor; - this.hoverColor = hoverColor; - this.border = border; - } - - public CustomPositionSizeWidget(int borderColor, int hoverColor, int border) { - super(Position.ORIGIN, Size.ZERO); - this.borderColor = borderColor; - this.hoverColor = hoverColor; - this.border = border; - } - - public CustomPositionSizeWidget setControlled(Widget controlled) { - this.controlled = controlled; - if (controlled != null) { - this.setSelfPosition(controlled.getSelfPosition()); - this.setSize(controlled.getSize()); - } - return this; - } - - public Widget getControlled() { - return controlled; - } - - public CustomPositionSizeWidget setOnUpdated(BiConsumer onUpdated) { - this.onUpdated = onUpdated; - return this; - } - - @Override - public void updateScreen() { - if (controlled != null) { - Position pos = controlled.getSelfPosition(); - Size size = controlled.getSize(); - if (!this.getSelfPosition().equals(pos)) { - this.setSelfPosition(pos); - } - if (this.getSize().equals(size)) { - this.setSize(size); - } - } - } - - private boolean hoverUp(int x, int y, int width, int height, int mouseX, int mouseY) { - return isMouseOver(x, y, width / 5, border, mouseX, mouseY) || - isMouseOver(x + width * 2 / 5, y, width / 5, border, mouseX, mouseY) || - isMouseOver(x + width * 4 / 5, y, width / 5, border, mouseX, mouseY) || - isMouseOver(x, y, border, height / 5, mouseX, mouseY) || - isMouseOver(x + width - border, y, border, height / 5, mouseX, mouseY); - } - - private boolean hoverDown(int x, int y, int width, int height, int mouseX, int mouseY) { - return isMouseOver(x, y + height - border, width / 5, border, mouseX, mouseY) || - isMouseOver(x + width * 2 / 5, y + height - border, width / 5, border, mouseX, mouseY) || - isMouseOver(x + width * 4 / 5, y + height - border, width / 5, border, mouseX, mouseY) || - isMouseOver(x, y + height * 4 / 5, border, height / 5, mouseX, mouseY) || - isMouseOver(x + width - border, y + height * 4 / 5, border, height / 5, mouseX, mouseY); - } - - private boolean hoverLeft(int x, int y, int width, int height, int mouseX, int mouseY) { - return isMouseOver(x, y, border, height / 5, mouseX, mouseY) || - isMouseOver(x, y + height * 2 / 5, border, height / 5, mouseX, mouseY) || - isMouseOver(x, y + height * 4 / 5, border, height / 5, mouseX, mouseY) || - isMouseOver(x, y, width / 5, border, mouseX, mouseY) || - isMouseOver(x, y + height - border, width / 5, border, mouseX, mouseY); - } - - private boolean hoverRight(int x, int y, int width, int height, int mouseX, int mouseY) { - return isMouseOver(x + width - border, y, border, height / 5, mouseX, mouseY) || - isMouseOver(x + width - border, y + height * 2 / 5, border, height / 5, mouseX, mouseY) || - isMouseOver(x + width - border, y + height * 4 / 5, border, height / 5, mouseX, mouseY) || - isMouseOver(x + width * 4 / 5, y, width / 5, border, mouseX, mouseY) || - isMouseOver(x + width * 4 / 5, y + height - border, width / 5, border, mouseX, mouseY); - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - if (controlled == null) return; - int x = controlled.getPosition().x; - int y = controlled.getPosition().y; - int width = controlled.getSize().width; - int height = controlled.getSize().height; - - boolean hoverUp = false; - boolean hoverDown = false; - boolean hoverLeft = false; - boolean hoverRight = false; - // UP - if (dragUp || hoverUp(x, y, width, height, mouseX, mouseY)) { - hoverUp = true; - } - if (dragDown || hoverDown(x, y, width, height, mouseX, mouseY)) { - hoverDown = true; - } - if (dragLeft || hoverLeft(x, y, width, height, mouseX, mouseY)) { - hoverLeft = true; - } - if (dragRight || hoverRight(x, y, width, height, mouseX, mouseY)) { - hoverRight = true; - } - // UP - drawSolidRect(x, y, width / 5, border, hoverUp && !hoverRight ? hoverColor : borderColor); - drawSolidRect(x + width * 2 / 5, y, width / 5, border, - hoverUp && !hoverLeft && !hoverRight ? hoverColor : borderColor); - drawSolidRect(x + width * 4 / 5, y, width / 5, border, hoverUp && !hoverLeft ? hoverColor : borderColor); - // DOWN - drawSolidRect(x, y + height - border, width / 5, border, hoverDown && !hoverRight ? hoverColor : borderColor); - drawSolidRect(x + width * 2 / 5, y + height - border, width / 5, border, - hoverDown && !hoverLeft && !hoverRight ? hoverColor : borderColor); - drawSolidRect(x + width * 4 / 5, y + height - border, width / 5, border, - hoverDown && !hoverLeft ? hoverColor : borderColor); - // LEFT - drawSolidRect(x, y, border, height / 5, hoverLeft && !hoverDown ? hoverColor : borderColor); - drawSolidRect(x, y + height * 2 / 5, border, height / 5, - hoverLeft && !hoverDown && !hoverUp ? hoverColor : borderColor); - drawSolidRect(x, y + height * 4 / 5, border, height / 5, hoverLeft && !hoverUp ? hoverColor : borderColor); - // RIGHT - drawSolidRect(x + width - border, y, border, height / 5, hoverRight && !hoverDown ? hoverColor : borderColor); - drawSolidRect(x + width - border, y + height * 2 / 5, border, height / 5, - hoverRight && !hoverDown && !hoverUp ? hoverColor : borderColor); - drawSolidRect(x + width - border, y + height * 4 / 5, border, height / 5, - hoverRight && !hoverUp ? hoverColor : borderColor); - } - - @Override - public boolean allowDrag(int mouseX, int mouseY, int button) { - if (controlled == null || !isActive()) return false; - int x = controlled.getPosition().x; - int y = controlled.getPosition().y; - int width = controlled.getSize().width; - int height = controlled.getSize().height; - if (isMouseOver(x, y, width, height, mouseX, mouseY)) { - // UP - dragUp = hoverUp(x, y, width, height, mouseX, mouseY); - // DOWN - dragDown = hoverDown(x, y, width, height, mouseX, mouseY); - // LEFT - dragLeft = hoverLeft(x, y, width, height, mouseX, mouseY); - // RIGHT - dragRight = hoverRight(x, y, width, height, mouseX, mouseY); - dragPos = !dragUp && !dragDown && !dragLeft && !dragRight; - return true; - } - return false; - } - - @Override - public boolean dragging(int mouseX, int mouseY, int deltaX, int deltaY) { - if (controlled == null || !isActive()) return false; - int width = controlled.getSize().width; - int height = controlled.getSize().height; - int addX = 0, addY = 0; - if (!dragPos) { - if (dragUp) { - addY = deltaY; - height = Math.max(1, height - deltaY); - } - if (dragDown) { - height = Math.max(1, height + deltaY); - } - if (dragLeft) { - addX = deltaX; - width = Math.max(1, width - deltaX); - } - if (dragRight) { - width = Math.max(1, width + deltaX); - } - controlled.addSelfPosition(addX, addY); - controlled.setSize(new Size(width, height)); - } else { - controlled.addSelfPosition(deltaX, deltaY); - } - if (onUpdated != null) { - onUpdated.accept(controlled.getSelfPosition(), controlled.getSize()); - } - this.setSelfPosition(controlled.getSelfPosition()); - this.setSize(controlled.getSize()); - return false; - } - - @Override - public void endDrag(int mouseX, int mouseY) { - dragDown = false; - dragUp = false; - dragLeft = false; - dragRight = false; - dragPos = false; - } -} diff --git a/src/main/java/gregtech/api/terminal/gui/widgets/MachineSceneWidget.java b/src/main/java/gregtech/api/terminal/gui/widgets/MachineSceneWidget.java deleted file mode 100644 index 43fceb358f9..00000000000 --- a/src/main/java/gregtech/api/terminal/gui/widgets/MachineSceneWidget.java +++ /dev/null @@ -1,345 +0,0 @@ -package gregtech.api.terminal.gui.widgets; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.TextTexture; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.metatileentity.multiblock.IMultiblockPart; -import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; -import gregtech.api.pattern.PatternMatchContext; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.util.FacingPos; -import gregtech.client.renderer.scene.FBOWorldSceneRenderer; -import gregtech.client.renderer.scene.WorldSceneRenderer; -import gregtech.client.utils.RenderUtil; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.resources.I18n; -import net.minecraft.init.Blocks; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.BlockRenderLayer; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL14; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.function.BiConsumer; -import java.util.stream.Collectors; - -import javax.vecmath.Vector3f; - -/** - * Created with IntelliJ IDEA. - * - * @Author: KilaBash - * @Date: 2021/08/23/19:21 - * @Description: - */ -public class MachineSceneWidget extends WidgetGroup { - - private static FBOWorldSceneRenderer worldSceneRenderer; - private boolean dragging; - private int lastMouseX; - private int lastMouseY; - private int currentMouseX; - private int currentMouseY; - private Vector3f center; - private float rotationYaw = 45; - private float rotationPitch; - private float zoom = 5; - private float alpha = 1f; - private boolean blendColor = true; - private Set cores; - private Set around; - private FacingPos hoveredFacingPos; - private FacingPos selectedFacingPos; - private BiConsumer onSelected; - - protected MetaTileEntity mte; - protected final BlockPos pos; - - public MachineSceneWidget(int x, int y, int width, int height, MetaTileEntity mte) { - this(x, y, width, height, mte.getPos()); - this.mte = mte; - updateScene(); - } - - public MachineSceneWidget(int x, int y, int width, int height, BlockPos pos) { - super(x, y, width, height); - this.pos = pos; - this.addWidget(new ScrollBarWidget(5, height - 13, width - 50, 8, 0, 1, 0.05f) - .setOnChanged(value -> alpha = value, true).setInitValue(1f)); - this.addWidget(new RectButtonWidget(width - 40, height - 15, 35, 12, 1) - .setToggleButton(new TextTexture("COLOR", -1), (c, b) -> blendColor = b) - .setValueSupplier(true, () -> blendColor) - .setColors(TerminalTheme.COLOR_7.getColor(), TerminalTheme.COLOR_F_1.getColor(), 0) - .setIcon(new TextTexture("ALPHA", -1))); - if (worldSceneRenderer != null) { - worldSceneRenderer.releaseFBO(); - worldSceneRenderer = null; - } - } - - public Set getCores() { - return cores; - } - - public Set getAround() { - return around; - } - - public static FBOWorldSceneRenderer getWorldSceneRenderer() { - return worldSceneRenderer; - } - - public MachineSceneWidget setOnSelected(BiConsumer onSelected) { - this.onSelected = onSelected; - return this; - } - - @SideOnly(Side.CLIENT) - private void renderBlockOverLay(WorldSceneRenderer renderer) { - hoveredFacingPos = null; - if (isMouseOverElement(currentMouseX, currentMouseY)) { - int x = getPosition().x; - int y = getPosition().y; - int width = getSize().width; - int height = getSize().height; - int resolutionWidth = worldSceneRenderer.getResolutionWidth(); - int resolutionHeight = worldSceneRenderer.getResolutionHeight(); - int mouseX = resolutionWidth * (currentMouseX - x) / width; - int mouseY = (int) (resolutionHeight * (1 - (currentMouseY - y) / (float) height)); - Vector3f hitPos = WorldSceneRenderer.unProject(mouseX, mouseY); - World world = renderer.world; - Vec3d eyePos = new Vec3d(renderer.getEyePos().x, renderer.getEyePos().y, renderer.getEyePos().z); - hitPos.scale(2); // Double view range to ensure pos can be seen. - Vec3d endPos = new Vec3d((hitPos.x - eyePos.x), (hitPos.y - eyePos.y), (hitPos.z - eyePos.z)); - double min = Float.MAX_VALUE; - for (BlockPos core : cores) { - IBlockState blockState = world.getBlockState(core); - if (blockState.getBlock() == Blocks.AIR) { - continue; - } - RayTraceResult hit = blockState.collisionRayTrace(world, core, eyePos, endPos); - if (hit != null && hit.typeOfHit != RayTraceResult.Type.MISS) { - double dist = eyePos.distanceTo(new Vec3d(hit.getBlockPos())); - if (dist < min) { - min = dist; - hoveredFacingPos = new FacingPos(hit.getBlockPos(), hit.sideHit); - } - } - } - } - if (selectedFacingPos != null || hoveredFacingPos != null) { - GlStateManager.pushMatrix(); - RenderUtil.useLightMap(240, 240, () -> { - GlStateManager.disableDepth(); - if (selectedFacingPos != null) { - drawFacingBorder(selectedFacingPos, 0xff00ff00); - } - if (hoveredFacingPos != null && !hoveredFacingPos.equals(selectedFacingPos)) { - drawFacingBorder(hoveredFacingPos, 0xffffffff); - } - GlStateManager.enableDepth(); - }); - GlStateManager.popMatrix(); - } - GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f); - GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, - GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, - GlStateManager.DestFactor.ZERO); - } - - private static void drawFacingBorder(FacingPos posFace, int color) { - GlStateManager.pushMatrix(); - RenderUtil.moveToFace(posFace.getPos().getX(), posFace.getPos().getY(), posFace.getPos().getZ(), - posFace.getFacing()); - RenderUtil.rotateToFace(posFace.getFacing(), null); - GlStateManager.scale(1f / 16, 1f / 16, 0); - GlStateManager.translate(-8, -8, 0); - Widget.drawBorder(1, 1, 14, 14, color, 1); - GlStateManager.popMatrix(); - } - - @Override - public void updateScreen() { - super.updateScreen(); - if (mte == null) { - World world = this.gui.entityPlayer.world; - TileEntity tileEntity = world.getTileEntity(pos); - if (tileEntity instanceof IGregTechTileEntity && - ((IGregTechTileEntity) tileEntity).getMetaTileEntity() != null) { - mte = ((IGregTechTileEntity) tileEntity).getMetaTileEntity(); - updateScene(); - } - } else if (!mte.isValid()) { - worldSceneRenderer.releaseFBO(); - worldSceneRenderer = null; - mte = null; - } - } - - private void updateScene() { - if (!mte.isValid()) return; - World world = mte.getWorld(); - if (worldSceneRenderer != null) { - worldSceneRenderer.releaseFBO(); - } - worldSceneRenderer = new FBOWorldSceneRenderer(world, 1080, 1080); - worldSceneRenderer.setAfterWorldRender(this::renderBlockOverLay); - cores = new HashSet<>(); - around = new HashSet<>(); - cores.add(pos); - if (mte instanceof MultiblockControllerBase multi && multi.isStructureFormed()) { - PatternMatchContext context = multi.structurePattern.checkPatternFastAt( - world, pos, mte.getFrontFacing().getOpposite(), multi.getUpwardsFacing(), multi.allowsFlip()); - if (context != null) { - List validPos = multi.structurePattern.cache.keySet().stream().map(BlockPos::fromLong) - .collect(Collectors.toList()); - Set parts = context.getOrCreate("MultiblockParts", HashSet::new); - for (IMultiblockPart part : parts) { - if (part instanceof MetaTileEntity) { - cores.add(((MetaTileEntity) part).getPos()); - } - } - for (EnumFacing facing : EnumFacing.VALUES) { - cores.forEach(pos -> around.add(pos.offset(facing))); - } - int minX = Integer.MAX_VALUE; - int minY = Integer.MAX_VALUE; - int minZ = Integer.MAX_VALUE; - int maxX = Integer.MIN_VALUE; - int maxY = Integer.MIN_VALUE; - int maxZ = Integer.MIN_VALUE; - for (BlockPos vPos : validPos) { - around.add(vPos); - minX = Math.min(minX, vPos.getX()); - minY = Math.min(minY, vPos.getY()); - minZ = Math.min(minZ, vPos.getZ()); - maxX = Math.max(maxX, vPos.getX()); - maxY = Math.max(maxY, vPos.getY()); - maxZ = Math.max(maxZ, vPos.getZ()); - } - around.removeAll(cores); - center = new Vector3f((minX + maxX) / 2f, (minY + maxY) / 2f, (minZ + maxZ) / 2f); - } else { - for (EnumFacing facing : EnumFacing.VALUES) { - around.add(pos.offset(facing)); - } - center = new Vector3f(pos.getX() + 0.5f, pos.getY() + 0.5f, pos.getZ() + 0.5f); - } - } else { - for (EnumFacing facing : EnumFacing.VALUES) { - around.add(pos.offset(facing)); - } - center = new Vector3f(pos.getX() + 0.5f, pos.getY() + 0.5f, pos.getZ() + 0.5f); - } - worldSceneRenderer.addRenderedBlocks(cores, null); - worldSceneRenderer.addRenderedBlocks(around, this::aroundBlocksRenderHook); - worldSceneRenderer.setCameraLookAt(center, zoom, Math.toRadians(rotationPitch), Math.toRadians(rotationYaw)); - } - - private void aroundBlocksRenderHook(boolean isTESR, int pass, BlockRenderLayer layer) { - GlStateManager.color(1, 1, 1, 1); - GlStateManager.enableDepth(); - GlStateManager.enableBlend(); - if (blendColor) { - GlStateManager.tryBlendFuncSeparate( - GlStateManager.SourceFactor.CONSTANT_ALPHA, GlStateManager.DestFactor.CONSTANT_COLOR, - GlStateManager.SourceFactor.CONSTANT_ALPHA, GlStateManager.DestFactor.DST_ALPHA); - } else { - GlStateManager.blendFunc(GL11.GL_CONSTANT_ALPHA, GL11.GL_ONE_MINUS_CONSTANT_ALPHA); - } - GL14.glBlendColor(1, 1, 1, alpha); - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (super.mouseClicked(mouseX, mouseY, button)) { - return true; - } - if (isMouseOverElement(mouseX, mouseY)) { - dragging = true; - lastMouseX = mouseX; - lastMouseY = mouseY; - if (hoveredFacingPos != null && !hoveredFacingPos.equals(selectedFacingPos)) { - selectedFacingPos = hoveredFacingPos; - if (onSelected != null) { - onSelected.accept(selectedFacingPos.getPos(), selectedFacingPos.getFacing()); - } - } - return true; - } - dragging = false; - return false; - } - - @Override - public boolean mouseWheelMove(int mouseX, int mouseY, int wheelDelta) { - if (isMouseOverElement(mouseX, mouseY)) { - zoom = (float) MathHelper.clamp(zoom + (wheelDelta < 0 ? 0.5 : -0.5), 3, 999); - if (worldSceneRenderer != null) { - worldSceneRenderer.setCameraLookAt(center, zoom, Math.toRadians(rotationPitch), - Math.toRadians(rotationYaw)); - } - } - return super.mouseWheelMove(mouseX, mouseY, wheelDelta); - } - - @Override - public boolean mouseDragged(int mouseX, int mouseY, int button, long timeDragged) { - if (dragging) { - rotationPitch += mouseX - lastMouseX + 360; - rotationPitch = rotationPitch % 360; - rotationYaw = (float) MathHelper.clamp(rotationYaw + (mouseY - lastMouseY), -89.9, 89.9); - lastMouseY = mouseY; - lastMouseX = mouseX; - if (worldSceneRenderer != null) { - worldSceneRenderer.setCameraLookAt(center, zoom, Math.toRadians(rotationPitch), - Math.toRadians(rotationYaw)); - } - return true; - } - return super.mouseDragged(mouseX, mouseY, button, timeDragged); - } - - @Override - public boolean mouseReleased(int mouseX, int mouseY, int button) { - dragging = false; - return super.mouseReleased(mouseX, mouseY, button); - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - int x = getPosition().x; - int y = getPosition().y; - int width = getSize().width; - int height = getSize().height; - drawSolidRect(x, y, width, height, 0xaf000000); - if (worldSceneRenderer != null) { - GL11.glDisable(GL11.GL_SCISSOR_TEST); - worldSceneRenderer.render(x, y, width, height, mouseX - x, mouseY - y); - GL11.glEnable(GL11.GL_SCISSOR_TEST); - } - drawBorder(x + 1, y + 1, width - 2, height - 2, 0xff000000, 1); - if (mte != null) { - drawStringSized(I18n.format(mte.getMetaFullName()), x + width / 2f, y + 10, -1, true, 1, true); - } - super.drawInBackground(mouseX, mouseY, partialTicks, context); - currentMouseX = mouseX; - currentMouseY = mouseY; - } -} diff --git a/src/main/java/gregtech/api/terminal/gui/widgets/ScrollBarWidget.java b/src/main/java/gregtech/api/terminal/gui/widgets/ScrollBarWidget.java deleted file mode 100644 index 619fd1cbd6d..00000000000 --- a/src/main/java/gregtech/api/terminal/gui/widgets/ScrollBarWidget.java +++ /dev/null @@ -1,137 +0,0 @@ -package gregtech.api.terminal.gui.widgets; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.resources.TextureArea; -import gregtech.api.util.Position; -import gregtech.api.util.Size; - -import net.minecraft.network.PacketBuffer; -import net.minecraft.util.math.MathHelper; - -import java.util.function.Consumer; - -public class ScrollBarWidget extends Widget { - - protected final float min; - protected final float max; - protected final float dur; - protected int xOffset; - protected boolean draggedOnScrollBar; - protected IGuiTexture background; - protected IGuiTexture buttonTexture; - protected int buttonWidth; - protected int buttonHeight; - protected Consumer onChanged; - protected boolean isClient; - - public ScrollBarWidget(int x, int y, int width, int height, float min, float max, float dur) { - super(new Position(x, y), new Size(width, height)); - this.max = max; - this.min = min; - this.dur = dur; - this.xOffset = width / 2; - this.buttonTexture = new ColorRectTexture(-1); - this.buttonWidth = Math.max((int) (width / ((max - min) / dur)), 5); - this.buttonHeight = height; - } - - public ScrollBarWidget setOnChanged(Consumer onChanged, boolean isClient) { - this.onChanged = onChanged; - this.isClient = isClient; - return this; - } - - public ScrollBarWidget setBackground(IGuiTexture background) { - this.background = background; - return this; - } - - public ScrollBarWidget setInitValue(float value) { - if (value >= min && value <= max) { - this.xOffset = (int) ((value - min) / (max - min) * (this.getSize().width - buttonWidth)); - } - return this; - } - - public ScrollBarWidget setButtonTexture(TextureArea buttonTexture, int buttonWidth, int buttonHeight) { - this.buttonTexture = buttonTexture; - this.buttonWidth = buttonWidth; - this.buttonHeight = buttonHeight; - return this; - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - int x = getPosition().x; - int y = getPosition().y; - int width = getSize().width; - int height = getSize().height; - if (this.background != null) { - this.background.draw(x, y, width, height); - } else { - drawBorder(x - 1, y - 1, width + 2, height + 2, -1, 1); - } - if (this.buttonTexture != null) { - this.buttonTexture.draw(x + xOffset, y + (height - buttonHeight) / 2f, buttonWidth, buttonHeight); - } - } - - private boolean isOnScrollPane(int mouseX, int mouseY) { - Position position = this.getPosition(); - Size size = this.getSize(); - return isMouseOver(position.x, position.y, size.width, buttonHeight, mouseX, mouseY); - } - - private float getValue() { - return (float) (min + - Math.floor((max - min) * xOffset * 1.0f / (this.getSize().width - buttonWidth) / dur) * dur); - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (this.isOnScrollPane(mouseX, mouseY)) { - this.xOffset = MathHelper.clamp(mouseX - this.getPosition().x - buttonWidth / 2, 0, - this.getSize().width - buttonWidth); - this.draggedOnScrollBar = true; - } - return this.isMouseOverElement(mouseX, mouseY); - } - - @Override - public boolean mouseDragged(int mouseX, int mouseY, int button, long timeDragged) { - if (draggedOnScrollBar) { - this.xOffset = MathHelper.clamp(mouseX - this.getPosition().x - buttonWidth / 2, 0, - this.getSize().width - buttonWidth); - if (onChanged != null) { - onChanged.accept(getValue()); - } - return true; - } - return false; - } - - @Override - public boolean mouseReleased(int mouseX, int mouseY, int button) { - if (this.draggedOnScrollBar) { - if (!isClient) { - this.writeClientAction(2, packetBuffer -> packetBuffer.writeFloat(getValue())); - } - } - this.draggedOnScrollBar = false; - return this.isMouseOverElement(mouseX, mouseY); - } - - @Override - public void handleClientAction(int id, PacketBuffer buffer) { - super.handleClientAction(id, buffer); - if (id == 2) { - float value = buffer.readFloat(); - if (this.onChanged != null) { - onChanged.accept(value); - } - } - } -} diff --git a/src/main/java/gregtech/api/terminal/gui/widgets/TextEditorWidget.java b/src/main/java/gregtech/api/terminal/gui/widgets/TextEditorWidget.java deleted file mode 100644 index 4837420bcc5..00000000000 --- a/src/main/java/gregtech/api/terminal/gui/widgets/TextEditorWidget.java +++ /dev/null @@ -1,463 +0,0 @@ -package gregtech.api.terminal.gui.widgets; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.resources.TextureArea; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.util.Position; -import gregtech.api.util.Size; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.gui.GuiScreen; -import net.minecraft.util.ChatAllowedCharacters; -import net.minecraft.util.text.TextFormatting; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class TextEditorWidget extends WidgetGroup { - - private static final TextureArea PALETTE = TextureArea.fullImage("textures/gui/widget/palette.png"); - private static final TextureArea STYLE = TextureArea.fullImage("textures/gui/widget/formatting.png"); - private final TextPanelWidget textPanelWidget; - - private static final Pattern COMMENT = Pattern.compile("(//.*|/\\*[\\s\\S]*?\\*/)|(#.*)"); - private static final Pattern STRING = Pattern - .compile("(\"(?:[^\"\\\\]|\\\\[\\s\\S])*\"|'(?:[^'\\\\]|\\\\[\\s\\S])*')"); - private static final Pattern BOOL = Pattern.compile("\\b(true|false|null|undefined|NaN)\\b"); - private static final Pattern KEYWORD = Pattern.compile( - "\\b(import|var|for|if|else|return|this|while|new|function|switch|case|typeof|do|in|throw|try|catch|finally|with|instance|delete|void|break|continue)\\b"); - private static final Pattern KEYWORD_2 = Pattern.compile( - "\\b(String|int|long|boolean|float|double|byte|short|document|Date|Math|window|Object|location|navigator|Array|Number|Boolean|Function|RegExp)\\b"); - private static final Pattern VARIABLE = Pattern.compile("(?:[^\\W\\d]|\\$)[\\$\\w]*"); - private static final Pattern NUMBER = Pattern - .compile("(0[xX][0-9a-fA-F]+|\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?|\\.\\d+(?:[eE][+-]?\\d+)?)"); - private static final Pattern ANY = Pattern.compile("[\\s\\S]"); - - public TextEditorWidget(int x, int y, int width, int height, Consumer stringUpdate, boolean allowToolBox) { - super(new Position(x, y), - new Size(Math.max(width, allowToolBox ? 80 : width), Math.max(height, allowToolBox ? 32 : height))); - textPanelWidget = new TextPanelWidget(0, 32, Math.max(width, allowToolBox ? 80 : width), - Math.max(height, allowToolBox ? 32 : height) - 32, stringUpdate); - this.addWidget(textPanelWidget); - if (allowToolBox) { - initToolBox(); - } - } - - public TextEditorWidget setBackground(IGuiTexture background) { - textPanelWidget.setBackground(background); - return this; - } - - public TextEditorWidget setContent(String content) { - textPanelWidget.pageSetCurrent(content); - return this; - } - - @Override - public void setActive(boolean active) { - super.setActive(active); - textPanelWidget.setActive(active); - } - - private void initToolBox() { - TextFormatting[] formatting = TextFormatting.values(); - // palette - for (int y = 0; y < 4; y++) { - for (int x = 0; x < 4; x++) { - TextFormatting colorFormatting = formatting[y * 4 + x]; - this.addWidget(new RectButtonWidget(x * 8, y * 8, 8, 8, 1) - .setToggleButton(PALETTE.getSubArea(0.5 + x * 0.125, y * 0.25, 0.125, 0.25), - (cd, pressed) -> { - if (pressed) { - textPanelWidget.addFormatting(colorFormatting); - } else { - textPanelWidget.removeFormatting(colorFormatting); - } - }) - .setValueSupplier(true, () -> colorFormatting == textPanelWidget.getFrontColorFormatting()) - .setIcon(PALETTE.getSubArea(x * 0.125, y * 0.25, 0.125, 0.25)) - .setColors(0, -1, 0) - .setHoverText(colorFormatting.getFriendlyName())); - } - } - // style - for (int y = 0; y < 2; y++) { - for (int x = 0; x < 3; x++) { - TextFormatting styleFormatting = formatting[16 + y * 3 + x]; - if (styleFormatting == TextFormatting.RESET) break; - this.addWidget(new RectButtonWidget(x * 16 + 32, y * 16, 16, 16, 1) - .setToggleButton(STYLE.getSubArea(0.5 + x * 1.0 / 6, y * 0.5, 1.0 / 6, 0.5), - (cd, pressed) -> { - if (pressed) { - textPanelWidget.addFormatting(styleFormatting); - } else { - textPanelWidget.removeFormatting(styleFormatting); - } - }) - .setValueSupplier(true, - () -> textPanelWidget.getFrontStyleFormatting().contains(styleFormatting)) - .setIcon(STYLE.getSubArea(x * 1.0 / 6, y * 0.5, 1.0 / 6, 0.5)) - .setColors(0, -1, 0) - .setHoverText(styleFormatting.getFriendlyName())); - } - } - this.addWidget(new RectButtonWidget(3 * 16 + 32, 0, 16, 16, 3) - .setToggleButton(new ColorRectTexture(TerminalTheme.COLOR_B_2.getColor()), - (c, p) -> textPanelWidget.allowMarkdown = !p) - .setValueSupplier(true, () -> !textPanelWidget.allowMarkdown) - .setColors(TerminalTheme.COLOR_B_3.getColor(), TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_3.getColor()) - .setIcon(new ColorRectTexture(TerminalTheme.COLOR_7.getColor())) - .setHoverText("Check Markdown when Ctrl+V")); - this.addWidget(new RectButtonWidget(3 * 16 + 32, 16, 16, 16, 3) - .setClickListener(clickData -> textPanelWidget.pageSetCurrent("")) - .setColors(TerminalTheme.COLOR_B_3.getColor(), TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_3.getColor()) - .setIcon(new ColorRectTexture(TerminalTheme.COLOR_7.getColor())) - .setHoverText("Clean Up")); - } - - private static class TextPanelWidget extends DraggableScrollableWidgetGroup { - - public final static int SPACE = 0; - public int updateCount; - public String content; - public int textHeight; - public final Consumer stringUpdate; - public TextFormatting frontColor; - public List frontStyle; - public boolean allowMarkdown; - - private static final char SECTION_SIGN = '\u00A7'; - - @SideOnly(Side.CLIENT) - public FontRenderer fontRenderer; - @SideOnly(Side.CLIENT) - private static final Pattern R_CODE_PATTERN = Pattern.compile("(?i)" + SECTION_SIGN + "[R]"); - @SideOnly(Side.CLIENT) - private static final Pattern COLOR_CODE_PATTERN = Pattern.compile("(?i)" + SECTION_SIGN + "[0-9A-F]"); - - public TextPanelWidget(int x, int y, int width, int height, Consumer stringUpdate) { - super(x, y, width, height); - this.stringUpdate = stringUpdate; - this.content = ""; - this.allowMarkdown = true; - if (isClientSide()) { - fontRenderer = Minecraft.getMinecraft().fontRenderer; - textHeight = fontRenderer.getWordWrappedHeight(content, width - yBarWidth); - frontColor = null; - frontStyle = new ArrayList<>(); - } - } - - @Override - public int getMaxHeight() { - return textHeight + SPACE + xBarHeight; - } - - public void updateScreen() { - super.updateScreen(); - ++this.updateCount; - } - - @Override - public boolean keyTyped(char typedChar, int keyCode) { - if (!focus || !isActive()) return false; - if (GuiScreen.isKeyComboCtrlV(keyCode)) { - this.pageInsertIntoCurrent(allowMarkdown ? formatFromMarkdown(GuiScreen.getClipboardString()) : - GuiScreen.getClipboardString()); - findFrontFormatting(); - } else { - switch (keyCode) { - case 14: - if (!content.isEmpty()) { - this.pageSetCurrent(content.substring(0, content.length() - 1)); - } - break; - case 28: - case 156: - this.pageInsertIntoCurrent("\n"); - break; - default: - if (ChatAllowedCharacters.isAllowedCharacter(typedChar)) { - this.pageInsertIntoCurrent(Character.toString(typedChar)); - } - } - } - if (getMaxHeight() > getSize().height) { - setScrollYOffset(getMaxHeight() - getSize().height); - } else { - setScrollYOffset(0); - } - return true; - } - - private static String formatFromMarkdown(String markdown) { - StringBuilder builder = new StringBuilder(); - Deque stack = new ArrayDeque<>(); - int[] chars = markdown.chars().toArray(); - for (int i = 0; i < chars.length; i++) { - if (chars[i] == '\\' && i + 1 < chars.length) { - if (chars[i + 1] == '*' || chars[i + 1] == '_' || chars[i + 1] == '~' || chars[i + 1] == '`') { - builder.append(chars[i + 1]); - i++; - } else { - builder.append('\\'); - } - } else if (chars[i] == '*' && i + 1 < chars.length && chars[i + 1] == ' ') { // SUBLINE - builder.append(' ').append(TextFormatting.BOLD).append('*').append(TextFormatting.RESET) - .append(' '); - i++; - } else if (chars[i] == '*' && i + 1 < chars.length && chars[i + 1] == '*') { // BOLD - checkTextFormatting(builder, TextFormatting.BOLD, stack); - i++; - } else if (chars[i] == '_') { - if (i - 1 == -1 || !Character.isLetterOrDigit(chars[i - 1])) { // ITALIC - checkTextFormatting(builder, TextFormatting.ITALIC, stack); - } else if (i + 1 == chars.length || !Character.isLetterOrDigit(chars[i + 1])) { - checkTextFormatting(builder, TextFormatting.ITALIC, stack); - } else { - builder.append('_'); - } - } else if (chars[i] == '~') { // STRIKETHROUGH - checkTextFormatting(builder, TextFormatting.STRIKETHROUGH, stack); - } else if (chars[i] == '`' && i + 1 < chars.length && chars[i + 1] == '`' && i + 2 < chars.length && - chars[i + 2] == '`') { // code - boolean find = false; - for (int j = i + 3; j < chars.length - 2; j++) { - if (chars[j] == '`' && chars[j + 1] == '`' && chars[j + 2] == '`') { - find = true; - builder.append(checkCode(markdown.substring(i + 3, j))); - i += j - i; - } - } - if (!find) { - builder.append("```"); - } - i += 2; - } else - if (chars[i] == '`') { - checkTextFormatting(builder, TextFormatting.UNDERLINE, stack); - } else { - builder.append((char) chars[i]); - } - } - return builder.toString(); - } - - private static String checkCode(String code) { - Pattern[] patterns = new Pattern[] { COMMENT, STRING, BOOL, KEYWORD, KEYWORD_2, VARIABLE, NUMBER, ANY }; - TextFormatting[] colors = new TextFormatting[] { - TextFormatting.DARK_GRAY, // comment - TextFormatting.DARK_GREEN, // string - TextFormatting.RED, // value - TextFormatting.BLUE, // keyword - TextFormatting.LIGHT_PURPLE, // keyword2 - TextFormatting.BLACK, // variable - TextFormatting.RED, // variable - TextFormatting.DARK_PURPLE }; // else - StringBuilder builder = new StringBuilder(); - while (code.length() > 0) { - boolean find = false; - for (int i = 0; i < patterns.length; i++) { - Matcher matcher = patterns[i].matcher(code); - if (matcher.find() && matcher.start() == 0) { - builder.append(colors[i]).append(code, 0, matcher.end()).append(TextFormatting.RESET); - find = true; - code = code.substring(matcher.end()); - break; - } - } - if (!find) { - builder.append(code.charAt(0)); - code = code.substring(1); - } - } - return builder.toString(); - } - - private static void checkTextFormatting(StringBuilder builder, TextFormatting formatting, - Deque stack) { - if (!stack.isEmpty() && stack.peek() == formatting) { - builder.append(TextFormatting.RESET); - stack.pop(); - for (TextFormatting pre : stack) { - builder.append(pre.toString()); - } - } else { - stack.push(formatting); - builder.append(formatting.toString()); - } - } - - private static TextFormatting lookAheadChars(final String content, int index) { - if (index > 1 && content.charAt(index - 2) == SECTION_SIGN) { - int t = content.charAt(index - 1); - if ('0' <= t && t <= '9') { - return TextFormatting.values()[t - '0']; - } else if ('a' <= t && t <= 'f') { - return TextFormatting.values()[t - 'a' + 10]; - } else if ('k' <= t && t <= 'o') { - return TextFormatting.values()[t - 'k' + 16]; - } else if (t == 'r') { - return TextFormatting.values()[21]; - } - } - return null; - } - - public static String cleanUpFormatting(final String content) { - Set removed = new HashSet<>(); - Matcher marcher = R_CODE_PATTERN.matcher(content); - while (marcher.find()) { - int index = marcher.start(); - while (index > 1) { - TextFormatting ahead = lookAheadChars(content, index); - if (ahead != null) { - removed.add(index - 2); - } else { - break; - } - index -= 2; - } - } - marcher = COLOR_CODE_PATTERN.matcher(content); - while (marcher.find()) { - int index = marcher.start(); - while (index > 1) { - TextFormatting ahead = lookAheadChars(content, index); - if (ahead == null) { - break; - } else if (TextFormatting.RESET != ahead) { - if (!removed.add(index - 2)) { - break; - } - } else { - break; - } - index -= 2; - } - } - StringBuilder builder = new StringBuilder(); - AtomicInteger start = new AtomicInteger(); - removed.stream().sorted().forEach(remove -> { - builder.append(content, start.get(), remove); - start.set(remove + 2); - }); - builder.append(content, start.get(), content.length()); - return builder.toString(); - } - - private void findFrontFormatting() { - int lastReset = content.lastIndexOf(SECTION_SIGN + "r"); - int lastColor = -1; - frontColor = null; - frontStyle.clear(); - for (TextFormatting value : TextFormatting.values()) { - int index = content.lastIndexOf(value.toString()); - if (index > lastReset) { - if (value.isColor()) { - if (index > lastColor) { - lastColor = index; - frontColor = value; - } - } else if (value.isFancyStyling() && index > lastColor) { - frontStyle.add(value); - } - } - } - } - - public void addFormatting(TextFormatting formatting) { - if (formatting.isColor()) { - frontColor = formatting; - pageInsertIntoCurrent(formatting.toString()); - for (TextFormatting style : frontStyle) { - pageInsertIntoCurrent(style.toString()); - } - } else if (formatting.isFancyStyling()) { - if (frontStyle.contains(formatting)) { - return; - } - frontStyle.add(formatting); - pageInsertIntoCurrent(formatting.toString()); - } - } - - public void removeFormatting(TextFormatting formatting) { - if (formatting.isColor()) { - frontColor = null; - pageInsertIntoCurrent(TextFormatting.RESET.toString()); - frontStyle.forEach(style -> pageInsertIntoCurrent(style.toString())); - } else if (formatting.isFancyStyling()) { - pageInsertIntoCurrent(TextFormatting.RESET.toString()); - if (frontColor != null) { - pageInsertIntoCurrent(frontColor.toString()); - } - frontStyle.remove(formatting); - frontStyle.forEach(style -> pageInsertIntoCurrent(style.toString())); - } - } - - public TextFormatting getFrontColorFormatting() { - return frontColor; - } - - public List getFrontStyleFormatting() { - return frontStyle; - } - - public void pageSetCurrent(String string) { - if (!content.equals(string)) { - content = cleanUpFormatting(string); - findFrontFormatting(); - if (stringUpdate != null) { - stringUpdate.accept(content); - } - textHeight = this.fontRenderer.getWordWrappedHeight(content + TextFormatting.BLACK + "_", - this.getSize().width - yBarWidth); - } - } - - public void pageInsertIntoCurrent(String string) { - content = cleanUpFormatting(content + string); - if (stringUpdate != null) { - stringUpdate.accept(content); - } - textHeight = this.fontRenderer.getWordWrappedHeight(content + TextFormatting.BLACK + "_", - this.getSize().width - yBarWidth); - } - - @Override - public boolean hookDrawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - String contentString = content; - if (focus && isActive()) { - if (this.fontRenderer.getBidiFlag()) { - contentString += "_"; - } else if (this.updateCount / 6 % 2 == 0) { - contentString += TextFormatting.BLACK + "_"; - } else { - contentString += TextFormatting.GRAY + "_"; - } - } - int x = getPosition().x - scrollXOffset; - int y = getPosition().y + SPACE - scrollYOffset; - for (String textLine : this.fontRenderer.listFormattedStringToWidth(contentString, - getSize().width - yBarWidth)) { - fontRenderer.drawString(textLine, x, y, 0xff000000, false); - y += fontRenderer.FONT_HEIGHT; - } - return true; - } - } -} diff --git a/src/main/java/gregtech/api/terminal/gui/widgets/TreeListWidget.java b/src/main/java/gregtech/api/terminal/gui/widgets/TreeListWidget.java deleted file mode 100644 index 45e5c12d55e..00000000000 --- a/src/main/java/gregtech/api/terminal/gui/widgets/TreeListWidget.java +++ /dev/null @@ -1,247 +0,0 @@ -package gregtech.api.terminal.gui.widgets; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.terminal.util.TreeNode; -import gregtech.api.util.Position; -import gregtech.api.util.Size; -import gregtech.client.utils.RenderUtil; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.resources.I18n; -import net.minecraft.util.math.MathHelper; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Function; - -public class TreeListWidget extends Widget { - - private static final int ITEM_HEIGHT = 11; - protected int scrollOffset; - protected List> list; - protected TreeNode selected; - protected IGuiTexture background; - protected IGuiTexture nodeTexture; - protected IGuiTexture leafTexture; - protected Consumer> onSelected; - protected Function keyIconSupplier; - protected Function keyNameSupplier; - protected Function contentIconSupplier; - protected Function contentNameSupplier; - protected boolean canSelectNode; - private int tick; - - public TreeListWidget(int xPosition, int yPosition, int width, int height, - TreeNode root, - Consumer> onSelected) { - super(new Position(xPosition, yPosition), new Size(width, height)); - list = new ArrayList<>(); - if (root.getChildren() != null) { - list.addAll(root.getChildren()); - } - this.onSelected = onSelected; - } - - public TreeListWidget canSelectNode(boolean canSelectNode) { - this.canSelectNode = canSelectNode; - return this; - } - - public TreeListWidget setBackground(IGuiTexture background) { - this.background = background; - return this; - } - - public TreeListWidget setNodeTexture(IGuiTexture nodeTexture) { - this.nodeTexture = nodeTexture; - return this; - } - - public TreeListWidget setLeafTexture(IGuiTexture leafTexture) { - this.leafTexture = leafTexture; - return this; - } - - public TreeListWidget setContentIconSupplier(Function iconSupplier) { - contentIconSupplier = iconSupplier; - return this; - } - - public TreeListWidget setKeyIconSupplier(Function iconSupplier) { - keyIconSupplier = iconSupplier; - return this; - } - - public TreeListWidget setContentNameSupplier(Function nameSupplier) { - contentNameSupplier = nameSupplier; - return this; - } - - public TreeListWidget setKeyNameSupplier(Function nameSupplier) { - keyNameSupplier = nameSupplier; - return this; - } - - @Override - public void updateScreen() { - tick++; - } - - @Override - public boolean mouseWheelMove(int mouseX, int mouseY, int wheelDelta) { - if (this.isMouseOverElement(mouseX, mouseY)) { - int moveDelta = -MathHelper.clamp(wheelDelta, -1, 1) * 5; - this.scrollOffset = MathHelper.clamp(scrollOffset + moveDelta, 0, - Math.max(list.size() * ITEM_HEIGHT - getSize().height, 0)); - return true; - } - return false; - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - int x = getPosition().x; - int y = getPosition().y; - int width = getSize().width; - int height = getSize().height; - if (background != null) { - background.draw(x, y, width, height); - } else { - drawGradientRect(x, y, width, height, 0x8f000000, 0x8f000000); - } - RenderUtil.useScissor(x, y, width, height, () -> { - FontRenderer fr = Minecraft.getMinecraft().fontRenderer; - int minToRender = scrollOffset / ITEM_HEIGHT; - int maxToRender = Math.min(list.size(), height / ITEM_HEIGHT + 2 + minToRender); - for (int i = minToRender; i < maxToRender; i++) { - GlStateManager.color(1, 1, 1, 1); - TreeNode node = list.get(i); - int sX = x + 10 * node.dimension; - int sY = y - scrollOffset + i * ITEM_HEIGHT; - String name = node.toString(); - if (node.isLeaf()) { - if (leafTexture != null) { - leafTexture.draw(x, sY, width, ITEM_HEIGHT); - } else { - drawSolidRect(x, sY, width, ITEM_HEIGHT, 0xffff0000); - } - if (node.getContent() != null) { - String nameS = contentNameSupplier == null ? null : - contentNameSupplier.apply(node.getContent()); - name = nameS == null ? name : nameS; - IGuiTexture icon = contentIconSupplier == null ? null : - contentIconSupplier.apply(node.getContent()); - if (icon != null) { - icon.draw(sX - 9, sY + 1, 8, 8); - } - } - } else { - if (nodeTexture != null) { - nodeTexture.draw(x, sY, width, ITEM_HEIGHT); - } else { - drawSolidRect(x, sY, width, ITEM_HEIGHT, 0xffffff00); - } - String nameS = keyNameSupplier == null ? null : keyNameSupplier.apply(node.getKey()); - name = nameS == null ? name : nameS; - IGuiTexture icon = keyIconSupplier == null ? null : keyIconSupplier.apply(node.getKey()); - if (icon != null) { - icon.draw(sX - 9, sY + 1, 8, 8); - } - } - if (node == selected) { - drawSolidRect(x, sY, width, ITEM_HEIGHT, 0x7f000000); - } - int textW = Math.max(width - 10 * node.dimension, 10); - List list = fr.listFormattedStringToWidth(I18n.format(name), textW); - fr.drawString(list.get(Math.abs((tick / 20) % list.size())), sX, sY + 2, 0xff000000); - } - }); - GlStateManager.enableBlend(); - GlStateManager.color(1, 1, 1, 1); - } - - public TreeNode jumpTo(List path) { - list.removeIf(node -> node.dimension != 1); - this.selected = null; - int dim = 1; - int index = 0; - boolean flag = false; - TreeNode node = null; - for (K key : path) { - flag = false; - for (int i = index; i < list.size(); i++) { - node = list.get(i); - if (node.dimension != dim) { - return null; - } else if (node.getKey().equals(key)) { // expand - if (!node.isLeaf() && path.size() > dim) { - for (int j = 0; j < node.getChildren().size(); j++) { - list.add(index + 1 + j, node.getChildren().get(j)); - } - } - index++; - dim++; - flag = true; - break; - } else { - index++; - } - } - if (!flag) return null; - } - if (flag) { - this.selected = node; - this.scrollOffset = MathHelper.clamp(ITEM_HEIGHT * (index - 1), 0, - Math.max(list.size() * ITEM_HEIGHT - getSize().height, 0)); - return this.selected; - } - return null; - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (this.isMouseOverElement(mouseX, mouseY)) { - int index = ((mouseY - getPosition().y) + scrollOffset) / ITEM_HEIGHT; - if (index < list.size()) { - TreeNode node = list.get(index); - if (node.isLeaf()) { - if (node != this.selected) { - this.selected = node; - if (onSelected != null) { - onSelected.accept(node); - } - } - } else { - if (canSelectNode && this.selected != node) { - this.selected = node; - if (onSelected != null) { - onSelected.accept(node); - } - } else if (node.getChildren().size() > 0 && list.contains(node.getChildren().get(0))) { - removeNode(node); - } else { - for (int i = 0; i < node.getChildren().size(); i++) { - list.add(index + 1 + i, node.getChildren().get(i)); - } - } - } - playButtonClickSound(); - } - return true; - } - return false; - } - - private void removeNode(TreeNode node) { - if (node.isLeaf()) return; - for (TreeNode child : node.getChildren()) { - list.remove(child); - removeNode(child); - } - } -} diff --git a/src/main/java/gregtech/api/terminal/hardware/Hardware.java b/src/main/java/gregtech/api/terminal/hardware/Hardware.java deleted file mode 100644 index 6a34ff4de48..00000000000 --- a/src/main/java/gregtech/api/terminal/hardware/Hardware.java +++ /dev/null @@ -1,101 +0,0 @@ -package gregtech.api.terminal.hardware; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.resources.IGuiTexture; - -import net.minecraft.client.resources.I18n; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -/** - * Created with IntelliJ IDEA. - * - * @Author: KilaBash - * @Date: 2021/08/27 - * @Description: Hardware - */ -public abstract class Hardware { - - protected HardwareProvider provider; - - public abstract String getRegistryName(); - - @SideOnly(Side.CLIENT) - public String getLocalizedName() { - return I18n.format("terminal.hw." + getRegistryName()); - } - - @SideOnly(Side.CLIENT) - public IGuiTexture getIcon() { - return GuiTextures.ICON_REMOVE; - } - - /** - * Check whether the current hardware (this) meets requirement (demand); - */ - public boolean isHardwareAdequate(Hardware demand) { - return this.getClass() == demand.getClass() || this.getRegistryName().equals(demand.getRegistryName()); - } - - /** - * Check whether the terminal has this hardware. - */ - public final boolean hasHW() { - return provider != null && provider.hasHardware(getRegistryName()); - } - - public final ItemStack getItem() { - return provider.getHardwareItem(getRegistryName()); - } - - /** - * Returns the NBT of the this hardware. - */ - public final NBTTagCompound getNBT() { - return provider.getHardwareNBT(getRegistryName()); - } - - /** - * Check whether the terminal is in creative mode. - */ - public final boolean isCreative() { - return provider != null && provider.isCreative(); - } - - /** - * information added to tooltips - * - * @return null->nothing added. - */ - @SideOnly(Side.CLIENT) - public String addInformation() { - return null; - } - - /** - * Create the hardware instance, NOTE!!! do not check nbt or anything here. Terminal has not been initialized here. - * - * @param itemStack terminal - * @return instance - */ - protected abstract Hardware createHardware(ItemStack itemStack); - - /** - * Use the item to install this hardware. - * - * @return The NBT of the hardware is returned if the item is valid, otherwise NULL is returned - */ - public abstract NBTTagCompound acceptItemStack(ItemStack itemStack); - - /** - * Called when the hardware is removed and back to the player inventory. - * - * @param itemStack (original one) - * @return result - */ - public ItemStack onHardwareRemoved(ItemStack itemStack) { - return itemStack; - } -} diff --git a/src/main/java/gregtech/api/terminal/hardware/HardwareProvider.java b/src/main/java/gregtech/api/terminal/hardware/HardwareProvider.java deleted file mode 100644 index 1df64c9efc0..00000000000 --- a/src/main/java/gregtech/api/terminal/hardware/HardwareProvider.java +++ /dev/null @@ -1,143 +0,0 @@ -package gregtech.api.terminal.hardware; - -import gregtech.api.capability.GregtechCapabilities; -import gregtech.api.items.metaitem.stats.IItemCapabilityProvider; -import gregtech.api.terminal.TerminalRegistry; -import gregtech.common.items.behaviors.TerminalBehaviour; - -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumFacing; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.capabilities.ICapabilityProvider; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * Created with IntelliJ IDEA. - * - * @Author: KilaBash - * @Date: 2021/08/28 - * @Description: - */ -public class HardwareProvider implements ICapabilityProvider, IItemCapabilityProvider { - - private Map providers; - private Map itemCache; - private Boolean isCreative; - private ItemStack itemStack; - private NBTTagCompound tag; - - public HardwareProvider() {} - - public void cleanCache(String name) { - itemCache.remove(name); - } - - public boolean isCreative() { - if (isCreative == null) { - isCreative = TerminalBehaviour.isCreative(getItemStack()); - } - return isCreative; - } - - public Map getProviders() { - return providers; - } - - public ItemStack getItemStack() { - return itemStack; - } - - public NBTTagCompound getOrCreateHardwareCompound() { - if (tag == null) { - NBTTagCompound terminal = itemStack.getOrCreateSubCompound("terminal"); - if (!terminal.hasKey("_hw")) { - terminal.setTag("_hw", new NBTTagCompound()); - } - tag = terminal.getCompoundTag("_hw"); - } - return tag; - } - - public List getHardware() { - if (TerminalBehaviour.isCreative(itemStack)) { - return new ArrayList<>(providers.values()); - } - return getOrCreateHardwareCompound().getKeySet().stream().map(providers::get).filter(Objects::nonNull) - .collect(Collectors.toList()); - } - - public boolean hasHardware(String name) { - return itemStack != null && - (TerminalBehaviour.isCreative(getItemStack()) || getOrCreateHardwareCompound().hasKey(name)); - } - - public NBTTagCompound getHardwareNBT(String name) { - return getOrCreateHardwareCompound().getCompoundTag(name); - } - - public ItemStack getHardwareItem(String name) { - if (!itemCache.containsKey(name)) { - NBTTagCompound tag = getHardwareNBT(name); - if (tag.hasKey("item")) { - itemCache.put(name, new ItemStack(tag.getCompoundTag("item"))); - } else { - itemCache.put(name, ItemStack.EMPTY); - } - } - return itemCache.get(name); - } - - @Override - public ICapabilityProvider createProvider(ItemStack itemStack) { - HardwareProvider provider = new HardwareProvider(); - provider.providers = new LinkedHashMap<>(); - provider.itemCache = new HashMap<>(); - provider.itemStack = itemStack; - for (Hardware hardware : TerminalRegistry.getAllHardware()) { - Hardware instance = hardware.createHardware(itemStack); - if (instance != null) { - instance.provider = provider; - provider.providers.put(hardware.getRegistryName(), instance); - } - } - return provider; - } - - @Override - public boolean hasCapability(@NotNull Capability capability, @Nullable EnumFacing facing) { - if (providers != null) { - for (Map.Entry entry : providers.entrySet()) { - Hardware provider = entry.getValue(); - if (provider instanceof IHardwareCapability && - hasHardware(entry.getKey()) && - ((IHardwareCapability) provider).hasCapability(capability)) { - return true; - } - } - } - return capability == GregtechCapabilities.CAPABILITY_HARDWARE_PROVIDER; - } - - @Nullable - @Override - public T getCapability(@NotNull Capability capability, @Nullable EnumFacing facing) { - if (providers != null) { - for (Map.Entry entry : providers.entrySet()) { - Hardware provider = entry.getValue(); - if (provider instanceof IHardwareCapability && - hasHardware(entry.getKey()) && - ((IHardwareCapability) provider).hasCapability(capability)) { - return ((IHardwareCapability) provider).getCapability(capability); - } - } - } - return capability == GregtechCapabilities.CAPABILITY_HARDWARE_PROVIDER ? - GregtechCapabilities.CAPABILITY_HARDWARE_PROVIDER.cast(this) : null; - } -} diff --git a/src/main/java/gregtech/api/terminal/hardware/IHardwareCapability.java b/src/main/java/gregtech/api/terminal/hardware/IHardwareCapability.java deleted file mode 100644 index a02caa5b76f..00000000000 --- a/src/main/java/gregtech/api/terminal/hardware/IHardwareCapability.java +++ /dev/null @@ -1,14 +0,0 @@ -package gregtech.api.terminal.hardware; - -import net.minecraftforge.common.capabilities.Capability; - -import org.jetbrains.annotations.NotNull; - -public interface IHardwareCapability { - - default boolean hasCapability(@NotNull Capability capability) { - return getCapability(capability) != null; - } - - T getCapability(@NotNull Capability capability); -} diff --git a/src/main/java/gregtech/api/terminal/os/SystemCall.java b/src/main/java/gregtech/api/terminal/os/SystemCall.java deleted file mode 100644 index 2110775b5db..00000000000 --- a/src/main/java/gregtech/api/terminal/os/SystemCall.java +++ /dev/null @@ -1,60 +0,0 @@ -package gregtech.api.terminal.os; - -import gregtech.api.terminal.TerminalRegistry; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.util.function.TriConsumer; - -public enum SystemCall { - - CALL_MENU("call_menu", 0, (os, side, args) -> os.callMenu(side)), - FULL_SCREEN("full_screen", 1, (os, side, args) -> os.maximize(side)), - MINIMIZE_FOCUS_APP("minimize_focus_app", 2, (os, side, args) -> os.minimizeApplication(os.getFocusApp(), side)), - CLOSE_FOCUS_APP("close_focus_app", 3, (os, side, args) -> os.closeApplication(os.getFocusApp(), side)), - SHUT_DOWN("shutdown", 4, (os, side, args) -> os.shutdown(side)), - OPEN_APP("open_app", 5, (os, side, args) -> { - if (args.length > 0 && args[0] != null) { - AbstractApplication app = TerminalRegistry.getApplication(args[0]); - if (app != null) { - os.openApplication(app, side); - } - } - }); - - TriConsumer action; - String name; - int index; - - SystemCall(String name, int index, TriConsumer action) { - this.action = action; - this.name = name; - this.index = index; - } - - public void call(TerminalOSWidget os, boolean isClient, String... args) { - action.accept(os, isClient, args); - } - - public String getTranslateKey() { - return "terminal.system_call." + name; - } - - public static SystemCall getFromName(String name) { - for (SystemCall value : SystemCall.values()) { - if (value.name.equalsIgnoreCase(name)) { - return value; - } else if (value.getTranslateKey().equals(name)) { - return value; - } - } - return null; - } - - public static SystemCall getFromIndex(int index) { - for (SystemCall value : SystemCall.values()) { - if (value.index == index) { - return value; - } - } - return null; - } -} diff --git a/src/main/java/gregtech/api/terminal/os/TerminalDesktopWidget.java b/src/main/java/gregtech/api/terminal/os/TerminalDesktopWidget.java deleted file mode 100644 index 19ad7f969b2..00000000000 --- a/src/main/java/gregtech/api/terminal/os/TerminalDesktopWidget.java +++ /dev/null @@ -1,117 +0,0 @@ -package gregtech.api.terminal.os; - -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.gui.widgets.CircleButtonWidget; -import gregtech.api.util.Position; -import gregtech.api.util.Size; - -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import java.util.LinkedList; -import java.util.List; - -public class TerminalDesktopWidget extends WidgetGroup { - - private final TerminalOSWidget os; - private final WidgetGroup appDiv; - private final List topWidgets; - private int rowCount = 7; - - public TerminalDesktopWidget(Position position, Size size, TerminalOSWidget os) { - super(position, size); - this.os = os; - this.appDiv = new WidgetGroup(); - this.addWidget(appDiv); - this.topWidgets = new LinkedList<>(); - } - - public void installApplication(AbstractApplication application) { - int r = 12; - int index = appDiv.widgets.size(); - int x = this.getSize().width / 2 + (3 * r) * (index % rowCount - rowCount / 2); - int y = (index / rowCount) * (3 * r) + 40; - CircleButtonWidget button = new CircleButtonWidget(x, y) - .setColors(TerminalTheme.COLOR_B_2.getColor(), - application.getThemeColor(), - TerminalTheme.COLOR_B_2.getColor()) - .setIcon(application.getIcon()) - .setHoverText(application.getUnlocalizedName()); - button.setClickListener(clickData -> os.openApplication(application, clickData.isClient)); - appDiv.addWidget(button); - } - - @SideOnly(Side.CLIENT) - public void addTopWidget(Widget widget) { - topWidgets.add(widget); - } - - @SideOnly(Side.CLIENT) - public void removeTopWidget(Widget widget) { - topWidgets.remove(widget); - } - - @SideOnly(Side.CLIENT) - private static boolean topWidgetsMouseOver(Widget widget, int mouseX, int mouseY) { - if (widget.isMouseOverElement(mouseX, mouseY)) { - return true; - } - if (widget instanceof WidgetGroup) { - for (Widget child : ((WidgetGroup) widget).widgets) { - if (child.isVisible() && topWidgetsMouseOver(child, mouseX, mouseY)) { - return true; - } - } - } - return false; - } - - @Override - public void drawInForeground(int mouseX, int mouseY) { - boolean isBlocked = false; - for (Widget topWidget : topWidgets) { - if (topWidgetsMouseOver(topWidget, mouseX, mouseY)) { - isBlocked = true; - break; - } - } - for (Widget widget : widgets) { - if (widget.isVisible() && !(isBlocked && widget instanceof AbstractApplication)) { - widget.drawInForeground(mouseX, mouseY); - } - } - } - - public void showDesktop() { - appDiv.setActive(true); - appDiv.setVisible(true); - } - - public void hideDesktop() { - appDiv.setActive(false); - appDiv.setVisible(false); - } - - public void removeAllDialogs() { - for (Widget widget : widgets) { - if (widget instanceof TerminalDialogWidget) { - ((TerminalDialogWidget) widget).close(); - } - } - } - - @Override - public void setSize(Size size) { - super.setSize(size); - this.rowCount = (size.width - 81) / 36; - int r = 12; - for (int i = appDiv.widgets.size() - 1; i >= 0; i--) { - Widget widget = appDiv.widgets.get(i); - int x = this.getSize().width / 2 + (3 * r) * (i % rowCount - rowCount / 2); - int y = (i / rowCount) * (3 * r) + 40; - widget.setSelfPosition(new Position(x - r, y - r)); - } - } -} diff --git a/src/main/java/gregtech/api/terminal/os/TerminalDialogWidget.java b/src/main/java/gregtech/api/terminal/os/TerminalDialogWidget.java deleted file mode 100644 index 30cd7ee1150..00000000000 --- a/src/main/java/gregtech/api/terminal/os/TerminalDialogWidget.java +++ /dev/null @@ -1,421 +0,0 @@ -package gregtech.api.terminal.os; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.resources.TextureArea; -import gregtech.api.gui.widgets.*; -import gregtech.api.terminal.gui.widgets.AnimaWidgetGroup; -import gregtech.api.terminal.gui.widgets.CircleButtonWidget; -import gregtech.api.terminal.gui.widgets.ColorWidget; -import gregtech.api.terminal.gui.widgets.TreeListWidget; -import gregtech.api.terminal.util.FileTree; -import gregtech.api.util.GTLog; -import gregtech.api.util.Position; -import gregtech.api.util.Size; - -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.resources.I18n; -import net.minecraft.inventory.IInventory; -import net.minecraft.item.ItemStack; -import net.minecraft.network.PacketBuffer; - -import java.awt.*; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; -import java.util.function.Predicate; - -public class TerminalDialogWidget extends AnimaWidgetGroup { - - private static final IGuiTexture DIALOG_BACKGROUND = TextureArea - .fullImage("textures/gui/terminal/terminal_dialog.png"); - private static final IGuiTexture OK_NORMAL = TextureArea.fullImage("textures/gui/terminal/icon/ok_normal.png"); - private static final IGuiTexture OK_HOVER = TextureArea.fullImage("textures/gui/terminal/icon/ok_hover.png"); - // private static final IGuiTexture OK_DISABLE = TextureArea.fullImage("textures/gui/terminal/icon/ok_disable.png"); - private static final IGuiTexture CANCEL_NORMAL = TextureArea - .fullImage("textures/gui/terminal/icon/cancel_normal.png"); - private static final IGuiTexture CANCEL_HOVER = TextureArea - .fullImage("textures/gui/terminal/icon/cancel_hover.png"); - // private static final IGuiTexture CANCEL_DISABLE = - // TextureArea.fullImage("textures/gui/terminal/icon/cancel_disable.png"); - private static final int HEIGHT = 128; - private static final int WIDTH = 184; - - private final TerminalOSWidget os; - private IGuiTexture background; - private boolean isClient; - private List iNativeWidgets; - boolean isClosed; - - public TerminalDialogWidget(TerminalOSWidget os, int x, int y, int width, int height) { - super(x, y, width, height); - this.os = os; - } - - public boolean isClient() { - return isClient; - } - - public TerminalDialogWidget open() { - os.openDialog(this); - if (iNativeWidgets != null) { - iNativeWidgets.forEach(this::addWidget); - } - if (isRemote()) { - os.desktop.addTopWidget(this); - } - return this; - } - - public void close() { - if (isClosed) return; - isClosed = true; - os.closeDialog(this); - if (isRemote()) { - os.desktop.removeTopWidget(this); - } - } - - /** - * Should be a client side dialog. - * This is very important, please make sure the right side. - */ - public TerminalDialogWidget setClientSide() { - this.isClient = true; - return this; - } - - public TerminalDialogWidget setBackground(IGuiTexture background) { - this.background = background; - return this; - } - - public TerminalDialogWidget addOkButton(Runnable callback) { - addWidget(new CircleButtonWidget(WIDTH / 2, HEIGHT - 22, 12, 0, 24) - .setClickListener(cd -> { - close(); - if (callback != null) - callback.run(); - }) - .setColors(0, 0, 0) - .setIcon(OK_NORMAL) - .setHoverIcon(OK_HOVER)); - return this; - } - - public TerminalDialogWidget addConfirmButton(Consumer result) { - addWidget(new CircleButtonWidget(WIDTH / 2 - 30, HEIGHT - 22, 12, 0, 24) - .setClickListener(cd -> { - close(); - if (result != null) - result.accept(true); - }) - .setColors(0, 0, 0) - .setIcon(OK_NORMAL) - .setHoverIcon(OK_HOVER)); - addWidget(new CircleButtonWidget(WIDTH / 2 + 30, HEIGHT - 22, 12, 0, 24) - .setClickListener(cd -> { - close(); - if (result != null) - result.accept(false); - }) - .setColors(0, 0, 0) - .setIcon(CANCEL_NORMAL) - .setHoverIcon(CANCEL_HOVER)); - return this; - } - - public TerminalDialogWidget addTitle(String title) { - this.addWidget(new LabelWidget(WIDTH / 2, 11, title, -1).setXCentered(true)); - return this; - } - - public TerminalDialogWidget addInfo(String info) { - this.addWidget(new LabelWidget(WIDTH / 2, HEIGHT / 2, info, -1).setWidth(WIDTH - 16).setYCentered(true) - .setXCentered(true)); - return this; - } - - public static TerminalDialogWidget createEmptyTemplate(TerminalOSWidget os) { - Size size = os.getSize(); - return new TerminalDialogWidget(os, (size.width - WIDTH) / 2, (size.height - HEIGHT) / 2, WIDTH, HEIGHT) - .setBackground(DIALOG_BACKGROUND); - } - - public static TerminalDialogWidget showInfoDialog(TerminalOSWidget os, String title, String info, - Runnable callback) { - return createEmptyTemplate(os).addTitle(title).addInfo(info).addOkButton(callback); - } - - public static TerminalDialogWidget showInfoDialog(TerminalOSWidget os, String title, String info) { - return createEmptyTemplate(os).addTitle(title).addInfo(info).addOkButton(null); - } - - public static TerminalDialogWidget showConfirmDialog(TerminalOSWidget os, String title, String info, - Consumer result) { - return createEmptyTemplate(os).addConfirmButton(result).addTitle(title).addInfo(info); - } - - public static TerminalDialogWidget showTextFieldDialog(TerminalOSWidget os, String title, - Predicate validator, Consumer result) { - TextFieldWidget textFieldWidget = new TextFieldWidget(WIDTH / 2 - 50, HEIGHT / 2 - 15, 100, 20, - new ColorRectTexture(0x2fffffff), null, null).setValidator(validator); - TerminalDialogWidget dialog = createEmptyTemplate(os).addTitle(title).addConfirmButton(b -> { - if (b) { - if (result != null) - result.accept(textFieldWidget.getCurrentString()); - } else { - if (result != null) - result.accept(null); - } - }); - dialog.addWidget(textFieldWidget); - return dialog; - } - - /** - * Show Color Dialog - * - * @return color (rgba) - */ - public static TerminalDialogWidget showColorDialog(TerminalOSWidget os, String title, Consumer result, - int startColor) { - TerminalDialogWidget dialog = createEmptyTemplate(os).addTitle(title); - ColorWidget colorWidget = new ColorWidget(WIDTH / 2 - 60, HEIGHT / 2 - 35, 80, 10); - colorWidget.setStartColor(startColor); - dialog.addWidget(colorWidget); - dialog.addConfirmButton(b -> { - if (b) { - if (result != null) - result.accept(colorWidget.getColor()); - } else { - if (result != null) - result.accept(null); - } - }); - return dialog; - } - - /** - * Show FileDialog - * - * @param dir root directory - * @param isSelector select a file or save a file - * @param result selected file or (saved) - */ - public static TerminalDialogWidget showFileDialog(TerminalOSWidget os, String title, File dir, boolean isSelector, - Consumer result) { - Size size = os.getSize(); - TerminalDialogWidget dialog = new TerminalDialogWidget(os, 0, 0, size.width, size.height) - .setBackground(new ColorRectTexture(0x4f000000)); - if (!dir.isDirectory()) { - if (!dir.mkdirs()) { - return dialog.addInfo(I18n.format("terminal.dialog.error_path") + dir.getPath()).addOkButton(null); - } - } - AtomicReference selected = new AtomicReference<>(); - selected.set(dir); - dialog.addWidget( - new TreeListWidget<>(0, 0, 130, size.height, new FileTree(dir), node -> selected.set(node.getKey())) - .setNodeTexture(GuiTextures.BORDERED_BACKGROUND) - .canSelectNode(true) - .setLeafTexture(GuiTextures.SLOT_DARKENED)); - int x = 130 + (size.width - 133 - WIDTH) / 2; - int y = (size.height - HEIGHT) / 2; - dialog.addWidget(new ImageWidget(x, y, WIDTH, HEIGHT, DIALOG_BACKGROUND)); - dialog.addWidget(new CircleButtonWidget(x + WIDTH / 2 - 30, y + HEIGHT - 22, 12, 0, 24) - .setClickListener(cd -> { - dialog.close(); - if (result != null) - result.accept(selected.get()); - }) - .setColors(0, 0, 0) - .setIcon(OK_NORMAL) - .setHoverIcon(OK_HOVER)); - dialog.addWidget(new CircleButtonWidget(x + WIDTH / 2 + 30, y + HEIGHT - 22, 12, 0, 24) - .setClickListener(cd -> { - dialog.close(); - if (result != null) - result.accept(null); - }) - .setColors(0, 0, 0) - .setIcon(CANCEL_NORMAL) - .setHoverIcon(CANCEL_HOVER)); - if (isSelector) { - dialog.addWidget(new SimpleTextWidget(x + WIDTH / 2, y + HEIGHT / 2 - 5, "", -1, () -> { - if (selected.get() != null) { - return selected.get().toString(); - } - return "terminal.dialog.no_file_selected"; - }, true).setWidth(WIDTH - 16)); - } else { - dialog.addWidget(new TextFieldWidget(x + WIDTH / 2 - 38, y + HEIGHT / 2 - 10, 76, 20, - new ColorRectTexture(0x4f000000), null, null) - .setTextResponder(res -> { - File file = selected.get(); - if (file == null) return; - if (file.isDirectory()) { - selected.set(new File(file, res)); - } else { - selected.set(new File(file.getParent(), res)); - } - }, true) - .setTextSupplier(() -> { - File file = selected.get(); - if (file != null && !file.isDirectory()) { - return selected.get().getName(); - } - return ""; - }, true) - .setMaxStringLength(Integer.MAX_VALUE) - .setValidator(s -> true)); - } - dialog.addWidget(new CircleButtonWidget(x + 17, y + 15, 10, 1, 16) - .setClickListener(cd -> { - File file = selected.get(); - if (file != null && Desktop.isDesktopSupported()) { - try { - Desktop.getDesktop().open(file.isDirectory() ? file : file.getParentFile()); - } catch (IOException e) { - GTLog.logger.error("Error reading opening file " + file.getPath(), e); - } - } - }) - .setColors(0, 0xFFFFFFFF, 0) - .setHoverText("terminal.dialog.folder") - .setIcon(GuiTextures.ICON_LOAD)); - dialog.addWidget(new LabelWidget(x + WIDTH / 2, y + 11, title, -1).setXCentered(true)); - if (os.isRemote()) { - os.menu.hideMenu(); - } - return dialog.setClientSide(); - } - - public static TerminalDialogWidget showItemSelector(TerminalOSWidget os, String title, boolean cost, - Predicate filter, Consumer result) { - TerminalDialogWidget dialog = createEmptyTemplate(os); - dialog.addWidget(new LabelWidget(WIDTH / 2, -7, title, -1).setShadow(true).setXCentered(true)); - IInventory inventoryPlayer = os.getModularUI().entityPlayer.inventory; - if (dialog.iNativeWidgets == null) { - dialog.iNativeWidgets = new ArrayList<>(); - } - int x = 11; - int y = 30; - final SlotWidget[] selected = { null }; - for (int row = 0; row < 4; row++) { - for (int col = 0; col < 9; col++) { - boolean pass = filter == null || filter.test(inventoryPlayer.getStackInSlot(col + row * 9)); - SlotWidget slotWidget = new SlotWidget(inventoryPlayer, col + row * 9, x + col * 18, - (int) (y + (row == 0 ? -1.2 : (row - 1)) * 18), false, false) { - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - super.drawInBackground(mouseX, mouseY, partialTicks, context); - if (selected[0] == this) { - drawBorder(getPosition().x, getPosition().y, getSize().width, getSize().height, -1, 1); - } - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (pass && isMouseOverElement(mouseX, mouseY)) { - if (selected[0] == this) { - selected[0] = null; - } else { - selected[0] = this; - } - writeClientAction(7, buffer -> buffer.writeBoolean(selected[0] == this)); - } - return super.mouseClicked(mouseX, mouseY, button); - } - - @Override - public void handleClientAction(int id, PacketBuffer buffer) { - if (id == 7) { - if (buffer.readBoolean()) { - selected[0] = this; - } else { - selected[0] = null; - } - } - super.readUpdateInfo(id, buffer); - } - }.setBackgroundTexture(TerminalTheme.COLOR_B_1).setLocationInfo(true, false); - slotWidget.setActive(pass); - dialog.iNativeWidgets.add(slotWidget); - } - } - dialog.addConfirmButton(confirm -> { - if (result != null && confirm && selected[0] != null && !selected[0].getHandle().getStack().isEmpty()) { - ItemStack stack = selected[0].getHandle().getStack().copy(); - if (cost) { - selected[0].getHandle().getStack().setCount(stack.getCount() - 1); - } - stack.setCount(1); - result.accept(stack); - } - }); - return dialog; - } - - @Override - public void hookDrawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - GlStateManager.disableDepth(); - if (background != null) { - background.draw(getPosition().x, getPosition().y, getSize().width, getSize().height); - } - super.hookDrawInBackground(mouseX, mouseY, partialTicks, context); - GlStateManager.enableDepth(); - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - for (int i = widgets.size() - 1; i >= 0; i--) { - Widget widget = widgets.get(i); - if (widget.isVisible()) { - if (widget.mouseClicked(mouseX, mouseY, button)) { - return true; - } - } - } - return true; - } - - @Override - protected void writeClientAction(int id, Consumer packetBufferWriter) { - if (isClient || isClosed) return; - super.writeClientAction(id, packetBufferWriter); - } - - @Override - public void handleClientAction(int id, PacketBuffer buffer) { - if (id == -1) { // esc close - if (buffer.readBoolean()) { - close(); - } - } else { - super.handleClientAction(id, buffer); - } - } - - @Override - public boolean keyTyped(char charTyped, int keyCode) { - if (keyCode == 1 && super.interpolator == null) { - writeClientAction(-1, buffer -> buffer.writeBoolean(true)); - close(); - return true; - } - return super.keyTyped(charTyped, keyCode); - } - - public void onOSSizeUpdate(int width, int height) { - setSelfPosition( - Position.ORIGIN.add(new Position((width - getSize().width) / 2, (height - getSize().height) / 2))); - } -} diff --git a/src/main/java/gregtech/api/terminal/os/TerminalHomeButtonWidget.java b/src/main/java/gregtech/api/terminal/os/TerminalHomeButtonWidget.java deleted file mode 100644 index 0b9c7683e4c..00000000000 --- a/src/main/java/gregtech/api/terminal/os/TerminalHomeButtonWidget.java +++ /dev/null @@ -1,145 +0,0 @@ -package gregtech.api.terminal.os; - -import gregtech.api.terminal.TerminalRegistry; -import gregtech.api.terminal.gui.widgets.CircleButtonWidget; -import gregtech.api.util.GTLog; - -import net.minecraft.nbt.CompressedStreamTools; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.PacketBuffer; -import net.minecraftforge.fml.common.FMLCommonHandler; - -import org.apache.commons.lang3.tuple.MutablePair; -import org.apache.commons.lang3.tuple.Pair; - -import java.io.File; -import java.io.IOException; - -public class TerminalHomeButtonWidget extends CircleButtonWidget { - - private final TerminalOSWidget os; - private int mouseClickTime = -1; - private final Pair[] actions; - - public TerminalHomeButtonWidget(TerminalOSWidget os) { - super(351, 115, 11, 2, 18); - this.os = os; - this.setColors(0, TerminalTheme.COLOR_F_1.getColor(), 0); - this.actions = new Pair[8]; - if (FMLCommonHandler.instance().getSide().isClient()) { - NBTTagCompound nbt = null; - try { - nbt = CompressedStreamTools.read(new File(TerminalRegistry.TERMINAL_PATH, "config/home_button.nbt")); - } catch (IOException e) { - GTLog.logger.error("error while loading local nbt for the home button", e); - } - if (nbt == null) { - actions[actionMap(false, false, false)] = new MutablePair<>(SystemCall.CALL_MENU, null); - actions[actionMap(true, false, false)] = new MutablePair<>(SystemCall.MINIMIZE_FOCUS_APP, null); - } else { - for (int i = 0; i < actions.length; i++) { - if (nbt.hasKey(String.valueOf(i))) { - NBTTagCompound tag = nbt.getCompoundTag(String.valueOf(i)); - actions[i] = new MutablePair<>(SystemCall.getFromIndex(tag.getInteger("action")), - tag.hasKey("arg") ? tag.getString("arg") : null); - } - } - } - } - } - - public Pair[] getActions() { - return actions; - } - - public static int actionMap(boolean doubleClick, boolean isCtrl, boolean isShift) { - return (doubleClick ? 1 : 0) + (isCtrl ? 2 : 0) + (isShift ? 4 : 0); - } - - public void saveConfig() { - if (FMLCommonHandler.instance().getSide().isClient()) { - NBTTagCompound nbt = new NBTTagCompound(); - for (int i = 0; i < actions.length; i++) { - if (actions[i] != null) { - NBTTagCompound tag = new NBTTagCompound(); - tag.setInteger("action", actions[i].getKey().index); - if (actions[i].getValue() != null) { - tag.setString("arg", actions[i].getValue()); - } - nbt.setTag(String.valueOf(i), tag); - } - } - try { - if (!nbt.isEmpty()) { - CompressedStreamTools.safeWrite(nbt, - new File(TerminalRegistry.TERMINAL_PATH, "config/home_button.nbt")); - } - } catch (IOException e) { - GTLog.logger.error("error while saving local nbt for the home button", e); - } - } - } - - private void click(int index, boolean isClient, String... args) { - SystemCall action = SystemCall.getFromIndex(index); - if (action != null) { - action.call(os, isClient, args); - } - } - - @Override - public void handleClientAction(int id, PacketBuffer buffer) { - if (id == 1) { - int index = buffer.readVarInt(); - int length = buffer.readVarInt(); - String[] args = new String[length]; - for (int i = 0; i < length; i++) { - args[i] = buffer.readString(32767); - } - click(index, false, args); - } - } - - @Override - public void updateScreen() { - super.updateScreen(); - if (mouseClickTime > 3) { // click - Pair pair = actions[actionMap(false, isCtrlDown(), isShiftDown())]; - sendToServer(pair); - playButtonClickSound(); - mouseClickTime = -1; - } else if (mouseClickTime > -1) { - mouseClickTime++; - } - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (isMouseOverElement(mouseX, mouseY)) { - if (mouseClickTime == -1) { - mouseClickTime = 0; - } else if (mouseClickTime <= 3) { // double click - Pair pair = actions[actionMap(true, isCtrlDown(), isShiftDown())]; - sendToServer(pair); - playButtonClickSound(); - mouseClickTime = -1; - } - return true; - } - return false; - } - - private void sendToServer(Pair pair) { - if (pair != null) { - String[] args = pair.getValue() == null ? new String[0] : pair.getValue().split(" "); - writeClientAction(1, buffer -> { - buffer.writeVarInt(pair.getKey().index); - buffer.writeVarInt(args.length); - for (String arg : args) { - buffer.writeString(arg); - } - }); - click(pair.getKey().index, true, args); - } - } -} diff --git a/src/main/java/gregtech/api/terminal/os/TerminalOSWidget.java b/src/main/java/gregtech/api/terminal/os/TerminalOSWidget.java deleted file mode 100644 index 518609c585a..00000000000 --- a/src/main/java/gregtech/api/terminal/os/TerminalOSWidget.java +++ /dev/null @@ -1,543 +0,0 @@ -package gregtech.api.terminal.os; - -import gregtech.api.capability.GregtechCapabilities; -import gregtech.api.capability.IElectricItem; -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.resources.TextureArea; -import gregtech.api.gui.widgets.AbstractWidgetGroup; -import gregtech.api.terminal.TerminalRegistry; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.hardware.Hardware; -import gregtech.api.terminal.hardware.HardwareProvider; -import gregtech.api.terminal.os.menu.TerminalMenuWidget; -import gregtech.api.util.GTLog; -import gregtech.api.util.Position; -import gregtech.api.util.Size; -import gregtech.client.utils.RenderUtil; -import gregtech.common.items.behaviors.TerminalBehaviour; -import gregtech.common.terminal.app.settings.widgets.OsSettings; -import gregtech.common.terminal.hardware.BatteryHardware; -import gregtech.common.terminal.hardware.DeviceHardware; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.I18n; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.*; -import net.minecraft.network.PacketBuffer; -import net.minecraft.util.math.BlockPos; -import net.minecraftforge.common.util.Constants; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.atomic.AtomicLong; -import java.util.stream.Collectors; - -public class TerminalOSWidget extends AbstractWidgetGroup { - - public static final TextureArea TERMINAL_FRAME = TextureArea.fullImage("textures/gui/terminal/terminal_frame.png"); - public static final TextureArea TERMINAL_HOME = TextureArea.fullImage("textures/gui/terminal/terminal_home.png"); - public static final int DEFAULT_WIDTH = 333; - public static final int DEFAULT_HEIGHT = 232; - - private IGuiTexture background; - private AbstractApplication focusApp; - public final NBTTagCompound tabletNBT; - public final List openedApps; - public final List installedApps; - public final TerminalMenuWidget menu; - public final TerminalDesktopWidget desktop; - public final TerminalHomeButtonWidget home; - public final BlockPos clickPos; - public final ItemStack itemStack; - public final HardwareProvider hardwareProvider; - private int tickCounter; - private long lastCharge; - private boolean maximize; - private boolean showMenuHover = false; - - public TerminalOSWidget(int xPosition, int yPosition, ItemStack itemStack) { - super(new Position(xPosition, yPosition), new Size(DEFAULT_WIDTH, DEFAULT_HEIGHT)); - this.background = TerminalTheme.WALL_PAPER; - this.openedApps = new ArrayList<>(); - this.installedApps = new ArrayList<>(); - this.desktop = new TerminalDesktopWidget(Position.ORIGIN, new Size(DEFAULT_WIDTH, DEFAULT_HEIGHT), this); - this.menu = new TerminalMenuWidget(Position.ORIGIN, new Size(31, DEFAULT_HEIGHT), this) - .setBackground(TerminalTheme.COLOR_B_2); - this.home = new TerminalHomeButtonWidget(this); - this.addWidget(desktop); - this.addWidget(menu); - this.addWidget(home); - this.itemStack = itemStack; - this.tabletNBT = itemStack.getOrCreateSubCompound("terminal"); - this.tabletNBT.removeTag("_ar"); - this.hardwareProvider = itemStack.getCapability(GregtechCapabilities.CAPABILITY_HARDWARE_PROVIDER, null); - if (TerminalBehaviour.isCreative(itemStack)) { - TerminalRegistry.getAllApps().forEach(this::installApplication); - } else { - TerminalRegistry.getDefaultApps().forEach(this::installApplication); - NBTTagList installed = tabletNBT.getTagList("_installed", Constants.NBT.TAG_STRING); - for (NBTBase nbtBase : installed) { - if (nbtBase instanceof NBTTagString) { - AbstractApplication app = TerminalRegistry.getApplication(((NBTTagString) nbtBase).getString()); - if (app != null) { - installApplication(app); - } - } - } - } - if (tabletNBT.hasKey("_click")) { - clickPos = NBTUtil.getPosFromTag(tabletNBT.getCompoundTag("_click")); - } else { - clickPos = null; - } - } - - public ModularUI getModularUI() { - return this.gui; - } - - public TerminalOSWidget setBackground(IGuiTexture background) { - this.background = background; - return this; - } - - public AbstractApplication getFocusApp() { - return focusApp; - } - - public List getHardware() { - if (hardwareProvider == null) { - return Collections.emptyList(); - } - return hardwareProvider.getHardware(); - } - - public List getHardware(Class clazz) { - return getHardware().stream().filter(hw -> hw.getClass() == clazz).map(hw -> (T) hw) - .collect(Collectors.toList()); - } - - public void installApplication(AbstractApplication application) { - desktop.installApplication(application); - installedApps.add(application); - } - - public void openApplication(AbstractApplication application, boolean isClient) { - desktop.removeAllDialogs(); - NBTTagCompound nbt = tabletNBT.getCompoundTag(application.getRegistryName()); - if (!TerminalBehaviour.isCreative(itemStack)) { - List hwDemand = TerminalRegistry.getAppHardwareDemand(application.getRegistryName(), - Math.min(nbt.getInteger("_tier"), application.getMaxTier())); - List unMatch = hwDemand.stream() - .filter(demand -> getHardware().stream().noneMatch(hw -> hw.isHardwareAdequate(demand))) - .collect(Collectors.toList()); - if (unMatch.size() > 0) { - if (isClient) { - StringBuilder tooltips = new StringBuilder("\n"); - for (Hardware match : unMatch) { - String info = match.addInformation(); - String name = match.getLocalizedName(); - if (info == null) { - tooltips.append(name); - } else if (match instanceof BatteryHardware) { - IElectricItem energyItem = itemStack - .getCapability(GregtechCapabilities.CAPABILITY_ELECTRIC_ITEM, null); - if (energyItem != null && energyItem.getCharge() <= 0) { - tooltips.append(I18n.format("terminal.battery.low_energy")); - } else { - tooltips.append(String.format("%s (%s+)", name, info)); - } - } else { - tooltips.append(String.format("%s (%s)", name, info)); - } - tooltips.append(" "); - } - TerminalDialogWidget.showInfoDialog(this, - "terminal.component.error", - I18n.format("terminal.os.hw_demand") + tooltips).setClientSide().open(); - } - return; - } - } - if (!application.canPlayerUse(gui.entityPlayer)) { - return; - } - if (focusApp != null) { - closeApplication(focusApp, isClient); - } - for (AbstractApplication app : openedApps) { - if (app.getRegistryName().equals(application.getRegistryName()) && application.canLaunchConcurrently(app)) { - app.onOSSizeUpdate(this.getSize().width, this.getSize().height); - maximizeApplication(app, isClient); - return; - } - } - AbstractApplication app = application.createAppInstance(this, isClient, nbt); - if (app != null) { - desktop.addWidget(app); - app.setOs(this).initApp(); - app.onOSSizeUpdate(this.getSize().width, this.getSize().height); - openedApps.add(app); - maximizeApplication(app, isClient); - } - } - - public void maximizeApplication(AbstractApplication application, boolean isClient) { - application.setActive(true); - if (isClient) { - application.maximizeWidget(app -> desktop.hideDesktop()); - if (!menu.isHide) { - menu.hideMenu(); - } - } - focusApp = application; - menu.loadComponents(focusApp); - desktop.hideDesktop(); - } - - public void minimizeApplication(AbstractApplication application, boolean isClient) { - desktop.removeAllDialogs(); - if (application != null) { - if (focusApp == application) { - if (isClient) { - application.minimizeWidget(app -> { - if (!application.isBackgroundApp()) { - application.setActive(false); - } - }); - } else if (!application.isBackgroundApp()) { - application.setActive(false); - } - focusApp = null; - } - menu.removeComponents(); - desktop.showDesktop(); - } - } - - public void closeApplication(AbstractApplication application, boolean isClient) { - desktop.removeAllDialogs(); - if (application != null) { - String appName = application.getRegistryName(); - NBTTagCompound synced = application.closeApp(); - - if (synced != null && !synced.isEmpty()) { - tabletNBT.setTag(appName, synced); - if (application.isClientSideApp() && isClient) { - writeClientAction(-2, buffer -> { - buffer.writeString(appName); - buffer.writeCompoundTag(synced); - }); - } - } - - if (isClient && focusApp == application) { - application.minimizeWidget(desktop::waitToRemoved); - } else { - desktop.waitToRemoved(application); - } - openedApps.remove(application); - if (focusApp == application) { - focusApp = null; - } - menu.removeComponents(); - desktop.showDesktop(); - } - } - - public void callMenu(boolean isClient) { - if (isClient) { - if (menu.isHide) { - menu.showMenu(); - } else { - menu.hideMenu(); - } - } - } - - public void shutdown(boolean isClient) { - if (isClient) { - NBTTagCompound nbt = new NBTTagCompound(); - for (AbstractApplication openedApp : openedApps) { - String appName = openedApp.getRegistryName(); - NBTTagCompound synced = openedApp.closeApp(); - if (synced != null && !synced.isEmpty()) { - tabletNBT.setTag(appName, synced); - if (openedApp.isClientSideApp()) {// if its a clientSideApp and the nbt not null, meaning this nbt - // should be synced to the server side. - nbt.setTag(appName, synced); - } - } - } - writeClientAction(-1, buffer -> buffer.writeCompoundTag(nbt)); - } else { // request shutdown from the server side - writeUpdateInfo(-2, packetBuffer -> {}); - } - } - - protected void openDialog(TerminalDialogWidget widget) { - if (isRemote()) { - widget.onOSSizeUpdate(getSize().width, getSize().height); - widget.maximizeWidget(null); - } else if (widget.isClient()) { - return; - } - desktop.addWidget(widget); - } - - protected void closeDialog(TerminalDialogWidget widget) { - if (isRemote()) { - widget.minimizeWidget(desktop::waitToRemoved); - } else if (!widget.isClient()) { - desktop.waitToRemoved(widget); - } - } - - @Override - public void handleClientAction(int id, PacketBuffer buffer) { - if (id == -1) { // shutdown - NBTTagCompound nbt = null; - try { - nbt = buffer.readCompoundTag(); - } catch (IOException e) { - GTLog.logger.error("TerminalOSWidget Shutdown could not read NBT tag from buffer", e); - } - for (AbstractApplication openedApp : openedApps) { - String appName = openedApp.getRegistryName(); - NBTTagCompound data = openedApp.closeApp(); - if (data != null && !data.isEmpty()) { - tabletNBT.setTag(appName, data); - } else if (nbt != null && openedApp.isClientSideApp() && nbt.hasKey(appName)) { - tabletNBT.setTag(appName, nbt.getCompoundTag(appName)); - } - } - this.getModularUI().entityPlayer.closeScreen(); // must close tablet from server side. - } else if (id == -2) { // closeApp sync - String appName = buffer.readString(32767); - NBTTagCompound nbt = null; - try { - nbt = buffer.readCompoundTag(); - } catch (IOException e) { - GTLog.logger.error("TerminalOSWidget CloseApp could not read NBT tag from buffer", e); - } - if (nbt != null) { - tabletNBT.setTag(appName, nbt); - } - } else { - super.handleClientAction(id, buffer); - } - } - - @Override - public void readUpdateInfo(int id, PacketBuffer buffer) { - if (id == -1) { // disCharge - long charge = buffer.readLong(); - IElectricItem electricItem = itemStack.getCapability(GregtechCapabilities.CAPABILITY_ELECTRIC_ITEM, null); - if (electricItem instanceof BatteryHardware) { - ((BatteryHardware) electricItem).setCharge(charge); - } - if (charge <= 0) { - List toClosed = new LinkedList<>(); - for (AbstractApplication openedApp : openedApps) { - TerminalRegistry.getAppHardwareDemand(openedApp.getRegistryName(), openedApp.getAppTier()).stream() - .filter(i -> i instanceof BatteryHardware).findFirst() - .ifPresent(x -> toClosed.add(openedApp)); - } - for (AbstractApplication close : toClosed) { - this.closeApplication(close, true); - } - TerminalDialogWidget.showInfoDialog(this, "terminal.component.warning", "terminal.battery.low_energy") - .setClientSide().open(); - } - } else if (id == -2) { // shutdown - shutdown(true); - } else { - super.readUpdateInfo(id, buffer); - } - } - - @Override - public void updateScreen() { - super.updateScreen(); - tickCounter++; - if (background != null) { - background.updateTick(); - } - } - - @Override - public void detectAndSendChanges() { - super.detectAndSendChanges(); - tickCounter++; - if (tickCounter % 20 == 0) { - long energyStore = disCharge(); - if (lastCharge != energyStore) { - lastCharge = energyStore; - writeUpdateInfo(-1, packetBuffer -> packetBuffer.writeLong(lastCharge)); - } - } - } - - private long disCharge() { - IElectricItem electricItem = hardwareProvider.getCapability(GregtechCapabilities.CAPABILITY_ELECTRIC_ITEM, - null); - if (electricItem != null && !TerminalBehaviour.isCreative(itemStack)) { - AtomicLong costs = new AtomicLong(0); - List charged = new ArrayList<>(); - for (AbstractApplication openedApp : openedApps) { - TerminalRegistry.getAppHardwareDemand(openedApp.getRegistryName(), openedApp.getAppTier()).stream() - .filter(i -> i instanceof BatteryHardware).findFirst() - .ifPresent(battery -> { - costs.addAndGet(((BatteryHardware) battery).getCharge()); - charged.add(openedApp); - }); - } - for (DeviceHardware hardware : getHardware(DeviceHardware.class)) { - if (hardware.getDevice() == DeviceHardware.DEVICE.SOLAR_LV) { - costs.addAndGet(-200); - } - } - if (costs.get() > 0 && electricItem.discharge(costs.get(), 999, true, false, false) != costs.get()) { - charged.forEach(app -> closeApplication(app, false)); - } else if (costs.get() < 0) { - electricItem.charge(-costs.get(), 999, true, false); - } - return electricItem.getCharge(); - } - return lastCharge; - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - Position position = getPosition(); - Size size = getSize(); - - // show menu when mouse near the left edge - if ((focusApp == null || focusApp.canOpenMenuOnEdge()) && - isMouseOver(position.x, position.y, 7, size.height, mouseX, mouseY)) { - if (menu.isHide && !showMenuHover) { - menu.showMenu(); - showMenuHover = true; - } - } else if (!menu.isHide && showMenuHover && - !isMouseOver(position.x - 10, position.y, 41, size.height, mouseX, mouseY)) { - menu.hideMenu(); - showMenuHover = false; - } - - if (background != null) { - background.draw(position.x, position.y, size.width, size.height); - } else { - drawGradientRect(position.x, position.y, size.width, size.height, -1, -1); - } - if (maximize) { - desktop.drawInBackground(mouseX, mouseY, partialTicks, context); - if (menu.isVisible()) { - menu.drawInBackground(mouseX, mouseY, partialTicks, context); - } - } else { - RenderUtil.useScissor(position.x, position.y, size.width, size.height, () -> { - desktop.drawInBackground(mouseX, mouseY, partialTicks, context); - if (menu.isVisible()) { - menu.drawInBackground(mouseX, mouseY, partialTicks, context); - } - }); - TERMINAL_FRAME.draw(position.x - 12, position.y - 11, 380, 256); - } - home.drawInBackground(mouseX, mouseY, partialTicks, context); - } - - boolean waitShutdown; - - @Override - public boolean keyTyped(char charTyped, int keyCode) { - if (waitShutdown && - (keyCode == 1 || Minecraft.getMinecraft().gameSettings.keyBindInventory.isActiveAndMatches(keyCode))) { - shutdown(true); - return true; - } - if (super.keyTyped(charTyped, keyCode)) { - return true; - } - if (keyCode == 1 || Minecraft.getMinecraft().gameSettings.keyBindInventory.isActiveAndMatches(keyCode)) { // hook - // esc - // and - // e - waitShutdown = true; - if (!OsSettings.DOUBLE_CHECK) { - shutdown(true); - return true; - } - TerminalDialogWidget - .showConfirmDialog(this, "terminal.component.warning", "terminal.os.shutdown_confirm", result -> { - if (result) { - shutdown(true); - } else { - waitShutdown = false; - } - }).setClientSide().open(); - return true; - } - waitShutdown = false; - return false; - } - - public boolean isMaximize() { - return maximize; - } - - private void updateOSSize() { - int osWidth = getSize().width; - int osHeight = getSize().height; - if (this.maximize && (osWidth != gui.getScreenWidth() || osHeight != gui.getScreenHeight())) { - osWidth = gui.getScreenWidth(); - osHeight = gui.getScreenHeight(); - } else if (!this.maximize && (osWidth != DEFAULT_WIDTH || osHeight != DEFAULT_HEIGHT)) { - osWidth = DEFAULT_WIDTH; - osHeight = DEFAULT_HEIGHT; - } else { - return; - } - this.setSize(new Size(osWidth, osHeight)); - this.desktop.setSize(new Size(osWidth, osHeight)); - this.menu.setSize(new Size(31, osHeight)); - this.home.setSelfPosition(this.maximize ? - new Position((osWidth - this.home.getSize().width) / 2, osHeight - this.home.getSize().height - 10) : - new Position(340, 104)); - this.home.setIcon(this.maximize ? TERMINAL_HOME : null); - gui.setSize(this.maximize ? osWidth : 380, this.maximize ? osHeight : 256); - if (this.focusApp != null) { - this.focusApp.onOSSizeUpdate(osWidth, osHeight); - } - for (Widget widget : desktop.widgets) { - if (widget instanceof TerminalDialogWidget) { - ((TerminalDialogWidget) widget).onOSSizeUpdate(osWidth, osHeight); - } - } - } - - public void maximize(boolean isClient) { - if (isClient) { - this.maximize = !this.maximize; - updateOSSize(); - } - } - - @Override - public void setParentPosition(Position parentPosition) { - if (this.maximize) { - super.setParentPosition(parentPosition.subtract(this.getSelfPosition())); - if (isRemote()) { - updateOSSize(); - } - } else { - super.setParentPosition(parentPosition); - } - } -} diff --git a/src/main/java/gregtech/api/terminal/os/TerminalTheme.java b/src/main/java/gregtech/api/terminal/os/TerminalTheme.java deleted file mode 100644 index 66bf68c5bfd..00000000000 --- a/src/main/java/gregtech/api/terminal/os/TerminalTheme.java +++ /dev/null @@ -1,106 +0,0 @@ -package gregtech.api.terminal.os; - -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.gui.resources.ModifyGuiTexture; -import gregtech.api.gui.resources.TextureArea; -import gregtech.api.util.FileUtility; - -import net.minecraftforge.fml.common.FMLCommonHandler; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import java.awt.*; -import java.io.File; - -import static gregtech.api.terminal.TerminalRegistry.TERMINAL_PATH; - -public class TerminalTheme { - - private static final String FILE_PATH = "config/theme.json"; - public static final ColorRectTexture COLOR_1 = new ColorRectTexture(new Color(144, 243, 116)); - public static final ColorRectTexture COLOR_2 = new ColorRectTexture(new Color(243, 208, 116)); - public static final ColorRectTexture COLOR_3 = new ColorRectTexture(new Color(231, 95, 95)); - public static final ColorRectTexture COLOR_4 = new ColorRectTexture(new Color(0, 115, 255)); - public static final ColorRectTexture COLOR_5 = new ColorRectTexture(new Color(113, 27, 217)); - public static final ColorRectTexture COLOR_6 = new ColorRectTexture(new Color(30, 30, 30, 255)); - public static final ColorRectTexture COLOR_7 = new ColorRectTexture(new Color(230, 230, 230, 255)); - - public static final ColorRectTexture COLOR_F_1 = new ColorRectTexture(new Color(148, 226, 193)); - public static final ColorRectTexture COLOR_F_2 = new ColorRectTexture(new Color(175, 0, 0, 131)); - - public static final ColorRectTexture COLOR_B_1 = new ColorRectTexture(new Color(0, 0, 0, 80)); - public static final ColorRectTexture COLOR_B_2 = new ColorRectTexture(new Color(0, 0, 0, 160)); - public static final ColorRectTexture COLOR_B_3 = new ColorRectTexture(new Color(246, 120, 120, 160)); - - public static final ModifyGuiTexture WALL_PAPER = new ModifyGuiTexture( - TextureArea.fullImage("textures/gui/terminal/terminal_background.png")); - - static { - if (FMLCommonHandler.instance().getSide().isClient()) { - JsonElement element = FileUtility.loadJson(new File(TERMINAL_PATH, FILE_PATH)); - if (element == null || !element.isJsonObject()) { - saveConfig(); - } else { - JsonObject config = element.getAsJsonObject(); - if (config.has("COLOR_1")) { - COLOR_1.setColor(config.get("COLOR_1").getAsInt()); - } - if (config.has("COLOR_2")) { - COLOR_2.setColor(config.get("COLOR_2").getAsInt()); - } - if (config.has("COLOR_3")) { - COLOR_3.setColor(config.get("COLOR_3").getAsInt()); - } - if (config.has("COLOR_4")) { - COLOR_4.setColor(config.get("COLOR_4").getAsInt()); - } - if (config.has("COLOR_5")) { - COLOR_5.setColor(config.get("COLOR_5").getAsInt()); - } - if (config.has("COLOR_6")) { - COLOR_6.setColor(config.get("COLOR_6").getAsInt()); - } - if (config.has("COLOR_7")) { - COLOR_7.setColor(config.get("COLOR_7").getAsInt()); - } - if (config.has("COLOR_F_1")) { - COLOR_F_1.setColor(config.get("COLOR_F_1").getAsInt()); - } - if (config.has("COLOR_F_2")) { - COLOR_F_2.setColor(config.get("COLOR_F_2").getAsInt()); - } - if (config.has("COLOR_B_1")) { - COLOR_B_1.setColor(config.get("COLOR_B_1").getAsInt()); - } - if (config.has("COLOR_B_2")) { - COLOR_B_2.setColor(config.get("COLOR_B_2").getAsInt()); - } - if (config.has("COLOR_B_3")) { - COLOR_B_3.setColor(config.get("COLOR_B_3").getAsInt()); - } - if (config.has("WALL_PAPER")) { - WALL_PAPER.loadConfig(config.get("WALL_PAPER").getAsJsonObject()); - } - } - } - } - - public static boolean saveConfig() { - JsonObject config = new JsonObject(); - config.addProperty("COLOR_1", COLOR_1.getColor()); - config.addProperty("COLOR_2", COLOR_2.getColor()); - config.addProperty("COLOR_3", COLOR_3.getColor()); - config.addProperty("COLOR_4", COLOR_4.getColor()); - config.addProperty("COLOR_5", COLOR_5.getColor()); - config.addProperty("COLOR_6", COLOR_6.getColor()); - config.addProperty("COLOR_7", COLOR_7.getColor()); - config.addProperty("COLOR_F_1", COLOR_F_1.getColor()); - config.addProperty("COLOR_F_2", COLOR_F_2.getColor()); - config.addProperty("COLOR_B_1", COLOR_B_1.getColor()); - config.addProperty("COLOR_B_2", COLOR_B_2.getColor()); - config.addProperty("COLOR_B_3", COLOR_B_3.getColor()); - config.add("WALL_PAPER", WALL_PAPER.saveConfig()); - return FileUtility.saveJson(new File(TERMINAL_PATH, FILE_PATH), config); - } -} diff --git a/src/main/java/gregtech/api/terminal/os/menu/TerminalMenuWidget.java b/src/main/java/gregtech/api/terminal/os/menu/TerminalMenuWidget.java deleted file mode 100644 index daeaf572d4e..00000000000 --- a/src/main/java/gregtech/api/terminal/os/menu/TerminalMenuWidget.java +++ /dev/null @@ -1,189 +0,0 @@ -package gregtech.api.terminal.os.menu; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.gui.widgets.CircleButtonWidget; -import gregtech.api.terminal.os.SystemCall; -import gregtech.api.terminal.os.TerminalOSWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.util.Position; -import gregtech.api.util.Size; -import gregtech.api.util.interpolate.Eases; -import gregtech.api.util.interpolate.Interpolator; - -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.util.Tuple; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import java.util.ArrayList; -import java.util.List; - -public class TerminalMenuWidget extends WidgetGroup { - - @SideOnly(Side.CLIENT) - private Interpolator interpolator; - private IGuiTexture background; - private final TerminalOSWidget os; - private final List> components; - public boolean isHide; - - public TerminalMenuWidget(Position position, Size size, TerminalOSWidget os) { - super(position, size); - addSelfPosition(-size.width, 0); - setVisible(false); - isHide = true; - this.os = os; - components = new ArrayList<>(); - this.addWidget(new CircleButtonWidget(5, 10, 4, 1, 0) - .setColors(0, - TerminalTheme.COLOR_7.getColor(), - TerminalTheme.COLOR_3.getColor()) - .setHoverText("terminal.menu.close") - .setClickListener(this::close)); - this.addWidget(new CircleButtonWidget(15, 10, 4, 1, 0) - .setColors(0, - TerminalTheme.COLOR_7.getColor(), - TerminalTheme.COLOR_2.getColor()) - .setHoverText("terminal.menu.minimize") - .setClickListener(this::minimize)); - this.addWidget(new CircleButtonWidget(25, 10, 4, 1, 0) - .setColors(0, - TerminalTheme.COLOR_7.getColor(), - TerminalTheme.COLOR_1.getColor()) - .setHoverText("terminal.menu.maximize") - .setClickListener(this::maximize)); - } - - public TerminalMenuWidget setBackground(IGuiTexture background) { - this.background = background; - return this; - } - - public void close(ClickData clickData) { - SystemCall.CLOSE_FOCUS_APP.call(os, clickData.isClient); - } - - public void minimize(ClickData clickData) { - SystemCall.MINIMIZE_FOCUS_APP.call(os, clickData.isClient); - } - - public void maximize(ClickData clickData) { - SystemCall.FULL_SCREEN.call(os, clickData.isClient); - } - - public void addComponent(IMenuComponent component) { - WidgetGroup group = new WidgetGroup(); - int x = 15; - int y = 40 + components.size() * 25; - CircleButtonWidget button = new CircleButtonWidget(x, y, 10, 1, 16) - .setColors(0, 0xFFFFFFFF, 0) - .setHoverText(component.hoverText()) - .setIcon(component.buttonIcon()); - button.setClickListener(c -> { - components.forEach(tuple -> { - if (tuple.getFirst() instanceof Widget && tuple.getFirst() != component) { - ((Widget) tuple.getFirst()).setActive(false); - ((Widget) tuple.getFirst()).setVisible(false); - ((CircleButtonWidget) tuple.getSecond().widgets.get(0)).setFill(0); - } - }); - if (component instanceof Widget) { - Widget widget = (Widget) component; - widget.setVisible(!widget.isVisible()); - widget.setActive(!widget.isActive()); - button.setFill(widget.isVisible() ? 0xFF94E2C1 : 0); - } - component.click(c); - }); - group.addWidget(button); - if (component instanceof Widget) { - Widget widget = (Widget) component; - widget.setSelfPosition(new Position(x + 20, 0)); - widget.setVisible(false); - widget.setActive(false); - group.addWidget(widget); - } - this.addWidget(group); - components.add(new Tuple<>(component, group)); - } - - public void loadComponents(AbstractApplication app) { - removeComponents(); - if (app != null) { - app.getMenuComponents().forEach(this::addComponent); - } - } - - public void removeComponents() { - components.forEach(component -> this.removeWidget(component.getSecond())); - components.clear(); - } - - @SideOnly(Side.CLIENT) - public void hideMenu() { - if (!isHide && interpolator == null) { - int y = getSelfPosition().y; - interpolator = new Interpolator(getSelfPosition().x, getSelfPosition().x - getSize().width, 6, Eases.LINEAR, - value -> setSelfPosition(new Position(value.intValue(), y)), - value -> { - setVisible(false); - interpolator = null; - isHide = true; - }); - interpolator.start(); - os.desktop.removeTopWidget(this); - } - } - - @SideOnly(Side.CLIENT) - public void showMenu() { - if (isHide && interpolator == null) { - setVisible(true); - int y = getSelfPosition().y; - interpolator = new Interpolator(getSelfPosition().x, getSelfPosition().x + getSize().width, 6, Eases.LINEAR, - value -> setSelfPosition(new Position(value.intValue(), y)), - value -> { - interpolator = null; - isHide = false; - }); - interpolator.start(); - os.desktop.addTopWidget(this); - } - } - - @Override - public void updateScreenOnFrame() { - if (interpolator != null) interpolator.update(); - super.updateScreenOnFrame(); - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - GlStateManager.color(1, 1, 1, 0.5f); - if (background != null) { - background.draw(this.getPosition().x, this.getPosition().y, this.getSize().width, this.getSize().height); - } else { - drawGradientRect(this.getPosition().x, this.getPosition().y, this.getSize().width, this.getSize().height, - 0xff000000, 0xff000000); - } - GlStateManager.color(1, 1, 1, 1); - super.drawInBackground(mouseX, mouseY, partialTicks, context); - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (!super.mouseClicked(mouseX, mouseY, button)) { - if (isMouseOverElement(mouseX, mouseY)) { - return true; - } else if (!isHide) { - hideMenu(); - } - return false; - } - return true; - } -} diff --git a/src/main/java/gregtech/api/terminal/util/FileTree.java b/src/main/java/gregtech/api/terminal/util/FileTree.java deleted file mode 100644 index 5097c478aff..00000000000 --- a/src/main/java/gregtech/api/terminal/util/FileTree.java +++ /dev/null @@ -1,53 +0,0 @@ -package gregtech.api.terminal.util; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class FileTree extends TreeNode { - - public FileTree(File dir) { - this(0, dir); - } - - private FileTree(int dimension, File key) { - super(dimension, key); - } - - @Override - public boolean isLeaf() { - return getKey().isFile(); - } - - @Override - public File getContent() { - return isLeaf() ? getKey() : null; - } - - @Override - public List> getChildren() { - if (children == null && !isLeaf()) { - children = new ArrayList<>(); - File[] listFiles = key.listFiles(); - if (listFiles != null) { - Arrays.stream(listFiles).sorted((a, b) -> { - if (a.isFile() && b.isFile()) { - return a.compareTo(b); - } else if (a.isDirectory() && b.isDirectory()) { - return a.compareTo(b); - } else if (a.isDirectory()) { - return -1; - } - return 1; - }).forEach(file -> children.add(new FileTree(dimension + 1, file))); - } - } - return super.getChildren(); - } - - @Override - public String toString() { - return getKey().getName(); - } -} diff --git a/src/main/java/gregtech/api/terminal/util/TreeNode.java b/src/main/java/gregtech/api/terminal/util/TreeNode.java deleted file mode 100644 index 7f99ac830ae..00000000000 --- a/src/main/java/gregtech/api/terminal/util/TreeNode.java +++ /dev/null @@ -1,75 +0,0 @@ -package gregtech.api.terminal.util; - -import java.util.ArrayList; -import java.util.List; - -/*** - * Tree - * - * @param key - * @param leaf - */ -public class TreeNode { - - public final int dimension; - protected final T key; - protected K content; - protected List> children; - - public TreeNode(int dimension, T key) { - this.dimension = dimension; - this.key = key; - } - - public boolean isLeaf() { - return getChildren() == null || getChildren().isEmpty(); - } - - public TreeNode getOrCreateChild(T childKey) { - TreeNode result; - if (getChildren() != null) { - result = getChildren().stream().filter(child -> child.key.equals(childKey)).findFirst().orElseGet(() -> { - TreeNode newNode = new TreeNode<>(dimension + 1, childKey); - getChildren().add(newNode); - return newNode; - }); - } else { - children = new ArrayList<>(); - result = new TreeNode<>(dimension + 1, childKey); - getChildren().add(result); - } - return result; - } - - public TreeNode getChild(T key) { - if (getChildren() != null) { - for (TreeNode child : getChildren()) { - if (child.key.equals(key)) { - return child; - } - } - } - return null; - } - - public void addContent(T key, K content) { - getOrCreateChild(key).content = content; - } - - public T getKey() { - return key; - } - - public K getContent() { - return content; - } - - public List> getChildren() { - return children; - } - - @Override - public String toString() { - return key.toString(); - } -} diff --git a/src/main/java/gregtech/api/unification/Element.java b/src/main/java/gregtech/api/unification/Element.java index 2826212ecc0..5b4f85aafcc 100644 --- a/src/main/java/gregtech/api/unification/Element.java +++ b/src/main/java/gregtech/api/unification/Element.java @@ -21,7 +21,7 @@ public class Element { @ZenProperty("isotope") public final boolean isIsotope; @ZenProperty("halfLifeSeconds") - public final long halfLifeSeconds; + public final double halfLifeSeconds; @ZenProperty("decayTo") public final String decayTo; @@ -34,8 +34,8 @@ public class Element { * @param name Name of the Element * @param symbol Symbol of the Element */ - public Element(long protons, long neutrons, long halfLifeSeconds, String decayTo, String name, String symbol, - boolean isIsotope) { + protected Element(long protons, long neutrons, double halfLifeSeconds, String decayTo, String name, String symbol, + boolean isIsotope) { this.protons = protons; this.neutrons = neutrons; this.halfLifeSeconds = halfLifeSeconds; @@ -73,6 +73,6 @@ public long getMass() { @Override @ZenMethod public String toString() { - return super.toString(); + return name; } } diff --git a/src/main/java/gregtech/api/unification/Elements.java b/src/main/java/gregtech/api/unification/Elements.java index d49203d32f6..3f0e198faff 100644 --- a/src/main/java/gregtech/api/unification/Elements.java +++ b/src/main/java/gregtech/api/unification/Elements.java @@ -1,178 +1,249 @@ package gregtech.api.unification; +import gregtech.api.util.GTLog; + import com.google.common.base.CaseFormat; import crafttweaker.annotations.ZenRegister; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import stanhebben.zenscript.annotations.ZenClass; import stanhebben.zenscript.annotations.ZenMethod; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; @ZenClass("mods.gregtech.material.Elements") @ZenRegister public class Elements { - private static final Map elements = new HashMap<>(); + private static final Pattern namePattern = Pattern.compile("[A-Z]+[A-Za-z]*(-\\d+)?"); + + private static final Map elements = new Object2ObjectOpenHashMap<>(); + private static final Map elementsBySymbol = new Object2ObjectOpenHashMap<>(); + private static final List elementList = new ArrayList<>(); + private static final List elementsView = Collections.unmodifiableList(elementList); private Elements() {} - public static final Element H = add(1, 0, -1, null, "Hydrogen", "H", false); + public static final Element H = add(1, 0, "Hydrogen", "H"); public static final Element D = add(1, 1, -1, "H", "Deuterium", "D", true); public static final Element T = add(1, 2, -1, "D", "Tritium", "T", true); - public static final Element He = add(2, 2, -1, null, "Helium", "He", false); + public static final Element He = add(2, 2, "Helium", "He"); public static final Element He3 = add(2, 1, -1, "H&D", "Helium-3", "He-3", true); - public static final Element Li = add(3, 4, -1, null, "Lithium", "Li", false); - public static final Element Be = add(4, 5, -1, null, "Beryllium", "Be", false); - public static final Element B = add(5, 5, -1, null, "Boron", "B", false); - public static final Element C = add(6, 6, -1, null, "Carbon", "C", false); - public static final Element N = add(7, 7, -1, null, "Nitrogen", "N", false); - public static final Element O = add(8, 8, -1, null, "Oxygen", "O", false); - public static final Element F = add(9, 9, -1, null, "Fluorine", "F", false); - public static final Element Ne = add(10, 10, -1, null, "Neon", "Ne", false); - public static final Element Na = add(11, 11, -1, null, "Sodium", "Na", false); - public static final Element Mg = add(12, 12, -1, null, "Magnesium", "Mg", false); - public static final Element Al = add(13, 13, -1, null, "Aluminium", "Al", false); - public static final Element Si = add(14, 14, -1, null, "Silicon", "Si", false); - public static final Element P = add(15, 15, -1, null, "Phosphorus", "P", false); - public static final Element S = add(16, 16, -1, null, "Sulfur", "S", false); - public static final Element Cl = add(17, 18, -1, null, "Chlorine", "Cl", false); - public static final Element Ar = add(18, 22, -1, null, "Argon", "Ar", false); - public static final Element K = add(19, 20, -1, null, "Potassium", "K", false); - public static final Element Ca = add(20, 20, -1, null, "Calcium", "Ca", false); - public static final Element Sc = add(21, 24, -1, null, "Scandium", "Sc", false); - public static final Element Ti = add(22, 26, -1, null, "Titanium", "Ti", false); - public static final Element V = add(23, 28, -1, null, "Vanadium", "V", false); - public static final Element Cr = add(24, 28, -1, null, "Chrome", "Cr", false); - public static final Element Mn = add(25, 30, -1, null, "Manganese", "Mn", false); - public static final Element Fe = add(26, 30, -1, null, "Iron", "Fe", false); - public static final Element Co = add(27, 32, -1, null, "Cobalt", "Co", false); - public static final Element Ni = add(28, 30, -1, null, "Nickel", "Ni", false); - public static final Element Cu = add(29, 34, -1, null, "Copper", "Cu", false); - public static final Element Zn = add(30, 35, -1, null, "Zinc", "Zn", false); - public static final Element Ga = add(31, 39, -1, null, "Gallium", "Ga", false); - public static final Element Ge = add(32, 40, -1, null, "Germanium", "Ge", false); - public static final Element As = add(33, 42, -1, null, "Arsenic", "As", false); - public static final Element Se = add(34, 45, -1, null, "Selenium", "Se", false); - public static final Element Br = add(35, 45, -1, null, "Bromine", "Br", false); - public static final Element Kr = add(36, 48, -1, null, "Krypton", "Kr", false); - public static final Element Rb = add(37, 48, -1, null, "Rubidium", "Rb", false); - public static final Element Sr = add(38, 49, -1, null, "Strontium", "Sr", false); - public static final Element Y = add(39, 50, -1, null, "Yttrium", "Y", false); - public static final Element Zr = add(40, 51, -1, null, "Zirconium", "Zr", false); - public static final Element Nb = add(41, 53, -1, null, "Niobium", "Nb", false); - public static final Element Mo = add(42, 53, -1, null, "Molybdenum", "Mo", false); - public static final Element Tc = add(43, 55, -1, null, "Technetium", "Tc", false); - public static final Element Ru = add(44, 57, -1, null, "Ruthenium", "Ru", false); - public static final Element Rh = add(45, 58, -1, null, "Rhodium", "Rh", false); - public static final Element Pd = add(46, 60, -1, null, "Palladium", "Pd", false); - public static final Element Ag = add(47, 60, -1, null, "Silver", "Ag", false); - public static final Element Cd = add(48, 64, -1, null, "Cadmium", "Cd", false); - public static final Element In = add(49, 65, -1, null, "Indium", "In", false); - public static final Element Sn = add(50, 68, -1, null, "Tin", "Sn", false); - public static final Element Sb = add(51, 70, -1, null, "Antimony", "Sb", false); - public static final Element Te = add(52, 75, -1, null, "Tellurium", "Te", false); - public static final Element I = add(53, 74, -1, null, "Iodine", "I", false); - public static final Element Xe = add(54, 77, -1, null, "Xenon", "Xe", false); - public static final Element Cs = add(55, 77, -1, null, "Caesium", "Cs", false); - public static final Element Ba = add(56, 81, -1, null, "Barium", "Ba", false); - public static final Element La = add(57, 81, -1, null, "Lanthanum", "La", false); - public static final Element Ce = add(58, 82, -1, null, "Cerium", "Ce", false); - public static final Element Pr = add(59, 81, -1, null, "Praseodymium", "Pr", false); - public static final Element Nd = add(60, 84, -1, null, "Neodymium", "Nd", false); - public static final Element Pm = add(61, 83, -1, null, "Promethium", "Pm", false); - public static final Element Sm = add(62, 88, -1, null, "Samarium", "Sm", false); - public static final Element Eu = add(63, 88, -1, null, "Europium", "Eu", false); - public static final Element Gd = add(64, 93, -1, null, "Gadolinium", "Gd", false); - public static final Element Tb = add(65, 93, -1, null, "Terbium", "Tb", false); - public static final Element Dy = add(66, 96, -1, null, "Dysprosium", "Dy", false); - public static final Element Ho = add(67, 97, -1, null, "Holmium", "Ho", false); - public static final Element Er = add(68, 99, -1, null, "Erbium", "Er", false); - public static final Element Tm = add(69, 99, -1, null, "Thulium", "Tm", false); - public static final Element Yb = add(70, 103, -1, null, "Ytterbium", "Yb", false); - public static final Element Lu = add(71, 103, -1, null, "Lutetium", "Lu", false); - public static final Element Hf = add(72, 106, -1, null, "Hafnium", "Hf", false); - public static final Element Ta = add(73, 107, -1, null, "Tantalum", "Ta", false); - public static final Element W = add(74, 109, -1, null, "Tungsten", "W", false); - public static final Element Re = add(75, 111, -1, null, "Rhenium", "Re", false); - public static final Element Os = add(76, 114, -1, null, "Osmium", "Os", false); - public static final Element Ir = add(77, 115, -1, null, "Iridium", "Ir", false); - public static final Element Pt = add(78, 117, -1, null, "Platinum", "Pt", false); - public static final Element Au = add(79, 117, -1, null, "Gold", "Au", false); - public static final Element Hg = add(80, 120, -1, null, "Mercury", "Hg", false); - public static final Element Tl = add(81, 123, -1, null, "Thallium", "Tl", false); - public static final Element Pb = add(82, 125, -1, null, "Lead", "Pb", false); - public static final Element Bi = add(83, 125, -1, null, "Bismuth", "Bi", false); - public static final Element Po = add(84, 124, -1, null, "Polonium", "Po", false); - public static final Element At = add(85, 124, -1, null, "Astatine", "At", false); - public static final Element Rn = add(86, 134, -1, null, "Radon", "Rn", false); - public static final Element Fr = add(87, 134, -1, null, "Francium", "Fr", false); - public static final Element Ra = add(88, 136, -1, null, "Radium", "Ra", false); - public static final Element Ac = add(89, 136, -1, null, "Actinium", "Ac", false); - public static final Element Th = add(90, 140, -1, null, "Thorium", "Th", false); - public static final Element Pa = add(91, 138, -1, null, "Protactinium", "Pa", false); - public static final Element U = add(92, 146, -1, null, "Uranium", "U", false); - public static final Element U238 = add(92, 146, -1, null, "Uranium-238", "U-238", false); - public static final Element U235 = add(92, 143, -1, null, "Uranium-235", "U-235", true); - public static final Element Np = add(93, 144, -1, null, "Neptunium", "Np", false); - public static final Element Pu = add(94, 152, -1, null, "Plutonium", "Pu", false); - public static final Element Pu239 = add(94, 145, -1, null, "Plutonium-239", "Pu-239", false); - public static final Element Pu241 = add(94, 149, -1, null, "Plutonium-241", "Pu-241", true); - public static final Element Am = add(95, 150, -1, null, "Americium", "Am", false); - public static final Element Cm = add(96, 153, -1, null, "Curium", "Cm", false); - public static final Element Bk = add(97, 152, -1, null, "Berkelium", "Bk", false); - public static final Element Cf = add(98, 153, -1, null, "Californium", "Cf", false); - public static final Element Es = add(99, 153, -1, null, "Einsteinium", "Es", false); - public static final Element Fm = add(100, 157, -1, null, "Fermium", "Fm", false); - public static final Element Md = add(101, 157, -1, null, "Mendelevium", "Md", false); - public static final Element No = add(102, 157, -1, null, "Nobelium", "No", false); - public static final Element Lr = add(103, 159, -1, null, "Lawrencium", "Lr", false); - public static final Element Rf = add(104, 161, -1, null, "Rutherfordium", "Rf", false); - public static final Element Db = add(105, 163, -1, null, "Dubnium", "Db", false); - public static final Element Sg = add(106, 165, -1, null, "Seaborgium", "Sg", false); - public static final Element Bh = add(107, 163, -1, null, "Bohrium", "Bh", false); - public static final Element Hs = add(108, 169, -1, null, "Hassium", "Hs", false); - public static final Element Mt = add(109, 167, -1, null, "Meitnerium", "Mt", false); - public static final Element Ds = add(110, 171, -1, null, "Darmstadtium", "Ds", false); - public static final Element Rg = add(111, 169, -1, null, "Roentgenium", "Rg", false); - public static final Element Cn = add(112, 173, -1, null, "Copernicium", "Cn", false); - public static final Element Nh = add(113, 171, -1, null, "Nihonium", "Nh", false); - public static final Element Fl = add(114, 175, -1, null, "Flerovium", "Fl", false); - public static final Element Mc = add(115, 173, -1, null, "Moscovium", "Mc", false); - public static final Element Lv = add(116, 177, -1, null, "Livermorium", "Lv", false); - public static final Element Ts = add(117, 177, -1, null, "Tennessine", "Ts", false); - public static final Element Og = add(118, 176, -1, null, "Oganesson", "Og", false); + public static final Element Li = add(3, 4, "Lithium", "Li"); + public static final Element Be = add(4, 5, "Beryllium", "Be"); + public static final Element B = add(5, 5, "Boron", "B"); + public static final Element C = add(6, 6, "Carbon", "C"); + public static final Element N = add(7, 7, "Nitrogen", "N"); + public static final Element O = add(8, 8, "Oxygen", "O"); + public static final Element F = add(9, 9, "Fluorine", "F"); + public static final Element Ne = add(10, 10, "Neon", "Ne"); + public static final Element Na = add(11, 11, "Sodium", "Na"); + public static final Element Mg = add(12, 12, "Magnesium", "Mg"); + public static final Element Al = add(13, 13, "Aluminium", "Al"); + public static final Element Si = add(14, 14, "Silicon", "Si"); + public static final Element P = add(15, 15, "Phosphorus", "P"); + public static final Element S = add(16, 16, "Sulfur", "S"); + public static final Element Cl = add(17, 18, "Chlorine", "Cl"); + public static final Element Ar = add(18, 22, "Argon", "Ar"); + public static final Element K = add(19, 20, "Potassium", "K"); + public static final Element Ca = add(20, 20, "Calcium", "Ca"); + public static final Element Sc = add(21, 24, "Scandium", "Sc"); + public static final Element Ti = add(22, 26, "Titanium", "Ti"); + public static final Element V = add(23, 28, "Vanadium", "V"); + public static final Element Cr = add(24, 28, "Chrome", "Cr"); + public static final Element Mn = add(25, 30, "Manganese", "Mn"); + public static final Element Fe = add(26, 30, "Iron", "Fe"); + public static final Element Co = add(27, 32, "Cobalt", "Co"); + public static final Element Ni = add(28, 30, "Nickel", "Ni"); + public static final Element Cu = add(29, 34, "Copper", "Cu"); + public static final Element Zn = add(30, 35, "Zinc", "Zn"); + public static final Element Ga = add(31, 39, "Gallium", "Ga"); + public static final Element Ge = add(32, 40, "Germanium", "Ge"); + public static final Element As = add(33, 42, "Arsenic", "As"); + public static final Element Se = add(34, 45, "Selenium", "Se"); + public static final Element Br = add(35, 45, "Bromine", "Br"); + public static final Element Kr = add(36, 48, "Krypton", "Kr"); + public static final Element Rb = add(37, 48, "Rubidium", "Rb"); + public static final Element Sr = add(38, 49, "Strontium", "Sr"); + public static final Element Y = add(39, 50, "Yttrium", "Y"); + public static final Element Zr = add(40, 51, "Zirconium", "Zr"); + public static final Element Nb = add(41, 53, "Niobium", "Nb"); + public static final Element Mo = add(42, 53, "Molybdenum", "Mo"); + public static final Element Tc = add(43, 55, "Technetium", "Tc"); + public static final Element Ru = add(44, 57, "Ruthenium", "Ru"); + public static final Element Rh = add(45, 58, "Rhodium", "Rh"); + public static final Element Pd = add(46, 60, "Palladium", "Pd"); + public static final Element Ag = add(47, 60, "Silver", "Ag"); + public static final Element Cd = add(48, 64, "Cadmium", "Cd"); + public static final Element In = add(49, 65, "Indium", "In"); + public static final Element Sn = add(50, 68, "Tin", "Sn"); + public static final Element Sb = add(51, 70, "Antimony", "Sb"); + public static final Element Te = add(52, 75, "Tellurium", "Te"); + public static final Element I = add(53, 74, "Iodine", "I"); + public static final Element Xe = add(54, 77, "Xenon", "Xe"); + public static final Element Cs = add(55, 77, "Caesium", "Cs"); + public static final Element Ba = add(56, 81, "Barium", "Ba"); + public static final Element La = add(57, 81, "Lanthanum", "La"); + public static final Element Ce = add(58, 82, "Cerium", "Ce"); + public static final Element Pr = add(59, 81, "Praseodymium", "Pr"); + public static final Element Nd = add(60, 84, "Neodymium", "Nd"); + public static final Element Pm = add(61, 83, "Promethium", "Pm"); + public static final Element Sm = add(62, 88, "Samarium", "Sm"); + public static final Element Eu = add(63, 88, "Europium", "Eu"); + public static final Element Gd = add(64, 93, "Gadolinium", "Gd"); + public static final Element Tb = add(65, 93, "Terbium", "Tb"); + public static final Element Dy = add(66, 96, "Dysprosium", "Dy"); + public static final Element Ho = add(67, 97, "Holmium", "Ho"); + public static final Element Er = add(68, 99, "Erbium", "Er"); + public static final Element Tm = add(69, 99, "Thulium", "Tm"); + public static final Element Yb = add(70, 103, "Ytterbium", "Yb"); + public static final Element Lu = add(71, 103, "Lutetium", "Lu"); + public static final Element Hf = add(72, 106, "Hafnium", "Hf"); + public static final Element Ta = add(73, 107, "Tantalum", "Ta"); + public static final Element W = add(74, 109, "Tungsten", "W"); + public static final Element Re = add(75, 111, "Rhenium", "Re"); + public static final Element Os = add(76, 114, "Osmium", "Os"); + public static final Element Ir = add(77, 115, "Iridium", "Ir"); + public static final Element Pt = add(78, 117, "Platinum", "Pt"); + public static final Element Au = add(79, 117, "Gold", "Au"); + public static final Element Hg = add(80, 120, "Mercury", "Hg"); + public static final Element Tl = add(81, 123, "Thallium", "Tl"); + public static final Element Pb = add(82, 125, "Lead", "Pb"); + public static final Element Bi = add(83, 125, "Bismuth", "Bi"); + public static final Element Po = add(84, 124, "Polonium", "Po"); + public static final Element At = add(85, 124, "Astatine", "At"); + public static final Element Rn = add(86, 134, "Radon", "Rn"); + public static final Element Fr = add(87, 134, "Francium", "Fr"); + public static final Element Ra = add(88, 136, "Radium", "Ra"); + public static final Element Ac = add(89, 136, "Actinium", "Ac"); + public static final Element Th = add(90, 140, "Thorium", "Th"); + public static final Element Pa = add(91, 138, "Protactinium", "Pa"); + public static final Element U = add(92, 146, 1.4090285e+17, null, "Uranium", "U", false); + public static final Element U238 = add(92, 146, 1.4090285e+17, null, "Uranium-238", "U-238", true); + public static final Element U235 = add(92, 143, 2.2195037e+16, null, "Uranium-235", "U-235", true); + public static final Element Np = add(93, 144, "Neptunium", "Np"); + public static final Element Pu = add(94, 152, 760332960000.0, null, "Plutonium", "Pu", false); + public static final Element Pu239 = add(94, 145, 760332960000.0, null, "Plutonium-239", "Pu-239", true); + public static final Element Pu241 = add(94, 147, 450649440.0, null, "Plutonium-241", "Pu-241", true); + public static final Element Am = add(95, 150, "Americium", "Am"); + public static final Element Cm = add(96, 153, "Curium", "Cm"); + public static final Element Bk = add(97, 152, "Berkelium", "Bk"); + public static final Element Cf = add(98, 153, "Californium", "Cf"); + public static final Element Es = add(99, 153, "Einsteinium", "Es"); + public static final Element Fm = add(100, 157, "Fermium", "Fm"); + public static final Element Md = add(101, 157, "Mendelevium", "Md"); + public static final Element No = add(102, 157, "Nobelium", "No"); + public static final Element Lr = add(103, 159, "Lawrencium", "Lr"); + public static final Element Rf = add(104, 161, "Rutherfordium", "Rf"); + public static final Element Db = add(105, 163, "Dubnium", "Db"); + public static final Element Sg = add(106, 165, "Seaborgium", "Sg"); + public static final Element Bh = add(107, 163, "Bohrium", "Bh"); + public static final Element Hs = add(108, 169, "Hassium", "Hs"); + public static final Element Mt = add(109, 167, "Meitnerium", "Mt"); + public static final Element Ds = add(110, 171, "Darmstadtium", "Ds"); + public static final Element Rg = add(111, 169, "Roentgenium", "Rg"); + public static final Element Cn = add(112, 173, "Copernicium", "Cn"); + public static final Element Nh = add(113, 171, "Nihonium", "Nh"); + public static final Element Fl = add(114, 175, "Flerovium", "Fl"); + public static final Element Mc = add(115, 173, "Moscovium", "Mc"); + public static final Element Lv = add(116, 177, "Livermorium", "Lv"); + public static final Element Ts = add(117, 177, "Tennessine", "Ts"); + public static final Element Og = add(118, 176, "Oganesson", "Og"); // fantasy todo Naquadah element names - public static final Element Tr = add(119, 178, -1, null, "Tritanium", "Tr", false); - public static final Element Dr = add(120, 180, -1, null, "Duranium", "Dr", false); - public static final Element Ke = add(125, 198, -1, null, "Trinium", "Ke", false); + public static final Element Tr = add(119, 178, "Tritanium", "Tr"); + public static final Element Dr = add(120, 180, "Duranium", "Dr"); + public static final Element Ke = add(125, 198, "Trinium", "Ke"); public static final Element Nq = add(174, 352, 140, null, "Naquadah", "Nq", true); public static final Element Nq1 = add(174, 354, 140, null, "NaquadahEnriched", "Nq+", true); public static final Element Nq2 = add(174, 348, 140, null, "Naquadria", "*Nq*", true); - public static final Element Nt = add(0, 1000, -1, null, "Neutronium", "Nt", false); - public static final Element Sp = add(1, 0, -1, null, "Space", "Sp", false); - public static final Element Ma = add(1, 0, -1, null, "Magic", "Ma", false); + public static final Element Nt = add(0, 1000, "Neutronium", "Nt"); + public static final Element Sp = add(1, 0, "Space", "Sp"); + public static final Element Ma = add(1, 0, "Magic", "Ma"); // TODO Cosmic Neutronium, other Gregicality Elements @ZenMethod - public static Element add(long protons, long neutrons, long halfLifeSeconds, String decayTo, String name, + public static Element add(long protons, long neutrons, String name, String symbol) { + return add(protons, neutrons, -1, null, name, symbol, false); + } + + @ZenMethod + public static Element add(long protons, long neutrons, String name, String symbol, boolean isotope) { + return add(protons, neutrons, -1, null, name, symbol, isotope); + } + + @ZenMethod + public static Element add(long protons, long neutrons, double halfLifeSeconds, String decayTo, String name, String symbol, boolean isIsotope) { + validateNameAndSymbol(name, symbol); + String key = toMapKey(name); + Element current = elements.get(key); + if (current != null) { + // this might be intended by addons or scripts + GTLog.logger.warn("Element with name '{}' already exists. Current element will be overwritten!", name); + elements.remove(key); + elementsBySymbol.remove(current.symbol); + elementList.remove(current); + } + if (elementsBySymbol.containsKey(symbol)) { + // this might be intended by addons or scripts + GTLog.logger.warn( + "Element with symbol '{}' already exists. The element in the symbol map will be overwritten!", + symbol); + } Element element = new Element(protons, neutrons, halfLifeSeconds, decayTo, name, symbol, isIsotope); - elements.put(name, element); + elements.put(key, element); + elementsBySymbol.put(symbol, element); + elementList.add(element); return element; } + private static String toMapKey(String name) { + name = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, name); + return name; + } + + private static void validateNameAndSymbol(String name, String symbol) { + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("Element name must not be null or empty"); + } + if (!namePattern.matcher(name).matches()) { + throw new IllegalArgumentException("Element name '" + name + "' does not match required format! " + + "Name must be in upper camel case format. Isotope number must be separated with an - at the end."); + } + if (symbol == null || symbol.isEmpty()) { + throw new IllegalArgumentException("Element symbol must not be null or empty!"); + } + } + public static List getAllElements() { - return Collections.unmodifiableList(new ArrayList<>(elements.values())); + return elementsView; } @ZenMethod("getAllElements") public static Element[] getAllElementsCT() { - return elements.values().toArray(new Element[0]); + return elementsView.toArray(new Element[0]); + } + + public static Element getByName(String name) { + if (name == null || name.isEmpty()) return null; + return elements.get(toMapKey(name)); + } + + public static Element getBySymbol(String name) { + if (name == null || name.isEmpty()) return null; + return elementsBySymbol.get(name); // symbol should be exact } @ZenMethod public static Element get(String name) { - return elements.get(CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name)); + if (name == null || name.isEmpty()) return null; + Element e = elementsBySymbol.get(name); + if (e != null) return e; + return elements.get(toMapKey(name)); } } diff --git a/src/main/java/gregtech/api/unification/OreDictUnifier.java b/src/main/java/gregtech/api/unification/OreDictUnifier.java index a945fe5b4f5..76e6c376086 100644 --- a/src/main/java/gregtech/api/unification/OreDictUnifier.java +++ b/src/main/java/gregtech/api/unification/OreDictUnifier.java @@ -13,7 +13,6 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.NonNullList; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.oredict.OreDictionary; @@ -87,8 +86,7 @@ public static void registerOre(ItemStack itemStack, String oreDict) { public static void init() { for (String registeredOreName : OreDictionary.getOreNames()) { - NonNullList theseOres = OreDictionary.getOres(registeredOreName); - for (ItemStack itemStack : theseOres) { + for (ItemStack itemStack : OreDictionary.getOres(registeredOreName)) { onItemRegistration(new OreRegisterEvent(registeredOreName, itemStack)); } } @@ -217,8 +215,13 @@ public static boolean hasOreDictionary(@NotNull ItemStack itemStack, @NotNull St return wildcardNames != null && wildcardNames != names && wildcardNames.contains(oreDictName); } - public static List getAllWithOreDictionaryName(String oreDictionaryName) { - return oreDictNameStacks.get(oreDictionaryName).stream() + public static @NotNull List<@NotNull ItemStack> getAllWithOreDictionaryName(@NotNull String oreDictionaryName) { + var stacks = oreDictNameStacks.get(oreDictionaryName); + if (stacks == null) { + return Collections.emptyList(); + } + + return stacks.stream() .map(ItemStack::copy) .collect(Collectors.toList()); } diff --git a/src/main/java/gregtech/api/unification/material/Material.java b/src/main/java/gregtech/api/unification/material/Material.java index 8a80801af48..29c4c9fd9e4 100644 --- a/src/main/java/gregtech/api/unification/material/Material.java +++ b/src/main/java/gregtech/api/unification/material/Material.java @@ -10,7 +10,22 @@ import gregtech.api.unification.material.info.MaterialFlag; import gregtech.api.unification.material.info.MaterialFlags; import gregtech.api.unification.material.info.MaterialIconSet; -import gregtech.api.unification.material.properties.*; +import gregtech.api.unification.material.properties.BlastProperty; +import gregtech.api.unification.material.properties.DustProperty; +import gregtech.api.unification.material.properties.FluidPipeProperties; +import gregtech.api.unification.material.properties.FluidProperty; +import gregtech.api.unification.material.properties.GemProperty; +import gregtech.api.unification.material.properties.IMaterialProperty; +import gregtech.api.unification.material.properties.IngotProperty; +import gregtech.api.unification.material.properties.ItemPipeProperties; +import gregtech.api.unification.material.properties.MaterialProperties; +import gregtech.api.unification.material.properties.OreProperty; +import gregtech.api.unification.material.properties.PolymerProperty; +import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.api.unification.material.properties.RotorProperty; +import gregtech.api.unification.material.properties.ToolProperty; +import gregtech.api.unification.material.properties.WireProperties; +import gregtech.api.unification.material.properties.WoodProperty; import gregtech.api.unification.material.registry.MaterialRegistry; import gregtech.api.unification.stack.MaterialStack; import gregtech.api.util.FluidTooltipUtil; @@ -35,7 +50,11 @@ import stanhebben.zenscript.annotations.ZenMethod; import stanhebben.zenscript.annotations.ZenOperator; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Objects; import java.util.function.Consumer; import java.util.function.UnaryOperator; @@ -110,6 +129,14 @@ public Material setFormula(String formula, boolean withFormatting) { return this; } + @ZenMethod + public Material setComponents(MaterialStack... components) { + this.materialInfo.setComponents(components); + this.chemicalFormula = null; + this.chemicalFormula = calculateChemicalFormula(); + return this; + } + public ImmutableList getMaterialComponents() { return materialInfo.componentList; } @@ -209,10 +236,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 +255,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 +546,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 +560,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; @@ -1173,5 +1199,10 @@ private void verifyInfo(MaterialProperties p, boolean averageRGB) { } } } + + public MaterialInfo setComponents(MaterialStack... components) { + this.componentList = ImmutableList.copyOf(Arrays.asList(components)); + return this; + } } } diff --git a/src/main/java/gregtech/api/unification/material/Materials.java b/src/main/java/gregtech/api/unification/material/Materials.java index d2d65e81f72..30174ce8f44 100644 --- a/src/main/java/gregtech/api/unification/material/Materials.java +++ b/src/main/java/gregtech/api/unification/material/Materials.java @@ -212,6 +212,7 @@ public static void register() { public static Material Phosphorus; public static Material Polonium; public static Material Platinum; + public static Material Plutonium; public static Material Plutonium239; public static Material Plutonium241; public static Material Potassium; @@ -247,6 +248,7 @@ public static void register() { public static Material Titanium; public static Material Tritium; public static Material Tungsten; + public static Material Uranium; public static Material Uranium238; public static Material Uranium235; public static Material Vanadium; @@ -467,6 +469,14 @@ public static void register() { public static Material NaquadriaSulfate; public static Material Pyrochlore; public static Material RTMAlloy; + public static Material IlmeniteSlag; + public static Material Zircon; + public static Material Zirconia; + public static Material ZirconiumTetrachloride; + public static Material Hafnia; + public static Material HafniumTetrachloride; + public static Material Zircaloy4; + public static Material Inconel718; /** * Organic chemistry @@ -682,6 +692,11 @@ public static void register() { public static Material Lapotron; public static Material UUMatter; public static Material PCBCoolant; + public static Material BauxiteSlurry; + public static Material CrackedBauxiteSlurry; + public static Material BauxiteSludge; + public static Material DecalcifiedBauxiteSludge; + public static Material BauxiteSlag; /** * Second Degree Compounds diff --git a/src/main/java/gregtech/api/unification/material/materials/ElementMaterials.java b/src/main/java/gregtech/api/unification/material/materials/ElementMaterials.java index 8d4af1f4fa7..3687efcf6d7 100644 --- a/src/main/java/gregtech/api/unification/material/materials/ElementMaterials.java +++ b/src/main/java/gregtech/api/unification/material/materials/ElementMaterials.java @@ -306,8 +306,11 @@ public static void register() { .build(); Hafnium = new Material.Builder(42, gregtechId("hafnium")) + .ingot() .color(0x99999A).iconSet(SHINY) .element(Elements.Hf) + .blast(b -> b.temp(2227, GasTier.HIGH) + .blastStats(GTValues.VA[GTValues.EV], 2000)) .build(); Hassium = new Material.Builder(43, gregtechId("hassium")) @@ -391,8 +394,7 @@ public static void register() { Krypton = new Material.Builder(52, gregtechId("krypton")) .gas(new FluidBuilder() - .customStill() - .translation("gregtech.fluid.generic")) + .customStill()) .color(0x80FF80) .element(Elements.Kr) .build(); @@ -611,10 +613,9 @@ public static void register() { .itemPipeProperties(512, 4.0f) .build(); - Plutonium239 = new Material.Builder(81, gregtechId("plutonium")) + Plutonium239 = new Material.Builder(81, gregtechId("plutonium_239")) .ingot(3) .liquid(new FluidBuilder().temperature(913)) - .ore(true) .color(0xF03232).iconSet(METALLIC) .element(Elements.Pu239) .build(); @@ -623,7 +624,7 @@ public static void register() { .ingot(3) .liquid(new FluidBuilder().temperature(913)) .color(0xFA4646).iconSet(SHINY) - .flags(EXT_METAL, GENERATE_DOUBLE_PLATE) + .flags(GENERATE_DOUBLE_PLATE) .element(Elements.Pu241) .build(); @@ -865,19 +866,17 @@ public static void register() { .vacuumStats(VA[HV], 300)) .build(); - Uranium238 = new Material.Builder(116, gregtechId("uranium")) - .ingot(3) + Uranium = new Material.Builder(116, gregtechId("uranium")) + .dust(3) .liquid(new FluidBuilder().temperature(1405)) .color(0x32F032).iconSet(METALLIC) - .flags(EXT_METAL) - .element(Elements.U238) + .element(Elements.U) .build(); Uranium235 = new Material.Builder(117, gregtechId("uranium_235")) - .ingot(3) + .dust(3) .liquid(new FluidBuilder().temperature(1405)) .color(0x46FA46).iconSet(SHINY) - .flags(EXT_METAL) .element(Elements.U235) .build(); @@ -915,8 +914,11 @@ public static void register() { .build(); Zirconium = new Material.Builder(123, gregtechId("zirconium")) + .ingot() .color(0xC8FFFF).iconSet(METALLIC) .element(Elements.Zr) + .blast(b -> b.temp(2125, GasTier.MID) + .blastStats(GTValues.VA[GTValues.EV], 1200)) .build(); Naquadah = new Material.Builder(124, gregtechId("naquadah")) @@ -1007,5 +1009,16 @@ public static void register() { .blastStats(VA[LuV], 1500) .vacuumStats(VA[IV], 300)) .build(); + + Uranium238 = new Material.Builder(131, gregtechId("uranium_238")) + .dust(3) + .color(0x46FA46).iconSet(ROUGH) + .element(Elements.U238) + .build(); + + Plutonium = new Material.Builder(132, gregtechId("plutonium")) + .color(0xF03232).iconSet(ROUGH) + .element(Elements.Pu) + .build(); } } diff --git a/src/main/java/gregtech/api/unification/material/materials/FirstDegreeMaterials.java b/src/main/java/gregtech/api/unification/material/materials/FirstDegreeMaterials.java index c5136fc4a32..2863f07c1a9 100644 --- a/src/main/java/gregtech/api/unification/material/materials/FirstDegreeMaterials.java +++ b/src/main/java/gregtech/api/unification/material/materials/FirstDegreeMaterials.java @@ -166,7 +166,12 @@ public static void register() { .components(Hydrogen, 2, Oxygen, 1) .build(); - // FREE ID 270 + Zircon = new Material.Builder(270, gregtechId("zircon")) + .gem().ore() + .color(0xC31313) + .flags(DISABLE_DECOMPOSITION) + .components(Zirconium, 1, Silicon, 1, Oxygen, 4) + .build(); Coal = new Material.Builder(271, gregtechId("coal")) .gem(1, 1600).ore(2, 1) // default coal burn time in vanilla @@ -236,7 +241,6 @@ public static void register() { Galena = new Material.Builder(279, gregtechId("galena")) .dust(3).ore() .color(0x643C64) - .flags(NO_SMELTING) .components(Lead, 1, Sulfur, 1) .build(); @@ -626,7 +630,12 @@ public static void register() { .components(Antimony, 2, Sulfur, 3) .build(); - // Free ID 326 + Zirconia = new Material.Builder(326, gregtechId("zirconia")) + .dust() + .color(0x689F9F).iconSet(SHINY) + .flags(DISABLE_DECOMPOSITION) + .components(Zirconium, 1, Oxygen, 2) + .build(); Tetrahedrite = new Material.Builder(327, gregtechId("tetrahedrite")) .dust().ore() @@ -675,9 +684,8 @@ public static void register() { .dust(3).ore(true) .color(0x232323).iconSet(METALLIC) .flags(DISABLE_DECOMPOSITION) - .components(Uranium238, 1, Oxygen, 2) - .build() - .setFormula("UO2", true); + .components(Uranium, 1, Oxygen, 2) + .build(); Uvarovite = new Material.Builder(333, gregtechId("uvarovite")) .gem() @@ -822,9 +830,19 @@ public static void register() { .components(Copper, 2, Sulfur, 1) .build(); - // Free ID 349 + ZirconiumTetrachloride = new Material.Builder(349, gregtechId("zirconium_tetrachloride")) + .dust() + .color(0x689FBF).iconSet(METALLIC) + .flags(DISABLE_DECOMPOSITION) + .components(Zirconium, 1, Chlorine, 4) + .build(); - // Free ID 350 + Hafnia = new Material.Builder(350, gregtechId("hafnia")) + .dust() + .color(0x39393A).iconSet(SHINY) + .flags(DISABLE_DECOMPOSITION) + .components(Hafnium, 1, Oxygen, 2) + .build(); GalliumArsenide = new Material.Builder(351, gregtechId("gallium_arsenide")) .ingot(1) @@ -873,6 +891,7 @@ public static void register() { MagnesiumChloride = new Material.Builder(357, gregtechId("magnesium_chloride")) .dust(1) .color(0xD40D5C) + .flags(DISABLE_DECOMPOSITION) .components(Magnesium, 1, Chlorine, 2) .build(); @@ -931,6 +950,7 @@ public static void register() { SodiumBicarbonate = new Material.Builder(366, gregtechId("sodium_bicarbonate")) .dust(1) .color(0x565b96).iconSet(ROUGH) + .flags(DISABLE_DECOMPOSITION) .components(Sodium, 1, Hydrogen, 1, Carbon, 1, Oxygen, 3) .build(); @@ -1031,7 +1051,12 @@ public static void register() { .components(Potassium, 1, Lithium, 3, Aluminium, 4, Fluorine, 2, Oxygen, 10) .build(); - // Free ID 383 + HafniumTetrachloride = new Material.Builder(383, gregtechId("hafnium_tetrachloride")) + .dust() + .color(0x69699A).iconSet(METALLIC) + .flags(DISABLE_DECOMPOSITION) + .components(Hafnium, 1, Chlorine, 4) + .build(); GlauconiteSand = new Material.Builder(384, gregtechId("glauconite_sand")) .dust().ore(3, 1) @@ -1063,11 +1088,15 @@ public static void register() { .components(Potassium, 1, Aluminium, 3, Silicon, 2, Hydrogen, 6, Oxygen, 14) .build(); - // Free ID 389 - - // Free ID 390 + /* Free IDs: 389-390 */ - // Free ID 391 + Zircaloy4 = new Material.Builder(391, gregtechId("zircaloy_4")) + .ingot() + .color(0x8A6E68).iconSet(METALLIC) + .components(Zirconium, 16, Tin, 2, Chrome, 1) + .blast(b -> b.temp(2123, GasTier.MID) + .blastStats(GTValues.VA[EV])) + .build(); Talc = new Material.Builder(392, gregtechId("talc")) .dust().ore(2, 1) @@ -1204,7 +1233,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) @@ -1214,9 +1243,8 @@ public static void register() { .gas() .color(0x42D126) .flags(DISABLE_DECOMPOSITION) - .components(Uranium238, 1, Fluorine, 6) - .build() - .setFormula("UF6", true); + .components(Uranium, 1, Fluorine, 6) + .build(); EnrichedUraniumHexafluoride = new Material.Builder(413, gregtechId("enriched_uranium_hexafluoride")) .gas() @@ -1224,7 +1252,7 @@ public static void register() { .flags(DISABLE_DECOMPOSITION) .components(Uranium235, 1, Fluorine, 6) .build() - .setFormula("UF6", true); + .setFormula("(U-235)F6", true); DepletedUraniumHexafluoride = new Material.Builder(414, gregtechId("depleted_uranium_hexafluoride")) .gas() @@ -1232,7 +1260,7 @@ public static void register() { .flags(DISABLE_DECOMPOSITION) .components(Uranium238, 1, Fluorine, 6) .build() - .setFormula("UF6", true); + .setFormula("(U-238)F6", true); NitrousOxide = new Material.Builder(415, gregtechId("nitrous_oxide")) .gas() @@ -1347,14 +1375,13 @@ public static void register() { .liquid(new FluidBuilder().temperature(1882)) .color(0x008700).iconSet(SHINY) .flags(DECOMPOSITION_BY_CENTRIFUGING) - .components(Uranium238, 1, Platinum, 3) + .components(Uranium, 1, Platinum, 3) .cableProperties(GTValues.V[GTValues.EV], 6, 0, true, 30) .blast(b -> b .temp(4400, GasTier.MID) .blastStats(VA[EV], 1000) .vacuumStats(VA[EV], 200)) - .build() - .setFormula("UPt3", true); + .build(); SamariumIronArsenicOxide = new Material.Builder(428, gregtechId("samarium_iron_arsenic_oxide")) .ingot() @@ -1387,14 +1414,13 @@ public static void register() { .liquid(new FluidBuilder().temperature(3410)) .color(0x0A0A0A) .flags(DECOMPOSITION_BY_CENTRIFUGING, GENERATE_FINE_WIRE) - .components(Uranium238, 1, Rhodium, 1, Naquadah, 2) + .components(Uranium, 1, Rhodium, 1, Naquadah, 2) .cableProperties(GTValues.V[GTValues.ZPM], 8, 0, true, 5) .blast(b -> b .temp(9000, GasTier.HIGH) .blastStats(VA[IV], 1500) .vacuumStats(VA[ZPM], 200)) - .build() - .setFormula("URhNq2", true); + .build(); EnrichedNaquadahTriniumEuropiumDuranide = new Material.Builder(431, gregtechId("enriched_naquadah_trinium_europium_duranide")) @@ -1540,7 +1566,13 @@ public static void register() { .components(Calcium, 2, Niobium, 2, Oxygen, 7) .build(); - // FREE ID 450 + Inconel718 = new Material.Builder(450, gregtechId("inconel_718")) + .ingot() + .color(0x566570).iconSet(SHINY) + .components(Nickel, 5, Chrome, 2, Iron, 2, Niobium, 1, Molybdenum, 1) + .blast(b -> b.temp(2622, GasTier.LOW) + .blastStats(GTValues.VA[HV])) + .build(); RTMAlloy = new Material.Builder(451, gregtechId("rtm_alloy")) .ingot().fluid() @@ -1553,5 +1585,10 @@ public static void register() { .blastStats(VA[EV], 1400) .vacuumStats(VA[HV], 250)) .build(); + + IlmeniteSlag = new Material.Builder(452, gregtechId("ilmenite_slag")) + .dust(1) + .color(0x8B0000).iconSet(SAND) + .build(); } } diff --git a/src/main/java/gregtech/api/unification/material/materials/MaterialFlagAddition.java b/src/main/java/gregtech/api/unification/material/materials/MaterialFlagAddition.java index 8dbb3b48c6d..bd132ca9d3c 100644 --- a/src/main/java/gregtech/api/unification/material/materials/MaterialFlagAddition.java +++ b/src/main/java/gregtech/api/unification/material/materials/MaterialFlagAddition.java @@ -59,9 +59,6 @@ public static void register() { oreProp.setOreByProducts(Nickel, Nickel, Cobalt, Palladium); oreProp.setWashedIn(Mercury); - oreProp = Plutonium239.getProperty(PropertyKey.ORE); - oreProp.setOreByProducts(Uraninite, Lead, Uraninite); - // oreProp = Silicon.getProperty(PropertyKey.ORE); // oreProp.setOreByProducts(SiliconDioxide); @@ -164,8 +161,9 @@ public static void register() { oreProp.setOreByProducts(GarnetYellow, Calcium); oreProp = Ilmenite.getProperty(PropertyKey.ORE); - oreProp.setOreByProducts(Iron, Rutile); + oreProp.setOreByProducts(Iron, Rutile, Rutile, IlmeniteSlag); oreProp.setSeparatedInto(Iron); + oreProp.setWashedIn(SodiumPersulfate); oreProp = Bauxite.getProperty(PropertyKey.ORE); oreProp.setOreByProducts(Grossular, Rutile, Gallium); @@ -404,5 +402,8 @@ public static void register() { oreProp = Pyrochlore.getProperty(PropertyKey.ORE); oreProp.setOreByProducts(Apatite, Calcium, Niobium); + + oreProp = Zircon.getProperty(PropertyKey.ORE); + oreProp.setOreByProducts(Zircon, Ilmenite, Rutile); } } 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/materials/UnknownCompositionMaterials.java b/src/main/java/gregtech/api/unification/material/materials/UnknownCompositionMaterials.java index 2b8918b2abb..e4b76816d63 100644 --- a/src/main/java/gregtech/api/unification/material/materials/UnknownCompositionMaterials.java +++ b/src/main/java/gregtech/api/unification/material/materials/UnknownCompositionMaterials.java @@ -640,5 +640,22 @@ public static void register() { PCBCoolant = new Material.Builder(1650, gregtechId("pcb_coolant")) .fluid().color(0xD5D69C).build(); + + BauxiteSlurry = new Material.Builder(1651, gregtechId("bauxite_slurry")) + .fluid().color(0x051650).build(); + + CrackedBauxiteSlurry = new Material.Builder(1652, gregtechId("cracked_bauxite_slurry")) + .liquid(new FluidBuilder().temperature(775)).color(0x052C50).build(); + + BauxiteSludge = new Material.Builder(1653, gregtechId("bauxite_sludge")) + .fluid().color(0x563D2D).build(); + + DecalcifiedBauxiteSludge = new Material.Builder(1654, gregtechId("decalcified_bauxite_sludge")) + .fluid().color(0x6F2DA8).build(); + + BauxiteSlag = new Material.Builder(1655, gregtechId("bauxite_slag")) + .dust(1) + .color(0x0C0550).iconSet(SAND) + .build(); } } diff --git a/src/main/java/gregtech/api/unification/material/properties/BlastProperty.java b/src/main/java/gregtech/api/unification/material/properties/BlastProperty.java index 172e0981ac7..61670ea18f9 100644 --- a/src/main/java/gregtech/api/unification/material/properties/BlastProperty.java +++ b/src/main/java/gregtech/api/unification/material/properties/BlastProperty.java @@ -1,17 +1,18 @@ package gregtech.api.unification.material.properties; +import gregtech.integration.groovy.GroovyScriptModule; + import crafttweaker.CraftTweakerAPI; import org.jetbrains.annotations.NotNull; public class BlastProperty implements IMaterialProperty { /** - * Blast Furnace Temperature of this Material. - * If below 1000K, Primitive Blast Furnace recipes will be also added. + * Blast Furnace Temperature of this Material. If below 1000K, Primitive Blast Furnace recipes will be also added. * If above 1750K, a Hot Ingot and its Vacuum Freezer recipe will be also added. *

            - * If a Material with this Property has a Fluid, its temperature - * will be set to this if it is the default Fluid temperature. + * If a Material with this Property has a Fluid, its temperature will be set to this if it is the default Fluid + * temperature. */ private int blastTemperature; @@ -132,7 +133,10 @@ public void verifyProperty(MaterialProperties properties) { public static GasTier validateGasTier(String gasTierName) { if (gasTierName == null) return null; - else if ("LOW".equalsIgnoreCase(gasTierName)) return GasTier.LOW; + if (GroovyScriptModule.isCurrentlyRunning()) { + return GroovyScriptModule.parseAndValidateEnumValue(GasTier.class, gasTierName, "gas tier"); + } + if ("LOW".equalsIgnoreCase(gasTierName)) return GasTier.LOW; else if ("MID".equalsIgnoreCase(gasTierName)) return GasTier.MID; else if ("HIGH".equalsIgnoreCase(gasTierName)) return GasTier.HIGH; else if ("HIGHER".equalsIgnoreCase(gasTierName)) return GasTier.HIGHER; diff --git a/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java b/src/main/java/gregtech/api/unification/material/properties/FluidProperty.java index 48f92084252..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,36 +1,133 @@ 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; + } + + /** + * @see FluidStorageImpl#registerFluids(Material) + */ + @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 FluidStorageKey fluid is stored as primarily + * + * @return the key the fluid is stored with primarily */ - public @Nullable FluidStorageKey getPrimaryKey() { + 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 @Nullable Fluid solidifiesFrom() { + if (this.solidifyingFluid == null) { + return storage.get(FluidStorageKeys.LIQUID); + } + return solidifyingFluid; + } + + /** + * @param amount the size of the returned FluidStack. + * @return a FluidStack of the Fluid which solidifies into the material. + */ + public FluidStack solidifiesFrom(int amount) { + return new FluidStack(solidifiesFrom(), amount); + } + + /** + * Sets the fluid that solidifies into the material. + * + * @param solidifyingFluid The Fluid which solidifies into the material. If left null, it will be left as the + * default value: the material's liquid. + */ + public void setSolidifyingFluid(@Nullable Fluid solidifyingFluid) { + this.solidifyingFluid = solidifyingFluid; + } } diff --git a/src/main/java/gregtech/api/unification/ore/OrePrefix.java b/src/main/java/gregtech/api/unification/ore/OrePrefix.java index 30239988324..0a159028f1d 100644 --- a/src/main/java/gregtech/api/unification/ore/OrePrefix.java +++ b/src/main/java/gregtech/api/unification/ore/OrePrefix.java @@ -23,7 +23,15 @@ import stanhebben.zenscript.annotations.ZenClass; import stanhebben.zenscript.annotations.ZenMethod; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import java.util.function.Predicate; @@ -631,11 +639,11 @@ private void runGeneratedMaterialHandlers() { for (IOreRegistrationHandler registrationHandler : oreProcessingHandlers) { registrationHandler.processMaterial(this, registeredMaterial); } - currentMaterial.set(null); + currentMaterial.remove(); } // clear generated materials for next pass generatedMaterials.clear(); - currentProcessingPrefix.set(null); + currentProcessingPrefix.remove(); } public void setAlternativeOreName(String name) { diff --git a/src/main/java/gregtech/api/unification/ore/StoneType.java b/src/main/java/gregtech/api/unification/ore/StoneType.java index f92bb9c68bf..9e87a43a0b8 100644 --- a/src/main/java/gregtech/api/unification/ore/StoneType.java +++ b/src/main/java/gregtech/api/unification/ore/StoneType.java @@ -1,9 +1,9 @@ package gregtech.api.unification.ore; -import gregtech.api.GTValues; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.properties.PropertyKey; import gregtech.api.util.GTControlledRegistry; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import gregtech.integration.jei.basic.OreByProduct; @@ -11,7 +11,6 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; -import net.minecraftforge.fml.common.Loader; import com.google.common.base.Preconditions; import org.jetbrains.annotations.NotNull; @@ -50,7 +49,7 @@ public StoneType(int id, String name, SoundType soundType, OrePrefix processingP this.predicate = predicate::test; this.shouldBeDroppedAsItem = shouldBeDroppedAsItem || ConfigHolder.worldgen.allUniqueStoneTypes; STONE_TYPE_REGISTRY.register(id, name, this); - if (Loader.isModLoaded(GTValues.MODID_JEI) && this.shouldBeDroppedAsItem) { + if (Mods.JustEnoughItems.isModLoaded() && this.shouldBeDroppedAsItem) { OreByProduct.addOreByProductPrefix(this.processingPrefix); } } diff --git a/src/main/java/gregtech/api/util/AssemblyLineManager.java b/src/main/java/gregtech/api/util/AssemblyLineManager.java index a2652acfa84..7601c0e73cd 100644 --- a/src/main/java/gregtech/api/util/AssemblyLineManager.java +++ b/src/main/java/gregtech/api/util/AssemblyLineManager.java @@ -11,7 +11,7 @@ import gregtech.api.recipes.ingredients.nbtmatch.NBTMatcher; import gregtech.api.recipes.machines.IScannerRecipeMap; import gregtech.api.recipes.machines.RecipeMapScanner; -import gregtech.api.recipes.recipeproperties.ScanProperty; +import gregtech.api.recipes.properties.impl.ScanProperty; import gregtech.common.ConfigHolder; import gregtech.common.items.MetaItems; diff --git a/src/main/java/gregtech/api/util/BlockUtility.java b/src/main/java/gregtech/api/util/BlockUtility.java index 77b816da15a..daa6e382e2d 100644 --- a/src/main/java/gregtech/api/util/BlockUtility.java +++ b/src/main/java/gregtech/api/util/BlockUtility.java @@ -47,9 +47,8 @@ public BlockWrapper() { super(Material.AIR); } - @NotNull @Override - public NonNullList captureDrops(boolean start) { + public @NotNull NonNullList captureDrops(boolean start) { return super.captureDrops(start); } } @@ -58,7 +57,7 @@ public static void startCaptureDrops() { WRAPPER.captureDrops(true); } - public static NonNullList stopCaptureDrops() { + public static @NotNull NonNullList stopCaptureDrops() { return WRAPPER.captureDrops(false); } diff --git a/src/main/java/gregtech/api/util/CapesRegistry.java b/src/main/java/gregtech/api/util/CapesRegistry.java index 50972a56236..7d0acaa0ba6 100644 --- a/src/main/java/gregtech/api/util/CapesRegistry.java +++ b/src/main/java/gregtech/api/util/CapesRegistry.java @@ -1,6 +1,5 @@ package gregtech.api.util; -import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.client.renderer.texture.Textures; import gregtech.core.network.packets.PacketNotifyCapeChange; @@ -214,13 +213,13 @@ public static void addFreeCape(ResourceLocation cape) { private static final List> ctRegisterCapes = new ArrayList<>(); private static final List ctFreeCapes = new ArrayList<>(); - @Optional.Method(modid = GTValues.MODID_CT) + @Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) @ZenMethod public static void registerCape(String advancement, String cape) { ctRegisterCapes.add(new Tuple<>(new ResourceLocation(advancement), new ResourceLocation(cape))); } - @Optional.Method(modid = GTValues.MODID_CT) + @Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) @ZenMethod public static void registerFreeCape(String cape) { ctFreeCapes.add(new ResourceLocation(cape)); diff --git a/src/main/java/gregtech/api/util/FluidTankSwitchShim.java b/src/main/java/gregtech/api/util/FluidTankSwitchShim.java index e0210eee145..0e4c556da3a 100644 --- a/src/main/java/gregtech/api/util/FluidTankSwitchShim.java +++ b/src/main/java/gregtech/api/util/FluidTankSwitchShim.java @@ -11,14 +11,17 @@ // probably causes problems public class FluidTankSwitchShim implements IFluidTank, IFluidHandler { - IFluidTank tank; + @Nullable + private IFluidTank tank; + private static final FluidTankInfo NO_INFO = new FluidTankInfo(null, 0); + private static final IFluidTankProperties[] NO_PROPS = new IFluidTankProperties[0]; public FluidTankSwitchShim(IFluidTank tank) { changeTank(tank); } public void changeTank(IFluidTank tank) { - if (!(tank instanceof IFluidHandler)) { + if (tank != null && !(tank instanceof IFluidHandler)) { throw new IllegalArgumentException("Shim tank must be both IFluidTank and IFluidHandler!"); } this.tank = tank; @@ -27,43 +30,49 @@ public void changeTank(IFluidTank tank) { @Nullable @Override public FluidStack getFluid() { - return tank.getFluid(); + return tank == null ? null : tank.getFluid(); } @Override public int getFluidAmount() { - return tank.getFluidAmount(); + return tank == null ? 0 : tank.getFluidAmount(); } @Override public int getCapacity() { - return tank.getCapacity(); + return tank == null ? 0 : tank.getCapacity(); } @Override public FluidTankInfo getInfo() { - return tank.getInfo(); + return tank == null ? NO_INFO : tank.getInfo(); } @Override public IFluidTankProperties[] getTankProperties() { + if (tank == null) + return NO_PROPS; + return ((IFluidHandler) tank).getTankProperties(); } @Override public int fill(FluidStack resource, boolean doFill) { + if (tank == null) return 0; return ((IFluidHandler) tank).fill(resource, doFill); } @Nullable @Override public FluidStack drain(FluidStack resource, boolean doDrain) { + if (tank == null) return null; return ((IFluidHandler) tank).drain(resource, doDrain); } @Nullable @Override public FluidStack drain(int maxDrain, boolean doDrain) { + if (tank == null) return null; return tank.drain(maxDrain, doDrain); } } diff --git a/src/main/java/gregtech/api/util/GTLog.java b/src/main/java/gregtech/api/util/GTLog.java index 56a003fde5b..a7e980f1e52 100644 --- a/src/main/java/gregtech/api/util/GTLog.java +++ b/src/main/java/gregtech/api/util/GTLog.java @@ -1,5 +1,7 @@ package gregtech.api.util; +import gregtech.api.GTValues; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -9,7 +11,7 @@ */ public class GTLog { - public static Logger logger = LogManager.getLogger("GregTech"); + public static Logger logger = LogManager.getLogger(GTValues.MOD_NAME); private GTLog() {} } diff --git a/src/main/java/gregtech/api/util/GTTransferUtils.java b/src/main/java/gregtech/api/util/GTTransferUtils.java index 2e3c3655a49..d79024f844b 100644 --- a/src/main/java/gregtech/api/util/GTTransferUtils.java +++ b/src/main/java/gregtech/api/util/GTTransferUtils.java @@ -175,9 +175,6 @@ public static ItemStack insertItem(IItemHandler handler, ItemStack stack, boolea if (handler == null || stack.isEmpty()) { return stack; } - if (!stack.isStackable()) { - return insertToEmpty(handler, stack, simulate); - } IntList emptySlots = new IntArrayList(); int slots = handler.getSlots(); diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index 2b95a31fe0f..39b4a6a0d65 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; @@ -53,7 +54,6 @@ import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; -import com.google.common.collect.Lists; import com.google.common.util.concurrent.AtomicDouble; import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; import org.apache.commons.lang3.ArrayUtils; @@ -63,9 +63,11 @@ import org.jetbrains.annotations.Nullable; import java.util.AbstractList; +import java.util.ArrayList; 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; @@ -73,8 +75,6 @@ import java.util.function.Function; import java.util.function.Predicate; -import static gregtech.api.GTValues.V; - public class GTUtility { public static String[] mapToString(T[] array, Function mapper) { @@ -254,7 +254,22 @@ public static int nearestLesser(@NotNull long[] array, long value) { * tier that can handle it, {@code MAX} is returned. */ public static byte getTierByVoltage(long voltage) { - return (byte) Math.min(GTValues.MAX, nearestLesser(V, voltage) + 1); + if (voltage >= GTValues.V[GTValues.MAX]) { + return GTValues.MAX; + } + return getOCTierByVoltage(voltage); + } + + /** + * @return Lowest tier of the voltage that can handle {@code voltage}, extended up to max long value; that is, + * a voltage with value greater than equal than {@code voltage}. If there's no + * tier that can handle it, {@code MAX_TRUE} is returned. + */ + public static byte getOCTierByVoltage(long voltage) { + if (voltage <= GTValues.V[GTValues.ULV]) { + return GTValues.ULV; + } + return (byte) ((62 - Long.numberOfLeadingZeros(voltage - 1)) >> 1); } /** @@ -264,7 +279,14 @@ public static byte getTierByVoltage(long voltage) { * {@code ULV} if there's no tier below */ public static byte getFloorTierByVoltage(long voltage) { - return (byte) Math.max(GTValues.ULV, nearestLesserOrEqual(V, voltage)); + if (voltage < GTValues.V[GTValues.LV]) { + return GTValues.ULV; + } + if (voltage == GTValues.VOC[GTValues.MAX_TRUE]) { + return GTValues.MAX_TRUE; + } + + return (byte) ((60 - Long.numberOfLeadingZeros(voltage)) >> 1); } @SuppressWarnings("deprecation") @@ -444,18 +466,20 @@ public static NBTTagCompound getOrCreateNbtCompound(ItemStack stack) { return compound; } - public static NonNullList copyStackList(List itemStacks) { - ItemStack[] stacks = new ItemStack[itemStacks.size()]; - for (int i = 0; i < itemStacks.size(); i++) { - stacks[i] = copy(itemStacks.get(i)); + public static @NotNull List<@NotNull ItemStack> copyStackList(@NotNull List<@NotNull ItemStack> itemStacks) { + List list = new ArrayList<>(itemStacks.size()); + for (ItemStack itemStack : itemStacks) { + list.add(copy(itemStack)); } - return NonNullList.from(ItemStack.EMPTY, stacks); + return list; } - public static List copyFluidList(List fluidStacks) { - FluidStack[] stacks = new FluidStack[fluidStacks.size()]; - for (int i = 0; i < fluidStacks.size(); i++) stacks[i] = fluidStacks.get(i).copy(); - return Lists.newArrayList(stacks); + public static @NotNull List<@NotNull FluidStack> copyFluidList(@NotNull List<@NotNull FluidStack> fluidStacks) { + List list = new ArrayList<>(fluidStacks.size()); + for (FluidStack stack : fluidStacks) { + list.add(stack.copy()); + } + return list; } /** @@ -464,8 +488,7 @@ public static List copyFluidList(List fluidStacks) { * @param stack item stack for copying * @return a copy of ItemStack, or {@link ItemStack#EMPTY} if the stack is empty */ - @NotNull - public static ItemStack copy(@NotNull ItemStack stack) { + public static @NotNull ItemStack copy(@NotNull ItemStack stack) { return stack.isEmpty() ? ItemStack.EMPTY : stack.copy(); } @@ -704,18 +727,24 @@ 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()); } - public static boolean canSeeSunClearly(World world, BlockPos blockPos) { - if (!world.canSeeSky(blockPos.up())) { + /** + * @param world the world containing the block + * @param blockPos the position of the block to check + * @return if the block can see the sun clearly + */ + public static boolean canSeeSunClearly(@NotNull World world, @NotNull BlockPos blockPos) { + BlockPos up = blockPos.up(); + if (!world.canSeeSky(up)) { return false; } - Biome biome = world.getBiome(blockPos.up()); - if (world.isRaining()) { - if (biome.canRain() || biome.getEnableSnow()) { - return false; - } + Biome biome = world.getBiome(up); + if (world.isRaining() && (biome.canRain() || biome.getEnableSnow())) { + return false; } Set biomeTypes = BiomeDictionary.getTypes(biome); if (biomeTypes.contains(BiomeDictionary.Type.END)) { @@ -812,9 +841,7 @@ public static Set getAllSubItems(@NotNull Item item) { if (tab == null || tab == CreativeTabs.SEARCH) continue; item.getSubItems(tab, subItems); } - Set set = new ObjectOpenCustomHashSet<>(ItemStackHashStrategy.comparingItemDamageCount()); - set.addAll(subItems); - return set; + return new ObjectOpenCustomHashSet<>(subItems, ItemStackHashStrategy.comparingItemDamageCount()); } /** @@ -883,4 +910,14 @@ public double getAsDouble() { (1.0 / (1 - splitPoint)) * (tracker.get() - splitPoint) : 0; return Pair.of(supplier1, supplier2); } + + /** + * Safely cast a Long to an Int without overflow. + * + * @param v The Long value to cast to an Int. + * @return v, cast to Int, or Integer.MAX_VALUE if it would overflow. + */ + public static int safeCastLongToInt(long v) { + return v > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) v; + } } diff --git a/src/main/java/gregtech/api/util/ModCompatibility.java b/src/main/java/gregtech/api/util/ModCompatibility.java index 9881948147d..d6b627d3b6a 100644 --- a/src/main/java/gregtech/api/util/ModCompatibility.java +++ b/src/main/java/gregtech/api/util/ModCompatibility.java @@ -1,66 +1,22 @@ package gregtech.api.util; -import gregtech.api.util.world.DummyWorld; +import gregtech.client.utils.ItemRenderCompat; import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import java.lang.reflect.Method; -import java.util.List; -import java.util.Objects; +import org.jetbrains.annotations.ApiStatus; @SideOnly(Side.CLIENT) public class ModCompatibility { - private static RefinedStorage refinedStorage; - - public static void initCompat() { - try { - Class itemClass = Class.forName("com.raoulvdberge.refinedstorage.item.ItemPattern"); - refinedStorage = new RefinedStorage(itemClass); - GTLog.logger.info("RefinedStorage found; enabling integration."); - } catch (ClassNotFoundException ignored) { - GTLog.logger.info("RefinedStorage not found; skipping integration."); - } catch (Throwable exception) { - GTLog.logger.error("Failed to enable RefinedStorage integration", exception); - } - } - + /** + * @deprecated Use {@link ItemRenderCompat#getRepresentedStack(ItemStack)} + */ + @ApiStatus.ScheduledForRemoval(inVersion = "2.10") + @Deprecated public static ItemStack getRealItemStack(ItemStack itemStack) { - if (refinedStorage != null && RefinedStorage.canHandleItemStack(itemStack)) { - return refinedStorage.getRealItemStack(itemStack); - } - return itemStack; - } - - private static class RefinedStorage { - - private final Method getPatternFromCacheMethod; - private final Method getOutputsMethod; - - public RefinedStorage(Class itemPatternClass) throws ReflectiveOperationException { - this.getPatternFromCacheMethod = itemPatternClass.getMethod("getPatternFromCache", World.class, - ItemStack.class); - this.getOutputsMethod = getPatternFromCacheMethod.getReturnType().getMethod("getOutputs"); - } - - public static boolean canHandleItemStack(ItemStack itemStack) { - ResourceLocation registryName = Objects.requireNonNull(itemStack.getItem().getRegistryName()); - return registryName.getNamespace().equals("refinedstorage") && - registryName.getPath().equals("pattern"); - } - - public ItemStack getRealItemStack(ItemStack itemStack) { - try { - Object craftingPattern = getPatternFromCacheMethod.invoke(null, DummyWorld.INSTANCE, itemStack); - List outputs = (List) getOutputsMethod.invoke(craftingPattern); - return outputs.isEmpty() ? itemStack : outputs.get(0); - } catch (ReflectiveOperationException ex) { - throw new RuntimeException("Failed to obtain item from ItemPattern", ex); - } - } + return ItemRenderCompat.getRepresentedStack(itemStack); } } diff --git a/src/main/java/gregtech/api/util/ModIncompatibilityException.java b/src/main/java/gregtech/api/util/ModIncompatibilityException.java new file mode 100644 index 00000000000..c21439cc5fe --- /dev/null +++ b/src/main/java/gregtech/api/util/ModIncompatibilityException.java @@ -0,0 +1,35 @@ +package gregtech.api.util; + +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiErrorScreen; +import net.minecraftforge.fml.client.CustomModLoadingErrorDisplayException; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import java.util.List; + +@SideOnly(Side.CLIENT) +public class ModIncompatibilityException extends CustomModLoadingErrorDisplayException { + + @SuppressWarnings("all") + private static final long serialVersionUID = 1L; + + private final List messages; + + public ModIncompatibilityException(List messages) { + this.messages = messages; + } + + @Override + public void initGui(GuiErrorScreen guiErrorScreen, FontRenderer fontRenderer) {} + + @Override + public void drawScreen(GuiErrorScreen errorScreen, FontRenderer fontRenderer, int mouseX, int mouseY, float time) { + int x = errorScreen.width / 2; + int y = 75; + for (String message : messages) { + errorScreen.drawCenteredString(fontRenderer, message, x, y, 0xFFFFFF); + y += 15; + } + } +} diff --git a/src/main/java/gregtech/api/util/Mods.java b/src/main/java/gregtech/api/util/Mods.java new file mode 100644 index 00000000000..9b56b74688d --- /dev/null +++ b/src/main/java/gregtech/api/util/Mods.java @@ -0,0 +1,263 @@ +package gregtech.api.util; + +import gregtech.api.GTValues; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.ModContainer; +import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.relauncher.FMLLaunchHandler; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; + +public enum Mods { + + AdvancedRocketry(Names.ADVANCED_ROCKETRY), + AppliedEnergistics2(Names.APPLIED_ENERGISTICS2), + Baubles(Names.BAUBLES), + BetterQuestingUnofficial(Names.BETTER_QUESTING, mod -> { + var container = Loader.instance().getIndexedModList().get(Names.BETTER_QUESTING); + return container.getVersion().startsWith("4."); + }), + BinnieCore(Names.BINNIE_CORE), + BiomesOPlenty(Names.BIOMES_O_PLENTY), + BuildCraftCore(Names.BUILD_CRAFT_CORE), + Chisel(Names.CHISEL), + CoFHCore(Names.COFH_CORE), + CTM(Names.CONNECTED_TEXTURES_MOD), + CubicChunks(Names.CUBIC_CHUNKS), + CraftTweaker(Names.CRAFT_TWEAKER), + EnderCore(Names.ENDER_CORE), + EnderIO(Names.ENDER_IO), + ExtraBees(Names.EXTRA_BEES), + ExtraTrees(Names.EXTRA_TREES), + ExtraUtilities2(Names.EXTRA_UTILITIES2), + Forestry(Names.FORESTRY), + ForestryApiculture(Names.FORESTRY, forestryModule(Names.FORESTRY_APICULTURE)), + ForestryArboriculture(Names.FORESTRY, forestryModule(Names.FORESTRY_ARBORICULTURE)), + ForestryLepidopterology(Names.FORESTRY, forestryModule(Names.FORESTRY_LEPIDOPTEROLOGY)), + GalacticraftCore(Names.GALACTICRAFT_CORE), + Genetics(Names.GENETICS), + GregTech(Names.GREGTECH), + GregTechFoodOption(Names.GREGTECH_FOOD_OPTION), + GroovyScript(Names.GROOVY_SCRIPT), + GTCE2OC(Names.GTCE_2_OC), + HWYLA(Names.HWYLA), + ImmersiveEngineering(Names.IMMERSIVE_ENGINEERING), + IndustrialCraft2(Names.INDUSTRIAL_CRAFT2), + InventoryTweaks(Names.INVENTORY_TWEAKS), + JourneyMap(Names.JOURNEY_MAP), + JustEnoughItems(Names.JUST_ENOUGH_ITEMS), + LittleTiles(Names.LITTLE_TILES), + MagicBees(Names.MAGIC_BEES), + Nothirium(Names.NOTHIRIUM), + NuclearCraft(Names.NUCLEAR_CRAFT, versionExcludes("2o")), + NuclearCraftOverhauled(Names.NUCLEAR_CRAFT, versionContains("2o")), + OpenComputers(Names.OPEN_COMPUTERS), + ProjectRedCore(Names.PROJECT_RED_CORE), + Railcraft(Names.RAILCRAFT), + RefinedStorage(Names.REFINED_STORAGE), + TechReborn(Names.TECH_REBORN), + TheOneProbe(Names.THE_ONE_PROBE), + TinkersConstruct(Names.TINKERS_CONSTRUCT), + TOPAddons(Names.TOP_ADDONS), + VoxelMap(Names.VOXEL_MAP), + XaerosMinimap(Names.XAEROS_MINIMAP), + Vintagium(Names.VINTAGIUM), + Alfheim(Names.ALFHEIM), + + // Special Optifine handler, but consolidated here for simplicity + Optifine(null) { + + @Override + public boolean isModLoaded() { + if (this.modLoaded == null) { + try { + Class c = Class.forName("net.optifine.shaders.Shaders"); + Field f = c.getDeclaredField("shaderPackLoaded"); + f.setAccessible(true); + this.modLoaded = f.getBoolean(null); + } catch (Exception ignored) { + this.modLoaded = false; + } + } + return this.modLoaded; + } + }; + + public static class Names { + + public static final String ADVANCED_ROCKETRY = "advancedrocketry"; + public static final String APPLIED_ENERGISTICS2 = "appliedenergistics2"; + public static final String BAUBLES = "baubles"; + public static final String BETTER_QUESTING = "betterquesting"; + public static final String BINNIE_CORE = "binniecore"; + public static final String BIOMES_O_PLENTY = "biomesoplenty"; + public static final String BUILD_CRAFT_CORE = "buildcraftcore"; + public static final String CHISEL = "chisel"; + public static final String COFH_CORE = "cofhcore"; + public static final String CONNECTED_TEXTURES_MOD = "ctm"; + public static final String CUBIC_CHUNKS = "cubicchunks"; + public static final String CRAFT_TWEAKER = "crafttweaker"; + public static final String ENDER_CORE = "endercore"; + public static final String ENDER_IO = "enderio"; + public static final String EXTRA_BEES = "extrabees"; + public static final String EXTRA_TREES = "extratrees"; + public static final String EXTRA_UTILITIES2 = "extrautils2"; + public static final String FORESTRY = "forestry"; + public static final String FORESTRY_APICULTURE = "apiculture"; + public static final String FORESTRY_ARBORICULTURE = "arboriculture"; + public static final String FORESTRY_LEPIDOPTEROLOGY = "lepidopterology"; + public static final String GALACTICRAFT_CORE = "galacticraftcore"; + public static final String GENETICS = "genetics"; + public static final String GREGTECH = GTValues.MODID; + public static final String GREGTECH_FOOD_OPTION = "gregtechfoodoption"; + public static final String GROOVY_SCRIPT = "groovyscript"; + public static final String GTCE_2_OC = "gtce2oc"; + public static final String HWYLA = "hwyla"; + public static final String IMMERSIVE_ENGINEERING = "immersiveengineering"; + public static final String INDUSTRIAL_CRAFT2 = "ic2"; + public static final String INVENTORY_TWEAKS = "inventorytweaks"; + public static final String JOURNEY_MAP = "journeymap"; + public static final String JUST_ENOUGH_ITEMS = "jei"; + public static final String LITTLE_TILES = "littletiles"; + public static final String MAGIC_BEES = "magicbees"; + public static final String NOTHIRIUM = "nothirium"; + public static final String NUCLEAR_CRAFT = "nuclearcraft"; + public static final String OPEN_COMPUTERS = "opencomputers"; + public static final String PROJECT_RED_CORE = "projred-core"; + public static final String RAILCRAFT = "railcraft"; + public static final String REFINED_STORAGE = "refinedstorage"; + public static final String TECH_REBORN = "techreborn"; + public static final String THE_ONE_PROBE = "theoneprobe"; + public static final String TINKERS_CONSTRUCT = "tconstruct"; + public static final String TOP_ADDONS = "topaddons"; + public static final String VOXEL_MAP = "voxelmap"; + public static final String XAEROS_MINIMAP = "xaerominimap"; + public static final String VINTAGIUM = "vintagium"; + public static final String ALFHEIM = "alfheim"; + } + + private final String ID; + private final Function extraCheck; + protected Boolean modLoaded; + + Mods(String ID) { + this.ID = ID; + this.extraCheck = null; + } + + /** + * @param extraCheck A supplier that can be used to test additional factors, such as + * checking if a mod is at a specific version, or a sub-mod is loaded. + * Used in cases like NC vs NCO, where the mod id is the same + * so the version has to be parsed to test which is loaded. + * Another case is checking for specific Forestry modules, checking + * if Forestry is loaded and if a specific module is enabled. + */ + Mods(String ID, Function extraCheck) { + this.ID = ID; + this.extraCheck = extraCheck; + } + + public boolean isModLoaded() { + if (this.modLoaded == null) { + this.modLoaded = Loader.isModLoaded(this.ID); + if (this.modLoaded) { + if (this.extraCheck != null && !this.extraCheck.apply(this)) { + this.modLoaded = false; + } + } + } + return this.modLoaded; + } + + /** + * Throw an exception if this mod is found to be loaded. + * This must be called in or after + * {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent}! + */ + public void throwIncompatibilityIfLoaded(String... customMessages) { + if (isModLoaded()) { + String modName = TextFormatting.BOLD + ID + TextFormatting.RESET; + List messages = new ArrayList<>(); + messages.add(modName + " mod detected, this mod is incompatible with GregTech CE Unofficial."); + messages.addAll(Arrays.asList(customMessages)); + if (FMLLaunchHandler.side() == Side.SERVER) { + throw new RuntimeException(String.join(",", messages)); + } else { + throwClientIncompatibility(messages); + } + } + } + + @SideOnly(Side.CLIENT) + private static void throwClientIncompatibility(List messages) { + throw new ModIncompatibilityException(messages); + } + + public ItemStack getItem(@NotNull String name) { + return getItem(name, 0, 1, null); + } + + @NotNull + public ItemStack getItem(@NotNull String name, int meta) { + return getItem(name, meta, 1, null); + } + + @NotNull + public ItemStack getItem(@NotNull String name, int meta, int amount) { + return getItem(name, meta, amount, null); + } + + @NotNull + public ItemStack getItem(@NotNull String name, int meta, int amount, @Nullable String nbt) { + if (!isModLoaded()) { + return ItemStack.EMPTY; + } + return GameRegistry.makeItemStack(ID + ":" + name, meta, amount, nbt); + } + + // Helpers for the extra checker + + /** Test if the mod version string contains the passed value. */ + private static Function versionContains(String versionPart) { + return mod -> { + if (mod.ID == null) return false; + if (!mod.isModLoaded()) return false; + ModContainer container = Loader.instance().getIndexedModList().get(mod.ID); + if (container == null) return false; + return container.getVersion().contains(versionPart); + }; + } + + /** Test if the mod version string does not contain the passed value. */ + private static Function versionExcludes(String versionPart) { + return mod -> { + if (mod.ID == null) return false; + if (!mod.isModLoaded()) return false; + ModContainer container = Loader.instance().getIndexedModList().get(mod.ID); + if (container == null) return false; + return !container.getVersion().contains(versionPart); + }; + } + + /** Test if a specific Forestry module is enabled. */ + private static Function forestryModule(String moduleID) { + if (Forestry.isModLoaded()) { + return mod -> forestry.modules.ModuleHelper.isEnabled(moduleID); + } else { + return $ -> false; + } + } +} diff --git a/src/main/java/gregtech/api/util/OverlayedItemHandler.java b/src/main/java/gregtech/api/util/OverlayedItemHandler.java index 83c63422930..dcd73ddb281 100644 --- a/src/main/java/gregtech/api/util/OverlayedItemHandler.java +++ b/src/main/java/gregtech/api/util/OverlayedItemHandler.java @@ -58,7 +58,8 @@ public int insertStackedItemStack(@NotNull ItemStack stack, int amountToInsert) ItemStack slotKey = this.slots[i].getItemStack(); if (slotKey.isEmpty() || ItemStackHashStrategy.comparingAllButCount().equals(slotKey, stack)) { // if the slot is not full - int canInsertUpTo = this.slots[i].getSlotLimit() - this.slots[i].getCount(); + int canInsertUpTo = Math.min(this.slots[i].getSlotLimit() - this.slots[i].getCount(), + stack.getMaxStackSize()); if (canInsertUpTo > 0) { int insertedAmount = Math.min(canInsertUpTo, amountToInsert); this.slots[i].setItemStack(stack.copy()); // this copy may not be need, needs further tests diff --git a/src/main/java/gregtech/api/util/RelativeDirection.java b/src/main/java/gregtech/api/util/RelativeDirection.java index 1e4b2102761..41c67e91f09 100644 --- a/src/main/java/gregtech/api/util/RelativeDirection.java +++ b/src/main/java/gregtech/api/util/RelativeDirection.java @@ -163,4 +163,120 @@ public static EnumFacing simulateAxisRotation(EnumFacing newFrontFacing, EnumFac return upwardsFacing.getOpposite(); } } + + /** + * Offset a BlockPos relatively in any direction by any amount. Pass negative values to offset down, right or + * backwards. + */ + public static BlockPos offsetPos(BlockPos pos, EnumFacing frontFacing, EnumFacing upwardsFacing, boolean isFlipped, + int upOffset, int leftOffset, int forwardOffset) { + if (upOffset == 0 && leftOffset == 0 && forwardOffset == 0) { + return pos; + } + + int oX = 0, oY = 0, oZ = 0; + final EnumFacing relUp = UP.getRelativeFacing(frontFacing, upwardsFacing, isFlipped); + oX += relUp.getXOffset() * upOffset; + oY += relUp.getYOffset() * upOffset; + oZ += relUp.getZOffset() * upOffset; + + final EnumFacing relLeft = LEFT.getRelativeFacing(frontFacing, upwardsFacing, isFlipped); + oX += relLeft.getXOffset() * leftOffset; + oY += relLeft.getYOffset() * leftOffset; + oZ += relLeft.getZOffset() * leftOffset; + + final EnumFacing relForward = FRONT.getRelativeFacing(frontFacing, upwardsFacing, isFlipped); + oX += relForward.getXOffset() * forwardOffset; + oY += relForward.getYOffset() * forwardOffset; + oZ += relForward.getZOffset() * forwardOffset; + + return pos.add(oX, oY, oZ); + } + + /** + * Offset a BlockPos relatively in any direction by any amount. Pass negative values to offset down, right or + * backwards. + */ + public static BlockPos setActualRelativeOffset(int x, int y, int z, EnumFacing facing, EnumFacing upwardsFacing, + boolean isFlipped, RelativeDirection[] structureDir) { + int[] c0 = new int[] { x, y, z }, c1 = new int[3]; + if (facing == EnumFacing.UP || facing == EnumFacing.DOWN) { + EnumFacing of = facing == EnumFacing.DOWN ? upwardsFacing : upwardsFacing.getOpposite(); + for (int i = 0; i < 3; i++) { + switch (structureDir[i].getActualFacing(of)) { + case UP -> c1[1] = c0[i]; + case DOWN -> c1[1] = -c0[i]; + case WEST -> c1[0] = -c0[i]; + case EAST -> c1[0] = c0[i]; + case NORTH -> c1[2] = -c0[i]; + case SOUTH -> c1[2] = c0[i]; + } + } + int xOffset = upwardsFacing.getXOffset(); + int zOffset = upwardsFacing.getZOffset(); + int tmp; + if (xOffset == 0) { + tmp = c1[2]; + c1[2] = zOffset > 0 ? c1[1] : -c1[1]; + c1[1] = zOffset > 0 ? -tmp : tmp; + } else { + tmp = c1[0]; + c1[0] = xOffset > 0 ? c1[1] : -c1[1]; + c1[1] = xOffset > 0 ? -tmp : tmp; + } + if (isFlipped) { + if (upwardsFacing == EnumFacing.NORTH || upwardsFacing == EnumFacing.SOUTH) { + c1[0] = -c1[0]; // flip X-axis + } else { + c1[2] = -c1[2]; // flip Z-axis + } + } + } else { + for (int i = 0; i < 3; i++) { + switch (structureDir[i].getActualFacing(facing)) { + case UP -> c1[1] = c0[i]; + case DOWN -> c1[1] = -c0[i]; + case WEST -> c1[0] = -c0[i]; + case EAST -> c1[0] = c0[i]; + case NORTH -> c1[2] = -c0[i]; + case SOUTH -> c1[2] = c0[i]; + } + } + if (upwardsFacing == EnumFacing.WEST || upwardsFacing == EnumFacing.EAST) { + int xOffset = upwardsFacing == EnumFacing.WEST ? facing.rotateY().getXOffset() : + facing.rotateY().getOpposite().getXOffset(); + int zOffset = upwardsFacing == EnumFacing.WEST ? facing.rotateY().getZOffset() : + facing.rotateY().getOpposite().getZOffset(); + int tmp; + if (xOffset == 0) { + tmp = c1[2]; + c1[2] = zOffset > 0 ? -c1[1] : c1[1]; + c1[1] = zOffset > 0 ? tmp : -tmp; + } else { + tmp = c1[0]; + c1[0] = xOffset > 0 ? -c1[1] : c1[1]; + c1[1] = xOffset > 0 ? tmp : -tmp; + } + } else if (upwardsFacing == EnumFacing.SOUTH) { + c1[1] = -c1[1]; + if (facing.getXOffset() == 0) { + c1[0] = -c1[0]; + } else { + c1[2] = -c1[2]; + } + } + if (isFlipped) { + if (upwardsFacing == EnumFacing.NORTH || upwardsFacing == EnumFacing.SOUTH) { + if (facing == EnumFacing.NORTH || facing == EnumFacing.SOUTH) { + c1[0] = -c1[0]; // flip X-axis + } else { + c1[2] = -c1[2]; // flip Z-axis + } + } else { + c1[1] = -c1[1]; // flip Y-axis + } + } + } + return new BlockPos(c1[0], c1[1], c1[2]); + } } diff --git a/src/main/java/gregtech/api/util/VirtualTankRegistry.java b/src/main/java/gregtech/api/util/VirtualTankRegistry.java deleted file mode 100644 index f43809d7eb3..00000000000 --- a/src/main/java/gregtech/api/util/VirtualTankRegistry.java +++ /dev/null @@ -1,338 +0,0 @@ -package gregtech.api.util; - -import gregtech.api.GTValues; - -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.world.World; -import net.minecraft.world.storage.MapStorage; -import net.minecraft.world.storage.WorldSavedData; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTankInfo; -import net.minecraftforge.fluids.IFluidTank; -import net.minecraftforge.fluids.capability.IFluidHandler; -import net.minecraftforge.fluids.capability.IFluidTankProperties; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -public class VirtualTankRegistry extends WorldSavedData { - - private static final int DEFAULT_CAPACITY = 64000; // 64B - private static final String DATA_ID = GTValues.MODID + ".vtank_data"; - - protected static Map> tankMap = new HashMap<>(); - - public VirtualTankRegistry() { - super(DATA_ID); - } - - // for some reason, MapStorage throws an error if this constructor is not present - @SuppressWarnings("unused") - public VirtualTankRegistry(String name) { - super(name); - } - - /** - * Retrieves a tank from the registry - * - * @param key The name of the tank - * @param uuid The uuid of the player the tank is private to, or null if the tank is public - * @return The tank object - */ - public static IFluidTank getTank(String key, UUID uuid) { - return tankMap.get(uuid).get(key); - } - - /** - * @return the internal Map of tanks. - * Do not use to modify the map! - */ - public static Map> getTankMap() { - return tankMap; - } - - /** - * Retrieves a tank from the registry, creating it if it does not exist - * - * @param key The name of the tank - * @param uuid The uuid of the player the tank is private to, or null if the tank is public - * @param capacity The initial capacity of the tank - * @return The tank object - */ - public static IFluidTank getTankCreate(String key, UUID uuid, int capacity) { - if (!tankMap.containsKey(uuid) || !tankMap.get(uuid).containsKey(key)) { - addTank(key, uuid, capacity); - } - return getTank(key, uuid); - } - - /** - * Retrieves a tank from the registry, creating it with {@link #DEFAULT_CAPACITY the default capacity} if it does - * not exist - * - * @param key The name of the tank - * @param uuid The uuid of the player the tank is private to, or null if the tank is public - * @return The tank object - */ - public static IFluidTank getTankCreate(String key, UUID uuid) { - return getTankCreate(key, uuid, DEFAULT_CAPACITY); - } - - /** - * Adds a tank to the registry - * - * @param key The name of the tank - * @param uuid The uuid of the player the tank is private to, or null if the tank is public - * @param capacity The initial capacity of the tank - */ - public static void addTank(String key, UUID uuid, int capacity) { - if (tankMap.containsKey(uuid) && tankMap.get(uuid).containsKey(key)) { - GTLog.logger.warn("Overwriting virtual tank " + key + "/" + (uuid == null ? "null" : uuid.toString()) + - ", this might cause fluid loss!"); - } else if (!tankMap.containsKey(uuid)) { - tankMap.put(uuid, new HashMap<>()); - } - tankMap.get(uuid).put(key, new VirtualTank(capacity)); - } - - /** - * Adds a tank to the registry with {@link #DEFAULT_CAPACITY the default capacity} - * - * @param key The name of the tank - * @param uuid The uuid of the player the tank is private to, or null if the tank is public - */ - public static void addTank(String key, UUID uuid) { - addTank(key, uuid, DEFAULT_CAPACITY); - } - - /** - * Removes a tank from the registry. Use with caution! - * - * @param key The name of the tank - * @param uuid The uuid of the player the tank is private to, or null if the tank is public - * @param removeFluid Whether to remove the tank if it has fluid in it - */ - public static void delTank(String key, UUID uuid, boolean removeFluid) { - if (tankMap.containsKey(uuid) && tankMap.get(uuid).containsKey(key)) { - if (removeFluid || tankMap.get(uuid).get(key).getFluidAmount() <= 0) { - tankMap.get(uuid).remove(key); - if (tankMap.get(uuid).size() == 0) { - tankMap.remove(uuid); - } - } - } else { - GTLog.logger.warn("Attempted to delete tank " + key + "/" + (uuid == null ? "null" : uuid.toString()) + - ", which does not exist!"); - } - } - - /** - * To be called on server stopped event - */ - public static void clearMaps() { - tankMap.clear(); - } - - @Override - public void readFromNBT(NBTTagCompound nbt) { - if (nbt.hasKey("Public")) { - NBTTagCompound publicTanks = nbt.getCompoundTag("Public"); - for (String key : publicTanks.getKeySet()) { - NBTTagCompound tankCompound = publicTanks.getCompoundTag(key); - VirtualTankRegistry.addTank(key, null, tankCompound.getInteger("Capacity")); - if (!tankCompound.hasKey("Empty")) { - VirtualTankRegistry.getTank(key, null).fill(FluidStack.loadFluidStackFromNBT(tankCompound), true); - } - } - } - if (nbt.hasKey("Private")) { - NBTTagCompound privateTankUUIDs = nbt.getCompoundTag("Private"); - for (String uuidStr : privateTankUUIDs.getKeySet()) { - UUID uuid = UUID.fromString(uuidStr); - NBTTagCompound privateTanks = privateTankUUIDs.getCompoundTag(uuidStr); - for (String key : privateTanks.getKeySet()) { - NBTTagCompound tankCompound = privateTanks.getCompoundTag(key); - VirtualTankRegistry.addTank(key, uuid, tankCompound.getInteger("Capacity")); - if (!tankCompound.hasKey("Empty")) { - VirtualTankRegistry.getTank(key, uuid).fill(FluidStack.loadFluidStackFromNBT(tankCompound), - true); - } - } - } - } - } - - @NotNull - @Override - public NBTTagCompound writeToNBT(NBTTagCompound compound) { - compound.setTag("Private", new NBTTagCompound()); - tankMap.forEach((uuid, map) -> { - NBTTagCompound mapCompound = new NBTTagCompound(); - map.forEach((key, tank) -> { - if (tank.getFluid() != null || tank.getCapacity() != DEFAULT_CAPACITY) { - NBTTagCompound tankCompound = new NBTTagCompound(); - tankCompound.setInteger("Capacity", tank.getCapacity()); - if (tank.getFluid() != null) { - tank.getFluid().writeToNBT(tankCompound); - } else { - tankCompound.setString("Empty", ""); - } - mapCompound.setTag(key, tankCompound); - } - }); - if (mapCompound.getSize() > 0) { - if (uuid == null) { - compound.setTag("Public", mapCompound); - } else { - compound.getCompoundTag("Private").setTag(uuid.toString(), mapCompound); - } - } - }); - return compound; - } - - @Override - public boolean isDirty() { - // can't think of a good way to mark dirty other than always - return true; - } - - /** - * To be called on world load event - */ - public static void initializeStorage(World world) { - MapStorage storage = world.getMapStorage(); - VirtualTankRegistry instance = (VirtualTankRegistry) storage.getOrLoadData(VirtualTankRegistry.class, DATA_ID); - - if (instance == null) { - instance = new VirtualTankRegistry(); - storage.setData(DATA_ID, instance); - } - } - - private static class VirtualTank implements IFluidTank, IFluidHandler { - - @Nullable - protected FluidStack fluid; - protected int capacity; - protected IFluidTankProperties[] tankProperties; - - public VirtualTank(int capacity) { - this.capacity = capacity; - } - - @Nullable - @Override - public FluidStack getFluid() { - return this.fluid; - } - - @Override - public int getFluidAmount() { - return this.fluid == null ? 0 : this.fluid.amount; - } - - @Override - public int getCapacity() { - return this.capacity; - } - - @Override - public FluidTankInfo getInfo() { - return new FluidTankInfo(this); - } - - @Override - public IFluidTankProperties[] getTankProperties() { - if (this.tankProperties == null) { - this.tankProperties = new IFluidTankProperties[] { new VirtualTankProperties(this) }; - } - return this.tankProperties; - } - - @Override - public int fill(FluidStack fluidStack, boolean doFill) { - if (fluidStack == null || fluidStack.amount <= 0 || - (this.fluid != null && !fluidStack.isFluidEqual(this.fluid))) - return 0; - - int fillAmt = Math.min(fluidStack.amount, this.capacity - this.getFluidAmount()); - if (doFill) { - if (this.fluid == null) { - this.fluid = new FluidStack(fluidStack, fillAmt); - } else { - this.fluid.amount += fillAmt; - } - } - return fillAmt; - } - - @Nullable - @Override - public FluidStack drain(FluidStack resource, boolean doDrain) { - return resource == null || !resource.isFluidEqual(this.fluid) ? null : drain(resource.amount, doDrain); - } - - @Nullable - @Override - public FluidStack drain(int amount, boolean doDrain) { - if (this.fluid == null || amount <= 0) - return null; - - int drainAmt = Math.min(this.getFluidAmount(), amount); - FluidStack drainedFluid = new FluidStack(fluid, drainAmt); - if (doDrain) { - this.fluid.amount -= drainAmt; - if (this.fluid.amount <= 0) { - this.fluid = null; - } - } - return drainedFluid; - } - - private static class VirtualTankProperties implements IFluidTankProperties { - - protected final VirtualTank tank; - - private VirtualTankProperties(VirtualTank tank) { - this.tank = tank; - } - - @Nullable - @Override - public FluidStack getContents() { - FluidStack contents = tank.getFluid(); - return contents == null ? null : contents.copy(); - } - - @Override - public int getCapacity() { - return tank.getCapacity(); - } - - @Override - public boolean canFill() { - return true; - } - - @Override - public boolean canDrain() { - return true; - } - - @Override - public boolean canFillFluidType(FluidStack fluidStack) { - return true; - } - - @Override - public boolean canDrainFluidType(FluidStack fluidStack) { - return true; - } - } - } -} diff --git a/src/main/java/gregtech/api/util/input/KeyBind.java b/src/main/java/gregtech/api/util/input/KeyBind.java index 309a4d28c1c..74ec9442afb 100644 --- a/src/main/java/gregtech/api/util/input/KeyBind.java +++ b/src/main/java/gregtech/api/util/input/KeyBind.java @@ -1,5 +1,6 @@ package gregtech.api.util.input; +import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.util.GTLog; import gregtech.core.network.packets.PacketKeysPressed; @@ -99,14 +100,14 @@ public static boolean scrollingDown() { KeyBind(String langKey, int button) { if (FMLCommonHandler.instance().getSide().isClient()) { - this.keybinding = new KeyBinding(langKey, button, "GregTech"); + this.keybinding = new KeyBinding(langKey, button, GTValues.MOD_NAME); ClientRegistry.registerKeyBinding(this.keybinding); } } KeyBind(String langKey, IKeyConflictContext ctx, int button) { if (FMLCommonHandler.instance().getSide().isClient()) { - this.keybinding = new KeyBinding(langKey, ctx, button, "GregTech"); + this.keybinding = new KeyBinding(langKey, ctx, button, GTValues.MOD_NAME); ClientRegistry.registerKeyBinding(this.keybinding); } } diff --git a/src/main/java/gregtech/api/util/virtualregistry/EntryTypes.java b/src/main/java/gregtech/api/util/virtualregistry/EntryTypes.java new file mode 100644 index 00000000000..6324958b8c7 --- /dev/null +++ b/src/main/java/gregtech/api/util/virtualregistry/EntryTypes.java @@ -0,0 +1,66 @@ +package gregtech.api.util.virtualregistry; + +import gregtech.api.util.GTLog; +import gregtech.api.util.virtualregistry.entries.VirtualTank; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; + +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; +import java.util.function.Supplier; + +import static gregtech.api.util.GTUtility.gregtechId; + +public final class EntryTypes { + + private static final Map> TYPES_MAP = new Object2ObjectOpenHashMap<>(); + public static final EntryTypes ENDER_FLUID = addEntryType(gregtechId("ender_fluid"), VirtualTank::new); + // ENDER_ITEM("ender_item", null), + // ENDER_ENERGY("ender_energy", null), + // ENDER_REDSTONE("ender_redstone", null); + private final ResourceLocation location; + private final Supplier factory; + + private EntryTypes(ResourceLocation location, Supplier supplier) { + this.location = location; + this.factory = supplier; + } + + public T createInstance(NBTTagCompound nbt) { + var entry = createInstance(); + entry.deserializeNBT(nbt); + return entry; + } + + public T createInstance() { + return factory.get(); + } + + @Override + public String toString() { + return this.location.toString(); + } + + @Nullable + public static EntryTypes fromString(String name) { + return TYPES_MAP.getOrDefault(gregtechId(name), null); + } + + @Nullable + public static EntryTypes fromLocation(String location) { + return TYPES_MAP.getOrDefault(new ResourceLocation(location), null); + } + + public static EntryTypes addEntryType(ResourceLocation location, Supplier supplier) { + var type = new EntryTypes<>(location, supplier); + if (!TYPES_MAP.containsKey(location)) { + TYPES_MAP.put(location, type); + } else { + GTLog.logger.warn("Entry \"{}\" is already registered!", location); + } + return type; + } +} diff --git a/src/main/java/gregtech/api/util/virtualregistry/VirtualEnderRegistry.java b/src/main/java/gregtech/api/util/virtualregistry/VirtualEnderRegistry.java new file mode 100644 index 00000000000..3d8ccd78224 --- /dev/null +++ b/src/main/java/gregtech/api/util/virtualregistry/VirtualEnderRegistry.java @@ -0,0 +1,175 @@ +package gregtech.api.util.virtualregistry; + +import gregtech.api.GTValues; +import gregtech.api.util.GTLog; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; +import net.minecraft.world.storage.MapStorage; +import net.minecraft.world.storage.WorldSavedData; +import net.minecraftforge.fluids.IFluidTank; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.function.Predicate; + +@SuppressWarnings("SameParameterValue") +public class VirtualEnderRegistry extends WorldSavedData { + + private static final String DATA_ID = GTValues.MODID + ".virtual_entry_data"; + private static final String OLD_DATA_ID = GTValues.MODID + ".vtank_data"; + private static final String PUBLIC_KEY = "Public"; + private static final String PRIVATE_KEY = "Private"; + private static final Map VIRTUAL_REGISTRIES = new HashMap<>(); + + public VirtualEnderRegistry(String name) { + super(name); + } + + public static T getEntry(@Nullable UUID owner, EntryTypes type, String name) { + return getRegistry(owner).getEntry(type, name); + } + + public static void addEntry(@Nullable UUID owner, String name, VirtualEntry entry) { + getRegistry(owner).addEntry(name, entry); + } + + public static boolean hasEntry(@Nullable UUID owner, EntryTypes type, String name) { + return getRegistry(owner).contains(type, name); + } + + public static @NotNull T getOrCreateEntry(@Nullable UUID owner, EntryTypes type, + String name) { + if (!hasEntry(owner, type, name)) + addEntry(owner, name, type.createInstance()); + + return getEntry(owner, type, name); + } + + /** + * Removes an entry from the registry. Use with caution! + * + * @param owner The uuid of the player the entry is private to, or null if the entry is public + * @param type Type of the registry to remove from + * @param name The name of the entry + */ + public static void deleteEntry(@Nullable UUID owner, EntryTypes type, String name) { + var registry = getRegistry(owner); + if (registry.contains(type, name)) { + registry.deleteEntry(type, name); + return; + } + GTLog.logger.warn("Attempted to delete {} entry {} of type {}, which does not exist", + owner == null ? "public" : String.format("private [%s]", owner), name, type); + } + + public static void deleteEntry(@Nullable UUID owner, EntryTypes type, String name, + Predicate shouldDelete) { + T entry = getEntry(owner, type, name); + if (entry != null && shouldDelete.test(entry)) + deleteEntry(owner, type, name); + } + + public static Set getEntryNames(UUID owner, EntryTypes type) { + return getRegistry(owner).getEntryNames(type); + } + + /** + * To be called on server stopped event + */ + public static void clearMaps() { + VIRTUAL_REGISTRIES.clear(); + } + + private static VirtualRegistryMap getRegistry(UUID owner) { + return VIRTUAL_REGISTRIES.computeIfAbsent(owner, key -> new VirtualRegistryMap()); + } + + // remove if tank app is removed + public static Map> createTankMap() { + Map> map = new HashMap<>(); + for (var uuid : VIRTUAL_REGISTRIES.keySet()) { + map.put(uuid, new HashMap<>()); + for (var name : getEntryNames(uuid, EntryTypes.ENDER_FLUID)) { + map.get(uuid).put(name, getEntry(uuid, EntryTypes.ENDER_FLUID, name)); + } + } + return map; + } + + @Override + public final void readFromNBT(NBTTagCompound nbt) { + if (nbt.hasKey(PUBLIC_KEY)) { + VIRTUAL_REGISTRIES.put(null, new VirtualRegistryMap(nbt.getCompoundTag(PUBLIC_KEY))); + } + if (nbt.hasKey(PRIVATE_KEY)) { + NBTTagCompound privateEntries = nbt.getCompoundTag(PRIVATE_KEY); + for (String owner : privateEntries.getKeySet()) { + var privateMap = privateEntries.getCompoundTag(owner); + VIRTUAL_REGISTRIES.put(UUID.fromString(owner), new VirtualRegistryMap(privateMap)); + } + } + } + + @NotNull + @Override + public final NBTTagCompound writeToNBT(@NotNull NBTTagCompound tag) { + var privateTag = new NBTTagCompound(); + for (var owner : VIRTUAL_REGISTRIES.keySet()) { + var mapTag = VIRTUAL_REGISTRIES.get(owner).serializeNBT(); + if (owner != null) { + privateTag.setTag(owner.toString(), mapTag); + } else { + tag.setTag(PUBLIC_KEY, mapTag); + } + } + tag.setTag(PRIVATE_KEY, privateTag); + return tag; + } + + @Override + public boolean isDirty() { + // can't think of a good way to mark dirty other than always + return true; + } + + /** + * To be called on world load event + */ + @SuppressWarnings("DataFlowIssue") + public static void initializeStorage(World world) { + MapStorage storage = world.getMapStorage(); + + VirtualEnderRegistry instance = (VirtualEnderRegistry) storage.getOrLoadData(VirtualEnderRegistry.class, + DATA_ID); + VirtualEnderRegistry old = (VirtualEnderRegistry) storage.getOrLoadData(VirtualEnderRegistry.class, + OLD_DATA_ID); + + if (instance == null) { + instance = new VirtualEnderRegistry(DATA_ID); + storage.setData(DATA_ID, instance); + } + + if (old != null) { + instance.readFromNBT(old.serializeNBT()); + var file = world.getSaveHandler().getMapFileFromName(OLD_DATA_ID); + var split = file.getName().split("\\."); + var stringBuilder = new StringBuilder(split[0]) + .append('.') + .append(split[1]) + .append(".backup") + .append('.') + .append(split[2]); + if (file.renameTo(new File(file.getParent(), stringBuilder.toString()))) { + file.deleteOnExit(); + GTLog.logger.warn("Moved Virtual Tank Data to new format, created backup!"); + } + } + } +} diff --git a/src/main/java/gregtech/api/util/virtualregistry/VirtualEntry.java b/src/main/java/gregtech/api/util/virtualregistry/VirtualEntry.java new file mode 100644 index 00000000000..2775069f0e3 --- /dev/null +++ b/src/main/java/gregtech/api/util/virtualregistry/VirtualEntry.java @@ -0,0 +1,79 @@ +package gregtech.api.util.virtualregistry; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.INBTSerializable; + +import org.jetbrains.annotations.NotNull; + +public abstract class VirtualEntry implements INBTSerializable { + + public static final String DEFAULT_COLOR = "FFFFFFFF"; + protected static final String COLOR_KEY = "color"; + protected static final String DESC_KEY = "description"; + + private int color = 0xFFFFFFFF; + private String colorStr = DEFAULT_COLOR; + private @NotNull String description = ""; + + public abstract EntryTypes getType(); + + public String getColorStr() { + return colorStr; + } + + public int getColor() { + return this.color; + } + + public void setColor(String color) { + this.color = parseColor(color); + this.colorStr = color.toUpperCase(); + } + + public void setColor(int color) { + setColor(Integer.toHexString(color)); + } + + private int parseColor(String s) { + // stupid java not having actual unsigned ints + long tmp = Long.parseLong(s, 16); + if (tmp > 0x7FFFFFFF) { + tmp -= 0x100000000L; + } + return (int) tmp; + } + + public @NotNull String getDescription() { + return this.description; + } + + public void setDescription(@NotNull String desc) { + this.description = desc; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof VirtualEntry other)) return false; + return this.getType() == other.getType() && + this.color == other.color; + } + + @Override + public NBTTagCompound serializeNBT() { + var tag = new NBTTagCompound(); + tag.setString(COLOR_KEY, this.colorStr); + + if (description != null && !description.isEmpty()) + tag.setString(DESC_KEY, this.description); + + return tag; + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + setColor(nbt.getString(COLOR_KEY)); + + if (nbt.hasKey(DESC_KEY)) + setDescription(nbt.getString(DESC_KEY)); + } +} diff --git a/src/main/java/gregtech/api/util/virtualregistry/VirtualRegistryMap.java b/src/main/java/gregtech/api/util/virtualregistry/VirtualRegistryMap.java new file mode 100644 index 00000000000..18a2b9a81e8 --- /dev/null +++ b/src/main/java/gregtech/api/util/virtualregistry/VirtualRegistryMap.java @@ -0,0 +1,87 @@ +package gregtech.api.util.virtualregistry; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.INBTSerializable; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class VirtualRegistryMap implements INBTSerializable { + + private final Map, Map> registryMap = new HashMap<>(); + + public VirtualRegistryMap(NBTTagCompound tag) { + deserializeNBT(tag); + } + + public VirtualRegistryMap() {} + + @SuppressWarnings("unchecked") + public @Nullable T getEntry(EntryTypes type, String name) { + if (!contains(type, name)) + return null; + + return (T) registryMap.get(type).get(name); + } + + public void addEntry(String name, VirtualEntry entry) { + registryMap.computeIfAbsent(entry.getType(), k -> new HashMap<>()) + .put(name, entry); + } + + public boolean contains(EntryTypes type, String name) { + if (!registryMap.containsKey(type)) + return false; + + return registryMap.get(type).containsKey(name); + } + + public void deleteEntry(EntryTypes type, String name) { + registryMap.get(type).remove(name); + } + + public void clear() { + registryMap.clear(); + } + + public Set getEntryNames(EntryTypes type) { + return registryMap.get(type).keySet(); + } + + @Override + public @NotNull NBTTagCompound serializeNBT() { + var tag = new NBTTagCompound(); + for (var type : registryMap.keySet()) { + var entriesTag = new NBTTagCompound(); + var entries = registryMap.get(type); + for (var name : entries.keySet()) { + entriesTag.setTag(name, entries.get(name).serializeNBT()); + } + tag.setTag(type.toString(), entriesTag); + } + return tag; + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + for (var entryType : nbt.getKeySet()) { + EntryTypes type; + if (entryType.contains(":")) { + type = EntryTypes.fromLocation(entryType); + } else { + type = EntryTypes.fromString(entryType); + } + if (type == null) continue; + + var virtualEntries = nbt.getCompoundTag(entryType); + for (var name : virtualEntries.getKeySet()) { + var entry = virtualEntries.getCompoundTag(name); + addEntry(name, type.createInstance(entry)); + } + } + } +} diff --git a/src/main/java/gregtech/api/util/virtualregistry/entries/VirtualTank.java b/src/main/java/gregtech/api/util/virtualregistry/entries/VirtualTank.java new file mode 100644 index 00000000000..3ad02e5969c --- /dev/null +++ b/src/main/java/gregtech/api/util/virtualregistry/entries/VirtualTank.java @@ -0,0 +1,180 @@ +package gregtech.api.util.virtualregistry.entries; + +import gregtech.api.util.virtualregistry.EntryTypes; +import gregtech.api.util.virtualregistry.VirtualEntry; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.IFluidTankProperties; + +import org.jetbrains.annotations.Nullable; + +public class VirtualTank extends VirtualEntry implements IFluidTank, IFluidHandler { + + protected static final String CAPACITY_KEY = "capacity"; + protected static final String FLUID_KEY = "fluid"; + private static final int DEFAULT_CAPACITY = 64000; // 64B + + @Nullable + private FluidStack fluidStack = null; + private int capacity; + private final IFluidTankProperties[] props = new IFluidTankProperties[] { + createProperty(this) + }; + + public VirtualTank(int capacity) { + this.capacity = capacity; + } + + public VirtualTank() { + this(DEFAULT_CAPACITY); + } + + @Override + public EntryTypes getType() { + return EntryTypes.ENDER_FLUID; + } + + @Override + public FluidStack getFluid() { + return this.fluidStack; + } + + public void setFluid(FluidStack fluid) { + this.fluidStack = fluid; + } + + @Override + public int getFluidAmount() { + return fluidStack == null ? 0 : fluidStack.amount; + } + + @Override + public int getCapacity() { + return this.capacity; + } + + @Override + public FluidTankInfo getInfo() { + return new FluidTankInfo(this); + } + + @Override + public IFluidTankProperties[] getTankProperties() { + return this.props; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof VirtualTank other)) return false; + if (this.fluidStack == null && other.fluidStack == null) + return super.equals(o); + if (this.fluidStack == null || other.fluidStack == null) + return false; + if (this.fluidStack.isFluidStackIdentical(other.fluidStack)) + return super.equals(o); + + return false; + } + + @Override + public NBTTagCompound serializeNBT() { + var tag = super.serializeNBT(); + tag.setInteger(CAPACITY_KEY, this.capacity); + + if (this.fluidStack != null) + tag.setTag(FLUID_KEY, this.fluidStack.writeToNBT(new NBTTagCompound())); + + return tag; + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + super.deserializeNBT(nbt); + this.capacity = nbt.getInteger(CAPACITY_KEY); + + if (nbt.hasKey(FLUID_KEY)) + setFluid(FluidStack.loadFluidStackFromNBT(nbt.getCompoundTag(FLUID_KEY))); + } + + @Override + public int fill(FluidStack fluidStack, boolean doFill) { + if (fluidStack == null || fluidStack.amount <= 0 || + (this.fluidStack != null && !fluidStack.isFluidEqual(this.fluidStack))) + return 0; + + int fillAmt = Math.min(fluidStack.amount, getCapacity() - this.getFluidAmount()); + + if (doFill) { + if (this.fluidStack == null) { + this.fluidStack = new FluidStack(fluidStack, fillAmt); + } else { + this.fluidStack.amount += fillAmt; + } + } + return fillAmt; + } + + @Nullable + @Override + public FluidStack drain(FluidStack resource, boolean doDrain) { + return resource == null || !resource.isFluidEqual(this.fluidStack) ? null : drain(resource.amount, doDrain); + } + + @Nullable + @Override + public FluidStack drain(int amount, boolean doDrain) { + if (this.fluidStack == null || amount <= 0) + return null; + + int drainAmt = Math.min(this.getFluidAmount(), amount); + FluidStack drainedFluid = new FluidStack(this.fluidStack, drainAmt); + if (doDrain) { + this.fluidStack.amount -= drainAmt; + if (this.fluidStack.amount <= 0) { + this.fluidStack = null; + } + } + return drainedFluid; + } + + private static IFluidTankProperties createProperty(VirtualTank tank) { + return new IFluidTankProperties() { + + @Nullable + @Override + public FluidStack getContents() { + FluidStack contents = tank.getFluid(); + return contents == null ? null : contents.copy(); + } + + @Override + public int getCapacity() { + return tank.getCapacity(); + } + + @Override + public boolean canFill() { + return true; + } + + @Override + public boolean canDrain() { + return true; + } + + @Override + public boolean canFillFluidType(FluidStack fluidStack) { + return true; + } + + @Override + public boolean canDrainFluidType(FluidStack fluidStack) { + return true; + } + }; + } +} 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/api/worldgen/config/WorldGenRegistry.java b/src/main/java/gregtech/api/worldgen/config/WorldGenRegistry.java index 2a30f9e1eeb..858f28bc328 100644 --- a/src/main/java/gregtech/api/worldgen/config/WorldGenRegistry.java +++ b/src/main/java/gregtech/api/worldgen/config/WorldGenRegistry.java @@ -3,6 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.util.FileUtility; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.api.worldgen.filler.BlacklistedBlockFiller; import gregtech.api.worldgen.filler.BlockFiller; import gregtech.api.worldgen.filler.LayeredBlockFiller; @@ -123,7 +124,7 @@ public void initializeRegistry() { } catch (IOException | RuntimeException exception) { GTLog.logger.fatal("Failed to initialize worldgen registry.", exception); } - if (Loader.isModLoaded("galacticraftcore")) { + if (Mods.GalacticraftCore.isModLoaded()) { try { Class transformerHooksClass = Class.forName("micdoodle8.mods.galacticraft.core.TransformerHooks"); Field otherModGeneratorsWhitelistField = transformerHooksClass diff --git a/src/main/java/gregtech/asm/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 4d98621cfa8..9a13badeaf5 100644 --- a/src/main/java/gregtech/asm/GregTechTransformer.java +++ b/src/main/java/gregtech/asm/GregTechTransformer.java @@ -1,23 +1,8 @@ package gregtech.asm; -import gregtech.api.GTValues; -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 net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.common.ModContainer; -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 { @@ -25,187 +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 underhaul - ModContainer container = Loader.instance().getIndexedModList().get(GTValues.MODID_NC); - if (container.getVersion().contains("2o")) { // overhauled - classReader.accept(new TargetClassVisitor(classWriter, - NuclearCraftRecipeHelperVisitor.TARGET_METHOD_NCO, NuclearCraftRecipeHelperVisitor::new), - 0); - } else { - 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/hooks/CTMHooks.java b/src/main/java/gregtech/asm/hooks/CTMHooks.java index 33ddc0d7754..bf254934d5c 100644 --- a/src/main/java/gregtech/asm/hooks/CTMHooks.java +++ b/src/main/java/gregtech/asm/hooks/CTMHooks.java @@ -1,6 +1,6 @@ package gregtech.asm.hooks; -import gregtech.client.shader.Shaders; +import gregtech.api.util.Mods; import gregtech.client.utils.BloomEffectUtil; import net.minecraft.block.state.IBlockState; @@ -20,7 +20,7 @@ public class CTMHooks { public static ThreadLocal ENABLE = new ThreadLocal<>(); public static boolean checkLayerWithOptiFine(boolean canRenderInLayer, byte layers, BlockRenderLayer layer) { - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { if (canRenderInLayer) { if (layer == BloomEffectUtil.getBloomLayer()) return false; } else if ((layers >> BloomEffectUtil.getBloomLayer().ordinal() & 1) == 1 && @@ -34,7 +34,7 @@ public static boolean checkLayerWithOptiFine(boolean canRenderInLayer, byte laye public static List getQuadsWithOptiFine(List ret, BlockRenderLayer layer, IBakedModel bakedModel, IBlockState state, EnumFacing side, long rand) { - if (Shaders.isOptiFineShaderPackLoaded() && CTMHooks.ENABLE.get() == null) { + if (Mods.Optifine.isModLoaded() && CTMHooks.ENABLE.get() == null) { if (layer == BloomEffectUtil.getBloomLayer()) { return Collections.emptyList(); } else if (layer == BloomEffectUtil.getEffectiveBloomLayer()) { @@ -43,7 +43,7 @@ public static List getQuadsWithOptiFine(List ret, BlockRen ForgeHooksClient.setRenderLayer(BloomEffectUtil.getBloomLayer()); result.addAll(bakedModel.getQuads(state, side, rand)); ForgeHooksClient.setRenderLayer(layer); - CTMHooks.ENABLE.set(null); + CTMHooks.ENABLE.remove(); return result; } } diff --git a/src/main/java/gregtech/asm/visitors/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/RenderItemVisitor.java b/src/main/java/gregtech/asm/visitors/RenderItemVisitor.java index f1b87a1fc12..750de53af3b 100644 --- a/src/main/java/gregtech/asm/visitors/RenderItemVisitor.java +++ b/src/main/java/gregtech/asm/visitors/RenderItemVisitor.java @@ -1,6 +1,6 @@ package gregtech.asm.visitors; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.asm.util.ObfMapping; import net.minecraftforge.fml.common.Loader; @@ -28,7 +28,7 @@ public static void transform(Iterator methods) { callRenderLampOverlay.add(new MethodInsnNode(INVOKESTATIC, "gregtech/asm/hooks/RenderItemHooks", "renderLampOverlay", "(Lnet/minecraft/item/ItemStack;II)V", false)); - boolean enderCoreLoaded = Loader.instance().getIndexedModList().containsKey(GTValues.MODID_ECORE); + boolean enderCoreLoaded = Loader.instance().getIndexedModList().containsKey(Mods.Names.ENDER_CORE); // do not conflict with EnderCore's changes, which already do what we need InsnList callRenderElectricBar; diff --git a/src/main/java/gregtech/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/ClientProxy.java b/src/main/java/gregtech/client/ClientProxy.java index 0210563b18c..35969198260 100644 --- a/src/main/java/gregtech/client/ClientProxy.java +++ b/src/main/java/gregtech/client/ClientProxy.java @@ -4,18 +4,24 @@ import gregtech.api.fluids.GTFluidRegistration; import gregtech.api.items.metaitem.MetaOreDictItem; import gregtech.api.items.toolitem.IGTTool; -import gregtech.api.terminal.TerminalRegistry; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Materials; import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.FluidTooltipUtil; import gregtech.api.util.IBlockOre; -import gregtech.api.util.ModCompatibility; +import gregtech.api.util.Mods; import gregtech.client.model.customtexture.CustomTextureModelHandler; import gregtech.client.model.customtexture.MetadataSectionCTM; import gregtech.client.renderer.handler.FacadeRenderer; import gregtech.client.renderer.handler.MetaTileEntityRenderer; -import gregtech.client.renderer.pipe.*; +import gregtech.client.renderer.pipe.CableRenderer; +import gregtech.client.renderer.pipe.FluidPipeRenderer; +import gregtech.client.renderer.pipe.ItemPipeRenderer; +import gregtech.client.renderer.pipe.LaserPipeRenderer; +import gregtech.client.renderer.pipe.OpticalPipeRenderer; +import gregtech.client.renderer.pipe.PipeRenderer; +import gregtech.client.renderer.texture.Textures; +import gregtech.client.utils.ItemRenderCompat; import gregtech.client.utils.TooltipHelper; import gregtech.common.CommonProxy; import gregtech.common.ConfigHolder; @@ -28,6 +34,7 @@ import net.minecraft.block.Block; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.resources.I18n; import net.minecraft.client.resources.SimpleReloadableResourceManager; import net.minecraft.entity.player.EntityPlayer; @@ -41,13 +48,13 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.client.event.ModelRegistryEvent; +import net.minecraftforge.client.event.TextureStitchEvent; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.util.Constants; import net.minecraftforge.event.entity.player.ItemTooltipEvent; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.IFluidBlock; import net.minecraftforge.fluids.capability.templates.FluidHandlerItemStack; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -55,7 +62,6 @@ import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.oredict.OreDictionary; -import codechicken.lib.texture.TextureUtils; import org.jetbrains.annotations.NotNull; import paulscode.sound.SoundSystemConfig; @@ -72,7 +78,7 @@ public void onPreLoad() { SoundSystemConfig.setNumberNormalChannels(ConfigHolder.client.maxNumSounds); - if (!Loader.isModLoaded(GTValues.MODID_CTM)) { + if (!Mods.CTM.isModLoaded()) { Minecraft.getMinecraft().metadataSerializer.registerMetadataSectionType(new MetadataSectionCTM.Serializer(), MetadataSectionCTM.class); MinecraftForge.EVENT_BUS.register(CustomTextureModelHandler.INSTANCE); @@ -87,8 +93,6 @@ public void onPreLoad() { OpticalPipeRenderer.INSTANCE.preInit(); LaserPipeRenderer.INSTANCE.preInit(); MetaEntities.initRenderers(); - TextureUtils.addIconRegister(GTFluidRegistration.INSTANCE::registerSprites); - TextureUtils.addIconRegister(PipeRenderer::initializeRestrictor); } @Override @@ -100,8 +104,7 @@ public void onLoad() { @Override public void onPostLoad() { super.onPostLoad(); - TerminalRegistry.initTerminalFiles(); - ModCompatibility.initCompat(); + ItemRenderCompat.init(); FacadeRenderer.init(); } @@ -111,6 +114,19 @@ public static void registerColors() { ToolItems.registerColors(); } + @SubscribeEvent + public static void textureStitchPre(@NotNull TextureStitchEvent.Pre event) { + TextureMap map = event.getMap(); + GTFluidRegistration.INSTANCE.registerSprites(map); + PipeRenderer.initializeRestrictor(map); + Textures.register(map); + CableRenderer.INSTANCE.registerIcons(map); + FluidPipeRenderer.INSTANCE.registerIcons(map); + ItemPipeRenderer.INSTANCE.registerIcons(map); + OpticalPipeRenderer.INSTANCE.registerIcons(map); + LaserPipeRenderer.INSTANCE.registerIcons(map); + } + @SubscribeEvent public static void registerModels(ModelRegistryEvent event) { MetaBlocks.registerStateMappers(); diff --git a/src/main/java/gregtech/client/event/ClientEventHandler.java b/src/main/java/gregtech/client/event/ClientEventHandler.java index c83851d8e34..57c79a3afb7 100644 --- a/src/main/java/gregtech/client/event/ClientEventHandler.java +++ b/src/main/java/gregtech/client/event/ClientEventHandler.java @@ -10,7 +10,7 @@ import gregtech.client.particle.GTParticleManager; 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 +24,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; @@ -67,7 +68,6 @@ public static void onPreWorldRender(TickEvent.RenderTickEvent event) { @SubscribeEvent public static void onClientTick(TickEvent.ClientTickEvent event) { GTParticleManager.clientTick(event); - TerminalARRenderer.onClientTick(event); TooltipHelper.onClientTick(event); if (event.phase == TickEvent.Phase.END) { CLIENT_TIME++; @@ -79,23 +79,16 @@ public static void onRenderWorldLast(RenderWorldLastEvent event) { DepthTextureUtil.renderWorld(event); MultiblockPreviewRenderer.renderWorldLastEvent(event); BlockPosHighlightRenderer.renderWorldLastEvent(event); - TerminalARRenderer.renderWorldLastEvent(event); GTParticleManager.renderWorld(event); } @SubscribeEvent public static void onRenderGameOverlayPre(RenderGameOverlayEvent.Pre event) { - TerminalARRenderer.renderGameOverlayEvent(event); if (ConfigHolder.misc.debug && event instanceof RenderGameOverlayEvent.Text text) { GTParticleManager.debugOverlay(text); } } - @SubscribeEvent - public static void onRenderSpecificHand(RenderSpecificHandEvent event) { - TerminalARRenderer.renderHandEvent(event); - } - private static final Map DEFAULT_CAPES = new Object2ObjectOpenHashMap<>(); @SubscribeEvent @@ -157,4 +150,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/model/modelfactories/BakedModelHandler.java b/src/main/java/gregtech/client/model/modelfactories/BakedModelHandler.java index 3aa4d37f038..7506494a04b 100644 --- a/src/main/java/gregtech/client/model/modelfactories/BakedModelHandler.java +++ b/src/main/java/gregtech/client/model/modelfactories/BakedModelHandler.java @@ -1,24 +1,16 @@ package gregtech.client.model.modelfactories; +import gregtech.client.utils.RenderUtil; + import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.ItemMeshDefinition; -import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.IBakedModel; -import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType; -import net.minecraft.client.renderer.block.model.ItemOverrideList; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.renderer.block.statemap.StateMapperBase; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.Tuple; import net.minecraftforge.client.event.ModelBakeEvent; import net.minecraftforge.client.model.ModelFluid; import net.minecraftforge.client.model.ModelLoader; -import net.minecraftforge.client.model.PerspectiveMapWrapper; import net.minecraftforge.fluids.BlockFluidBase; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fml.common.ObfuscationReflectionHelper; @@ -26,19 +18,9 @@ import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import codechicken.lib.render.item.CCRenderItem; -import codechicken.lib.texture.TextureUtils; -import codechicken.lib.util.TransformUtils; -import org.apache.commons.lang3.tuple.Pair; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import javax.vecmath.Matrix4f; - @SideOnly(Side.CLIENT) public class BakedModelHandler { @@ -49,25 +31,13 @@ protected ModelResourceLocation getModelResourceLocation(IBlockState state) { return getSimpleModelLocation(state.getBlock()); } }; - private static final ItemMeshDefinition SIMPLE_MESH_DEFINITION = (stack) -> getSimpleModelLocation( - Block.getBlockFromItem(stack.getItem())); private static ModelResourceLocation getSimpleModelLocation(Block block) { return new ModelResourceLocation(Block.REGISTRY.getNameForObject(block), ""); } - private final List> builtInBlocks = new ArrayList<>(); private final List fluidBlocks = new ArrayList<>(); - public void addBuiltInBlock(Block block, String particleTexture) { - this.builtInBlocks.add(new Tuple<>(block, particleTexture)); - ModelLoader.setCustomStateMapper(block, SIMPLE_STATE_MAPPER); - Item itemFromBlock = Item.getItemFromBlock(block); - if (itemFromBlock != Items.AIR) { - ModelLoader.setCustomMeshDefinition(itemFromBlock, SIMPLE_MESH_DEFINITION); - } - } - public void addFluidBlock(BlockFluidBase fluidBase) { this.fluidBlocks.add(fluidBase); ModelLoader.setCustomStateMapper(fluidBase, SIMPLE_STATE_MAPPER); @@ -79,63 +49,9 @@ public void onModelsBake(ModelBakeEvent event) { Fluid fluid = ObfuscationReflectionHelper.getPrivateValue(BlockFluidBase.class, fluidBlock, "definedFluid"); ModelFluid modelFluid = new ModelFluid(fluid); IBakedModel bakedModel = modelFluid.bake(modelFluid.getDefaultState(), DefaultVertexFormats.ITEM, - TextureUtils::getTexture); + RenderUtil::getTexture); ModelResourceLocation resourceLocation = getSimpleModelLocation(fluidBlock); event.getModelRegistry().putObject(resourceLocation, bakedModel); } - for (Tuple tuple : builtInBlocks) { - ModelResourceLocation resourceLocation = getSimpleModelLocation(tuple.getFirst()); - ModelBuiltInRenderer bakedModel = new ModelBuiltInRenderer(tuple.getSecond()); - event.getModelRegistry().putObject(resourceLocation, bakedModel); - } - } - - private static class ModelBuiltInRenderer implements IBakedModel { - - private final String particleTexture; - - public ModelBuiltInRenderer(String particleTexture) { - this.particleTexture = particleTexture; - } - - @NotNull - @Override - public List getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) { - return Collections.emptyList(); - } - - @Override - public boolean isAmbientOcclusion() { - return true; - } - - @Override - public boolean isGui3d() { - return true; - } - - @Override - public boolean isBuiltInRenderer() { - return true; - } - - @NotNull - @Override - public TextureAtlasSprite getParticleTexture() { - return TextureUtils.getBlockTexture(particleTexture); - } - - @NotNull - @Override - public ItemOverrideList getOverrides() { - return ItemOverrideList.NONE; - } - - @NotNull - @Override - public Pair handlePerspective(@NotNull TransformType cameraTransformType) { - CCRenderItem.notifyTransform(cameraTransformType); - return PerspectiveMapWrapper.handlePerspective(this, TransformUtils.DEFAULT_BLOCK, cameraTransformType); - } } } diff --git a/src/main/java/gregtech/client/model/pipeline/VertexLighterFlatSpecial.java b/src/main/java/gregtech/client/model/pipeline/VertexLighterFlatSpecial.java index 75f05440797..9f8580344ec 100644 --- a/src/main/java/gregtech/client/model/pipeline/VertexLighterFlatSpecial.java +++ b/src/main/java/gregtech/client/model/pipeline/VertexLighterFlatSpecial.java @@ -1,6 +1,6 @@ package gregtech.client.model.pipeline; -import gregtech.client.shader.Shaders; +import gregtech.api.util.Mods; import net.minecraft.client.renderer.color.BlockColors; import net.minecraft.client.renderer.vertex.VertexFormat; @@ -134,7 +134,7 @@ protected void processQuad() { updateColor(normal[v], color[v], x, y, z, tint, multiplier); // When enabled this causes the rendering to be black with Optifine - if (!Shaders.isOptiFineShaderPackLoaded() && diffuse) { + if (!Mods.Optifine.isModLoaded() && diffuse) { float d = LightUtil.diffuseLight(normal[v][0], normal[v][1], normal[v][2]); for (int i = 0; i < 3; i++) { color[v][i] *= d; diff --git a/src/main/java/gregtech/client/model/pipeline/VertexLighterSmoothAoSpecial.java b/src/main/java/gregtech/client/model/pipeline/VertexLighterSmoothAoSpecial.java index 79b83e9998e..f1d6f852e3c 100644 --- a/src/main/java/gregtech/client/model/pipeline/VertexLighterSmoothAoSpecial.java +++ b/src/main/java/gregtech/client/model/pipeline/VertexLighterSmoothAoSpecial.java @@ -1,6 +1,6 @@ package gregtech.client.model.pipeline; -import gregtech.client.shader.Shaders; +import gregtech.api.util.Mods; import net.minecraft.client.renderer.color.BlockColors; import net.minecraft.util.math.MathHelper; @@ -15,7 +15,7 @@ public VertexLighterSmoothAoSpecial(BlockColors colors) { @Override protected void updateLightmap(float[] normal, float[] lightmap, float x, float y, float z) { - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { super.updateLightmap(normal, lightmap, x, y, z); return; } @@ -28,7 +28,7 @@ protected void updateLightmap(float[] normal, float[] lightmap, float x, float y protected void updateColor(float[] normal, float[] color, float x, float y, float z, float tint, int multiplier) { super.updateColor(normal, color, x, y, z, tint, multiplier); - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { return; } @@ -146,7 +146,7 @@ protected float getAo(float x, float y, float z) { @Override public void updateBlockInfo() { - if (Shaders.isOptiFineShaderPackLoaded()) { + if (Mods.Optifine.isModLoaded()) { super.updateBlockInfo(); return; } diff --git a/src/main/java/gregtech/client/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/ICCLBlockRenderer.java b/src/main/java/gregtech/client/renderer/ICCLBlockRenderer.java deleted file mode 100644 index f1d70220390..00000000000 --- a/src/main/java/gregtech/client/renderer/ICCLBlockRenderer.java +++ /dev/null @@ -1,19 +0,0 @@ -package gregtech.client.renderer; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.block.model.ItemCameraTransforms; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IBlockAccess; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -public interface ICCLBlockRenderer { - - @SideOnly(Side.CLIENT) - void renderItem(ItemStack rawStack, ItemCameraTransforms.TransformType transformType); - - @SideOnly(Side.CLIENT) - void renderBlock(IBlockAccess world, BlockPos pos, IBlockState state, BufferBuilder buffer); -} diff --git a/src/main/java/gregtech/client/renderer/ICubeRenderer.java b/src/main/java/gregtech/client/renderer/ICubeRenderer.java index 5fb0a866a42..1830ecad570 100644 --- a/src/main/java/gregtech/client/renderer/ICubeRenderer.java +++ b/src/main/java/gregtech/client/renderer/ICubeRenderer.java @@ -1,6 +1,7 @@ package gregtech.client.renderer; import gregtech.api.gui.resources.ResourceHelper; +import gregtech.client.texture.IconRegistrar; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureMap; @@ -11,13 +12,12 @@ import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; -import codechicken.lib.texture.TextureUtils.IIconRegister; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public interface ICubeRenderer extends IIconRegister { +public interface ICubeRenderer extends IconRegistrar { String EMISSIVE = "_emissive"; diff --git a/src/main/java/gregtech/client/renderer/handler/BlockPosHighlightRenderer.java b/src/main/java/gregtech/client/renderer/handler/BlockPosHighlightRenderer.java index df5f186744f..c4b1254beb2 100644 --- a/src/main/java/gregtech/client/renderer/handler/BlockPosHighlightRenderer.java +++ b/src/main/java/gregtech/client/renderer/handler/BlockPosHighlightRenderer.java @@ -19,22 +19,33 @@ public class BlockPosHighlightRenderer { private static BlockPos posHighLight; - private static long hlEndTime; + private static long duration; + private static long offset; + private static long start; public static void renderBlockBoxHighLight(BlockPos blockpos, long durTimeMillis) { posHighLight = blockpos; - hlEndTime = System.currentTimeMillis() + durTimeMillis; + duration = durTimeMillis; + offset = 1500; + start = System.currentTimeMillis(); + } + + public static void renderBlockBoxHighLight(BlockPos blockpos, long durTimeMillis, long offsetTimeMillis) { + posHighLight = blockpos; + duration = durTimeMillis; + offset = offsetTimeMillis; + start = System.currentTimeMillis(); } public static void renderWorldLastEvent(RenderWorldLastEvent evt) { if (posHighLight != null) { long time = System.currentTimeMillis(); - if (time > hlEndTime) { + if (time > duration + start) { posHighLight = null; - hlEndTime = 0; + duration = 0; return; } - if (((time / 500) & 1) == 0) { + if (time % offset >= offset / 2) { return; } EntityPlayerSP p = Minecraft.getMinecraft().player; diff --git a/src/main/java/gregtech/client/renderer/handler/CCLBlockRenderer.java b/src/main/java/gregtech/client/renderer/handler/CCLBlockRenderer.java deleted file mode 100644 index 5dabff41d6a..00000000000 --- a/src/main/java/gregtech/client/renderer/handler/CCLBlockRenderer.java +++ /dev/null @@ -1,122 +0,0 @@ -package gregtech.client.renderer.handler; - -import gregtech.api.util.GTLog; -import gregtech.api.util.GTUtility; -import gregtech.api.util.ModCompatibility; -import gregtech.client.renderer.ICCLBlockRenderer; -import gregtech.client.renderer.texture.Textures; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.block.model.ItemCameraTransforms; -import net.minecraft.client.renderer.block.model.ModelResourceLocation; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.renderer.texture.TextureMap; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumBlockRenderType; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.IBlockAccess; -import net.minecraftforge.client.event.ModelBakeEvent; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.model.IModelState; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import codechicken.lib.render.CCRenderState; -import codechicken.lib.render.block.BlockRenderingRegistry; -import codechicken.lib.render.block.ICCBlockRenderer; -import codechicken.lib.render.item.IItemRenderer; -import codechicken.lib.texture.TextureUtils; -import codechicken.lib.util.TransformUtils; -import codechicken.lib.vec.Cuboid6; -import codechicken.lib.vec.Vector3; -import codechicken.lib.vec.uv.IconTransformation; - -@SideOnly(Side.CLIENT) -public class CCLBlockRenderer implements ICCBlockRenderer, IItemRenderer { - - public static final ModelResourceLocation MODEL_LOCATION = new ModelResourceLocation( - GTUtility.gregtechId("ccl_block"), "normal"); - public static final CCLBlockRenderer INSTANCE = new CCLBlockRenderer(); - public static EnumBlockRenderType BLOCK_RENDER_TYPE; - public static Minecraft mc = Minecraft.getMinecraft(); - - public static void preInit() { - BLOCK_RENDER_TYPE = BlockRenderingRegistry.createRenderType("gregtech_ccl_block"); - BlockRenderingRegistry.registerRenderer(BLOCK_RENDER_TYPE, INSTANCE); - MinecraftForge.EVENT_BUS.register(INSTANCE); - TextureUtils.addIconRegister(Textures::register); - } - - @SubscribeEvent - public void onModelsBake(ModelBakeEvent event) { - GTLog.logger.info("Injected ccl block render model"); - event.getModelRegistry().putObject(MODEL_LOCATION, this); - } - - @Override - public void renderItem(ItemStack rawStack, ItemCameraTransforms.TransformType transformType) { - ItemStack stack = ModCompatibility.getRealItemStack(rawStack); - if (stack.getItem() instanceof ItemBlock && - ((ItemBlock) stack.getItem()).getBlock() instanceof ICCLBlockRenderer) { - ((ICCLBlockRenderer) ((ItemBlock) stack.getItem()).getBlock()).renderItem(stack, transformType); - } - } - - @Override - public boolean renderBlock(IBlockAccess world, BlockPos pos, IBlockState state, BufferBuilder buffer) { - if (state != null && (state.getBlock() instanceof ICCLBlockRenderer)) { - ((ICCLBlockRenderer) state.getBlock()).renderBlock(world, pos, state, buffer); - return true; - } - return false; - } - - @Override - public IModelState getTransforms() { - return TransformUtils.DEFAULT_BLOCK; - } - - @Override - public boolean isBuiltInRenderer() { - return true; - } - - @Override - public void renderBrightness(IBlockState state, float brightness) {} - - @Override - public void handleRenderBlockDamage(IBlockAccess world, BlockPos pos, IBlockState state, TextureAtlasSprite sprite, - BufferBuilder buffer) { - if (state == null || !(state.getBlock() instanceof ICCLBlockRenderer)) { - return; - } - CCRenderState renderState = CCRenderState.instance(); - renderState.reset(); - renderState.bind(buffer); - renderState.setPipeline(new Vector3(new Vec3d(pos)).translation(), new IconTransformation(sprite)); - codechicken.lib.render.BlockRenderer.renderCuboid(renderState, Cuboid6.full, 0); - } - - @Override - public TextureAtlasSprite getParticleTexture() { - return TextureUtils.getMissingSprite(); - } - - @Override - public void registerTextures(TextureMap map) {} - - @Override - public boolean isAmbientOcclusion() { - return true; - } - - @Override - public boolean isGui3d() { - return true; - } -} diff --git a/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java b/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java index fcd0c3ba523..6db1848659a 100644 --- a/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java +++ b/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java @@ -2,11 +2,11 @@ import gregtech.api.cover.CoverUtil; import gregtech.api.items.metaitem.MetaItem; -import gregtech.api.util.ModCompatibility; import gregtech.client.model.pipeline.VertexLighterFlatSpecial; import gregtech.client.model.pipeline.VertexLighterSmoothAoSpecial; import gregtech.client.utils.AdvCCRSConsumer; import gregtech.client.utils.FacadeBlockAccess; +import gregtech.client.utils.ItemRenderCompat; import gregtech.common.covers.facade.FacadeHelper; import gregtech.common.items.behaviors.FacadeItem; @@ -82,7 +82,7 @@ public static void init() { @Override public void renderItem(ItemStack rawStack, ItemCameraTransforms.TransformType transformType) { - ItemStack itemStack = ModCompatibility.getRealItemStack(rawStack); + ItemStack itemStack = ItemRenderCompat.getRepresentedStack(rawStack); if (!(itemStack.getItem() instanceof MetaItem)) { return; } diff --git a/src/main/java/gregtech/client/renderer/handler/GTExplosiveRenderer.java b/src/main/java/gregtech/client/renderer/handler/GTExplosiveRenderer.java new file mode 100644 index 00000000000..4b0efe1ae63 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/handler/GTExplosiveRenderer.java @@ -0,0 +1,81 @@ +package gregtech.client.renderer.handler; + +import gregtech.common.entities.EntityGTExplosive; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BlockRendererDispatcher; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; + +@SideOnly(Side.CLIENT) +public class GTExplosiveRenderer extends Render { + + public GTExplosiveRenderer(RenderManager renderManager) { + super(renderManager); + this.shadowSize = 0.5F; + } + + @Override + public void doRender(@NotNull T entity, double x, double y, double z, float entityYaw, float partialTicks) { + BlockRendererDispatcher brd = Minecraft.getMinecraft().getBlockRendererDispatcher(); + GlStateManager.pushMatrix(); + GlStateManager.translate((float) x, (float) y + 0.5F, (float) z); + float f2; + if ((float) entity.getFuse() - partialTicks + 1.0F < 10.0F) { + f2 = 1.0F - ((float) entity.getFuse() - partialTicks + 1.0F) / 10.0F; + f2 = MathHelper.clamp(f2, 0.0F, 1.0F); + f2 *= f2; + f2 *= f2; + float f1 = 1.0F + f2 * 0.3F; + GlStateManager.scale(f1, f1, f1); + } + + f2 = (1.0F - ((float) entity.getFuse() - partialTicks + 1.0F) / 100.0F) * 0.8F; + this.bindEntityTexture(entity); + GlStateManager.rotate(-90.0F, 0.0F, 1.0F, 0.0F); + GlStateManager.translate(-0.5F, -0.5F, 0.5F); + + IBlockState state = entity.getExplosiveState(); + brd.renderBlockBrightness(state, entity.getBrightness()); + GlStateManager.translate(0.0F, 0.0F, 1.0F); + if (this.renderOutlines) { + GlStateManager.enableColorMaterial(); + GlStateManager.enableOutlineMode(this.getTeamColor(entity)); + brd.renderBlockBrightness(state, 1.0F); + GlStateManager.disableOutlineMode(); + GlStateManager.disableColorMaterial(); + } else if (entity.getFuse() / 5 % 2 == 0) { + GlStateManager.disableTexture2D(); + GlStateManager.disableLighting(); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.DST_ALPHA); + GlStateManager.color(1.0F, 1.0F, 1.0F, f2); + GlStateManager.doPolygonOffset(-3.0F, -3.0F); + GlStateManager.enablePolygonOffset(); + brd.renderBlockBrightness(state, 1.0F); + GlStateManager.doPolygonOffset(0.0F, 0.0F); + GlStateManager.disablePolygonOffset(); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.disableBlend(); + GlStateManager.enableLighting(); + GlStateManager.enableTexture2D(); + } + + GlStateManager.popMatrix(); + super.doRender(entity, x, y, z, entityYaw, partialTicks); + } + + @Override + protected ResourceLocation getEntityTexture(@NotNull T entity) { + return TextureMap.LOCATION_BLOCKS_TEXTURE; + } +} diff --git a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java index 5aa513fea8c..80db7976e18 100644 --- a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java +++ b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityRenderer.java @@ -4,9 +4,10 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; -import gregtech.api.util.ModCompatibility; import gregtech.client.renderer.CubeRendererState; import gregtech.client.renderer.texture.Textures; +import gregtech.client.utils.ItemRenderCompat; +import gregtech.client.utils.RenderUtil; import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.BufferBuilder; @@ -38,7 +39,6 @@ import codechicken.lib.render.block.ICCBlockRenderer; import codechicken.lib.render.item.IItemRenderer; import codechicken.lib.render.pipeline.IVertexOperation; -import codechicken.lib.texture.TextureUtils; import codechicken.lib.util.TransformUtils; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; @@ -61,7 +61,6 @@ public static void preInit() { BLOCK_RENDER_TYPE = BlockRenderingRegistry.createRenderType("meta_tile_entity"); BlockRenderingRegistry.registerRenderer(BLOCK_RENDER_TYPE, INSTANCE); MinecraftForge.EVENT_BUS.register(INSTANCE); - TextureUtils.addIconRegister(Textures::register); } @SubscribeEvent @@ -72,7 +71,7 @@ public void onModelsBake(ModelBakeEvent event) { @Override public void renderItem(ItemStack rawStack, TransformType transformType) { - ItemStack stack = ModCompatibility.getRealItemStack(rawStack); + ItemStack stack = ItemRenderCompat.getRepresentedStack(rawStack); MetaTileEntity metaTileEntity = GTUtility.getMetaTileEntity(stack); if (metaTileEntity == null) { return; @@ -94,7 +93,7 @@ public void renderItem(ItemStack rawStack, TransformType transformType) { @Override public boolean renderBlock(IBlockAccess world, BlockPos pos, IBlockState state, BufferBuilder buffer) { MetaTileEntity metaTileEntity = GTUtility.getMetaTileEntity(world, pos); - if (metaTileEntity == null) { + if (metaTileEntity == null || !metaTileEntity.isValid()) { return false; } CCRenderState renderState = CCRenderState.instance(); @@ -115,7 +114,7 @@ public boolean renderBlock(IBlockAccess world, BlockPos pos, IBlockState state, metaTileEntity.renderCovers(renderState, translation.copy(), renderLayer); - Textures.RENDER_STATE.set(null); + Textures.RENDER_STATE.remove(); return true; } @@ -153,17 +152,12 @@ public void handleRenderBlockDamage(IBlockAccess world, BlockPos pos, IBlockStat public static Pair getParticleTexture(IBlockAccess world, BlockPos pos) { MetaTileEntity metaTileEntity = GTUtility.getMetaTileEntity(world, pos); if (metaTileEntity == null) { - return Pair.of(TextureUtils.getMissingSprite(), 0xFFFFFF); + return Pair.of(RenderUtil.getMissingSprite(), 0xFFFFFF); } else { return metaTileEntity.getParticleTexture(); } } - @Override - public TextureAtlasSprite getParticleTexture() { - return TextureUtils.getMissingSprite(); - } - @Override public void registerTextures(TextureMap map) {} diff --git a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityTESR.java b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityTESR.java index c22b454748a..04f29382669 100644 --- a/src/main/java/gregtech/client/renderer/handler/MetaTileEntityTESR.java +++ b/src/main/java/gregtech/client/renderer/handler/MetaTileEntityTESR.java @@ -46,12 +46,12 @@ public void render(@NotNull MetaTileEntityHolder te, double x, double y, double buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); MetaTileEntity metaTileEntity = te.getMetaTileEntity(); - if (metaTileEntity instanceof IFastRenderMetaTileEntity) { + if (metaTileEntity instanceof IFastRenderMetaTileEntity fastRender) { CCRenderState renderState = CCRenderState.instance(); renderState.reset(); renderState.bind(buffer); renderState.setBrightness(te.getWorld(), te.getPos()); - ((IFastRenderMetaTileEntity) metaTileEntity).renderMetaTileEntityFast(renderState, + fastRender.renderMetaTileEntityFast(renderState, new Matrix4().translate(x, y, z), partialTicks); } if (metaTileEntity != null) { diff --git a/src/main/java/gregtech/client/renderer/handler/TerminalARRenderer.java b/src/main/java/gregtech/client/renderer/handler/TerminalARRenderer.java deleted file mode 100644 index 1bc5e61a13e..00000000000 --- a/src/main/java/gregtech/client/renderer/handler/TerminalARRenderer.java +++ /dev/null @@ -1,99 +0,0 @@ -package gregtech.client.renderer.handler; - -import gregtech.api.terminal.TerminalRegistry; -import gregtech.api.terminal.app.ARApplication; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.os.TerminalOSWidget; -import gregtech.client.utils.RenderUtil; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumHand; -import net.minecraftforge.client.event.RenderGameOverlayEvent; -import net.minecraftforge.client.event.RenderSpecificHandEvent; -import net.minecraftforge.client.event.RenderWorldLastEvent; -import net.minecraftforge.fml.common.gameevent.TickEvent; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -/** - * Created with IntelliJ IDEA. - * - * @Author: KilaBash - * @Date: 2021/09/13 - * @Description: Renderer for AR applications. - * Please don't render your stuff here, it's just a handler - */ -@SideOnly(Side.CLIENT) -public class TerminalARRenderer { - - public static ARApplication APP; - public static int x, y, width, height; - public static EnumHand HELD_HAND; - - public static void renderHandEvent(RenderSpecificHandEvent event) { - if (APP != null && event.getHand() == HELD_HAND) { - event.setCanceled(true); - } - } - - public static void renderGameOverlayEvent(RenderGameOverlayEvent.Pre event) { - if (APP != null && event.getType() == RenderGameOverlayEvent.ElementType.ALL) { - int sWidth = event.getResolution().getScaledWidth(); - int sHeight = event.getResolution().getScaledHeight(); - width = (int) (380 * 0.8 * sHeight / 256); - height = (int) (0.8 * sHeight); - x = (sWidth - width) / 2; - y = (sHeight - height) / 2; - GlStateManager.enableBlend(); - TerminalOSWidget.TERMINAL_FRAME.draw(x, y, width, height); - GlStateManager.disableBlend(); - } - } - - public static void renderWorldLastEvent(RenderWorldLastEvent event) { - if (APP != null) { - RenderUtil.useScissor(x, y, width, height, () -> APP.drawARScreen(event)); - } - } - - public static void onClientTick(TickEvent.ClientTickEvent event) { - if (event.phase == TickEvent.Phase.END) { - EntityPlayer player = Minecraft.getMinecraft().player; - if (player == null) { - if (APP != null) { - APP.onARClosed(); - APP = null; - } - return; - } - HELD_HAND = EnumHand.MAIN_HAND; - NBTTagCompound tag = player.getHeldItem(EnumHand.MAIN_HAND).getSubCompound("terminal"); - if (tag == null) { - tag = player.getHeldItem(EnumHand.OFF_HAND).getSubCompound("terminal"); - HELD_HAND = EnumHand.OFF_HAND; - } - if (tag != null && tag.hasKey("_ar")) { - AbstractApplication app = TerminalRegistry.getApplication(tag.getString("_ar")); - if (app instanceof ARApplication) { - if (APP != app) { - if (APP != null) { - APP.onARClosed(); - } - APP = (ARApplication) app; - APP.setAROpened(player.getHeldItem(HELD_HAND)); - APP.onAROpened(); - } - APP.tickAR(player); - return; - } - } - if (APP != null) { - APP.onARClosed(); - APP = null; - } - } - } -} diff --git a/src/main/java/gregtech/client/renderer/pipe/CableRenderer.java b/src/main/java/gregtech/client/renderer/pipe/CableRenderer.java index 17edbcd501d..5c91a2f44cc 100644 --- a/src/main/java/gregtech/client/renderer/pipe/CableRenderer.java +++ b/src/main/java/gregtech/client/renderer/pipe/CableRenderer.java @@ -6,6 +6,7 @@ import gregtech.api.pipenet.tile.IPipeTile; import gregtech.api.unification.material.Material; import gregtech.api.util.GTUtility; +import gregtech.client.utils.RenderUtil; import gregtech.common.pipelike.cable.Insulation; import net.minecraft.client.renderer.texture.TextureAtlasSprite; @@ -14,7 +15,6 @@ import codechicken.lib.render.pipeline.ColourMultiplier; import codechicken.lib.render.pipeline.IVertexOperation; -import codechicken.lib.texture.TextureUtils; import codechicken.lib.vec.uv.IconTransformation; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.Nullable; @@ -84,11 +84,11 @@ public TextureAtlasSprite getParticleTexture(IPipeType pipeType, @Nullable Ma @Override public Pair getParticleTexture(IPipeTile pipeTile) { if (pipeTile == null) { - return Pair.of(TextureUtils.getMissingSprite(), 0xFFFFFF); + return Pair.of(RenderUtil.getMissingSprite(), 0xFFFFFF); } IPipeType pipeType = pipeTile.getPipeType(); if (!(pipeType instanceof Insulation)) { - return Pair.of(TextureUtils.getMissingSprite(), 0xFFFFFF); + return Pair.of(RenderUtil.getMissingSprite(), 0xFFFFFF); } Material material = pipeTile instanceof TileEntityMaterialPipeBase ? ((TileEntityMaterialPipeBase) pipeTile).getPipeMaterial() : null; diff --git a/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java b/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java index 632bdad8f2b..563f780c26a 100644 --- a/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java +++ b/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java @@ -11,9 +11,10 @@ import gregtech.api.unification.material.Material; import gregtech.api.unification.material.info.MaterialIconType; import gregtech.api.util.GTUtility; -import gregtech.api.util.ModCompatibility; import gregtech.client.renderer.CubeRendererState; import gregtech.client.renderer.texture.Textures; +import gregtech.client.utils.ItemRenderCompat; +import gregtech.client.utils.RenderUtil; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; @@ -48,7 +49,6 @@ import codechicken.lib.render.item.IItemRenderer; import codechicken.lib.render.pipeline.ColourMultiplier; import codechicken.lib.render.pipeline.IVertexOperation; -import codechicken.lib.texture.TextureUtils; import codechicken.lib.util.TransformUtils; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; @@ -126,7 +126,6 @@ public void preInit() { blockRenderType = BlockRenderingRegistry.createRenderType(name); BlockRenderingRegistry.registerRenderer(blockRenderType, this); MinecraftForge.EVENT_BUS.register(this); - TextureUtils.addIconRegister(this::registerIcons); } public ModelResourceLocation getModelLocation() { @@ -150,7 +149,7 @@ public abstract void buildRenderer(PipeRenderContext renderContext, BlockPipe getParticleTexture(IPipeTile pipeTile) { if (pipeTile == null) { - return Pair.of(TextureUtils.getMissingSprite(), 0xFFFFFF); + return Pair.of(RenderUtil.getMissingSprite(), 0xFFFFFF); } IPipeType pipeType = pipeTile.getPipeType(); Material material = pipeTile instanceof TileEntityMaterialPipeBase ? ((TileEntityMaterialPipeBase) pipeTile).getPipeMaterial() : null; if (pipeType == null) { - return Pair.of(TextureUtils.getMissingSprite(), 0xFFFFFF); + return Pair.of(RenderUtil.getMissingSprite(), 0xFFFFFF); } TextureAtlasSprite atlasSprite = getParticleTexture(pipeType, material); int pipeColor = getPipeColor(material, pipeTile.getPaintingColor()); diff --git a/src/main/java/gregtech/client/renderer/texture/Textures.java b/src/main/java/gregtech/client/renderer/texture/Textures.java index 39db1d4f0e2..76f91891093 100644 --- a/src/main/java/gregtech/client/renderer/texture/Textures.java +++ b/src/main/java/gregtech/client/renderer/texture/Textures.java @@ -20,6 +20,7 @@ import gregtech.client.renderer.texture.custom.FireboxActiveRenderer; import gregtech.client.renderer.texture.custom.LargeTurbineRenderer; import gregtech.client.renderer.texture.custom.QuantumStorageRenderer; +import gregtech.client.texture.IconRegistrar; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureMap; @@ -32,7 +33,6 @@ import codechicken.lib.render.BlockRenderer.BlockFace; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; -import codechicken.lib.texture.TextureUtils.IIconRegister; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import codechicken.lib.vec.TransformationList; @@ -52,7 +52,7 @@ public class Textures { public static final Map CUBE_RENDERER_REGISTRY = new HashMap<>(); private static final ThreadLocal blockFaces = ThreadLocal.withInitial(BlockFace::new); - public static final List iconRegisters = new ArrayList<>(); + public static final List iconRegisters = new ArrayList<>(); // Custom Renderers public static final ClipboardRenderer CLIPBOARD_RENDERER = new ClipboardRenderer(); @@ -97,6 +97,32 @@ public class Textures { "casings/pipe/machine_casing_grate"); public static final SimpleOverlayRenderer HIGH_POWER_CASING = new SimpleOverlayRenderer( "casings/computer/high_power_casing"); + public static final SimpleOverlayRenderer QUANTUM_CASING = new SimpleOverlayRenderer( + "casings/quantum/quantum_casing"); + public static final SimpleOverlayRenderer QUANTUM_CONTROLLER_FRONT_INACTIVE = new SimpleOverlayRenderer( + "casings/quantum/controller_front_inactive"); + public static final SimpleOverlayRenderer QUANTUM_CONTROLLER_FRONT_ACTIVE = new SimpleOverlayRenderer( + "casings/quantum/controller_front_active"); + public static final SimpleOverlayRenderer QUANTUM_CONTROLLER_ACTIVE = new SimpleOverlayRenderer( + "casings/quantum/controller_active"); + public static final SimpleOverlayRenderer QUANTUM_CONTROLLER_INACTIVE = new SimpleOverlayRenderer( + "casings/quantum/controller_inactive"); + public static final SimpleOverlayRenderer QUANTUM_PROXY_INACTIVE = new SimpleOverlayRenderer( + "casings/quantum/proxy_inactive"); + public static final SimpleOverlayRenderer QUANTUM_PROXY_ACTIVE = new SimpleOverlayRenderer( + "casings/quantum/proxy_active"); + public static final SimpleOverlayRenderer QUANTUM_EXTENDER = new SimpleOverlayRenderer("casings/quantum/extender"); + public static final SimpleOverlayRenderer QUANTUM_EXTENDER_ACTIVE = new SimpleOverlayRenderer( + "casings/quantum/extender_active"); + + public static final SimpleOverlayRenderer QUANTUM_INDICATOR = new SimpleOverlayRenderer( + "casings/quantum/quantum_indicator_disconnected"); + + public static final SimpleOverlayRenderer QUANTUM_INDICATOR_CONNECTED = new SimpleOverlayRenderer( + "casings/quantum/quantum_indicator_connected"); + + public static final SimpleOverlayRenderer QUANTUM_INDICATOR_POWERED = new SimpleOverlayRenderer( + "casings/quantum/quantum_indicator_powered"); // Simple Sided Cube Renderers public static final SimpleSidedCubeRenderer STEAM_CASING_BRONZE = new SimpleSidedCubeRenderer( @@ -209,6 +235,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"); @@ -497,10 +525,18 @@ public class Textures { public static final SimpleOverlayRenderer ME_OUTPUT_HATCH = new SimpleOverlayRenderer( "overlay/appeng/me_output_hatch"); + public static final SimpleOverlayRenderer ME_OUTPUT_HATCH_ACTIVE = new SimpleOverlayRenderer( + "overlay/appeng/me_output_hatch_active"); public static final SimpleOverlayRenderer ME_INPUT_HATCH = new SimpleOverlayRenderer( "overlay/appeng/me_input_hatch"); + public static final SimpleOverlayRenderer ME_INPUT_HATCH_ACTIVE = new SimpleOverlayRenderer( + "overlay/appeng/me_input_hatch_active"); public static final SimpleOverlayRenderer ME_OUTPUT_BUS = new SimpleOverlayRenderer("overlay/appeng/me_output_bus"); + public static final SimpleOverlayRenderer ME_OUTPUT_BUS_ACTIVE = new SimpleOverlayRenderer( + "overlay/appeng/me_output_bus_active"); public static final SimpleOverlayRenderer ME_INPUT_BUS = new SimpleOverlayRenderer("overlay/appeng/me_input_bus"); + public static final SimpleOverlayRenderer ME_INPUT_BUS_ACTIVE = new SimpleOverlayRenderer( + "overlay/appeng/me_input_bus_active"); public static final ResourceLocation ACE_CAPE_TEXTURE = gregtechId("textures/capes/acecape.png"); public static final ResourceLocation AGENDER_CAPE_TEXTURE = gregtechId("textures/capes/agendercape.png"); @@ -612,8 +648,8 @@ public class Textures { @SideOnly(Side.CLIENT) public static void register(TextureMap textureMap) { GTLog.logger.info("Loading meta tile entity texture sprites..."); - for (IIconRegister iconRegister : iconRegisters) { - iconRegister.registerIcons(textureMap); + for (IconRegistrar registrar : iconRegisters) { + registrar.registerIcons(textureMap); } RESTRICTIVE_OVERLAY = textureMap.registerSprite(gregtechId("blocks/pipe/pipe_restrictive")); diff --git a/src/main/java/gregtech/client/renderer/texture/custom/ClipboardRenderer.java b/src/main/java/gregtech/client/renderer/texture/custom/ClipboardRenderer.java index 107200e2989..319fe32b325 100644 --- a/src/main/java/gregtech/client/renderer/texture/custom/ClipboardRenderer.java +++ b/src/main/java/gregtech/client/renderer/texture/custom/ClipboardRenderer.java @@ -1,6 +1,7 @@ package gregtech.client.renderer.texture.custom; import gregtech.client.renderer.texture.Textures; +import gregtech.client.texture.IconRegistrar; import gregtech.common.metatileentities.MetaTileEntityClipboard; import net.minecraft.client.Minecraft; @@ -17,17 +18,17 @@ import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; -import codechicken.lib.texture.TextureUtils.IIconRegister; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import codechicken.lib.vec.Rotation; import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; import java.util.Arrays; import java.util.HashMap; import java.util.List; -public class ClipboardRenderer implements IIconRegister { +public class ClipboardRenderer implements IconRegistrar { private static final Cuboid6 pageBox = new Cuboid6(3 / 16.0, 0.25 / 16.0, 0.25 / 16.0, 13 / 16.0, 14.25 / 16.0, 0.3 / 16.0); @@ -57,7 +58,7 @@ public ClipboardRenderer() { @Override @SideOnly(Side.CLIENT) - public void registerIcons(TextureMap textureMap) { + public void registerIcons(@NotNull TextureMap textureMap) { this.textures[0] = textureMap.registerSprite(new ResourceLocation("gregtech:blocks/clipboard/wood")); boxTextureMap.put(boardBox, this.textures[0]); this.textures[1] = textureMap.registerSprite(new ResourceLocation("gregtech:blocks/clipboard/clip")); diff --git a/src/main/java/gregtech/client/renderer/texture/custom/CrateRenderer.java b/src/main/java/gregtech/client/renderer/texture/custom/CrateRenderer.java index 0f999dd687d..78558aaa1aa 100644 --- a/src/main/java/gregtech/client/renderer/texture/custom/CrateRenderer.java +++ b/src/main/java/gregtech/client/renderer/texture/custom/CrateRenderer.java @@ -2,6 +2,7 @@ import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; +import gregtech.client.texture.IconRegistrar; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureMap; @@ -13,12 +14,12 @@ import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.ColourMultiplier; import codechicken.lib.render.pipeline.IVertexOperation; -import codechicken.lib.texture.TextureUtils.IIconRegister; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import org.apache.commons.lang3.ArrayUtils; +import org.jetbrains.annotations.NotNull; -public class CrateRenderer implements IIconRegister { +public class CrateRenderer implements IconRegistrar { private final String basePath; @@ -32,7 +33,7 @@ public CrateRenderer(String basePath) { @Override @SideOnly(Side.CLIENT) - public void registerIcons(TextureMap textureMap) { + public void registerIcons(@NotNull TextureMap textureMap) { this.sideSprite = textureMap.registerSprite(GTUtility.gregtechId("blocks/" + basePath)); } diff --git a/src/main/java/gregtech/client/renderer/texture/custom/DrumRenderer.java b/src/main/java/gregtech/client/renderer/texture/custom/DrumRenderer.java index d02d824d280..f2fd93de8ba 100644 --- a/src/main/java/gregtech/client/renderer/texture/custom/DrumRenderer.java +++ b/src/main/java/gregtech/client/renderer/texture/custom/DrumRenderer.java @@ -2,6 +2,7 @@ import gregtech.api.GTValues; import gregtech.client.renderer.texture.Textures; +import gregtech.client.texture.IconRegistrar; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureMap; @@ -13,11 +14,11 @@ import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; -import codechicken.lib.texture.TextureUtils.IIconRegister; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import org.jetbrains.annotations.NotNull; -public class DrumRenderer implements IIconRegister { +public class DrumRenderer implements IconRegistrar { private final String basePath; @@ -31,7 +32,7 @@ public DrumRenderer(String basePath) { @Override @SideOnly(Side.CLIENT) - public void registerIcons(TextureMap textureMap) { + public void registerIcons(@NotNull TextureMap textureMap) { String formattedBase = GTValues.MODID + ":blocks/" + basePath; this.textures = new TextureAtlasSprite[3]; this.textures[0] = textureMap.registerSprite(new ResourceLocation(formattedBase + "/top")); diff --git a/src/main/java/gregtech/client/renderer/texture/custom/LargeTurbineRenderer.java b/src/main/java/gregtech/client/renderer/texture/custom/LargeTurbineRenderer.java index f2f2e063d82..27545d1a47a 100644 --- a/src/main/java/gregtech/client/renderer/texture/custom/LargeTurbineRenderer.java +++ b/src/main/java/gregtech/client/renderer/texture/custom/LargeTurbineRenderer.java @@ -4,6 +4,7 @@ import gregtech.client.renderer.cclop.ColourOperation; import gregtech.client.renderer.cclop.LightMapOperation; import gregtech.client.renderer.texture.Textures; +import gregtech.client.texture.IconRegistrar; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureMap; @@ -15,12 +16,12 @@ import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.ColourMultiplier; import codechicken.lib.render.pipeline.IVertexOperation; -import codechicken.lib.texture.TextureUtils.IIconRegister; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import org.apache.commons.lang3.ArrayUtils; +import org.jetbrains.annotations.NotNull; -public class LargeTurbineRenderer implements IIconRegister { +public class LargeTurbineRenderer implements IconRegistrar { @SideOnly(Side.CLIENT) private TextureAtlasSprite baseRingSprite; @@ -37,7 +38,7 @@ public LargeTurbineRenderer() { @Override @SideOnly(Side.CLIENT) - public void registerIcons(TextureMap textureMap) { + public void registerIcons(@NotNull TextureMap textureMap) { this.baseRingSprite = textureMap .registerSprite(GTUtility.gregtechId("blocks/multiblock/large_turbine/base_ring")); this.baseBackgroundSprite = textureMap diff --git a/src/main/java/gregtech/client/renderer/texture/custom/QuantumStorageRenderer.java b/src/main/java/gregtech/client/renderer/texture/custom/QuantumStorageRenderer.java index 7e6485a155d..893cfa843ee 100644 --- a/src/main/java/gregtech/client/renderer/texture/custom/QuantumStorageRenderer.java +++ b/src/main/java/gregtech/client/renderer/texture/custom/QuantumStorageRenderer.java @@ -1,11 +1,15 @@ package gregtech.client.renderer.texture.custom; import gregtech.api.gui.resources.TextTexture; +import gregtech.api.metatileentity.ITieredMetaTileEntity; import gregtech.api.util.TextFormattingUtil; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleSidedCubeRenderer.RenderSide; +import gregtech.client.texture.IconRegistrar; import gregtech.client.utils.RenderUtil; +import gregtech.common.ConfigHolder; import gregtech.common.metatileentities.storage.MetaTileEntityQuantumChest; +import gregtech.common.metatileentities.storage.MetaTileEntityQuantumStorage; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GlStateManager; @@ -19,8 +23,10 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTank; import net.minecraftforge.fml.relauncher.Side; @@ -28,18 +34,20 @@ import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; -import codechicken.lib.texture.TextureUtils; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import org.jetbrains.annotations.NotNull; import java.util.EnumMap; -public class QuantumStorageRenderer implements TextureUtils.IIconRegister { +public class QuantumStorageRenderer implements IconRegistrar { private static final Cuboid6 glassBox = new Cuboid6(1 / 16.0, 1 / 16.0, 1 / 16.0, 15 / 16.0, 15 / 16.0, 15 / 16.0); private static final EnumMap boxFacingMap = new EnumMap<>(EnumFacing.class); + private static final TextTexture textRenderer = new TextTexture().setWidth(32); + @SideOnly(Side.CLIENT) private TextureAtlasSprite glassTexture; @@ -57,35 +65,57 @@ public QuantumStorageRenderer() { } @Override - public void registerIcons(TextureMap textureMap) { + public void registerIcons(@NotNull TextureMap textureMap) { this.glassTexture = textureMap .registerSprite(new ResourceLocation("gregtech:blocks/overlay/machine/overlay_screen_glass")); } - public void renderMachine(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline, - EnumFacing frontFacing, int tier) { + public & ITieredMetaTileEntity> void renderMachine(CCRenderState renderState, + Matrix4 translation, + IVertexOperation[] pipeline, + T mte) { + EnumFacing frontFacing = mte.getFrontFacing(); + int tier = mte.getTier(); Textures.renderFace(renderState, translation, pipeline, frontFacing, glassBox, glassTexture, BlockRenderLayer.CUTOUT_MIPPED); TextureAtlasSprite hullTexture = Textures.VOLTAGE_CASINGS[tier] .getSpriteOnSide(RenderSide.bySide(EnumFacing.NORTH)); - boxFacingMap.keySet().forEach(facing -> { - for (EnumFacing box : EnumFacing.VALUES) { - if ((facing != frontFacing || box != frontFacing) && - (facing != EnumFacing.DOWN || box.getAxis().isVertical())) { // Don't render the front facing - // box from the front, nor allow - // Z-fighting to occur on the - // bottom - Textures.renderFace(renderState, translation, pipeline, facing, boxFacingMap.get(box), hullTexture, - BlockRenderLayer.CUTOUT_MIPPED); - } - } - }); + + if (mte.isConnected()) { + hullTexture = Textures.QUANTUM_CASING.getParticleSprite(); + } + + for (var facing : boxFacingMap.keySet()) { + // do not render the box at the front face when "facing" is "frontFacing" + if (facing == frontFacing) continue; + + // render when the box face matches facing + Textures.renderFace(renderState, translation, pipeline, facing, boxFacingMap.get(facing), + hullTexture, BlockRenderLayer.CUTOUT_MIPPED); + + // render when the box face is opposite of facing + Textures.renderFace(renderState, translation, pipeline, facing.getOpposite(), boxFacingMap.get(facing), + hullTexture, BlockRenderLayer.CUTOUT_MIPPED); + } + + // render the sides of the box that face the front face + if (frontFacing.getAxis() == EnumFacing.Axis.Y) return; + Textures.renderFace(renderState, translation, pipeline, frontFacing, boxFacingMap.get(EnumFacing.DOWN), + hullTexture, BlockRenderLayer.CUTOUT_MIPPED); + Textures.renderFace(renderState, translation, pipeline, frontFacing, boxFacingMap.get(EnumFacing.UP), + hullTexture, BlockRenderLayer.CUTOUT_MIPPED); + + EnumFacing facing = frontFacing.rotateYCCW(); + Textures.renderFace(renderState, translation, pipeline, frontFacing, boxFacingMap.get(facing), + hullTexture, BlockRenderLayer.CUTOUT_MIPPED); + Textures.renderFace(renderState, translation, pipeline, frontFacing, boxFacingMap.get(facing.getOpposite()), + hullTexture, BlockRenderLayer.CUTOUT_MIPPED); } public static void renderChestStack(double x, double y, double z, MetaTileEntityQuantumChest machine, ItemStack stack, long count, float partialTicks) { - if (stack.isEmpty() || count == 0) + if (!ConfigHolder.client.enableFancyChestRender || stack.isEmpty() || count == 0) return; float lastBrightnessX = OpenGlHelper.lastBrightnessX; @@ -93,15 +123,19 @@ public static void renderChestStack(double x, double y, double z, MetaTileEntity World world = machine.getWorld(); setLightingCorrectly(world, machine.getPos()); EnumFacing frontFacing = machine.getFrontFacing(); - RenderItem itemRenderer = Minecraft.getMinecraft().getRenderItem(); - float tick = world.getWorldTime() + partialTicks; - GlStateManager.pushMatrix(); - GlStateManager.translate(x, y, z); - GlStateManager.translate(0.5D, 0.5D, 0.5D); - GlStateManager.rotate(tick * (float) Math.PI * 2 / 40, 0, 1, 0); - GlStateManager.scale(0.6f, 0.6f, 0.6f); - itemRenderer.renderItem(stack, ItemCameraTransforms.TransformType.FIXED); - GlStateManager.popMatrix(); + + if (canRender(x, y, z, 8 * + MathHelper.clamp((double) Minecraft.getMinecraft().gameSettings.renderDistanceChunks / 8, 1.0, 2.5))) { + RenderItem itemRenderer = Minecraft.getMinecraft().getRenderItem(); + float tick = world.getWorldTime() + partialTicks; + GlStateManager.pushMatrix(); + GlStateManager.translate(x, y, z); + GlStateManager.translate(0.5D, 0.5D, 0.5D); + GlStateManager.rotate(tick * (float) Math.PI * 2 / 40, 0, 1, 0); + GlStateManager.scale(0.6f, 0.6f, 0.6f); + itemRenderer.renderItem(stack, ItemCameraTransforms.TransformType.FIXED); + GlStateManager.popMatrix(); + } OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); renderAmountText(x, y, z, count, frontFacing); @@ -110,38 +144,63 @@ public static void renderChestStack(double x, double y, double z, MetaTileEntity public static void renderTankFluid(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline, FluidTank tank, IBlockAccess world, BlockPos pos, EnumFacing frontFacing) { - float lastBrightnessX = OpenGlHelper.lastBrightnessX; - float lastBrightnessY = OpenGlHelper.lastBrightnessY; + FluidStack stack = tank.getFluid(); + if (stack == null || stack.amount == 0 || !ConfigHolder.client.enableFancyChestRender) { + return; + } + + Fluid fluid = stack.getFluid(); + if (fluid == null) { + return; + } + if (world != null) { renderState.setBrightness(world, pos); } - FluidStack stack = tank.getFluid(); - if (stack == null || stack.amount == 0) - return; Cuboid6 partialFluidBox = new Cuboid6(1.0625 / 16.0, 2.0625 / 16.0, 1.0625 / 16.0, 14.9375 / 16.0, 14.9375 / 16.0, 14.9375 / 16.0); double fillFraction = (double) stack.amount / tank.getCapacity(); - if (tank.getFluid().getFluid().isGaseous()) { + boolean gas = fluid.isGaseous(stack); + if (gas) { partialFluidBox.min.y = Math.max(13.9375 - (11.875 * fillFraction), 2.0) / 16.0; } else { partialFluidBox.max.y = Math.min((11.875 * fillFraction) + 2.0625, 14.0) / 16.0; } renderState.setFluidColour(stack); - ResourceLocation fluidStill = stack.getFluid().getStill(stack); + ResourceLocation fluidStill = fluid.getStill(stack); TextureAtlasSprite fluidStillSprite = Minecraft.getMinecraft().getTextureMapBlocks() .getAtlasSprite(fluidStill.toString()); - for (EnumFacing facing : EnumFacing.VALUES) { - Textures.renderFace(renderState, translation, pipeline, facing, partialFluidBox, fluidStillSprite, - BlockRenderLayer.CUTOUT_MIPPED); - } + + Textures.renderFace(renderState, translation, pipeline, frontFacing, partialFluidBox, fluidStillSprite, + BlockRenderLayer.CUTOUT_MIPPED); + + Textures.renderFace(renderState, translation, pipeline, gas ? EnumFacing.DOWN : EnumFacing.UP, partialFluidBox, + fluidStillSprite, + BlockRenderLayer.CUTOUT_MIPPED); + GlStateManager.resetColor(); renderState.reset(); } + /** + * Takes in the difference in x, y, and z from the camera to the rendering TE and + * calculates the squared distance and checks if it's within the range squared + * + * @param x the difference in x from entity to this rendering TE + * @param y the difference in y from entity to this rendering TE + * @param z the difference in z from entity to this rendering TE + * @param range distance needed to be rendered + * @return true if the camera is within the given range, otherwise false + */ + public static boolean canRender(double x, double y, double z, double range) { + double distance = (x * x) + (y * y) + (z * z); + return distance < range * range; + } + public static void renderTankAmount(double x, double y, double z, EnumFacing frontFacing, long amount) { float lastBrightnessX = OpenGlHelper.lastBrightnessX; float lastBrightnessY = OpenGlHelper.lastBrightnessY; @@ -153,6 +212,9 @@ public static void renderTankAmount(double x, double y, double z, EnumFacing fro } public static void renderAmountText(double x, double y, double z, long amount, EnumFacing frontFacing) { + if (!ConfigHolder.client.enableFancyChestRender || !canRender(x, y, z, 64)) + return; + GlStateManager.pushMatrix(); GlStateManager.translate(x, y, z); GlStateManager.translate(frontFacing.getXOffset() * -1 / 16f, frontFacing.getYOffset() * -1 / 16f, @@ -167,7 +229,8 @@ public static void renderAmountText(double x, double y, double z, long amount, E GlStateManager.scale(1f / 64, 1f / 64, 0); GlStateManager.translate(-32, -32, 0); GlStateManager.disableLighting(); - new TextTexture(amountText, 0xFFFFFF).draw(0, 24, 64, 28); + textRenderer.setText(amountText); + textRenderer.draw(0, 24, 64, 28); GlStateManager.enableLighting(); GlStateManager.popMatrix(); } diff --git a/src/main/java/gregtech/client/shader/Shaders.java b/src/main/java/gregtech/client/shader/Shaders.java index e1eb6ef0474..409818af327 100644 --- a/src/main/java/gregtech/client/shader/Shaders.java +++ b/src/main/java/gregtech/client/shader/Shaders.java @@ -2,6 +2,7 @@ import gregtech.api.GTValues; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import net.minecraft.client.Minecraft; @@ -15,11 +16,10 @@ import codechicken.lib.render.shader.ShaderObject; import codechicken.lib.render.shader.ShaderProgram; +import org.jetbrains.annotations.ApiStatus; -import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; -import java.util.function.BooleanSupplier; import java.util.function.Consumer; import static codechicken.lib.render.shader.ShaderHelper.getStream; @@ -57,35 +57,12 @@ public class Shaders { public static ShaderObject S_BLUR; public static ShaderObject COMPOSITE; - // OptiFine - private static BooleanSupplier isShaderPackLoaded; - static { mc = Minecraft.getMinecraft(); FULL_IMAGE_PROGRAMS = new HashMap<>(); if (allowedShader()) { initShaders(); } - try { // hook optFine. thanks to Scannable. - final Class clazz = Class.forName("net.optifine.shaders.Shaders"); - final Field shaderPackLoaded = clazz.getDeclaredField("shaderPackLoaded"); - shaderPackLoaded.setAccessible(true); - isShaderPackLoaded = () -> { - try { - return shaderPackLoaded.getBoolean(null); - } catch (final IllegalAccessException e) { - GTLog.logger.warn( - "Failed reading field indicating whether shaders are enabled. Shader mod integration disabled."); - isShaderPackLoaded = null; - return false; - } - }; - GTLog.logger.info("Find optiFine mod loaded."); - } catch (ClassNotFoundException e) { - GTLog.logger.info("No optiFine mod found."); - } catch (NoSuchFieldException | NoClassDefFoundError e) { - GTLog.logger.warn("Failed integrating with shader mod. Ignoring."); - } } public static void initShaders() { @@ -128,8 +105,11 @@ public static boolean allowedShader() { return OpenGlHelper.shadersSupported && ConfigHolder.client.shader.useShader; } + /** @deprecated Use {@link Mods#Optifine} to check this instead. */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public static boolean isOptiFineShaderPackLoaded() { - return isShaderPackLoaded != null && isShaderPackLoaded.getAsBoolean(); + return Mods.Optifine.isModLoaded(); } public static Framebuffer renderFullImageInFBO(Framebuffer fbo, ShaderObject frag, @@ -168,6 +148,7 @@ public static Framebuffer renderFullImageInFBO(Framebuffer fbo, ShaderObject fra // GlStateManager.viewport(0, 0, mc.displayWidth, mc.displayHeight); // OpenGlHelper.glBindFramebuffer(OpenGlHelper.GL_FRAMEBUFFER, lastID); + fbo.bindFramebuffer(false); return fbo; } } diff --git a/src/main/java/gregtech/client/texture/IconRegistrar.java b/src/main/java/gregtech/client/texture/IconRegistrar.java new file mode 100644 index 00000000000..6e6ec35ea65 --- /dev/null +++ b/src/main/java/gregtech/client/texture/IconRegistrar.java @@ -0,0 +1,22 @@ +package gregtech.client.texture; + +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; + +/** + * Functional Interface for registering ResourceLocations to a TextureMap. + *

            + * Called during {@link net.minecraftforge.client.event.TextureStitchEvent.Pre} + */ +@FunctionalInterface +public interface IconRegistrar { + + /** + * @param map the map to register textures to + */ + @SideOnly(Side.CLIENT) + void registerIcons(@NotNull TextureMap map); +} diff --git a/src/main/java/gregtech/client/utils/BloomEffectUtil.java b/src/main/java/gregtech/client/utils/BloomEffectUtil.java index d1ac6f07cc0..36671852320 100644 --- a/src/main/java/gregtech/client/utils/BloomEffectUtil.java +++ b/src/main/java/gregtech/client/utils/BloomEffectUtil.java @@ -1,6 +1,7 @@ package gregtech.client.utils; import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.util.Mods; import gregtech.client.particle.GTParticle; import gregtech.client.renderer.IRenderSetup; import gregtech.client.shader.Shaders; @@ -17,29 +18,27 @@ import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.shader.Framebuffer; import net.minecraft.entity.Entity; -import net.minecraft.launchwrapper.Launch; import net.minecraft.util.BlockRenderLayer; -import net.minecraftforge.common.util.EnumHelper; -import net.minecraftforge.fml.common.Loader; +import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import com.github.bsideup.jabel.Desugar; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import org.apache.commons.lang3.reflect.FieldUtils; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.lwjgl.opengl.GL11; -import java.lang.reflect.Field; import java.util.ArrayList; 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 +46,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()} */ @@ -101,7 +102,7 @@ public static BlockRenderLayer getEffectiveBloomLayer() { */ @Contract("null -> _; !null -> !null") public static BlockRenderLayer getEffectiveBloomLayer(BlockRenderLayer fallback) { - return Shaders.isOptiFineShaderPackLoaded() ? fallback : bloom; + return Mods.Optifine.isModLoaded() ? fallback : bloom; } /** @@ -133,7 +134,7 @@ public static BlockRenderLayer getEffectiveBloomLayer(boolean isBloomActive) { */ @Contract("_, null -> _; _, !null -> !null") public static BlockRenderLayer getEffectiveBloomLayer(boolean isBloomActive, BlockRenderLayer fallback) { - return Shaders.isOptiFineShaderPackLoaded() || !isBloomActive ? fallback : bloom; + return Mods.Optifine.isModLoaded() || !isBloomActive ? fallback : bloom; } /** @@ -147,12 +148,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 +163,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 +194,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 +205,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 +220,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 +231,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 (Shaders.isOptiFineShaderPackLoaded()) 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 */ @@ -249,24 +332,9 @@ public boolean test(BloomRenderTicket bloomRenderTicket) { }, validityChecker); } - @SuppressWarnings({ "rawtypes", "unchecked" }) public static void init() { - bloom = EnumHelper.addEnum(BlockRenderLayer.class, "BLOOM", new Class[] { String.class }, "Bloom"); + bloom = BlockRenderLayer.valueOf("BLOOM"); BLOOM = bloom; - if (Loader.isModLoaded("nothirium")) { - try { - // Nothirium hard copies the BlockRenderLayer enum into a ChunkRenderPass enum. Add our BLOOM layer to - // that too. - Class crp = Class.forName("meldexun.nothirium.api.renderer.chunk.ChunkRenderPass", false, - Launch.classLoader); - EnumHelper.addEnum(crp, "BLOOM", new Class[] {}); - Field all = FieldUtils.getField(crp, "ALL", false); - FieldUtils.removeFinalModifier(all); - FieldUtils.writeStaticField(all, crp.getEnumConstants()); - } catch (ClassNotFoundException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } } // Calls injected via ASM @@ -281,14 +349,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 (Shaders.isOptiFineShaderPackLoaded()) { + 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 +389,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 +440,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 +572,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..68bd1469c38 --- /dev/null +++ b/src/main/java/gregtech/client/utils/BloomEffectVintagiumUtil.java @@ -0,0 +1,22 @@ +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 { + + /** + * @return {@link BlockRenderPass} instance for the bloom render layer. + */ + @NotNull + @SuppressWarnings("unused") + public static BlockRenderPass getBloomPass() { + return Objects.requireNonNull(BlockRenderPass.valueOf("BLOOM"), "Bloom effect is not initialized yet"); + } +} diff --git a/src/main/java/gregtech/client/utils/DepthTextureUtil.java b/src/main/java/gregtech/client/utils/DepthTextureUtil.java index 3aa59bf75b4..d3bd1c4f06d 100644 --- a/src/main/java/gregtech/client/utils/DepthTextureUtil.java +++ b/src/main/java/gregtech/client/utils/DepthTextureUtil.java @@ -1,6 +1,6 @@ package gregtech.client.utils; -import gregtech.client.shader.Shaders; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import net.minecraft.client.Minecraft; @@ -40,7 +40,7 @@ public class DepthTextureUtil { private static int lastWidth, lastHeight; private static boolean shouldRenderDepthTexture() { - return lastBind && !Shaders.isOptiFineShaderPackLoaded() && ConfigHolder.client.hookDepthTexture && + return lastBind && !Mods.Optifine.isModLoaded() && ConfigHolder.client.hookDepthTexture && OpenGlHelper.isFramebufferEnabled(); } diff --git a/src/main/java/gregtech/client/utils/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/client/utils/ItemRenderCompat.java b/src/main/java/gregtech/client/utils/ItemRenderCompat.java new file mode 100644 index 00000000000..4ea385c8910 --- /dev/null +++ b/src/main/java/gregtech/client/utils/ItemRenderCompat.java @@ -0,0 +1,169 @@ +package gregtech.client.utils; + +import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; +import gregtech.api.util.world.DummyWorld; + +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import appeng.items.misc.ItemEncodedPattern; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Method; +import java.util.List; + +public final class ItemRenderCompat { + + private static @Nullable ItemRenderCompat.RepresentativeStackExtractor rsHandler; + private static @Nullable ItemRenderCompat.RepresentativeStackExtractor ae2Handler; + + private ItemRenderCompat() {} + + @ApiStatus.Internal + public static void init() { + ae2Handler = AE2StackExtractor.create(); + rsHandler = RSStackExtractor.create(); + } + + /** + * Attempts to retrieve the actual ItemStack another stack represents. + *

            + * Primarily used to retrieve the output stack from AE2 or RS Patterns. + * + * @param stack the stack to retrieve from + * @return the actual represented ItemStack + */ + public static @NotNull ItemStack getRepresentedStack(@NotNull ItemStack stack) { + if (ae2Handler != null && ae2Handler.canHandleStack(stack)) { + return ae2Handler.getActualStack(stack); + } + if (rsHandler != null && rsHandler.canHandleStack(stack)) { + return rsHandler.getActualStack(stack); + } + return stack; + } + + /** + * An extractor to retrieve a represented stack from an ItemStack + */ + public interface RepresentativeStackExtractor { + + /** + * @param stack the stack to test + * @return if the extractor can handle the stack + */ + boolean canHandleStack(@NotNull ItemStack stack); + + /** + * @param stack the stack to retrieve from + * @return the represented stack + */ + @NotNull + ItemStack getActualStack(@NotNull ItemStack stack); + } + + /** + * Extracts the output stack from AE2 Patterns + */ + private static final class AE2StackExtractor implements RepresentativeStackExtractor { + + public static @Nullable ItemRenderCompat.AE2StackExtractor create() { + if (!Mods.AppliedEnergistics2.isModLoaded()) return null; + GTLog.logger.info("AppliedEnergistics2 found; enabling render integration."); + return new AE2StackExtractor(); + } + + @Override + public boolean canHandleStack(@NotNull ItemStack stack) { + return stack.getItem() instanceof ItemEncodedPattern; + } + + @Override + public @NotNull ItemStack getActualStack(@NotNull ItemStack stack) { + if (stack.isEmpty()) return ItemStack.EMPTY; + if (stack.getItem() instanceof ItemEncodedPattern encodedPattern) { + return encodedPattern.getOutput(stack); + } + return stack; + } + } + + /** + * Extracts the output stack from RS Patterns + */ + @SuppressWarnings("ClassCanBeRecord") + private static final class RSStackExtractor implements RepresentativeStackExtractor { + + private final MethodHandle getPatternFromCacheHandle; + private final MethodHandle getOutputsHandle; + private final Class itemPatternClass; + + private RSStackExtractor(MethodHandle getPatternFromCacheHandle, MethodHandle getOutputsHandle, + Class itemPatternClass) { + this.getPatternFromCacheHandle = getPatternFromCacheHandle; + this.getOutputsHandle = getOutputsHandle; + this.itemPatternClass = itemPatternClass; + } + + public static @Nullable ItemRenderCompat.RSStackExtractor create() { + if (!Mods.RefinedStorage.isModLoaded()) return null; + + Class clazz; + try { + clazz = Class.forName("com.raoulvdberge.refinedstorage.item.ItemPattern"); + GTLog.logger.info("RefinedStorage found; enabling render integration."); + } catch (ClassNotFoundException ignored) { + GTLog.logger.error("RefinedStorage classes not found; skipping render integration."); + return null; + } + + try { + Method method = clazz.getMethod("getPatternFromCache", World.class, ItemStack.class); + + MethodHandles.Lookup lookup = MethodHandles.publicLookup(); + + MethodHandle getPatternFromCacheHandle = lookup.unreflect(method); + + method = method.getReturnType().getMethod("getOutputs"); + MethodHandle getOutputsHandle = lookup.unreflect(method); + + return new RSStackExtractor(getPatternFromCacheHandle, getOutputsHandle, clazz); + } catch (NoSuchMethodException | IllegalAccessException e) { + GTLog.logger.error("Failed to enable RefinedStorage integration", e); + return null; + } + } + + @Override + public boolean canHandleStack(@NotNull ItemStack stack) { + return itemPatternClass.isAssignableFrom(stack.getItem().getClass()); + } + + @SuppressWarnings("unchecked") + @Override + public @NotNull ItemStack getActualStack(@NotNull ItemStack stack) { + if (stack.isEmpty()) return ItemStack.EMPTY; + + List outputs; + try { + // ItemPattern.getPatternFromCache: (World, ItemStack) -> CraftingPattern + Object craftingPattern = getPatternFromCacheHandle.invoke(DummyWorld.INSTANCE, stack); + // CraftingPattern#getOutputs: () -> List + outputs = (List) getOutputsHandle.invoke(craftingPattern); + } catch (Throwable e) { + GTLog.logger.error("Failed to obtain item from ItemPattern", e); + return stack; + } + + if (outputs.isEmpty()) { + return stack; + } + return outputs.get(0); + } + } +} diff --git a/src/main/java/gregtech/client/utils/RenderUtil.java b/src/main/java/gregtech/client/utils/RenderUtil.java index ed91be4e57e..f38d5cee0d4 100644 --- a/src/main/java/gregtech/client/utils/RenderUtil.java +++ b/src/main/java/gregtech/client/utils/RenderUtil.java @@ -25,7 +25,6 @@ import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import codechicken.lib.texture.TextureUtils; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -153,6 +152,9 @@ public static void useStencil(Runnable mask, Runnable renderInMask, boolean shou renderInMask.run(); GL11.glDisable(GL11.GL_STENCIL_TEST); + GL11.glClearStencil(0); + GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT); + GL11.glStencilFunc(GL11.GL_ALWAYS, 0, 0xFF); } public static void useLightMap(float x, float y, Runnable codeBlock) { @@ -389,7 +391,7 @@ public static void renderFluidOverLay(float x, float y, float width, float heigh float r = (color >> 16 & 255) / 255.0f; float g = (color >> 8 & 255) / 255.0f; float b = (color & 255) / 255.0f; - TextureAtlasSprite sprite = TextureUtils.getTexture(fluidStack.getFluid().getStill(fluidStack)); + TextureAtlasSprite sprite = getTexture(fluidStack.getFluid().getStill(fluidStack)); GlStateManager.enableBlend(); GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); @@ -527,8 +529,7 @@ public static void drawFluidForGui(FluidStack contents, int tankCapacity, int st heightT--; Fluid fluid = contents.getFluid(); ResourceLocation fluidStill = fluid.getStill(contents); - TextureAtlasSprite fluidStillSprite = Minecraft.getMinecraft().getTextureMapBlocks() - .getAtlasSprite(fluidStill.toString()); + TextureAtlasSprite fluidStillSprite = getTexture(fluidStill); int fluidColor = fluid.getColor(contents); int scaledAmount; if (contents.amount == tankCapacity) { @@ -664,4 +665,31 @@ public void put(int element, float @NotNull... data) { builder.setApplyDiffuseLighting(false); return builder.build(); } + + /** + * @return the block texture map + */ + public static @NotNull TextureMap getTextureMap() { + return Minecraft.getMinecraft().getTextureMapBlocks(); + } + + /** + * @param location the location of the texture in the Block Texture Map + * @return the texture at the location + * @throws IllegalArgumentException if the texture does not exist in the atlas + */ + public static @NotNull TextureAtlasSprite getTexture(@NotNull ResourceLocation location) { + TextureAtlasSprite sprite = getTextureMap().getTextureExtry(location.toString()); + if (sprite == null) { + throw new IllegalArgumentException("Texture does not exist at " + location); + } + return sprite; + } + + /** + * @return the missing texture atlas sprite + */ + public static @NotNull TextureAtlasSprite getMissingSprite() { + return getTextureMap().getMissingSprite(); + } } diff --git a/src/main/java/gregtech/common/CommonProxy.java b/src/main/java/gregtech/common/CommonProxy.java index f8a956e201b..59055bb74e1 100644 --- a/src/main/java/gregtech/common/CommonProxy.java +++ b/src/main/java/gregtech/common/CommonProxy.java @@ -6,10 +6,11 @@ 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.recipeproperties.FusionEUToStartProperty; -import gregtech.api.terminal.TerminalRegistry; +import gregtech.api.recipes.ingredients.GTRecipeOreInput; +import gregtech.api.recipes.properties.impl.FusionEUToStartProperty; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.info.MaterialFlags; import gregtech.api.unification.material.properties.DustProperty; @@ -20,7 +21,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 +43,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 +87,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(); @@ -153,6 +168,8 @@ public static void registerBlocks(RegistryEvent.Register event) { registry.register(RUBBER_WOOD_DOOR); registry.register(TREATED_WOOD_DOOR); registry.register(BRITTLE_CHARCOAL); + registry.register(POWDERBARREL); + registry.register(ITNT); registry.register(METAL_SHEET); registry.register(LARGE_METAL_SHEET); registry.register(STUDS); @@ -217,7 +234,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())) @@ -273,6 +292,8 @@ public static void registerItems(RegistryEvent.Register event) { registry.register(createItemBlock(RUBBER_LOG, ItemBlock::new)); registry.register(createItemBlock(RUBBER_LEAVES, ItemBlock::new)); registry.register(createItemBlock(RUBBER_SAPLING, ItemBlock::new)); + registry.register(createItemBlock(POWDERBARREL, ItemBlock::new)); + registry.register(createItemBlock(ITNT, ItemBlock::new)); for (BlockCompressed block : COMPRESSED_BLOCKS) { registry.register(createItemBlock(block, b -> new MaterialItemBlock(b, OrePrefix.block))); @@ -383,11 +404,11 @@ private static ItemBlock createItemBlock(T block, Function entity instanceof EntityItem && !checkAEEntity(entity)); + } + } + } + + private static boolean checkAEEntity(Entity entity) { + return Mods.AppliedEnergistics2.isModLoaded() && entity instanceof EntitySingularity; + } } diff --git a/src/main/java/gregtech/common/MetaEntities.java b/src/main/java/gregtech/common/MetaEntities.java index 00efb35f87d..965ce3bfb18 100644 --- a/src/main/java/gregtech/common/MetaEntities.java +++ b/src/main/java/gregtech/common/MetaEntities.java @@ -4,10 +4,13 @@ import gregtech.api.util.GTUtility; import gregtech.client.renderer.handler.DynamiteRenderer; import gregtech.client.renderer.handler.GTBoatRenderer; +import gregtech.client.renderer.handler.GTExplosiveRenderer; import gregtech.client.renderer.handler.PortalRenderer; import gregtech.common.entities.DynamiteEntity; import gregtech.common.entities.GTBoatEntity; +import gregtech.common.entities.ITNTEntity; import gregtech.common.entities.PortalEntity; +import gregtech.common.entities.PowderbarrelEntity; import net.minecraft.client.Minecraft; import net.minecraftforge.fml.client.registry.RenderingRegistry; @@ -24,6 +27,10 @@ public static void init() { GregTechAPI.instance, 64, 5, true); EntityRegistry.registerModEntity(GTUtility.gregtechId("gtboat"), GTBoatEntity.class, "GTBoat", 3, GregTechAPI.instance, 64, 2, true); + EntityRegistry.registerModEntity(GTUtility.gregtechId("powderbarrel"), PowderbarrelEntity.class, "Powderbarrel", + 4, GregTechAPI.instance, 64, 3, true); + EntityRegistry.registerModEntity(GTUtility.gregtechId("itnt"), ITNTEntity.class, "ITNT", 5, + GregTechAPI.instance, 64, 3, true); } @SideOnly(Side.CLIENT) @@ -32,5 +39,7 @@ public static void initRenderers() { manager -> new DynamiteRenderer(manager, Minecraft.getMinecraft().getRenderItem())); RenderingRegistry.registerEntityRenderingHandler(PortalEntity.class, PortalRenderer::new); RenderingRegistry.registerEntityRenderingHandler(GTBoatEntity.class, GTBoatRenderer::new); + RenderingRegistry.registerEntityRenderingHandler(PowderbarrelEntity.class, GTExplosiveRenderer::new); + RenderingRegistry.registerEntityRenderingHandler(ITNTEntity.class, GTExplosiveRenderer::new); } } diff --git a/src/main/java/gregtech/common/ToolEventHandlers.java b/src/main/java/gregtech/common/ToolEventHandlers.java index 65d407e9635..62195e49791 100644 --- a/src/main/java/gregtech/common/ToolEventHandlers.java +++ b/src/main/java/gregtech/common/ToolEventHandlers.java @@ -477,6 +477,8 @@ private static void drawGridOverlays(@NotNull AxisAlignedBB box) { @SideOnly(Side.CLIENT) private static void drawGridOverlays(EnumFacing facing, AxisAlignedBB box, Predicate test) { + if (facing == null) return; + Tessellator tessellator = Tessellator.getInstance(); BufferBuilder buffer = tessellator.getBuffer(); buffer.begin(3, DefaultVertexFormats.POSITION_COLOR); diff --git a/src/main/java/gregtech/common/blocks/BlockAsphalt.java b/src/main/java/gregtech/common/blocks/BlockAsphalt.java index 281e47c76b8..728245fcd90 100644 --- a/src/main/java/gregtech/common/blocks/BlockAsphalt.java +++ b/src/main/java/gregtech/common/blocks/BlockAsphalt.java @@ -1,8 +1,8 @@ package gregtech.common.blocks; -import gregtech.api.GregTechAPI; import gregtech.api.block.IStateHarvestLevel; import gregtech.api.block.VariantBlock; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; @@ -23,7 +23,7 @@ public BlockAsphalt() { setResistance(10.0f); setSoundType(SoundType.STONE); setDefaultState(getState(BlockType.ASPHALT)); - setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); } @Override diff --git a/src/main/java/gregtech/common/blocks/BlockCleanroomCasing.java b/src/main/java/gregtech/common/blocks/BlockCleanroomCasing.java index f21a5f29089..3a6afb0b629 100644 --- a/src/main/java/gregtech/common/blocks/BlockCleanroomCasing.java +++ b/src/main/java/gregtech/common/blocks/BlockCleanroomCasing.java @@ -1,8 +1,10 @@ package gregtech.common.blocks; +import gregtech.api.block.ICleanroomFilter; import gregtech.api.block.IStateHarvestLevel; import gregtech.api.block.VariantBlock; import gregtech.api.items.toolitem.ToolClasses; +import gregtech.api.metatileentity.multiblock.CleanroomType; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; @@ -38,16 +40,18 @@ public boolean canCreatureSpawn(@NotNull IBlockState state, @NotNull IBlockAcces return false; } - public enum CasingType implements IStringSerializable { + public enum CasingType implements IStringSerializable, ICleanroomFilter { - PLASCRETE("plascrete"), - FILTER_CASING("filter_casing"), - FILTER_CASING_STERILE("filter_casing_sterile"); + PLASCRETE("plascrete", null), + FILTER_CASING("filter_casing", CleanroomType.CLEANROOM), + FILTER_CASING_STERILE("filter_casing_sterile", CleanroomType.STERILE_CLEANROOM); private final String name; + private final CleanroomType cleanroomType; - CasingType(String name) { + CasingType(String name, CleanroomType cleanroomType) { this.name = name; + this.cleanroomType = cleanroomType; } @NotNull @@ -61,6 +65,17 @@ public String getName() { public String toString() { return getName(); } + + @Override + @Nullable + public CleanroomType getCleanroomType() { + return cleanroomType; + } + + @Override + public int getTier() { + return this.ordinal() - 1; + } } @Override diff --git a/src/main/java/gregtech/common/blocks/BlockCompressed.java b/src/main/java/gregtech/common/blocks/BlockCompressed.java index 18b71b293d6..9f2fb91fb16 100644 --- a/src/main/java/gregtech/common/blocks/BlockCompressed.java +++ b/src/main/java/gregtech/common/blocks/BlockCompressed.java @@ -1,6 +1,5 @@ package gregtech.common.blocks; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.info.MaterialIconType; @@ -9,6 +8,7 @@ import gregtech.client.model.modelfactories.MaterialBlockModelLoader; import gregtech.common.ConfigHolder; import gregtech.common.blocks.properties.PropertyMaterial; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.SoundType; import net.minecraft.block.state.IBlockState; @@ -46,7 +46,7 @@ private BlockCompressed() { setTranslationKey("compressed"); setHardness(5.0f); setResistance(10.0f); - setCreativeTab(GregTechAPI.TAB_GREGTECH_MATERIALS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_MATERIALS); } @Override diff --git a/src/main/java/gregtech/common/blocks/BlockFrame.java b/src/main/java/gregtech/common/blocks/BlockFrame.java index f4bb81f675d..88bbf3c2374 100644 --- a/src/main/java/gregtech/common/blocks/BlockFrame.java +++ b/src/main/java/gregtech/common/blocks/BlockFrame.java @@ -1,6 +1,5 @@ package gregtech.common.blocks; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; import gregtech.api.items.toolitem.ToolHelper; import gregtech.api.pipenet.block.BlockPipe; @@ -15,6 +14,7 @@ import gregtech.client.model.modelfactories.MaterialBlockModelLoader; import gregtech.common.ConfigHolder; import gregtech.common.blocks.properties.PropertyMaterial; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.Block; import net.minecraft.block.SoundType; @@ -68,7 +68,7 @@ private BlockFrame() { setTranslationKey("frame"); setHardness(3.0f); setResistance(6.0f); - setCreativeTab(GregTechAPI.TAB_GREGTECH_MATERIALS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_MATERIALS); } @Override diff --git a/src/main/java/gregtech/common/blocks/BlockGregStairs.java b/src/main/java/gregtech/common/blocks/BlockGregStairs.java index f04cddbe6df..e8b2a12f2c7 100644 --- a/src/main/java/gregtech/common/blocks/BlockGregStairs.java +++ b/src/main/java/gregtech/common/blocks/BlockGregStairs.java @@ -1,7 +1,7 @@ package gregtech.common.blocks; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.BlockStairs; import net.minecraft.block.state.IBlockState; @@ -15,7 +15,7 @@ public class BlockGregStairs extends BlockStairs { public BlockGregStairs(IBlockState state) { super(state); - setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); this.useNeighborBrightness = true; this.setHarvestLevel(ToolClasses.AXE, 0); } diff --git a/src/main/java/gregtech/common/blocks/BlockLamp.java b/src/main/java/gregtech/common/blocks/BlockLamp.java index 3cc7c273ddc..28d26cfd41a 100644 --- a/src/main/java/gregtech/common/blocks/BlockLamp.java +++ b/src/main/java/gregtech/common/blocks/BlockLamp.java @@ -1,13 +1,13 @@ package gregtech.common.blocks; import gregtech.api.GTValues; -import gregtech.api.GregTechAPI; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.MarkerMaterials; import gregtech.api.unification.ore.OrePrefix; import gregtech.client.model.lamp.LampBakedModel; import gregtech.client.model.lamp.LampModelType; import gregtech.client.utils.BloomEffectUtil; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.Block; import net.minecraft.block.SoundType; @@ -66,7 +66,7 @@ public BlockLamp(EnumDyeColor color) { .withProperty(LIGHT, true) .withProperty(INVERTED, false) .withProperty(POWERED, false)); - setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); } public boolean isLightEnabled(ItemStack stack) { diff --git a/src/main/java/gregtech/common/blocks/BlockOre.java b/src/main/java/gregtech/common/blocks/BlockOre.java index c0fc037097b..db69901b8ff 100644 --- a/src/main/java/gregtech/common/blocks/BlockOre.java +++ b/src/main/java/gregtech/common/blocks/BlockOre.java @@ -1,6 +1,5 @@ package gregtech.common.blocks; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.info.MaterialFlags; @@ -13,6 +12,7 @@ import gregtech.client.model.OreBakedModel; import gregtech.client.utils.BloomEffectUtil; import gregtech.common.blocks.properties.PropertyStoneType; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.Block; import net.minecraft.block.SoundType; @@ -54,7 +54,7 @@ public BlockOre(Material material, StoneType[] allowedValues) { this.material = Objects.requireNonNull(material, "Material in BlockOre can not be null!"); STONE_TYPE = PropertyStoneType.create("stone_type", allowedValues); initBlockState(); - setCreativeTab(GregTechAPI.TAB_GREGTECH_ORES); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_ORES); } @NotNull @@ -173,7 +173,7 @@ public boolean isFireSource(@NotNull World world, @NotNull BlockPos pos, @NotNul @Override public void getSubBlocks(@NotNull CreativeTabs tab, @NotNull NonNullList list) { - if (tab == CreativeTabs.SEARCH || tab == GregTechAPI.TAB_GREGTECH_ORES) { + if (tab == CreativeTabs.SEARCH || tab == GTCreativeTabs.TAB_GREGTECH_ORES) { blockState.getValidStates().stream() .filter(state -> state.getValue(STONE_TYPE).shouldBeDroppedAsItem) .forEach(blockState -> list.add(GTUtility.toItem(blockState))); diff --git a/src/main/java/gregtech/common/blocks/BlockWarningSign.java b/src/main/java/gregtech/common/blocks/BlockWarningSign.java index e452e203528..4fdf97dd2fd 100644 --- a/src/main/java/gregtech/common/blocks/BlockWarningSign.java +++ b/src/main/java/gregtech/common/blocks/BlockWarningSign.java @@ -1,8 +1,8 @@ package gregtech.common.blocks; -import gregtech.api.GregTechAPI; import gregtech.api.block.VariantBlock; import gregtech.api.items.toolitem.ToolClasses; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; @@ -24,7 +24,7 @@ public BlockWarningSign() { setSoundType(SoundType.METAL); setHarvestLevel(ToolClasses.WRENCH, 1); setDefaultState(getState(SignType.YELLOW_STRIPES)); - setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); } @Override diff --git a/src/main/java/gregtech/common/blocks/BlockWarningSign1.java b/src/main/java/gregtech/common/blocks/BlockWarningSign1.java index b25d74c9397..199a892d781 100644 --- a/src/main/java/gregtech/common/blocks/BlockWarningSign1.java +++ b/src/main/java/gregtech/common/blocks/BlockWarningSign1.java @@ -1,8 +1,8 @@ package gregtech.common.blocks; -import gregtech.api.GregTechAPI; import gregtech.api.block.VariantBlock; import gregtech.api.items.toolitem.ToolClasses; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; @@ -24,7 +24,7 @@ public BlockWarningSign1() { setSoundType(SoundType.METAL); setHarvestLevel(ToolClasses.WRENCH, 1); setDefaultState(getState(SignType.MOB_SPAWNER_HAZARD)); - setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); } @Override diff --git a/src/main/java/gregtech/common/blocks/MetaBlocks.java b/src/main/java/gregtech/common/blocks/MetaBlocks.java index ada71a669ac..ed353717832 100644 --- a/src/main/java/gregtech/common/blocks/MetaBlocks.java +++ b/src/main/java/gregtech/common/blocks/MetaBlocks.java @@ -3,6 +3,7 @@ import gregtech.api.GregTechAPI; import gregtech.api.block.machines.BlockMachine; import gregtech.api.metatileentity.MetaTileEntityHolder; +import gregtech.api.metatileentity.registry.MTERegistry; import gregtech.api.pipenet.longdist.BlockLongDistancePipe; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Material; @@ -24,6 +25,8 @@ import gregtech.client.renderer.pipe.LaserPipeRenderer; import gregtech.client.renderer.pipe.OpticalPipeRenderer; import gregtech.common.ConfigHolder; +import gregtech.common.blocks.explosive.BlockITNT; +import gregtech.common.blocks.explosive.BlockPowderbarrel; import gregtech.common.blocks.foam.BlockFoam; import gregtech.common.blocks.foam.BlockPetrifiedFoam; import gregtech.common.blocks.wood.BlockGregFence; @@ -111,7 +114,6 @@ public class MetaBlocks { private MetaBlocks() {} - public static BlockMachine MACHINE; public static final Map CABLES = new Object2ObjectOpenHashMap<>(); public static final Map FLUID_PIPES = new Object2ObjectOpenHashMap<>(); public static final Map ITEM_PIPES = new Object2ObjectOpenHashMap<>(); @@ -164,6 +166,8 @@ private MetaBlocks() {} public static BlockFenceGate TREATED_WOOD_FENCE_GATE; public static BlockWoodenDoor RUBBER_WOOD_DOOR; public static BlockWoodenDoor TREATED_WOOD_DOOR; + public static BlockPowderbarrel POWDERBARREL; + public static BlockITNT ITNT; public static BlockBrittleCharcoal BRITTLE_CHARCOAL; @@ -183,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(); @@ -312,6 +319,10 @@ public static void init() { RUBBER_WOOD_DOOR.setRegistryName("rubber_wood_door").setTranslationKey("rubber_wood_door"); TREATED_WOOD_DOOR = new BlockWoodenDoor(() -> MetaItems.TREATED_WOOD_DOOR.getStackForm()); TREATED_WOOD_DOOR.setRegistryName("treated_wood_door").setTranslationKey("treated_wood_door"); + POWDERBARREL = new BlockPowderbarrel(); + POWDERBARREL.setRegistryName("powderbarrel").setTranslationKey("powderbarrel"); + ITNT = new BlockITNT(); + ITNT.setRegistryName("itnt").setTranslationKey("itnt"); BRITTLE_CHARCOAL = new BlockBrittleCharcoal(); BRITTLE_CHARCOAL.setRegistryName("brittle_charcoal"); @@ -429,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(); @@ -481,6 +495,8 @@ public static void registerItemModels() { new ModelResourceLocation(Objects.requireNonNull(TREATED_WOOD_FENCE_GATE.getRegistryName()), "inventory")); registerItemModel(BRITTLE_CHARCOAL); + registerItemModel(POWDERBARREL); + registerItemModel(ITNT); registerItemModel(METAL_SHEET); registerItemModel(LARGE_METAL_SHEET); @@ -526,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/blocks/StoneVariantBlock.java b/src/main/java/gregtech/common/blocks/StoneVariantBlock.java index 39194eea2a0..72fcb6d5180 100644 --- a/src/main/java/gregtech/common/blocks/StoneVariantBlock.java +++ b/src/main/java/gregtech/common/blocks/StoneVariantBlock.java @@ -1,11 +1,11 @@ package gregtech.common.blocks; -import gregtech.api.GregTechAPI; import gregtech.api.block.VariantBlock; import gregtech.api.items.toolitem.ToolClasses; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.Materials; import gregtech.api.unification.ore.OrePrefix; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.SoundType; import net.minecraft.block.material.MapColor; @@ -40,7 +40,7 @@ public StoneVariantBlock(@NotNull StoneVariant stoneVariant) { setSoundType(SoundType.STONE); setHarvestLevel(ToolClasses.PICKAXE, 0); setDefaultState(getState(StoneType.BLACK_GRANITE)); - setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); } @NotNull diff --git a/src/main/java/gregtech/common/blocks/explosive/BlockGTExplosive.java b/src/main/java/gregtech/common/blocks/explosive/BlockGTExplosive.java new file mode 100644 index 00000000000..e18a97abbbf --- /dev/null +++ b/src/main/java/gregtech/common/blocks/explosive/BlockGTExplosive.java @@ -0,0 +1,175 @@ +package gregtech.common.blocks.explosive; + +import gregtech.common.creativetab.GTCreativeTabs; +import gregtech.common.entities.EntityGTExplosive; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.init.SoundEvents; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.Explosion; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +@SuppressWarnings("deprecation") +public abstract class BlockGTExplosive extends Block { + + private final boolean canRedstoneActivate; + private final boolean explodeOnMine; + private final int fuseLength; + + /** + * @param canRedstoneActivate whether redstone signal can prime this explosive + * @param explodeOnMine whether mining this block should prime it (sneak mine to drop normally) + * @param fuseLength explosion countdown after priming. Vanilla TNT is 80. + */ + public BlockGTExplosive(Material materialIn, boolean canRedstoneActivate, boolean explodeOnMine, int fuseLength) { + super(materialIn); + this.canRedstoneActivate = canRedstoneActivate; + this.explodeOnMine = explodeOnMine; + this.fuseLength = fuseLength; + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_TOOLS); + } + + protected abstract EntityGTExplosive createEntity(World world, BlockPos pos, EntityLivingBase exploder); + + @Override + public float getExplosionResistance(@NotNull Entity exploder) { + return 1.0f; + } + + @Override + public boolean canBeReplacedByLeaves(@NotNull IBlockState state, @NotNull IBlockAccess world, + @NotNull BlockPos pos) { + return false; + } + + @Override + public boolean isNormalCube(@NotNull IBlockState state) { + return true; + } + + @Override + public boolean canCreatureSpawn(@NotNull IBlockState state, @NotNull IBlockAccess world, @NotNull BlockPos pos, + @NotNull EntityLiving.SpawnPlacementType type) { + return false; + } + + @Override + public boolean canDropFromExplosion(@NotNull Explosion explosion) { + return false; + } + + public void explode(World world, BlockPos pos, EntityLivingBase exploder) { + if (!world.isRemote) { + EntityGTExplosive entity = createEntity(world, pos, exploder); + entity.setFuse(fuseLength); + world.spawnEntity(entity); + world.playSound(null, entity.posX, entity.posY, entity.posZ, SoundEvents.ENTITY_TNT_PRIMED, + SoundCategory.BLOCKS, 1.0f, 1.0f); + } + } + + @Override + public void onExplosionDestroy(@NotNull World world, @NotNull BlockPos pos, @NotNull Explosion explosion) { + if (!world.isRemote) { + EntityGTExplosive entity = createEntity(world, pos, explosion.getExplosivePlacedBy()); + entity.setFuse(world.rand.nextInt(fuseLength / 4) + fuseLength / 8); + world.spawnEntity(entity); + } + } + + @Override + public boolean onBlockActivated(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState state, + @NotNull EntityPlayer player, @NotNull EnumHand hand, @NotNull EnumFacing facing, + float hitX, float hitY, float hitZ) { + ItemStack stack = player.getHeldItem(hand); + if (!stack.isEmpty() && (stack.getItem() == Items.FLINT_AND_STEEL || stack.getItem() == Items.FIRE_CHARGE)) { + this.explode(world, pos, player); + world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11); + if (stack.getItem() == Items.FLINT_AND_STEEL) { + stack.damageItem(1, player); + } else if (!player.capabilities.isCreativeMode) { + stack.shrink(1); + } + return true; + } + return super.onBlockActivated(world, pos, state, player, hand, facing, hitX, hitY, hitZ); + } + + @Override + public void dropBlockAsItemWithChance(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState state, + float chance, int fortune) { + if (explodeOnMine) { + EntityPlayer player = this.harvesters.get(); + if (!player.isSneaking()) { + this.explode(world, pos, player); + return; + } + } + super.dropBlockAsItemWithChance(world, pos, state, chance, fortune); + } + + @Override + public void onEntityCollision(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState state, + @NotNull Entity entity) { + if (!world.isRemote && entity instanceof EntityArrow arrow) { + if (arrow.isBurning()) { + this.explode(world, pos, arrow.shootingEntity instanceof EntityLivingBase living ? living : null); + world.setBlockToAir(pos); + } + } + } + + @Override + public void onBlockAdded(@NotNull World world, @NotNull BlockPos pos, @NotNull IBlockState state) { + super.onBlockAdded(world, pos, state); + if (canRedstoneActivate) { + if (world.isBlockPowered(pos)) { + explode(world, pos, null); + world.setBlockToAir(pos); + } + } + } + + @Override + public void neighborChanged(@NotNull IBlockState state, @NotNull World world, @NotNull BlockPos pos, + @NotNull Block block, @NotNull BlockPos fromPos) { + if (canRedstoneActivate) { + if (world.isBlockPowered(pos)) { + explode(world, pos, null); + world.setBlockToAir(pos); + } + } + } + + @Override + public void addInformation(@NotNull ItemStack stack, @Nullable World world, @NotNull List tooltip, + @NotNull ITooltipFlag flag) { + if (explodeOnMine) { + tooltip.add(I18n.format("tile.gt_explosive.breaking_tooltip")); + } + if (!canRedstoneActivate) { + tooltip.add(I18n.format("tile.gt_explosive.lighting_tooltip")); + } + } +} diff --git a/src/main/java/gregtech/common/blocks/explosive/BlockITNT.java b/src/main/java/gregtech/common/blocks/explosive/BlockITNT.java new file mode 100644 index 00000000000..91a9614d4c4 --- /dev/null +++ b/src/main/java/gregtech/common/blocks/explosive/BlockITNT.java @@ -0,0 +1,40 @@ +package gregtech.common.blocks.explosive; + +import gregtech.common.entities.EntityGTExplosive; +import gregtech.common.entities.ITNTEntity; + +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class BlockITNT extends BlockGTExplosive { + + public BlockITNT() { + super(Material.TNT, true, true, 40); + setHardness(0); + setSoundType(SoundType.PLANT); + } + + @Override + protected EntityGTExplosive createEntity(World world, BlockPos pos, EntityLivingBase exploder) { + float x = pos.getX() + 0.5F, y = pos.getY(), z = pos.getZ() + 0.5F; + return new ITNTEntity(world, x, y, z, exploder); + } + + @Override + public void addInformation(@NotNull ItemStack stack, @Nullable World world, @NotNull List tooltip, + @NotNull ITooltipFlag flag) { + tooltip.add(I18n.format("tile.itnt.drops_tooltip")); + super.addInformation(stack, world, tooltip, flag); + } +} diff --git a/src/main/java/gregtech/common/blocks/explosive/BlockPowderbarrel.java b/src/main/java/gregtech/common/blocks/explosive/BlockPowderbarrel.java new file mode 100644 index 00000000000..a2549ad7ee5 --- /dev/null +++ b/src/main/java/gregtech/common/blocks/explosive/BlockPowderbarrel.java @@ -0,0 +1,42 @@ +package gregtech.common.blocks.explosive; + +import gregtech.api.items.toolitem.ToolClasses; +import gregtech.common.blocks.material.GTBlockMaterials; +import gregtech.common.entities.EntityGTExplosive; +import gregtech.common.entities.PowderbarrelEntity; + +import net.minecraft.block.SoundType; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class BlockPowderbarrel extends BlockGTExplosive { + + public BlockPowderbarrel() { + super(GTBlockMaterials.POWDERBARREL, false, true, 100); + setHarvestLevel(ToolClasses.AXE, 1); + setHardness(0.5F); + setSoundType(SoundType.WOOD); + } + + @Override + protected EntityGTExplosive createEntity(World world, BlockPos pos, EntityLivingBase exploder) { + float x = pos.getX() + 0.5F, y = pos.getY(), z = pos.getZ() + 0.5F; + return new PowderbarrelEntity(world, x, y, z, exploder); + } + + @Override + public void addInformation(@NotNull ItemStack stack, @Nullable World world, @NotNull List tooltip, + @NotNull ITooltipFlag flag) { + tooltip.add(I18n.format("tile.powderbarrel.drops_tooltip")); + super.addInformation(stack, world, tooltip, flag); + } +} diff --git a/src/main/java/gregtech/common/blocks/material/GTBlockMaterials.java b/src/main/java/gregtech/common/blocks/material/GTBlockMaterials.java new file mode 100644 index 00000000000..213ba58fdd9 --- /dev/null +++ b/src/main/java/gregtech/common/blocks/material/GTBlockMaterials.java @@ -0,0 +1,18 @@ +package gregtech.common.blocks.material; + +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; + +public class GTBlockMaterials { + + public static final Material POWDERBARREL = new PowderbarrelMaterial(); + + private static class PowderbarrelMaterial extends Material { + + public PowderbarrelMaterial() { + super(MapColor.STONE); + setAdventureModeExempt(); + setImmovableMobility(); + } + } +} diff --git a/src/main/java/gregtech/common/blocks/wood/BlockGregFence.java b/src/main/java/gregtech/common/blocks/wood/BlockGregFence.java index 975c0708a22..ba3188cac78 100644 --- a/src/main/java/gregtech/common/blocks/wood/BlockGregFence.java +++ b/src/main/java/gregtech/common/blocks/wood/BlockGregFence.java @@ -1,7 +1,7 @@ package gregtech.common.blocks.wood; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.BlockFence; import net.minecraft.block.SoundType; @@ -15,7 +15,7 @@ public BlockGregFence() { setHardness(2.0F); setResistance(5.0F); setSoundType(SoundType.WOOD); - setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); setHarvestLevel(ToolClasses.AXE, 0); } } diff --git a/src/main/java/gregtech/common/blocks/wood/BlockGregFenceGate.java b/src/main/java/gregtech/common/blocks/wood/BlockGregFenceGate.java index 29c539eca35..aff946015e2 100644 --- a/src/main/java/gregtech/common/blocks/wood/BlockGregFenceGate.java +++ b/src/main/java/gregtech/common/blocks/wood/BlockGregFenceGate.java @@ -1,7 +1,7 @@ package gregtech.common.blocks.wood; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.BlockFenceGate; import net.minecraft.block.BlockPlanks; @@ -14,7 +14,7 @@ public BlockGregFenceGate() { setHardness(2.0F); setResistance(5.0F); setSoundType(SoundType.WOOD); - setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); setHarvestLevel(ToolClasses.AXE, 0); } } diff --git a/src/main/java/gregtech/common/blocks/wood/BlockGregWoodSlab.java b/src/main/java/gregtech/common/blocks/wood/BlockGregWoodSlab.java index acab4c9dd43..d2cc8e2b96e 100644 --- a/src/main/java/gregtech/common/blocks/wood/BlockGregWoodSlab.java +++ b/src/main/java/gregtech/common/blocks/wood/BlockGregWoodSlab.java @@ -1,8 +1,8 @@ package gregtech.common.blocks.wood; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; import gregtech.common.blocks.MetaBlocks; +import gregtech.common.creativetab.GTCreativeTabs; import net.minecraft.block.BlockSlab; import net.minecraft.block.SoundType; @@ -35,7 +35,7 @@ public BlockGregWoodSlab() { setResistance(5.0F); setSoundType(SoundType.WOOD); setHarvestLevel(ToolClasses.AXE, 0); - setCreativeTab(GregTechAPI.TAB_GREGTECH_DECORATIONS); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); this.useNeighborBrightness = true; } diff --git a/src/main/java/gregtech/common/blocks/wood/BlockRubberLeaves.java b/src/main/java/gregtech/common/blocks/wood/BlockRubberLeaves.java index 533cf4249d2..2149165afa4 100644 --- a/src/main/java/gregtech/common/blocks/wood/BlockRubberLeaves.java +++ b/src/main/java/gregtech/common/blocks/wood/BlockRubberLeaves.java @@ -1,7 +1,7 @@ package gregtech.common.blocks.wood; -import gregtech.api.GregTechAPI; import gregtech.common.blocks.MetaBlocks; +import gregtech.common.creativetab.GTCreativeTabs; import gregtech.core.CoreModule; import net.minecraft.block.BlockLeaves; @@ -31,7 +31,7 @@ public BlockRubberLeaves() { .withProperty(CHECK_DECAY, true) .withProperty(DECAYABLE, true)); setTranslationKey("rubber_leaves"); - setCreativeTab(GregTechAPI.TAB_GREGTECH); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH); Blocks.FIRE.setFireInfo(this, 30, 60); } diff --git a/src/main/java/gregtech/common/blocks/wood/BlockRubberLog.java b/src/main/java/gregtech/common/blocks/wood/BlockRubberLog.java index bd89801a699..7c2f2b09f85 100644 --- a/src/main/java/gregtech/common/blocks/wood/BlockRubberLog.java +++ b/src/main/java/gregtech/common/blocks/wood/BlockRubberLog.java @@ -1,7 +1,7 @@ package gregtech.common.blocks.wood; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; +import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.items.MetaItems; import net.minecraft.block.BlockLog; @@ -27,7 +27,7 @@ public BlockRubberLog() { .withProperty(LOG_AXIS, BlockLog.EnumAxis.Y) .withProperty(NATURAL, false)); setTranslationKey("rubber_log"); - setCreativeTab(GregTechAPI.TAB_GREGTECH); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH); setHarvestLevel(ToolClasses.AXE, 0); } diff --git a/src/main/java/gregtech/common/blocks/wood/BlockRubberSapling.java b/src/main/java/gregtech/common/blocks/wood/BlockRubberSapling.java index cd9b35d8232..653a31fc9a8 100644 --- a/src/main/java/gregtech/common/blocks/wood/BlockRubberSapling.java +++ b/src/main/java/gregtech/common/blocks/wood/BlockRubberSapling.java @@ -1,6 +1,6 @@ package gregtech.common.blocks.wood; -import gregtech.api.GregTechAPI; +import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.worldgen.WorldGenRubberTree; import net.minecraft.block.BlockBush; @@ -28,7 +28,7 @@ public BlockRubberSapling() { this.setDefaultState(this.blockState.getBaseState() .withProperty(STAGE, 0)); setTranslationKey("rubber_sapling"); - setCreativeTab(GregTechAPI.TAB_GREGTECH); + setCreativeTab(GTCreativeTabs.TAB_GREGTECH); setHardness(0.0F); setSoundType(SoundType.PLANT); } diff --git a/src/main/java/gregtech/common/covers/CoverBehaviors.java b/src/main/java/gregtech/common/covers/CoverBehaviors.java index 3e5779fb3bf..355fe3b0dff 100644 --- a/src/main/java/gregtech/common/covers/CoverBehaviors.java +++ b/src/main/java/gregtech/common/covers/CoverBehaviors.java @@ -8,10 +8,7 @@ import gregtech.api.util.GTLog; import gregtech.client.renderer.texture.Textures; import gregtech.common.covers.detector.*; -import gregtech.common.covers.filter.OreDictionaryItemFilter; -import gregtech.common.covers.filter.SimpleFluidFilter; -import gregtech.common.covers.filter.SimpleItemFilter; -import gregtech.common.covers.filter.SmartItemFilter; +import gregtech.common.covers.ender.CoverEnderFluidLink; import gregtech.common.items.MetaItems; import gregtech.common.items.behaviors.CoverDigitalInterfaceWirelessPlaceBehaviour; @@ -67,12 +64,12 @@ public static void init() { registerBehavior(gregtechId("ore_dictionary_filter"), MetaItems.ORE_DICTIONARY_FILTER, (def, tile, side) -> new CoverItemFilter(def, tile, side, "cover.ore_dictionary_filter.title", - Textures.ORE_DICTIONARY_FILTER_OVERLAY, new OreDictionaryItemFilter())); + Textures.ORE_DICTIONARY_FILTER_OVERLAY)); registerBehavior(gregtechId("item_filter"), MetaItems.ITEM_FILTER, (def, tile, side) -> new CoverItemFilter(def, - tile, side, "cover.item_filter.title", Textures.ITEM_FILTER_FILTER_OVERLAY, new SimpleItemFilter())); + tile, side, "cover.item_filter.title", Textures.ITEM_FILTER_FILTER_OVERLAY)); registerBehavior(gregtechId("fluid_filter"), MetaItems.FLUID_FILTER, (def, tile, side) -> new CoverFluidFilter(def, tile, side, "cover.fluid_filter.title", - Textures.FLUID_FILTER_OVERLAY, new SimpleFluidFilter())); + Textures.FLUID_FILTER_OVERLAY)); registerBehavior(gregtechId("shutter"), MetaItems.COVER_SHUTTER, CoverShutter::new); registerBehavior(gregtechId("solar_panel.basic"), MetaItems.COVER_SOLAR_PANEL, @@ -100,7 +97,7 @@ public static void init() { CoverMachineController::new); registerBehavior(gregtechId("smart_filter"), MetaItems.SMART_FILTER, (def, tile, side) -> new CoverItemFilter(def, tile, side, "cover.smart_item_filter.title", - Textures.SMART_FILTER_FILTER_OVERLAY, new SmartItemFilter())); + Textures.SMART_FILTER_FILTER_OVERLAY)); registerBehavior(gregtechId("facade"), MetaItems.COVER_FACADE, CoverFacade::new); registerBehavior(gregtechId("screen"), MetaItems.COVER_SCREEN, CoverScreen::new); diff --git a/src/main/java/gregtech/common/covers/CoverConveyor.java b/src/main/java/gregtech/common/covers/CoverConveyor.java index 1408ae77c56..798c0000e8c 100644 --- a/src/main/java/gregtech/common/covers/CoverConveyor.java +++ b/src/main/java/gregtech/common/covers/CoverConveyor.java @@ -1,6 +1,5 @@ package gregtech.common.covers; -import gregtech.api.GTValues; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IControllable; @@ -9,9 +8,8 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverWithUI; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.*; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.ItemStackHashStrategy; import gregtech.client.renderer.texture.Textures; @@ -26,7 +24,12 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.*; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.IStringSerializable; +import net.minecraft.util.ITickable; import net.minecraft.util.math.MathHelper; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fml.relauncher.Side; @@ -39,10 +42,26 @@ 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; +import com.cleanroommc.modularui.utils.MouseData; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.IntSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.ButtonWidget; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; import org.jetbrains.annotations.NotNull; @@ -76,7 +95,7 @@ public CoverConveyor(@NotNull CoverDefinition definition, @NotNull CoverableView } public void setTransferRate(int transferRate) { - this.transferRate = transferRate; + this.transferRate = MathHelper.clamp(transferRate, 1, maxItemTransferRate); CoverableView coverable = getCoverableView(); coverable.markDirty(); @@ -168,7 +187,7 @@ protected int doTransferItemsAny(IItemHandler itemHandler, IItemHandler myItemHa } protected int doTransferItemsByGroup(IItemHandler itemHandler, IItemHandler myItemHandler, - Map itemInfos, int maxTransferAmount) { + Map itemInfos, int maxTransferAmount) { if (conveyorMode == ConveyorMode.IMPORT) { return moveInventoryItems(itemHandler, myItemHandler, itemInfos, maxTransferAmount); } else if (conveyorMode == ConveyorMode.EXPORT) { @@ -177,8 +196,8 @@ protected int doTransferItemsByGroup(IItemHandler itemHandler, IItemHandler myIt return 0; } - protected Map doCountDestinationInventoryItemsByMatchIndex(IItemHandler itemHandler, - IItemHandler myItemHandler) { + protected Map doCountDestinationInventoryItemsByMatchIndex(IItemHandler itemHandler, + IItemHandler myItemHandler) { if (conveyorMode == ConveyorMode.IMPORT) { return countInventoryItemsByMatchSlot(myItemHandler); } else if (conveyorMode == ConveyorMode.EXPORT) { @@ -265,15 +284,17 @@ protected static boolean moveInventoryItemsExact(IItemHandler sourceInventory, I } protected int moveInventoryItems(IItemHandler sourceInventory, IItemHandler targetInventory, - Map itemInfos, int maxTransferAmount) { + Map itemInfos, int maxTransferAmount) { int itemsLeftToTransfer = maxTransferAmount; for (int i = 0; i < sourceInventory.getSlots(); i++) { ItemStack itemStack = sourceInventory.getStackInSlot(i); if (itemStack.isEmpty()) { continue; } - Object matchSlotIndex = itemFilterContainer.matchItemStack(itemStack); - if (matchSlotIndex == null || !itemInfos.containsKey(matchSlotIndex)) { + + var matchResult = itemFilterContainer.match(itemStack); + int matchSlotIndex = matchResult.getFilterIndex(); + if (!matchResult.isMatched() || !itemInfos.containsKey(matchSlotIndex)) { continue; } @@ -317,9 +338,10 @@ protected int moveInventoryItems(IItemHandler sourceInventory, IItemHandler targ if (sourceStack.isEmpty()) { continue; } - if (!itemFilterContainer.testItemStack(sourceStack)) { - continue; - } + + var result = itemFilterContainer.match(sourceStack); + if (!result.isMatched()) continue; + ItemStack remainder = GTTransferUtils.insertItem(targetInventory, sourceStack, true); int amountToInsert = sourceStack.getCount() - remainder.getCount(); @@ -341,11 +363,11 @@ protected int moveInventoryItems(IItemHandler sourceInventory, IItemHandler targ protected static class TypeItemInfo { public final ItemStack itemStack; - public final Object filterSlot; + public final int filterSlot; public final IntList slots; public int totalCount; - public TypeItemInfo(ItemStack itemStack, Object filterSlot, IntList slots, int totalCount) { + public TypeItemInfo(ItemStack itemStack, int filterSlot, IntList slots, int totalCount) { this.itemStack = itemStack; this.filterSlot = filterSlot; this.slots = slots; @@ -355,11 +377,11 @@ public TypeItemInfo(ItemStack itemStack, Object filterSlot, IntList slots, int t protected static class GroupItemInfo { - public final Object filterSlot; + public final int filterSlot; public final Set itemStackTypes; public int totalCount; - public GroupItemInfo(Object filterSlot, Set itemStackTypes, int totalCount) { + public GroupItemInfo(int filterSlot, Set itemStackTypes, int totalCount) { this.filterSlot = filterSlot; this.itemStackTypes = itemStackTypes; this.totalCount = totalCount; @@ -375,12 +397,13 @@ protected Map countInventoryItemsByType(@NotNull IItemH if (itemStack.isEmpty()) { continue; } - Object transferSlotIndex = itemFilterContainer.matchItemStack(itemStack); - if (transferSlotIndex == null) { - continue; - } + + var matchResult = itemFilterContainer.match(itemStack); + if (!matchResult.isMatched()) continue; + if (!result.containsKey(itemStack)) { - TypeItemInfo itemInfo = new TypeItemInfo(itemStack.copy(), transferSlotIndex, new IntArrayList(), 0); + TypeItemInfo itemInfo = new TypeItemInfo(itemStack.copy(), matchResult.getFilterIndex(), + new IntArrayList(), 0); itemInfo.totalCount += itemStack.getCount(); itemInfo.slots.add(srcIndex); result.put(itemStack.copy(), itemInfo); @@ -394,28 +417,30 @@ protected Map countInventoryItemsByType(@NotNull IItemH } @NotNull - protected Map countInventoryItemsByMatchSlot(@NotNull IItemHandler inventory) { - Map result = new Object2ObjectOpenHashMap<>(); + protected Map countInventoryItemsByMatchSlot(@NotNull IItemHandler inventory) { + Map result = new Int2ObjectOpenHashMap<>(); for (int srcIndex = 0; srcIndex < inventory.getSlots(); srcIndex++) { ItemStack itemStack = inventory.getStackInSlot(srcIndex); if (itemStack.isEmpty()) { continue; } - Object transferSlotIndex = itemFilterContainer.matchItemStack(itemStack); - if (transferSlotIndex == null) { - continue; - } - if (!result.containsKey(transferSlotIndex)) { - GroupItemInfo itemInfo = new GroupItemInfo(transferSlotIndex, + + var matchResult = itemFilterContainer.match(itemStack); + if (!matchResult.isMatched()) continue; + int matchedSlot = matchResult.getFilterIndex(); + + if (!result.containsKey(matchedSlot)) { + GroupItemInfo itemInfo = new GroupItemInfo(matchedSlot, new ObjectOpenCustomHashSet<>(ItemStackHashStrategy.comparingAllButCount()), 0); itemInfo.itemStackTypes.add(itemStack.copy()); itemInfo.totalCount += itemStack.getCount(); - result.put(transferSlotIndex, itemInfo); + result.put(matchedSlot, itemInfo); } else { - GroupItemInfo itemInfo = result.get(transferSlotIndex); + GroupItemInfo itemInfo = result.get(matchedSlot); itemInfo.itemStackTypes.add(itemStack.copy()); itemInfo.totalCount += itemStack.getCount(); } + } return result; } @@ -432,7 +457,7 @@ public boolean canInteractWithOutputSide() { @Override public void onRemoval() { - dropInventoryContents(itemFilterContainer.getFilterInventory()); + dropInventoryContents(itemFilterContainer); } @Override @@ -473,57 +498,130 @@ public T getCapability(Capability capability, T defaultValue) { return defaultValue; } - protected String getUITitle() { - return "cover.conveyor.title"; + @Override + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager) { + var panel = GTGuis.createPanel(this, 176, 192 + 18); + + getItemFilterContainer().setMaxTransferSize(getMaxStackSize()); + + return panel.child(CoverWithUI.createTitleRow(getPickItem())) + .child(createUI(panel, guiSyncManager)) + .bindPlayerInventory(); + } + + protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager guiSyncManager) { + var column = new Column().top(24).margin(7, 0) + .widthRel(1f).coverChildrenHeight(); + + EnumSyncValue manualIOmode = new EnumSyncValue<>(ManualImportExportMode.class, + this::getManualImportExportMode, this::setManualImportExportMode); + + EnumSyncValue conveyorMode = new EnumSyncValue<>(ConveyorMode.class, + this::getConveyorMode, this::setConveyorMode); + + IntSyncValue throughput = new IntSyncValue(this::getTransferRate, this::setTransferRate); + throughput.updateCacheFromSource(true); + + StringSyncValue formattedThroughput = new StringSyncValue(throughput::getStringValue, + throughput::setStringValue); + + EnumSyncValue distributionMode = new EnumSyncValue<>(DistributionMode.class, + this::getDistributionMode, this::setDistributionMode); + + guiSyncManager.syncValue("manual_io", manualIOmode); + guiSyncManager.syncValue("conveyor_mode", conveyorMode); + guiSyncManager.syncValue("distribution_mode", distributionMode); + guiSyncManager.syncValue("throughput", throughput); + + if (createThroughputRow()) + column.child(new Row().coverChildrenHeight() + .marginBottom(2).widthRel(1f) + .child(new ButtonWidget<>() + .left(0).width(18) + .onMousePressed(mouseButton -> { + int val = throughput.getValue() - getIncrementValue(MouseData.create(mouseButton)); + throughput.setValue(val, true, true); + Interactable.playButtonClickSound(); + return true; + }) + .onUpdateListener(w -> w.overlay(createAdjustOverlay(false)))) + .child(new TextFieldWidget() + .left(18).right(18) + .setTextColor(Color.WHITE.darker(1)) + .setNumbers(1, maxItemTransferRate) + .value(formattedThroughput) + .background(GTGuiTextures.DISPLAY)) + .child(new ButtonWidget<>() + .right(0).width(18) + .onMousePressed(mouseButton -> { + int val = throughput.getValue() + getIncrementValue(MouseData.create(mouseButton)); + throughput.setValue(val, true, true); + Interactable.playButtonClickSound(); + return true; + }) + .onUpdateListener(w -> w.overlay(createAdjustOverlay(true))))); + + if (createFilterRow()) + column.child(getItemFilterContainer().initUI(mainPanel, guiSyncManager)); + + if (createManualIOModeRow()) + column.child(new EnumRowBuilder<>(ManualImportExportMode.class) + .value(manualIOmode) + .lang("cover.generic.manual_io") + .overlay(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()) + column.child(new EnumRowBuilder<>(ConveyorMode.class) + .value(conveyorMode) + .lang("cover.generic.io") + .overlay(GTGuiTextures.CONVEYOR_MODE_OVERLAY) + .build()); + + if (createDistributionModeRow()) + column.child(new EnumRowBuilder<>(DistributionMode.class) + .value(distributionMode) + .overlay(16, GTGuiTextures.DISTRIBUTION_MODE_OVERLAY) + .lang("cover.conveyor.distribution.name") + .build()); + + return column; + } + + protected boolean createThroughputRow() { + return true; } - protected ModularUI buildUI(ModularUI.Builder builder, EntityPlayer player) { - return builder.build(this, player); + protected boolean createFilterRow() { + return true; } - @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup primaryGroup = new WidgetGroup(); - primaryGroup.addWidget(new LabelWidget(10, 5, getUITitle(), GTValues.VN[tier])); - - primaryGroup.addWidget(new IncrementButtonWidget(136, 20, 30, 20, 1, 8, 64, 512, this::adjustTransferRate) - .setDefaultTooltip() - .setShouldClientCallback(false)); - primaryGroup.addWidget(new IncrementButtonWidget(10, 20, 30, 20, -1, -8, -64, -512, this::adjustTransferRate) - .setDefaultTooltip() - .setShouldClientCallback(false)); - - primaryGroup.addWidget(new ImageWidget(40, 20, 96, 20, GuiTextures.DISPLAY)); - primaryGroup.addWidget(new TextFieldWidget2(42, 26, 92, 20, () -> String.valueOf(transferRate), val -> { - if (val != null && !val.isEmpty()) - setTransferRate(MathHelper.clamp(Integer.parseInt(val), 1, maxItemTransferRate)); - }) - .setNumbersOnly(1, maxItemTransferRate) - .setMaxLength(4) - .setPostFix("cover.conveyor.transfer_rate")); - - primaryGroup.addWidget(new CycleButtonWidget(10, 45, 75, 20, - ConveyorMode.class, this::getConveyorMode, this::setConveyorMode)); - primaryGroup.addWidget(new CycleButtonWidget(7, 166, 116, 20, - ManualImportExportMode.class, this::getManualImportExportMode, this::setManualImportExportMode) - .setTooltipHoverString("cover.universal.manual_import_export.mode.description")); - - if (getTileEntityHere() instanceof TileEntityItemPipe || - getNeighbor(getAttachedSide()) instanceof TileEntityItemPipe) { - final ImageCycleButtonWidget distributionModeButton = new ImageCycleButtonWidget(149, 166, 20, 20, - GuiTextures.DISTRIBUTION_MODE, 3, - () -> distributionMode.ordinal(), - val -> setDistributionMode(DistributionMode.values()[val])) - .setTooltipHoverString(val -> DistributionMode.values()[val].getName()); - primaryGroup.addWidget(distributionModeButton); - } + protected boolean createManualIOModeRow() { + return true; + } + + protected boolean createConveyorModeRow() { + return true; + } - this.itemFilterContainer.initUI(70, primaryGroup::addWidget); + protected boolean createDistributionModeRow() { + return true; + } - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, 190 + 82) - .widget(primaryGroup) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 190); - return buildUI(builder, player); + protected int getMaxStackSize() { + return 1; } @Override @@ -546,17 +644,23 @@ public void readCustomData(int discriminator, @NotNull PacketBuffer buf) { } @Override - public void writeInitialSyncData(PacketBuffer packetBuffer) { + public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { super.writeInitialSyncData(packetBuffer); - packetBuffer.writeEnumValue(conveyorMode); - packetBuffer.writeEnumValue(distributionMode); + packetBuffer.writeInt(transferRate); + packetBuffer.writeByte(conveyorMode.ordinal()); + packetBuffer.writeByte(distributionMode.ordinal()); + packetBuffer.writeByte(manualImportExportMode.ordinal()); + getItemFilterContainer().writeInitialSyncData(packetBuffer); } @Override public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { super.readInitialSyncData(packetBuffer); - this.conveyorMode = packetBuffer.readEnumValue(ConveyorMode.class); - this.distributionMode = packetBuffer.readEnumValue(DistributionMode.class); + this.transferRate = packetBuffer.readInt(); + this.conveyorMode = ConveyorMode.VALUES[packetBuffer.readByte()]; + this.distributionMode = DistributionMode.VALUES[packetBuffer.readByte()]; + this.manualImportExportMode = ManualImportExportMode.VALUES[packetBuffer.readByte()]; + getItemFilterContainer().readInitialSyncData(packetBuffer); } @Override @@ -574,11 +678,16 @@ public void writeToNBT(@NotNull NBTTagCompound tagCompound) { public void readFromNBT(@NotNull NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); this.transferRate = tagCompound.getInteger("TransferRate"); - this.conveyorMode = ConveyorMode.values()[tagCompound.getInteger("ConveyorMode")]; - this.distributionMode = DistributionMode.values()[tagCompound.getInteger("DistributionMode")]; + this.conveyorMode = ConveyorMode.VALUES[tagCompound.getInteger("ConveyorMode")]; + this.distributionMode = DistributionMode.VALUES[tagCompound.getInteger("DistributionMode")]; this.isWorkingAllowed = tagCompound.getBoolean("WorkingAllowed"); - this.manualImportExportMode = ManualImportExportMode.values()[tagCompound.getInteger("ManualImportExportMode")]; - this.itemFilterContainer.deserializeNBT(tagCompound.getCompoundTag("Filter")); + this.manualImportExportMode = ManualImportExportMode.VALUES[tagCompound.getInteger("ManualImportExportMode")]; + var filterTag = tagCompound.getCompoundTag("Filter"); + if (filterTag.hasKey("IsBlacklist")) { + this.itemFilterContainer.handleLegacyNBT(filterTag); + } else { + this.itemFilterContainer.deserializeNBT(filterTag); + } } @Override @@ -592,6 +701,7 @@ public enum ConveyorMode implements IStringSerializable, IIOMode { IMPORT("cover.conveyor.mode.import"), EXPORT("cover.conveyor.mode.export"); + public static final ConveyorMode[] VALUES = values(); public final String localeName; ConveyorMode(String localeName) { @@ -623,7 +733,7 @@ public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate return stack; } if (manualImportExportMode == ManualImportExportMode.FILTERED && - !itemFilterContainer.testItemStack(stack)) { + !itemFilterContainer.test(stack)) { return stack; } return super.insertItem(slot, stack, simulate); @@ -637,7 +747,7 @@ public ItemStack extractItem(int slot, int amount, boolean simulate) { } if (manualImportExportMode == ManualImportExportMode.FILTERED) { ItemStack result = super.extractItem(slot, amount, true); - if (result.isEmpty() || !itemFilterContainer.testItemStack(result)) { + if (result.isEmpty() || !itemFilterContainer.test(result)) { return ItemStack.EMPTY; } return simulate ? result : super.extractItem(slot, amount, false); diff --git a/src/main/java/gregtech/common/covers/CoverDigitalInterface.java b/src/main/java/gregtech/common/covers/CoverDigitalInterface.java index 0a04343acde..0063a113faa 100644 --- a/src/main/java/gregtech/common/covers/CoverDigitalInterface.java +++ b/src/main/java/gregtech/common/covers/CoverDigitalInterface.java @@ -16,9 +16,11 @@ import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.util.GTLog; import gregtech.api.util.Position; +import gregtech.api.util.TextFormattingUtil; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.RenderUtil; -import gregtech.common.terminal.app.prospector.widget.WidgetOreList; +import gregtech.common.gui.widget.prospector.widget.WidgetOreList; +import gregtech.common.metatileentities.multi.electric.MetaTileEntityPowerSubstation; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GlStateManager; @@ -227,7 +229,7 @@ public void onAttachment(@NotNull CoverableView coverableView, @NotNull EnumFaci } else if (getItemCapability() != null) { items = new ItemStack[getItemCapability().getSlots()]; this.mode = MODE.ITEM; - } else if (getEnergyCapability() != null) { + } else if (getEnergyCapability() != null || getCoverableView() instanceof MetaTileEntityPowerSubstation) { this.mode = MODE.ENERGY; } else if (getMachineCapability() != null) { this.mode = MODE.MACHINE; @@ -578,22 +580,19 @@ private void syncAllInfo() { } } if (this.mode == MODE.ENERGY || (mode == MODE.PROXY && proxyMode[2] > 0)) { - IEnergyContainer energyContainer = this.getEnergyCapability(); - if (energyContainer != null) { - // TODO, figure out what to do when values exceed Long.MAX_VALUE, ie with multiple Ultimate batteries - if (energyStored != energyContainer.getEnergyStored() || - energyCapability != energyContainer.getEnergyCapacity()) { - energyStored = energyContainer.getEnergyStored(); - energyCapability = energyContainer.getEnergyCapacity(); + if (getCoverableView() instanceof MetaTileEntityPowerSubstation pss) { + if (energyStored != pss.getStoredLong() || energyCapability != pss.getCapacityLong()) { + energyStored = pss.getStoredLong(); + energyCapability = pss.getCapacityLong(); writeCustomData(GregtechDataCodes.UPDATE_ENERGY, packetBuffer -> { packetBuffer.writeLong(energyStored); packetBuffer.writeLong(energyCapability); }); } - if (this.getOffsetTimer() % 20 == 0) { // per second + if (this.getOffsetTimer() % 20 == 0) { writeCustomData(GregtechDataCodes.UPDATE_ENERGY_PER, packetBuffer -> { - packetBuffer.writeLong(energyContainer.getInputPerSec()); - packetBuffer.writeLong(energyContainer.getOutputPerSec()); + packetBuffer.writeLong(pss.getAverageInLastSec() * 20L); + packetBuffer.writeLong(pss.getAverageOutLastSec() * 20L); inputEnergyList.add(energyInputPerDur); outputEnergyList.add(energyOutputPerDur); if (inputEnergyList.size() > 13) { @@ -602,6 +601,33 @@ private void syncAllInfo() { } }); } + } else { + IEnergyContainer energyContainer = this.getEnergyCapability(); + if (energyContainer != null) { + // TODO, figure out what to do when values exceed Long.MAX_VALUE, ie with multiple Ultimate + // batteries + if (energyStored != energyContainer.getEnergyStored() || + energyCapability != energyContainer.getEnergyCapacity()) { + energyStored = energyContainer.getEnergyStored(); + energyCapability = energyContainer.getEnergyCapacity(); + writeCustomData(GregtechDataCodes.UPDATE_ENERGY, packetBuffer -> { + packetBuffer.writeLong(energyStored); + packetBuffer.writeLong(energyCapability); + }); + } + if (this.getOffsetTimer() % 20 == 0) { // per second + writeCustomData(GregtechDataCodes.UPDATE_ENERGY_PER, packetBuffer -> { + packetBuffer.writeLong(energyContainer.getInputPerSec()); + packetBuffer.writeLong(energyContainer.getOutputPerSec()); + inputEnergyList.add(energyInputPerDur); + outputEnergyList.add(energyOutputPerDur); + if (inputEnergyList.size() > 13) { + inputEnergyList.remove(0); + outputEnergyList.remove(0); + } + }); + } + } } } if (this.mode == MODE.MACHINE || (mode == MODE.PROXY && proxyMode[3] > 0)) { @@ -625,17 +651,28 @@ private void syncAllInfo() { }); } if (this.getOffsetTimer() % 20 == 0) { - IEnergyContainer energyContainer = this.getEnergyCapability(); - if (energyContainer != null) { - if (energyStored != energyContainer.getEnergyStored() || - energyCapability != energyContainer.getEnergyCapacity()) { - energyStored = energyContainer.getEnergyStored(); - energyCapability = energyContainer.getEnergyCapacity(); + if (getCoverableView() instanceof MetaTileEntityPowerSubstation pss) { + if (energyStored != pss.getStoredLong() || energyCapability != pss.getCapacityLong()) { + energyStored = pss.getStoredLong(); + energyCapability = pss.getCapacityLong(); writeCustomData(GregtechDataCodes.UPDATE_ENERGY, packetBuffer -> { packetBuffer.writeLong(energyStored); packetBuffer.writeLong(energyCapability); }); } + } else { + IEnergyContainer energyContainer = this.getEnergyCapability(); + if (energyContainer != null) { + if (energyStored != energyContainer.getEnergyStored() || + energyCapability != energyContainer.getEnergyCapacity()) { + energyStored = energyContainer.getEnergyStored(); + energyCapability = energyContainer.getEnergyCapacity(); + writeCustomData(GregtechDataCodes.UPDATE_ENERGY, packetBuffer -> { + packetBuffer.writeLong(energyStored); + packetBuffer.writeLong(energyCapability); + }); + } + } } } } @@ -860,6 +897,7 @@ public boolean canCapabilityAttach() { return getFluidCapability() != null || getItemCapability() != null || getEnergyCapability() != null || + getCoverableView() instanceof MetaTileEntityPowerSubstation || getMachineCapability() != null; } @@ -1046,9 +1084,11 @@ private void renderEnergyMode() { } RenderUtil.renderLineChart(inputEnergyList, max, -5.5f / 16, 5.5f / 16, 12f / 16, 6f / 16, 0.005f, 0XFF03FF00); RenderUtil.renderLineChart(outputEnergyList, max, -5.5f / 16, 5.5f / 16, 12f / 16, 6f / 16, 0.005f, 0XFFFF2F39); - RenderUtil.renderText(-5.7f / 16, -2.3f / 16, 0, 1.0f / 270, 0XFF03FF00, "EU I: " + energyInputPerDur + "EU/s", + RenderUtil.renderText(-5.7f / 16, -2.3f / 16, 0, 1.0f / 270, 0XFF03FF00, + "EU I: " + TextFormattingUtil.formatNumbers(energyInputPerDur / 20) + "EU/t", false); - RenderUtil.renderText(-5.7f / 16, -1.6f / 16, 0, 1.0f / 270, 0XFFFF0000, "EU O: " + energyOutputPerDur + "EU/s", + RenderUtil.renderText(-5.7f / 16, -1.6f / 16, 0, 1.0f / 270, 0XFFFF0000, + "EU O: " + TextFormattingUtil.formatNumbers(energyOutputPerDur / 20) + "EU/t", false); // Bandaid fix to prevent overflowing renders when dealing with items that cause long overflow, ie Ultimate // Battery diff --git a/src/main/java/gregtech/common/covers/CoverEnderFluidLink.java b/src/main/java/gregtech/common/covers/CoverEnderFluidLink.java deleted file mode 100644 index b34348c69bb..00000000000 --- a/src/main/java/gregtech/common/covers/CoverEnderFluidLink.java +++ /dev/null @@ -1,279 +0,0 @@ -package gregtech.common.covers; - -import gregtech.api.capability.GregtechTileCapabilities; -import gregtech.api.capability.IControllable; -import gregtech.api.cover.CoverBase; -import gregtech.api.cover.CoverDefinition; -import gregtech.api.cover.CoverWithUI; -import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.*; -import gregtech.api.util.FluidTankSwitchShim; -import gregtech.api.util.GTTransferUtils; -import gregtech.api.util.VirtualTankRegistry; -import gregtech.client.renderer.texture.Textures; -import gregtech.common.covers.filter.FluidFilterContainer; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.PacketBuffer; -import net.minecraft.util.*; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.fluids.capability.CapabilityFluidHandler; -import net.minecraftforge.fluids.capability.IFluidHandler; - -import codechicken.lib.raytracer.CuboidRayTraceResult; -import codechicken.lib.render.CCRenderState; -import codechicken.lib.render.pipeline.IVertexOperation; -import codechicken.lib.vec.Cuboid6; -import codechicken.lib.vec.Matrix4; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.UUID; -import java.util.regex.Pattern; - -public class CoverEnderFluidLink extends CoverBase implements CoverWithUI, ITickable, IControllable { - - public static final int TRANSFER_RATE = 8000; // mB/t - private static final Pattern COLOR_INPUT_PATTERN = Pattern.compile("[0-9a-fA-F]*"); - - protected CoverPump.PumpMode pumpMode = CoverPump.PumpMode.IMPORT; - private int color = 0xFFFFFFFF; - private UUID playerUUID = null; - private boolean isPrivate = false; - private boolean workingEnabled = true; - private boolean ioEnabled = false; - private String tempColorStr; - private boolean isColorTemp; - private final FluidTankSwitchShim linkedTank; - protected final FluidFilterContainer fluidFilter; - - protected CoverEnderFluidLink(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, - @NotNull EnumFacing attachedSide) { - super(definition, coverableView, attachedSide); - this.linkedTank = new FluidTankSwitchShim(VirtualTankRegistry.getTankCreate(makeTankName(), null)); - this.fluidFilter = new FluidFilterContainer(this); - } - - private String makeTankName() { - return "EFLink#" + Integer.toHexString(this.color).toUpperCase(); - } - - private UUID getTankUUID() { - return isPrivate ? playerUUID : null; - } - - public FluidFilterContainer getFluidFilterContainer() { - return this.fluidFilter; - } - - public boolean isIOEnabled() { - return this.ioEnabled; - } - - @Override - public boolean canAttach(@NotNull CoverableView coverable, @NotNull EnumFacing side) { - return coverable.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side); - } - - @Override - public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 translation, - IVertexOperation[] pipeline, @NotNull Cuboid6 plateBox, @NotNull BlockRenderLayer layer) { - Textures.ENDER_FLUID_LINK.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); - } - - @Override - public @NotNull EnumActionResult onScrewdriverClick(@NotNull EntityPlayer playerIn, @NotNull EnumHand hand, - @NotNull CuboidRayTraceResult hitResult) { - if (!getWorld().isRemote) { - openUI((EntityPlayerMP) playerIn); - } - return EnumActionResult.SUCCESS; - } - - @Override - public void onAttachment(@NotNull CoverableView coverableView, @NotNull EnumFacing side, - @Nullable EntityPlayer player, @NotNull ItemStack itemStack) { - super.onAttachment(coverableView, side, player, itemStack); - if (player != null) { - this.playerUUID = player.getUniqueID(); - } - } - - @Override - public void onRemoval() { - dropInventoryContents(fluidFilter.getFilterInventory()); - } - - @Override - public void update() { - if (workingEnabled && ioEnabled) { - transferFluids(); - } - } - - protected void transferFluids() { - IFluidHandler fluidHandler = getCoverableView().getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, - getAttachedSide()); - if (fluidHandler == null) return; - if (pumpMode == CoverPump.PumpMode.IMPORT) { - GTTransferUtils.transferFluids(fluidHandler, linkedTank, TRANSFER_RATE, fluidFilter::testFluidStack); - } else if (pumpMode == CoverPump.PumpMode.EXPORT) { - GTTransferUtils.transferFluids(linkedTank, fluidHandler, TRANSFER_RATE, fluidFilter::testFluidStack); - } - } - - public void setPumpMode(CoverPump.PumpMode pumpMode) { - this.pumpMode = pumpMode; - markDirty(); - } - - public CoverPump.PumpMode getPumpMode() { - return pumpMode; - } - - @Override - public void openUI(EntityPlayerMP player) { - CoverWithUI.super.openUI(player); - isColorTemp = false; - } - - @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup widgetGroup = new WidgetGroup(); - widgetGroup.addWidget(new LabelWidget(10, 5, "cover.ender_fluid_link.title")); - widgetGroup.addWidget(new ToggleButtonWidget(12, 18, 18, 18, GuiTextures.BUTTON_PUBLIC_PRIVATE, - this::isPrivate, this::setPrivate) - .setTooltipText("cover.ender_fluid_link.private.tooltip")); - widgetGroup.addWidget(new SyncableColorRectWidget(35, 18, 18, 18, () -> color) - .setBorderWidth(1) - .drawCheckerboard(4, 4)); - widgetGroup.addWidget(new TextFieldWidget(58, 13, 58, 18, true, - this::getColorStr, this::updateColor, 8) - .setValidator(str -> COLOR_INPUT_PATTERN.matcher(str).matches())); - widgetGroup.addWidget(new TankWidget(this.linkedTank, 123, 18, 18, 18) - .setContainerClicking(true, true) - .setBackgroundTexture(GuiTextures.FLUID_SLOT).setAlwaysShowFull(true)); - widgetGroup.addWidget(new ImageWidget(147, 19, 16, 16) - .setImage(GuiTextures.INFO_ICON) - .setPredicate(() -> isColorTemp) - .setTooltip("cover.ender_fluid_link.incomplete_hex") - .setIgnoreColor(true)); - widgetGroup.addWidget(new CycleButtonWidget(10, 42, 75, 18, - CoverPump.PumpMode.class, this::getPumpMode, this::setPumpMode)); - widgetGroup.addWidget(new CycleButtonWidget(92, 42, 75, 18, - this::isIoEnabled, this::setIoEnabled, "cover.ender_fluid_link.iomode.disabled", - "cover.ender_fluid_link.iomode.enabled")); - this.fluidFilter.initUI(65, widgetGroup::addWidget); - return ModularUI.builder(GuiTextures.BACKGROUND, 176, 221) - .widget(widgetGroup) - .bindPlayerInventory(player.inventory, 139) - .build(this, player); - } - - public void updateColor(String str) { - if (str.length() == 8) { - isColorTemp = false; - // stupid java not having actual unsigned ints - long tmp = Long.parseLong(str, 16); - if (tmp > 0x7FFFFFFF) { - tmp -= 0x100000000L; - } - this.color = (int) tmp; - updateTankLink(); - } else { - tempColorStr = str; - isColorTemp = true; - } - } - - public String getColorStr() { - return isColorTemp ? tempColorStr : Integer.toHexString(this.color).toUpperCase(); - } - - public void updateTankLink() { - this.linkedTank.changeTank(VirtualTankRegistry.getTankCreate(makeTankName(), getTankUUID())); - markDirty(); - } - - @Override - public void writeToNBT(NBTTagCompound tagCompound) { - super.writeToNBT(tagCompound); - tagCompound.setInteger("Frequency", color); - tagCompound.setInteger("PumpMode", pumpMode.ordinal()); - tagCompound.setBoolean("WorkingAllowed", workingEnabled); - tagCompound.setBoolean("IOAllowed", ioEnabled); - tagCompound.setBoolean("Private", isPrivate); - tagCompound.setString("PlacedUUID", playerUUID.toString()); - tagCompound.setTag("Filter", fluidFilter.serializeNBT()); - } - - @Override - public void readFromNBT(NBTTagCompound tagCompound) { - super.readFromNBT(tagCompound); - this.color = tagCompound.getInteger("Frequency"); - this.pumpMode = CoverPump.PumpMode.values()[tagCompound.getInteger("PumpMode")]; - this.workingEnabled = tagCompound.getBoolean("WorkingAllowed"); - this.ioEnabled = tagCompound.getBoolean("IOAllowed"); - this.isPrivate = tagCompound.getBoolean("Private"); - this.playerUUID = UUID.fromString(tagCompound.getString("PlacedUUID")); - this.fluidFilter.deserializeNBT(tagCompound.getCompoundTag("Filter")); - updateTankLink(); - } - - @Override - public void writeInitialSyncData(PacketBuffer packetBuffer) { - packetBuffer.writeInt(this.color); - packetBuffer.writeString(this.playerUUID == null ? "null" : this.playerUUID.toString()); - } - - @Override - public void readInitialSyncData(PacketBuffer packetBuffer) { - this.color = packetBuffer.readInt(); - // does client even need uuid info? just in case - String uuidStr = packetBuffer.readString(36); - this.playerUUID = uuidStr.equals("null") ? null : UUID.fromString(uuidStr); - // client does not need the actual tank reference, the default one will do just fine - } - - @Override - public boolean isWorkingEnabled() { - return workingEnabled; - } - - @Override - public void setWorkingEnabled(boolean isActivationAllowed) { - this.workingEnabled = isActivationAllowed; - } - - public T getCapability(Capability capability, T defaultValue) { - if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) { - return CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY.cast(linkedTank); - } - if (capability == GregtechTileCapabilities.CAPABILITY_CONTROLLABLE) { - return GregtechTileCapabilities.CAPABILITY_CONTROLLABLE.cast(this); - } - return defaultValue; - } - - private boolean isIoEnabled() { - return ioEnabled; - } - - private void setIoEnabled(boolean ioEnabled) { - this.ioEnabled = ioEnabled; - } - - private boolean isPrivate() { - return isPrivate; - } - - private void setPrivate(boolean isPrivate) { - this.isPrivate = isPrivate; - updateTankLink(); - } -} diff --git a/src/main/java/gregtech/common/covers/CoverFluidFilter.java b/src/main/java/gregtech/common/covers/CoverFluidFilter.java index cd5d06ee5a4..a103076e938 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidFilter.java +++ b/src/main/java/gregtech/common/covers/CoverFluidFilter.java @@ -5,19 +5,19 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverWithUI; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.CycleButtonWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.WidgetGroup; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; -import gregtech.common.covers.filter.FluidFilter; -import gregtech.common.covers.filter.FluidFilterWrapper; +import gregtech.common.covers.filter.BaseFilter; +import gregtech.common.covers.filter.BaseFilterContainer; +import gregtech.common.covers.filter.FluidFilterContainer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; @@ -32,26 +32,34 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.drawable.Rectangle; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.layout.Column; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.IOException; + public class CoverFluidFilter extends CoverBase implements CoverWithUI { protected final String titleLocale; protected final SimpleOverlayRenderer texture; - protected final FluidFilterWrapper fluidFilter; + protected final FluidFilterContainer fluidFilterContainer; protected FluidFilterMode filterMode; protected FluidHandlerFiltered fluidHandler; public CoverFluidFilter(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, - @NotNull EnumFacing attachedSide, String titleLocale, SimpleOverlayRenderer texture, - FluidFilter fluidFilter) { + @NotNull EnumFacing attachedSide, String titleLocale, SimpleOverlayRenderer texture) { super(definition, coverableView, attachedSide); + this.fluidFilterContainer = new FluidFilterContainer(this); this.filterMode = FluidFilterMode.FILTER_FILL; this.titleLocale = titleLocale; this.texture = texture; - this.fluidFilter = new FluidFilterWrapper(this); - this.fluidFilter.setFluidFilter(fluidFilter); } public void setFilterMode(FluidFilterMode filterMode) { @@ -59,16 +67,52 @@ public void setFilterMode(FluidFilterMode filterMode) { this.getCoverableView().markDirty(); } + @Override + public void onAttachment(@NotNull CoverableView coverableView, @NotNull EnumFacing side, + @Nullable EntityPlayer player, @NotNull ItemStack itemStack) { + super.onAttachment(coverableView, side, player, itemStack); + var dropStack = GTUtility.copy(1, itemStack); + this.fluidFilterContainer.setFilterStack(dropStack); + } + + @Override + public @NotNull ItemStack getPickItem() { + return this.fluidFilterContainer.getFilterStack(); + } + + @Override + public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { + packetBuffer.writeByte(this.filterMode.ordinal()); + packetBuffer.writeBoolean(this.fluidFilterContainer.hasFilter()); + if (this.fluidFilterContainer.hasFilter()) { + packetBuffer.writeItemStack(this.fluidFilterContainer.getFilterStack()); + } + } + + @Override + public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { + this.filterMode = FluidFilterMode.VALUES[packetBuffer.readByte()]; + if (!packetBuffer.readBoolean()) return; + try { + this.fluidFilterContainer.setFilterStack(packetBuffer.readItemStack()); + } catch (IOException e) { + GTLog.logger.error("Failed to read filter for CoverFluidFilter! %s", getPos().toString()); + } + } + public FluidFilterMode getFilterMode() { return filterMode; } - public FluidFilterWrapper getFluidFilter() { - return this.fluidFilter; + public @NotNull BaseFilter getFilter() { + var filter = getFilterContainer().getFilter(); + if (filter == null) return BaseFilter.ERROR_FILTER; + + return filter; } - public boolean testFluidStack(FluidStack stack) { - return fluidFilter.testFluidStack(stack); + public @NotNull BaseFilterContainer getFilterContainer() { + return this.fluidFilterContainer; } @Override @@ -89,18 +133,31 @@ public boolean canPipePassThrough() { return EnumActionResult.SUCCESS; } - public ModularUI createUI(EntityPlayer player) { - WidgetGroup fluidFilterGroup = new WidgetGroup(); - fluidFilterGroup.addWidget(new LabelWidget(10, 5, "cover.fluid_filter.title")); - fluidFilterGroup.addWidget(new CycleButtonWidget(10, 20, 110, 20, - GTUtility.mapToString(FluidFilterMode.values(), (it) -> it.localeName), () -> this.filterMode.ordinal(), - (newMode) -> this.setFilterMode(FluidFilterMode.values()[newMode]))); - this.fluidFilter.initUI(45, fluidFilterGroup::addWidget); - this.fluidFilter.blacklistUI(45, fluidFilterGroup::addWidget, () -> true); - return ModularUI.builder(GuiTextures.BACKGROUND, 176, 105 + 82) - .widget(fluidFilterGroup) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 105) - .build(this, player); + @Override + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager) { + var filteringMode = new EnumSyncValue<>(FluidFilterMode.class, this::getFilterMode, this::setFilterMode); + + guiSyncManager.syncValue("filtering_mode", filteringMode); + this.fluidFilterContainer.setMaxTransferSize(1); + + return getFilter().createPanel(guiSyncManager) + .size(176, 194).padding(7) + .child(CoverWithUI.createTitleRow(getFilterContainer().getFilterStack())) + .child(new Column().widthRel(1f).align(Alignment.TopLeft).top(22).coverChildrenHeight() + .child(new EnumRowBuilder<>(FluidFilterMode.class) + .value(filteringMode) + .lang("cover.filter.mode.title") + .overlay(16, GTGuiTextures.FILTER_MODE_OVERLAY) + .build()) + .child(new Rectangle().setColor(UI_TEXT_COLOR).asWidget() + .height(1).widthRel(0.95f).margin(0, 4)) + .child(getFilter().createWidgets(guiSyncManager))) + .child(SlotGroupWidget.playerInventory().bottom(7).left(7)); } @Override @@ -127,18 +184,20 @@ public T getCapability(@NotNull Capability capability, @Nullable T defaul public void writeToNBT(@NotNull NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); tagCompound.setInteger("FilterMode", this.filterMode.ordinal()); - tagCompound.setBoolean("IsBlacklist", this.fluidFilter.isBlacklistFilter()); - NBTTagCompound filterComponent = new NBTTagCompound(); - this.fluidFilter.getFluidFilter().writeToNBT(filterComponent); - tagCompound.setTag("Filter", filterComponent); + tagCompound.setTag("Filter", this.fluidFilterContainer.serializeNBT()); } @Override public void readFromNBT(@NotNull NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); this.filterMode = FluidFilterMode.values()[tagCompound.getInteger("FilterMode")]; - this.fluidFilter.setBlacklistFilter(tagCompound.getBoolean("IsBlacklist")); - this.fluidFilter.getFluidFilter().readFromNBT(tagCompound.getCompoundTag("Filter")); + if (tagCompound.hasKey("IsBlacklist")) { + this.fluidFilterContainer.setFilterStack(getDefinition().getDropItemStack()); + this.fluidFilterContainer.handleLegacyNBT(tagCompound); + this.fluidFilterContainer.setBlacklistFilter(tagCompound.getBoolean("IsBlacklist")); + } else { + this.fluidFilterContainer.deserializeNBT(tagCompound.getCompoundTag("Filter")); + } } private class FluidHandlerFiltered extends FluidHandlerDelegate { @@ -148,7 +207,7 @@ public FluidHandlerFiltered(@NotNull IFluidHandler delegate) { } public int fill(FluidStack resource, boolean doFill) { - if (getFilterMode() == FluidFilterMode.FILTER_DRAIN || !fluidFilter.testFluidStack(resource)) { + if (getFilterMode() == FluidFilterMode.FILTER_DRAIN || !fluidFilterContainer.test(resource)) { return 0; } return super.fill(resource, doFill); @@ -156,7 +215,7 @@ public int fill(FluidStack resource, boolean doFill) { @Nullable public FluidStack drain(FluidStack resource, boolean doDrain) { - if (getFilterMode() == FluidFilterMode.FILTER_FILL || !fluidFilter.testFluidStack(resource)) { + if (getFilterMode() == FluidFilterMode.FILTER_FILL || !fluidFilterContainer.test(resource)) { return null; } return super.drain(resource, doDrain); @@ -166,7 +225,7 @@ public FluidStack drain(FluidStack resource, boolean doDrain) { public FluidStack drain(int maxDrain, boolean doDrain) { if (getFilterMode() != FluidFilterMode.FILTER_FILL) { FluidStack result = super.drain(maxDrain, false); - if (result == null || result.amount <= 0 || !fluidFilter.testFluidStack(result)) { + if (result == null || result.amount <= 0 || !fluidFilterContainer.test(result)) { return null; } return doDrain ? super.drain(maxDrain, true) : result; diff --git a/src/main/java/gregtech/common/covers/CoverFluidRegulator.java b/src/main/java/gregtech/common/covers/CoverFluidRegulator.java index 553f2734b46..27122cdfa7a 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidRegulator.java +++ b/src/main/java/gregtech/common/covers/CoverFluidRegulator.java @@ -2,38 +2,37 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.*; +import gregtech.api.mui.GTGuiTextures; import gregtech.api.util.GTTransferUtils; -import gregtech.api.util.TextFormattingUtil; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleSidedCubeRenderer; -import gregtech.common.covers.filter.FluidFilter; import gregtech.common.covers.filter.FluidFilterContainer; +import gregtech.common.covers.filter.SimpleFluidFilter; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TextComponentString; -import net.minecraft.util.text.TextComponentTranslation; -import net.minecraft.util.text.event.HoverEvent; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidTankProperties; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import com.google.common.math.IntMath; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.apache.logging.log4j.message.FormattedMessage; import org.jetbrains.annotations.NotNull; import java.util.Arrays; -import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Predicate; @@ -41,21 +40,11 @@ public class CoverFluidRegulator extends CoverPump { protected TransferMode transferMode = TransferMode.TRANSFER_ANY; - protected int transferAmount = 0; public CoverFluidRegulator(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, @NotNull EnumFacing attachedSide, int tier, int mbPerTick) { super(definition, coverableView, attachedSide, tier, mbPerTick); - this.fluidFilter = new FluidFilterContainer(this, this::shouldShowTip, maxFluidTransferRate * 100); - } - - @Override - protected boolean shouldShowTip() { - return transferMode != TransferMode.TRANSFER_ANY; - } - - public int getTransferAmount() { - return transferAmount; + this.fluidFilterContainer = new FluidFilterContainer(this); } @Override @@ -75,11 +64,12 @@ protected int doTransferFluidsInternal(IFluidHandler myFluidHandler, IFluidHandl } return switch (transferMode) { case TRANSFER_ANY -> GTTransferUtils.transferFluids(sourceHandler, destHandler, transferLimit, - fluidFilter::testFluidStack); - case KEEP_EXACT -> doKeepExact(transferLimit, sourceHandler, destHandler, fluidFilter::testFluidStack, - this.transferAmount); + fluidFilterContainer::test); + case KEEP_EXACT -> doKeepExact(transferLimit, sourceHandler, destHandler, + fluidFilterContainer::test, + this.fluidFilterContainer.getTransferSize()); case TRANSFER_EXACT -> doTransferExact(transferLimit, sourceHandler, destHandler, - fluidFilter::testFluidStack, this.transferAmount); + fluidFilterContainer::test, this.fluidFilterContainer.getTransferSize()); }; } @@ -88,9 +78,8 @@ protected int doTransferExact(int transferLimit, IFluidHandler sourceHandler, IF int fluidLeftToTransfer = transferLimit; for (IFluidTankProperties tankProperties : sourceHandler.getTankProperties()) { FluidStack sourceFluid = tankProperties.getContents(); - if (this.fluidFilter.getFilterWrapper().getFluidFilter() != null && - transferMode != TransferMode.TRANSFER_ANY) { - supplyAmount = this.fluidFilter.getFilterWrapper().getFluidFilter().getFluidTransferLimit(sourceFluid); + if (this.fluidFilterContainer.hasFilter()) { + supplyAmount = this.fluidFilterContainer.getFilter().getTransferLimit(sourceFluid, supplyAmount); } if (fluidLeftToTransfer < supplyAmount) break; @@ -132,9 +121,8 @@ protected int doKeepExact(final int transferLimit, if (transferred >= transferLimit) break; - if (this.fluidFilter.getFilterWrapper().getFluidFilter() != null && - transferMode != TransferMode.TRANSFER_ANY) { - keepAmount = this.fluidFilter.getFilterWrapper().getFluidFilter().getFluidTransferLimit(fluidStack); + if (this.fluidFilterContainer.hasFilter()) { + keepAmount = this.fluidFilterContainer.getFilter().getTransferLimit(fluidStack, keepAmount); } // if fluid needs to be moved to meet the Keep Exact value @@ -235,8 +223,11 @@ private static Map collectDistinctFluids(IFluidHandler hand } public void setTransferMode(TransferMode transferMode) { - this.transferMode = transferMode; - this.markDirty(); + if (this.transferMode != transferMode) { + this.transferMode = transferMode; + this.fluidFilterContainer.setMaxTransferSize(getMaxTransferRate()); + this.markDirty(); + } } public TransferMode getTransferMode() { @@ -244,122 +235,87 @@ public TransferMode getTransferMode() { } private boolean shouldDisplayAmountSlider() { - if (this.fluidFilter.getFilterWrapper().getFluidFilter() != null) { + if (transferMode == TransferMode.TRANSFER_ANY) { return false; } - return this.transferMode == TransferMode.TRANSFER_EXACT || this.transferMode == TransferMode.KEEP_EXACT; - } - - public String getTransferAmountString() { - return Integer.toString(this.bucketMode == BucketMode.BUCKET ? transferAmount / 1000 : transferAmount); - } - - private String getTransferSizeString() { - int val = transferAmount; - if (this.bucketMode == BucketMode.BUCKET) { - val /= 1000; - } - return val == -1 ? "" : TextFormattingUtil.formatLongToCompactString(val); - } - - protected void getHoverString(List textList) { - ITextComponent keepComponent = new TextComponentString(getTransferSizeString()); - TextComponentTranslation hoverKeep = new TextComponentTranslation( - "cover.fluid_regulator." + transferMode.name().toLowerCase(), this.transferAmount); - keepComponent.getStyle().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hoverKeep)); - textList.add(keepComponent); + return fluidFilterContainer.showGlobalTransferLimitSlider(); } @Override - public void setBucketMode(BucketMode bucketMode) { - super.setBucketMode(bucketMode); - if (this.bucketMode == BucketMode.BUCKET) { - setTransferAmount(transferAmount / 1000 * 1000); - } + public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager) { + return super.buildUI(guiData, guiSyncManager).height(192 + 36); } - private void adjustTransferSize(int amount) { - if (bucketMode == BucketMode.BUCKET) - amount *= 1000; - switch (this.transferMode) { - case TRANSFER_EXACT -> setTransferAmount( - MathHelper.clamp(this.transferAmount + amount, 0, this.maxFluidTransferRate)); - case KEEP_EXACT -> setTransferAmount(MathHelper.clamp(this.transferAmount + amount, 0, Integer.MAX_VALUE)); - } + @Override + protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager syncManager) { + var transferMode = new EnumSyncValue<>(TransferMode.class, this::getTransferMode, this::setTransferMode); + transferMode.updateCacheFromSource(true); + syncManager.syncValue("transfer_mode", transferMode); + + var bucketMode = new EnumSyncValue<>(BucketMode.class, this::getBucketMode, this::setBucketMode); + bucketMode.updateCacheFromSource(true); + syncManager.syncValue("bucket_mode", bucketMode); + + var filterTransferSize = new StringSyncValue(this::getStringTransferRate, this::setStringTransferRate); + filterTransferSize.updateCacheFromSource(true); + + return super.createUI(mainPanel, syncManager) + .child(new EnumRowBuilder<>(TransferMode.class) + .value(transferMode) + .lang("cover.generic.transfer_mode") + .overlay(GTGuiTextures.FLUID_TRANSFER_MODE_OVERLAY) + .build()) + .child(new EnumRowBuilder<>(BucketMode.class) + .value(bucketMode) + .overlay(IKey.str("kL"), IKey.str("L")) + .build() + .child(new TextFieldWidget().widthRel(0.5f).right(0) + .setEnabledIf(w -> shouldDisplayAmountSlider()) + .setNumbers(0, Integer.MAX_VALUE) + .value(filterTransferSize) + .setTextColor(Color.WHITE.darker(1)))); } - private void setTransferAmount(int transferAmount) { - this.transferAmount = transferAmount; - markDirty(); + @Override + public int getMaxTransferRate() { + return switch (this.transferMode) { + case TRANSFER_ANY -> 1; + case TRANSFER_EXACT -> maxFluidTransferRate; + case KEEP_EXACT -> Integer.MAX_VALUE; + }; } @Override - protected String getUITitle() { - return "cover.fluid_regulator.title"; + public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.writeInitialSyncData(packetBuffer); + packetBuffer.writeByte(this.transferMode.ordinal()); } - @SuppressWarnings("UnstableApiUsage") @Override - protected ModularUI buildUI(ModularUI.Builder builder, EntityPlayer player) { - WidgetGroup filterGroup = new WidgetGroup(); - filterGroup.addWidget(new CycleButtonWidget(92, 43, 75, 18, - TransferMode.class, this::getTransferMode, this::setTransferMode) - .setTooltipHoverString("cover.fluid_regulator.transfer_mode.description")); - - ServerWidgetGroup stackSizeGroup = new ServerWidgetGroup(this::shouldDisplayAmountSlider); - stackSizeGroup.addWidget(new ImageWidget(110, 64, 38, 18, GuiTextures.DISPLAY)); - - stackSizeGroup.addWidget(new IncrementButtonWidget(148, 64, 18, 18, 1, 10, 100, 1000, this::adjustTransferSize) - .setDefaultTooltip() - .setTextScale(0.7f) - .setShouldClientCallback(false)); - stackSizeGroup - .addWidget(new IncrementButtonWidget(92, 64, 18, 18, -1, -10, -100, -1000, this::adjustTransferSize) - .setDefaultTooltip() - .setTextScale(0.7f) - .setShouldClientCallback(false)); - - stackSizeGroup.addWidget(new TextFieldWidget2(111, 70, 36, 11, this::getTransferAmountString, val -> { - if (val != null && !val.isEmpty()) { - int amount = Integer.parseInt(val); - if (this.bucketMode == BucketMode.BUCKET) { - amount = IntMath.saturatedMultiply(amount, 1000); - } - setTransferAmount(amount); - } - }) - .setCentered(true) - .setNumbersOnly(1, - transferMode == TransferMode.TRANSFER_EXACT ? maxFluidTransferRate : Integer.MAX_VALUE) - .setMaxLength(10) - .setScale(0.6f)); - - stackSizeGroup - .addWidget(new SimpleTextWidget(129, 78, "", 0xFFFFFF, () -> bucketMode.localeName).setScale(0.6f)); - - return super.buildUI(builder.widget(filterGroup).widget(stackSizeGroup), player); + public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.readInitialSyncData(packetBuffer); + this.transferMode = TransferMode.VALUES[packetBuffer.readByte()]; } @Override public void writeToNBT(@NotNull NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); tagCompound.setInteger("TransferMode", transferMode.ordinal()); - tagCompound.setInteger("TransferAmount", transferAmount); tagCompound.setTag("filterv2", new NBTTagCompound()); } @Override public void readFromNBT(@NotNull NBTTagCompound tagCompound) { + this.transferMode = TransferMode.VALUES[tagCompound.getInteger("TransferMode")]; + this.fluidFilterContainer.setMaxTransferSize(this.transferMode.maxStackSize); super.readFromNBT(tagCompound); - this.transferMode = TransferMode.values()[tagCompound.getInteger("TransferMode")]; // legacy NBT tag if (!tagCompound.hasKey("filterv2") && tagCompound.hasKey("TransferAmount")) { - FluidFilter filter = getFluidFilterContainer().getFilterWrapper().getFluidFilter(); - if (filter != null) { - filter.configureFilterTanks(tagCompound.getInteger("TransferAmount")); + if (this.fluidFilterContainer.getFilter() instanceof SimpleFluidFilter simpleFluidFilter) { + simpleFluidFilter + .configureFilterTanks(tagCompound.getInteger("TransferAmount")); } } - this.transferAmount = tagCompound.getInteger("TransferAmount"); } @Override diff --git a/src/main/java/gregtech/common/covers/CoverFluidVoiding.java b/src/main/java/gregtech/common/covers/CoverFluidVoiding.java index 4c1f097ccee..c6aa519660c 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidVoiding.java +++ b/src/main/java/gregtech/common/covers/CoverFluidVoiding.java @@ -3,11 +3,6 @@ import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.CycleButtonWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.WidgetGroup; import gregtech.api.util.GTTransferUtils; import gregtech.client.renderer.texture.Textures; import gregtech.common.covers.filter.FluidFilterContainer; @@ -29,6 +24,15 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.layout.Row; import org.jetbrains.annotations.NotNull; public class CoverFluidVoiding extends CoverPump { @@ -39,7 +43,8 @@ public CoverFluidVoiding(@NotNull CoverDefinition definition, @NotNull Coverable @NotNull EnumFacing attachedSide) { super(definition, coverableView, attachedSide, 0, Integer.MAX_VALUE); this.isWorkingAllowed = false; - this.fluidFilter = new FluidFilterContainer(this, this::shouldShowTip, Integer.MAX_VALUE); + this.fluidFilterContainer = new FluidFilterContainer(this); + this.fluidFilterContainer.setMaxTransferSize(Integer.MAX_VALUE); } @Override @@ -55,39 +60,46 @@ protected void doTransferFluids() { if (myFluidHandler == null) { return; } - GTTransferUtils.transferFluids(myFluidHandler, nullFluidTank, Integer.MAX_VALUE, fluidFilter::testFluidStack); + GTTransferUtils.transferFluids(myFluidHandler, nullFluidTank, Integer.MAX_VALUE, + fluidFilterContainer::test); } @Override - protected String getUITitle() { - return "cover.fluid.voiding.title"; + public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 translation, + IVertexOperation[] pipeline, @NotNull Cuboid6 plateBox, @NotNull BlockRenderLayer layer) { + Textures.FLUID_VOIDING.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup primaryGroup = new WidgetGroup(); - primaryGroup.addWidget(new LabelWidget(10, 5, getUITitle())); - - this.fluidFilter.initUI(20, primaryGroup::addWidget); - - primaryGroup.addWidget(new CycleButtonWidget(10, 92, 80, 18, this::isWorkingEnabled, this::setWorkingEnabled, - "cover.voiding.label.disabled", "cover.voiding.label.enabled") - .setTooltipHoverString("cover.voiding.tooltip")); + public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager) { + return super.buildUI(guiData, guiSyncManager).height(192 - 22); + } - primaryGroup.addWidget(new CycleButtonWidget(10, 112, 116, 18, - ManualImportExportMode.class, this::getManualImportExportMode, this::setManualImportExportMode) - .setTooltipHoverString("cover.universal.manual_import_export.mode.description")); + @Override + protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager syncManager) { + var isWorking = new BooleanSyncValue(this::isWorkingEnabled, this::setWorkingEnabled); + + return super.createUI(mainPanel, syncManager) + .child(new Row().height(18).widthRel(1f) + .marginBottom(2) + .child(new ToggleButton() + .value(isWorking) + .overlay(IKey.dynamic(() -> IKey.lang(this.isWorkingAllowed ? + "behaviour.soft_hammer.enabled" : + "behaviour.soft_hammer.disabled").get()) + .color(Color.WHITE.darker(1))) + .widthRel(0.6f) + .left(0))); + } - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, 100 + 82 + 16 + 24) - .widget(primaryGroup) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 100 + 16 + 24); - return builder.build(this, player); + @Override + protected boolean createPumpModeRow() { + return false; } @Override - public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 translation, - IVertexOperation[] pipeline, @NotNull Cuboid6 plateBox, @NotNull BlockRenderLayer layer) { - Textures.FLUID_VOIDING.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); + protected boolean createThroughputRow() { + return false; } @Override @@ -120,7 +132,7 @@ public NullFluidTank() { @Override public int fill(FluidStack resource, boolean doFill) { - if (fluidFilter.testFluidStack(resource)) { + if (fluidFilterContainer.test(resource)) { return resource.amount; } return 0; diff --git a/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java b/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java index 4d2290aa13b..80b7bb45564 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java +++ b/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java @@ -2,18 +2,14 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.*; +import gregtech.api.mui.GTGuiTextures; import gregtech.api.util.GTTransferUtils; import gregtech.client.renderer.texture.Textures; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.MathHelper; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; @@ -23,9 +19,17 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; -import java.util.function.Consumer; import java.util.function.Predicate; public class CoverFluidVoidingAdvanced extends CoverFluidVoiding { @@ -38,11 +42,6 @@ public CoverFluidVoidingAdvanced(@NotNull CoverDefinition definition, @NotNull C super(definition, coverableView, attachedSide); } - @Override - protected boolean shouldShowTip() { - return voidingMode != VoidingMode.VOID_ANY; - } - @Override protected void doTransferFluids() { IFluidHandler myFluidHandler = getCoverableView().getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, @@ -52,8 +51,9 @@ protected void doTransferFluids() { } switch (voidingMode) { case VOID_ANY -> GTTransferUtils.transferFluids(myFluidHandler, nullFluidTank, Integer.MAX_VALUE, - fluidFilter::testFluidStack); - case VOID_OVERFLOW -> voidOverflow(myFluidHandler, fluidFilter::testFluidStack, this.transferAmount); + fluidFilterContainer::test); + case VOID_OVERFLOW -> voidOverflow(myFluidHandler, fluidFilterContainer::test, + this.transferAmount); } } @@ -72,45 +72,26 @@ protected void voidOverflow(final IFluidHandler sourceHandler, for (IFluidTankProperties tankProperties : sourceHandler.getTankProperties()) { FluidStack sourceFluid = tankProperties.getContents(); - if (this.fluidFilter.getFilterWrapper().getFluidFilter() != null && + if (this.fluidFilterContainer.hasFilter() && voidingMode == VoidingMode.VOID_OVERFLOW) { - keepAmount = this.fluidFilter.getFilterWrapper().getFluidFilter().getFluidTransferLimit(sourceFluid); + keepAmount = this.fluidFilterContainer.getFilter() + .getTransferLimit(sourceFluid, getMaxTransferRate()); } if (sourceFluid == null || sourceFluid.amount == 0 || - !getFluidFilterContainer().testFluidStack(sourceFluid, true)) + !getFluidFilterContainer().test(sourceFluid)) continue; sourceFluid.amount = sourceFluid.amount - keepAmount; sourceHandler.drain(sourceFluid, true); } } - @Override - public void setBucketMode(BucketMode bucketMode) { - super.setBucketMode(bucketMode); - if (this.bucketMode == BucketMode.BUCKET) { - setTransferAmount(transferAmount / 1000 * 1000); - } - } - - private void adjustTransferSize(int amount) { - if (bucketMode == BucketMode.BUCKET) - amount *= 1000; - if (this.voidingMode == VoidingMode.VOID_OVERFLOW) { - setTransferAmount(MathHelper.clamp(this.transferAmount + amount, 0, Integer.MAX_VALUE)); - } - } - - private void setTransferAmount(int transferAmount) { - this.transferAmount = transferAmount; - markDirty(); - } - public int getTransferAmount() { - return this.transferAmount; + return this.fluidFilterContainer.getTransferSize(); } public void setVoidingMode(VoidingMode transferMode) { this.voidingMode = transferMode; + this.fluidFilterContainer.setMaxTransferSize(getMaxTransferRate()); this.markDirty(); } @@ -118,101 +99,64 @@ public VoidingMode getVoidingMode() { return voidingMode; } - private boolean shouldDisplayAmountSlider() { - if (this.fluidFilter.getFilterWrapper().getFluidFilter() != null) { - return false; - } - - return this.voidingMode == VoidingMode.VOID_OVERFLOW; + @Override + public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager) { + return super.buildUI(guiData, guiSyncManager).height(192 + 20); } - public String getTransferAmountString() { - return Integer.toString(this.bucketMode == BucketMode.BUCKET ? transferAmount / 1000 : transferAmount); + @Override + protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager syncManager) { + var voidingMode = new EnumSyncValue<>(VoidingMode.class, this::getVoidingMode, this::setVoidingMode); + syncManager.syncValue("voiding_mode", voidingMode); + + var bucketMode = new EnumSyncValue<>(BucketMode.class, this::getBucketMode, this::setBucketMode); + bucketMode.updateCacheFromSource(true); + syncManager.syncValue("bucket_mode", bucketMode); + + var filterTransferSize = new StringSyncValue(this::getStringTransferRate, this::setStringTransferRate); + var transferTextField = new TextFieldWidget().widthRel(0.5f).right(0); + transferTextField.setEnabled(this.fluidFilterContainer.showGlobalTransferLimitSlider() && + this.voidingMode == VoidingMode.VOID_OVERFLOW); + + return super.createUI(mainPanel, syncManager) + .child(new EnumRowBuilder<>(VoidingMode.class) + .value(voidingMode) + .lang("cover.voiding.voiding_mode") + .overlay(16, GTGuiTextures.VOIDING_MODE_OVERLAY) + .build()) + .child(new EnumRowBuilder<>(BucketMode.class) + .value(bucketMode) + .overlay(IKey.str("kL"), IKey.str("L")) + .build() + .child(transferTextField + .setEnabledIf(w -> this.fluidFilterContainer.showGlobalTransferLimitSlider() && + this.voidingMode == VoidingMode.VOID_OVERFLOW) + .setNumbers(0, Integer.MAX_VALUE) + .value(filterTransferSize) + .setTextColor(Color.WHITE.darker(1)))); } @Override - protected String getUITitle() { - return "cover.fluid.voiding.advanced.title"; + protected int getMaxTransferRate() { + return getVoidingMode().maxStackSize; } @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup primaryGroup = new WidgetGroup(); - primaryGroup.addWidget(new LabelWidget(10, 5, getUITitle())); - - primaryGroup.addWidget(new CycleButtonWidget(92, 15, 75, 18, - VoidingMode.class, this::getVoidingMode, this::setVoidingMode) - .setTooltipHoverString("cover.voiding.voiding_mode.description")); - - this.initFilterUI(20, primaryGroup::addWidget); - - primaryGroup.addWidget(new CycleButtonWidget(10, 92, 80, 18, this::isWorkingEnabled, this::setWorkingEnabled, - "cover.voiding.label.disabled", "cover.voiding.label.enabled") - .setTooltipHoverString("cover.voiding.tooltip")); - - primaryGroup.addWidget(new CycleButtonWidget(10, 112, 116, 18, - ManualImportExportMode.class, this::getManualImportExportMode, this::setManualImportExportMode) - .setTooltipHoverString("cover.universal.manual_import_export.mode.description")); - - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, 100 + 82 + 16 + 24) - .widget(primaryGroup) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 100 + 16 + 24); - return buildUI(builder, player); + public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 translation, + IVertexOperation[] pipeline, @NotNull Cuboid6 plateBox, @NotNull BlockRenderLayer layer) { + Textures.FLUID_VOIDING_ADVANCED.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } - public void initFilterUI(int y, Consumer widgetGroup) { - widgetGroup.accept(new LabelWidget(10, y, "cover.pump.fluid_filter.title")); - widgetGroup.accept(new SlotWidget(fluidFilter.getFilterInventory(), 0, 10, y + 15) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.FILTER_SLOT_OVERLAY)); - - ServerWidgetGroup stackSizeGroup = new ServerWidgetGroup(this::shouldDisplayAmountSlider); - stackSizeGroup.addWidget(new ImageWidget(110, 34, 38, 18, GuiTextures.DISPLAY)); - - stackSizeGroup.addWidget(new IncrementButtonWidget(148, 34, 18, 18, 1, 10, 100, 1000, this::adjustTransferSize) - .setDefaultTooltip() - .setTextScale(0.7f) - .setShouldClientCallback(false)); - stackSizeGroup - .addWidget(new IncrementButtonWidget(92, 34, 18, 18, -1, -10, -100, -1000, this::adjustTransferSize) - .setDefaultTooltip() - .setTextScale(0.7f) - .setShouldClientCallback(false)); - - stackSizeGroup.addWidget(new TextFieldWidget2(111, 39, 37, 11, this::getTransferAmountString, val -> { - if (val != null && !val.isEmpty()) { - int amount = Integer.parseInt(val); - if (this.bucketMode == BucketMode.BUCKET) { - amount *= 1000; - } - setTransferAmount(amount); - } - }) - .setCentered(true) - .setNumbersOnly(1, Integer.MAX_VALUE) - .setMaxLength(10) - .setScale(0.6f)); - - stackSizeGroup - .addWidget(new SimpleTextWidget(129, 47, "", 0xFFFFFF, () -> bucketMode.localeName).setScale(0.6f)); - - stackSizeGroup.addWidget(new CycleButtonWidget(114, 53, 30, 20, - BucketMode.class, this::getBucketMode, mode -> { - if (mode != bucketMode) { - setBucketMode(mode); - } - })); - - widgetGroup.accept(stackSizeGroup); - - this.fluidFilter.getFilterWrapper().initUI(y + 15, widgetGroup); - this.fluidFilter.getFilterWrapper().blacklistUI(y + 15, widgetGroup, - () -> voidingMode != VoidingMode.VOID_OVERFLOW); + @Override + public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.readInitialSyncData(packetBuffer); + this.voidingMode = VoidingMode.VALUES[packetBuffer.readByte()]; } @Override - public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 translation, - IVertexOperation[] pipeline, @NotNull Cuboid6 plateBox, @NotNull BlockRenderLayer layer) { - Textures.FLUID_VOIDING_ADVANCED.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); + public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.writeInitialSyncData(packetBuffer); + packetBuffer.writeByte(this.voidingMode.ordinal()); } @Override @@ -224,8 +168,9 @@ public void writeToNBT(@NotNull NBTTagCompound tagCompound) { @Override public void readFromNBT(@NotNull NBTTagCompound tagCompound) { - super.readFromNBT(tagCompound); - this.voidingMode = VoidingMode.values()[tagCompound.getInteger("VoidingMode")]; + this.voidingMode = VoidingMode.VALUES[tagCompound.getInteger("VoidingMode")]; + this.fluidFilterContainer.setMaxTransferSize(this.voidingMode.maxStackSize); this.transferAmount = tagCompound.getInteger("TransferAmount"); + super.readFromNBT(tagCompound); } } diff --git a/src/main/java/gregtech/common/covers/CoverItemFilter.java b/src/main/java/gregtech/common/covers/CoverItemFilter.java index 656fe17f5d8..043729ad075 100644 --- a/src/main/java/gregtech/common/covers/CoverItemFilter.java +++ b/src/main/java/gregtech/common/covers/CoverItemFilter.java @@ -5,20 +5,19 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverWithUI; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.CycleButtonWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.WidgetGroup; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; -import gregtech.common.covers.filter.ItemFilter; -import gregtech.common.covers.filter.ItemFilterWrapper; +import gregtech.common.covers.filter.BaseFilter; +import gregtech.common.covers.filter.BaseFilterContainer; +import gregtech.common.covers.filter.ItemFilterContainer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; @@ -32,25 +31,66 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.drawable.Rectangle; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.layout.Column; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; public class CoverItemFilter extends CoverBase implements CoverWithUI { protected final String titleLocale; protected final SimpleOverlayRenderer texture; - protected final ItemFilterWrapper itemFilter; + protected final ItemFilterContainer itemFilterContainer; protected ItemFilterMode filterMode = ItemFilterMode.FILTER_INSERT; protected ItemHandlerFiltered itemHandler; public CoverItemFilter(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, - @NotNull EnumFacing attachedSide, String titleLocale, SimpleOverlayRenderer texture, - ItemFilter itemFilter) { + @NotNull EnumFacing attachedSide, String titleLocale, SimpleOverlayRenderer texture) { super(definition, coverableView, attachedSide); this.titleLocale = titleLocale; this.texture = texture; - this.itemFilter = new ItemFilterWrapper(this); - this.itemFilter.setItemFilter(itemFilter); - this.itemFilter.setMaxStackSize(1); + this.itemFilterContainer = new ItemFilterContainer(this); + } + + @Override + public void onAttachment(@NotNull CoverableView coverableView, @NotNull EnumFacing side, + @Nullable EntityPlayer player, @NotNull ItemStack itemStack) { + super.onAttachment(coverableView, side, player, itemStack); + var dropStack = GTUtility.copy(1, itemStack); + this.itemFilterContainer.setFilterStack(dropStack); + } + + @Override + public @NotNull ItemStack getPickItem() { + return this.itemFilterContainer.getFilterStack(); + } + + @Override + public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { + packetBuffer.writeBoolean(itemFilterContainer.hasFilter()); + if (itemFilterContainer.hasFilter()) { + packetBuffer.writeByte(this.filterMode.ordinal()); + packetBuffer.writeItemStack(this.itemFilterContainer.getFilterStack()); + } + } + + @Override + public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { + if (!packetBuffer.readBoolean()) return; + this.filterMode = ItemFilterMode.VALUES[packetBuffer.readByte()]; + try { + this.itemFilterContainer.setFilterStack(packetBuffer.readItemStack()); + } catch (IOException e) { + GTLog.logger.error("Failed to read filter for CoverItemFilter! %s", getPos().toString()); + } } public void setFilterMode(ItemFilterMode filterMode) { @@ -62,8 +102,15 @@ public ItemFilterMode getFilterMode() { return filterMode; } - public ItemFilterWrapper getItemFilter() { - return this.itemFilter; + public @NotNull BaseFilter getFilter() { + var filter = getFilterContainer().getFilter(); + if (filter == null) return BaseFilter.ERROR_FILTER; + + return filter; + } + + public @NotNull BaseFilterContainer getFilterContainer() { + return this.itemFilterContainer; } @Override @@ -86,22 +133,33 @@ public boolean canPipePassThrough() { } public boolean testItemStack(ItemStack stack) { - return itemFilter.testItemStack(stack); + return itemFilterContainer.test(stack); } @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup filterGroup = new WidgetGroup(); - filterGroup.addWidget(new LabelWidget(10, 5, titleLocale)); - filterGroup.addWidget(new CycleButtonWidget(10, 20, 110, 20, - GTUtility.mapToString(ItemFilterMode.values(), it -> it.localeName), - () -> filterMode.ordinal(), (newMode) -> setFilterMode(ItemFilterMode.values()[newMode]))); - this.itemFilter.initUI(45, filterGroup::addWidget); - this.itemFilter.blacklistUI(45, filterGroup::addWidget, () -> true); - return ModularUI.builder(GuiTextures.BACKGROUND, 176, 105 + 82) - .widget(filterGroup) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 105) - .build(this, player); + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager) { + var filteringMode = new EnumSyncValue<>(ItemFilterMode.class, this::getFilterMode, this::setFilterMode); + + guiSyncManager.syncValue("filtering_mode", filteringMode); + + return getFilter().createPanel(guiSyncManager) + .size(176, 194).padding(7) + .child(CoverWithUI.createTitleRow(getFilterContainer().getFilterStack()).left(4)) + .child(new Column().widthRel(1f).align(Alignment.TopLeft).top(22).coverChildrenHeight() + .child(new EnumRowBuilder<>(ItemFilterMode.class) + .value(filteringMode) + .lang("cover.filter.mode.title") + .overlay(16, GTGuiTextures.FILTER_MODE_OVERLAY) + .build()) + .child(new Rectangle().setColor(UI_TEXT_COLOR).asWidget() + .height(1).widthRel(0.95f).margin(0, 4)) + .child(getFilter().createWidgets(guiSyncManager).left(0))) + .child(SlotGroupWidget.playerInventory().bottom(7).left(7)); } @Override @@ -114,18 +172,20 @@ public void renderCover(CCRenderState renderState, Matrix4 translation, IVertexO public void writeToNBT(@NotNull NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); tagCompound.setInteger("FilterMode", filterMode.ordinal()); - tagCompound.setBoolean("IsBlacklist", this.itemFilter.isBlacklistFilter()); - NBTTagCompound filterComponent = new NBTTagCompound(); - this.itemFilter.getItemFilter().writeToNBT(filterComponent); - tagCompound.setTag("Filter", filterComponent); + tagCompound.setTag("Filter", this.itemFilterContainer.serializeNBT()); } @Override public void readFromNBT(@NotNull NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); - this.filterMode = ItemFilterMode.values()[tagCompound.getInteger("FilterMode")]; - this.itemFilter.setBlacklistFilter(tagCompound.getBoolean("IsBlacklist")); - this.itemFilter.getItemFilter().readFromNBT(tagCompound.getCompoundTag("Filter")); + this.filterMode = ItemFilterMode.VALUES[tagCompound.getInteger("FilterMode")]; + if (tagCompound.hasKey("IsBlacklist")) { + this.itemFilterContainer.setFilterStack(getDefinition().getDropItemStack()); + this.itemFilterContainer.handleLegacyNBT(tagCompound); + this.itemFilterContainer.setBlacklistFilter(tagCompound.getBoolean("IsBlacklist")); + } else { + this.itemFilterContainer.deserializeNBT(tagCompound.getCompoundTag("Filter")); + } } @Override @@ -152,7 +212,7 @@ public ItemHandlerFiltered(IItemHandler delegate) { @NotNull @Override public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { - if (getFilterMode() == ItemFilterMode.FILTER_EXTRACT || !itemFilter.testItemStack(stack)) { + if (getFilterMode() == ItemFilterMode.FILTER_EXTRACT || !itemFilterContainer.test(stack)) { return stack; } return super.insertItem(slot, stack, simulate); @@ -163,7 +223,7 @@ public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate public ItemStack extractItem(int slot, int amount, boolean simulate) { if (getFilterMode() != ItemFilterMode.FILTER_INSERT) { ItemStack result = super.extractItem(slot, amount, true); - if (result.isEmpty() || !itemFilter.testItemStack(result)) { + if (result.isEmpty() || !itemFilterContainer.test(result)) { return ItemStack.EMPTY; } return simulate ? result : super.extractItem(slot, amount, false); diff --git a/src/main/java/gregtech/common/covers/CoverItemVoiding.java b/src/main/java/gregtech/common/covers/CoverItemVoiding.java index 9a515b670d3..35a64252725 100644 --- a/src/main/java/gregtech/common/covers/CoverItemVoiding.java +++ b/src/main/java/gregtech/common/covers/CoverItemVoiding.java @@ -3,11 +3,6 @@ import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.CycleButtonWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.WidgetGroup; import gregtech.client.renderer.texture.Textures; import net.minecraft.entity.player.EntityPlayer; @@ -26,6 +21,16 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; import org.jetbrains.annotations.NotNull; public class CoverItemVoiding extends CoverConveyor { @@ -60,7 +65,7 @@ void voidAny(IItemHandler myItemHandler) { if (sourceStack.isEmpty()) { continue; } - if (!itemFilterContainer.testItemStack(sourceStack)) { + if (!itemFilterContainer.test(sourceStack)) { continue; } myItemHandler.extractItem(srcIndex, Integer.MAX_VALUE, false); @@ -68,29 +73,40 @@ void voidAny(IItemHandler myItemHandler) { } @Override - protected String getUITitle() { - return "cover.item.voiding.title"; + public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager) { + return super.buildUI(guiData, guiSyncManager).height(192 - 22); } @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup primaryGroup = new WidgetGroup(); - primaryGroup.addWidget(new LabelWidget(10, 5, getUITitle())); - this.itemFilterContainer.initUI(20, primaryGroup::addWidget); - - primaryGroup - .addWidget(new CycleButtonWidget(10, 92 + 23, 80, 18, this::isWorkingEnabled, this::setWorkingEnabled, - "cover.voiding.label.disabled", "cover.voiding.label.enabled") - .setTooltipHoverString("cover.voiding.tooltip")); - - primaryGroup.addWidget(new CycleButtonWidget(10, 112 + 23, 116, 18, - ManualImportExportMode.class, this::getManualImportExportMode, this::setManualImportExportMode) - .setTooltipHoverString("cover.universal.manual_import_export.mode.description")); - - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, 125 + 82 + 16 + 24) - .widget(primaryGroup) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 125 + 16 + 24); - return builder.build(this, player); + protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager guiSyncManager) { + var isWorking = new BooleanSyncValue(this::isWorkingEnabled, this::setWorkingEnabled); + + return super.createUI(mainPanel, guiSyncManager) + .child(new Row().height(18).widthRel(1f) + .marginBottom(2) + .child(new ToggleButton() + .value(isWorking) + .overlay(IKey.dynamic(() -> IKey.lang(this.isWorkingAllowed ? + "behaviour.soft_hammer.enabled" : + "behaviour.soft_hammer.disabled").get()) + .color(Color.WHITE.darker(1))) + .widthRel(0.6f) + .left(0))); + } + + @Override + protected boolean createThroughputRow() { + return false; + } + + @Override + protected boolean createConveyorModeRow() { + return false; + } + + @Override + protected boolean createDistributionModeRow() { + return false; } @Override @@ -137,7 +153,7 @@ public ItemStack getStackInSlot(int slot) { @NotNull @Override public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { - if (!itemFilterContainer.testItemStack(stack)) { + if (!itemFilterContainer.test(stack)) { return stack; } return ItemStack.EMPTY; diff --git a/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java b/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java index 62d2844aaa3..4a062735ae3 100644 --- a/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java +++ b/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java @@ -2,18 +2,14 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.*; +import gregtech.api.mui.GTGuiTextures; import gregtech.client.renderer.texture.Textures; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.MathHelper; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; @@ -21,10 +17,19 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; import java.util.Map; -import java.util.function.Consumer; public class CoverItemVoidingAdvanced extends CoverItemVoiding { @@ -34,7 +39,7 @@ public CoverItemVoidingAdvanced(@NotNull CoverDefinition definition, @NotNull Co @NotNull EnumFacing attachedSide) { super(definition, coverableView, attachedSide); this.voidingMode = VoidingMode.VOID_ANY; - this.itemFilterContainer.setMaxStackSize(1); + this.itemFilterContainer.setMaxTransferSize(1); } @Override @@ -56,13 +61,11 @@ protected void voidOverflow(IItemHandler myItemHandler) { for (TypeItemInfo typeItemInfo : itemTypeCount.values()) { int itemToVoidAmount = 0; - if (getItemFilterContainer().getFilterWrapper().getItemFilter() == null) { - itemToVoidAmount = typeItemInfo.totalCount - itemFilterContainer.getTransferStackSize(); + if (!getItemFilterContainer().hasFilter()) { + itemToVoidAmount = typeItemInfo.totalCount - itemFilterContainer.getTransferSize(); } else { - if (itemFilterContainer.testItemStack(typeItemInfo.itemStack)) { - Object matchedSlot = itemFilterContainer.matchItemStack(typeItemInfo.itemStack); - itemToVoidAmount = typeItemInfo.totalCount - itemFilterContainer.getSlotTransferLimit(matchedSlot); - } + var result = itemFilterContainer.match(typeItemInfo.itemStack); + itemToVoidAmount = result.getItemStack().getCount(); } if (itemToVoidAmount <= 0) { @@ -86,75 +89,41 @@ protected void voidOverflow(IItemHandler myItemHandler) { } @Override - protected String getUITitle() { - return "cover.item.voiding.advanced.title"; + public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager) { + return super.buildUI(guiData, guiSyncManager).height(192 + 18); } @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup primaryGroup = new WidgetGroup(); - primaryGroup.addWidget(new LabelWidget(10, 5, getUITitle())); - - primaryGroup.addWidget(new CycleButtonWidget(91, 14, 75, 20, - VoidingMode.class, this::getVoidingMode, this::setVoidingMode) - .setTooltipHoverString("cover.voiding.voiding_mode.description")); - - this.initFilterUI(20, primaryGroup::addWidget); - - primaryGroup - .addWidget(new CycleButtonWidget(10, 92 + 23, 80, 18, this::isWorkingEnabled, this::setWorkingEnabled, - "cover.voiding.label.disabled", "cover.voiding.label.enabled") - .setTooltipHoverString("cover.voiding.tooltip")); - - primaryGroup.addWidget(new CycleButtonWidget(10, 112 + 23, 116, 18, - ManualImportExportMode.class, this::getManualImportExportMode, this::setManualImportExportMode) - .setTooltipHoverString("cover.universal.manual_import_export.mode.description")); - - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, 125 + 82 + 16 + 24) - .widget(primaryGroup) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 125 + 16 + 24); - return buildUI(builder, player); + protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager guiSyncManager) { + var voidingMode = new EnumSyncValue<>(VoidingMode.class, this::getVoidingMode, this::setVoidingMode); + guiSyncManager.syncValue("voiding_mode", voidingMode); + + var filterTransferSize = new StringSyncValue( + () -> String.valueOf(this.itemFilterContainer.getTransferSize()), + s -> this.itemFilterContainer.setTransferSize(Integer.parseInt(s))); + filterTransferSize.updateCacheFromSource(true); + var transferTextField = new TextFieldWidget().widthRel(0.5f).right(0); + transferTextField.setEnabled(this.itemFilterContainer.showGlobalTransferLimitSlider() && + this.voidingMode == VoidingMode.VOID_OVERFLOW); + + return super.createUI(mainPanel, guiSyncManager) + .child(new EnumRowBuilder<>(VoidingMode.class) + .value(voidingMode) + .lang("cover.voiding.voiding_mode") + .overlay(16, GTGuiTextures.VOIDING_MODE_OVERLAY) + .build()) + .child(new Row().right(0).coverChildrenHeight() + .child(transferTextField + .setEnabledIf(w -> this.itemFilterContainer.showGlobalTransferLimitSlider() && + this.voidingMode == VoidingMode.VOID_OVERFLOW) + .setNumbers(0, Integer.MAX_VALUE) + .value(filterTransferSize) + .setTextColor(Color.WHITE.darker(1)))); } - // Basically the item filter container GUI code, with different Y widget positioning - public void initFilterUI(int y, Consumer widgetGroup) { - widgetGroup.accept(new LabelWidget(10, y, "cover.conveyor.item_filter.title")); - widgetGroup.accept(new SlotWidget(itemFilterContainer.getFilterInventory(), 0, 10, y + 15) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.FILTER_SLOT_OVERLAY)); - - ServerWidgetGroup stackSizeGroup = new ServerWidgetGroup( - () -> itemFilterContainer.getFilterWrapper().getItemFilter() == null && - voidingMode == VoidingMode.VOID_OVERFLOW); - stackSizeGroup.addWidget(new ImageWidget(111, 34, 35, 20, GuiTextures.DISPLAY)); - - stackSizeGroup.addWidget( - new IncrementButtonWidget(146, 34, 20, 20, 1, 8, 64, 512, itemFilterContainer::adjustTransferStackSize) - .setDefaultTooltip() - .setTextScale(0.7f) - .setShouldClientCallback(false)); - stackSizeGroup.addWidget(new IncrementButtonWidget(91, 34, 20, 20, -1, -8, -64, -512, - itemFilterContainer::adjustTransferStackSize) - .setDefaultTooltip() - .setTextScale(0.7f) - .setShouldClientCallback(false)); - - stackSizeGroup.addWidget(new TextFieldWidget2(113, 41, 31, 20, - () -> String.valueOf(itemFilterContainer.getTransferStackSize()), val -> { - if (val != null && !val.isEmpty()) - itemFilterContainer.setTransferStackSize( - MathHelper.clamp(Integer.parseInt(val), 1, voidingMode.maxStackSize)); - }) - .setCentered(true) - .setNumbersOnly(1, Integer.MAX_VALUE) - .setMaxLength(10) - .setScale(0.9f)); - - widgetGroup.accept(stackSizeGroup); - - this.itemFilterContainer.getFilterWrapper().initUI(y + 38, widgetGroup); - - this.itemFilterContainer.getFilterWrapper().blacklistUI(y + 38, widgetGroup, - () -> voidingMode != VoidingMode.VOID_OVERFLOW); + @Override + protected int getMaxStackSize() { + return getVoidingMode().maxStackSize; } @Override @@ -165,7 +134,7 @@ public void renderCover(CCRenderState renderState, Matrix4 translation, IVertexO public void setVoidingMode(VoidingMode voidingMode) { this.voidingMode = voidingMode; - this.itemFilterContainer.setMaxStackSize(voidingMode.maxStackSize); + this.itemFilterContainer.setMaxTransferSize(getMaxStackSize()); this.getCoverableView().markDirty(); } @@ -173,6 +142,18 @@ public VoidingMode getVoidingMode() { return voidingMode; } + @Override + public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.writeInitialSyncData(packetBuffer); + packetBuffer.writeByte(this.voidingMode.ordinal()); + } + + @Override + public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.readInitialSyncData(packetBuffer); + this.voidingMode = VoidingMode.VALUES[packetBuffer.readByte()]; + } + @Override public void writeToNBT(NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); @@ -181,7 +162,8 @@ public void writeToNBT(NBTTagCompound tagCompound) { @Override public void readFromNBT(NBTTagCompound tagCompound) { + this.voidingMode = VoidingMode.VALUES[tagCompound.getInteger("VoidMode")]; + this.itemFilterContainer.setMaxTransferSize(this.voidingMode.maxStackSize); super.readFromNBT(tagCompound); - this.voidingMode = VoidingMode.values()[tagCompound.getInteger("VoidMode")]; } } diff --git a/src/main/java/gregtech/common/covers/CoverMachineController.java b/src/main/java/gregtech/common/covers/CoverMachineController.java index 8814da16ca4..2626d8f3acd 100644 --- a/src/main/java/gregtech/common/covers/CoverMachineController.java +++ b/src/main/java/gregtech/common/covers/CoverMachineController.java @@ -3,23 +3,36 @@ import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IControllable; import gregtech.api.cover.*; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.*; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; import gregtech.client.renderer.texture.Textures; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.*; -import net.minecraftforge.items.ItemStackHandler; +import net.minecraft.util.text.TextFormatting; import codechicken.lib.raytracer.CuboidRayTraceResult; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.drawable.ItemDrawable; +import com.cleanroommc.modularui.drawable.Rectangle; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.value.BoolValue; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.layout.Column; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -28,23 +41,16 @@ public class CoverMachineController extends CoverBase implements CoverWithUI { - private int minRedstoneStrength; private boolean isInverted; private ControllerMode controllerMode; - private final ItemStackHandler displayInventory = new ItemStackHandler(1); public CoverMachineController(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, @NotNull EnumFacing attachedSide) { super(definition, coverableView, attachedSide); - this.minRedstoneStrength = 1; this.isInverted = false; this.controllerMode = ControllerMode.MACHINE; } - public int getMinRedstoneStrength() { - return minRedstoneStrength; - } - public ControllerMode getControllerMode() { return controllerMode; } @@ -53,12 +59,6 @@ public boolean isInverted() { return isInverted; } - public void setMinRedstoneStrength(int minRedstoneStrength) { - this.minRedstoneStrength = minRedstoneStrength; - updateRedstoneStatus(); - getCoverableView().markDirty(); - } - public void setInverted(boolean inverted) { isInverted = inverted; updateRedstoneStatus(); @@ -69,21 +69,12 @@ public void setControllerMode(ControllerMode controllerMode) { resetCurrentControllable(); this.controllerMode = controllerMode; updateRedstoneStatus(); - updateDisplayInventory(); getCoverableView().markDirty(); } - private void cycleNextControllerMode() { - List allowedModes = getAllowedModes(getCoverableView(), getAttachedSide()); - int nextIndex = allowedModes.indexOf(controllerMode) + 1; - if (!allowedModes.isEmpty()) { - setControllerMode(allowedModes.get(nextIndex % allowedModes.size())); - } - } - public List getAllowedModes(@NotNull CoverableView coverable, @NotNull EnumFacing side) { List results = new ArrayList<>(); - for (ControllerMode controllerMode : ControllerMode.values()) { + for (ControllerMode controllerMode : ControllerMode.VALUES) { IControllable controllable = null; if (controllerMode.side == null) { controllable = coverable.getCapability(GregtechTileCapabilities.CAPABILITY_CONTROLLABLE, side); @@ -115,21 +106,111 @@ public boolean canAttach(@NotNull CoverableView coverable, @NotNull EnumFacing s } @Override - public ModularUI createUI(EntityPlayer player) { - updateDisplayInventory(); - return ModularUI.builder(GuiTextures.BACKGROUND, 176, 95) - .image(4, 4, 16, 16, GuiTextures.COVER_MACHINE_CONTROLLER) - .label(24, 8, "cover.machine_controller.title") - .widget(new SliderWidget("cover.machine_controller.redstone", 10, 24, 156, 20, 1.0f, 15.0f, - minRedstoneStrength, it -> setMinRedstoneStrength((int) it))) - .widget(new ClickButtonWidget(10, 48, 134, 18, "", data -> cycleNextControllerMode())) - .widget(new SimpleTextWidget(77, 58, "", 0xFFFFFF, () -> getControllerMode().getName()).setShadow(true)) - .widget(new SlotWidget(displayInventory, 0, 148, 48, false, false) - .setBackgroundTexture(GuiTextures.SLOT)) - .widget(new CycleButtonWidget(48, 70, 80, 18, this::isInverted, this::setInverted, - "cover.machine_controller.normal", "cover.machine_controller.inverted") - .setTooltipHoverString("cover.machine_controller.inverted.description")) - .build(this, player); + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager) { + EnumSyncValue controllerModeValue = new EnumSyncValue<>(ControllerMode.class, + this::getControllerMode, this::setControllerMode); + BooleanSyncValue invertedValue = new BooleanSyncValue(this::isInverted, this::setInverted); + + guiSyncManager.syncValue("controller_mode", controllerModeValue); + guiSyncManager.syncValue("inverted", invertedValue); + + return GTGuis.createPanel(this, 176, 112) + .child(CoverWithUI.createTitleRow(getPickItem())) + .child(new Column() + .widthRel(1.0f).margin(7, 0) + .top(24).coverChildrenHeight() + + // Inverted mode + .child(createSettingsRow() + .child(new ToggleButton() + .size(16).left(0) + .value(new BoolValue.Dynamic(invertedValue::getValue, + $ -> invertedValue.setValue(true))) + .overlay(GTGuiTextures.BUTTON_REDSTONE_ON) + .selectedBackground(GTGuiTextures.MC_BUTTON_DISABLED)) + .child(IKey.lang("cover.machine_controller.enable_with_redstone").asWidget() + .heightRel(1.0f).left(20))) + .child(createSettingsRow() + .child(new ToggleButton() + .size(16).left(0) + .value(new BoolValue.Dynamic(() -> !invertedValue.getValue(), + $ -> invertedValue.setValue(false))) + .overlay(GTGuiTextures.BUTTON_REDSTONE_OFF) + .selectedBackground(GTGuiTextures.MC_BUTTON_DISABLED)) + .child(IKey.lang("cover.machine_controller.disable_with_redstone").asWidget() + .heightRel(1.0f).left(20))) + + // Separating line + .child(new Rectangle().setColor(UI_TEXT_COLOR).asWidget() + .height(1).widthRel(0.9f).alignX(0.5f).marginBottom(4).marginTop(4)) + + // Controlling selector + .child(createSettingsRow().height(16 + 2 + 16) + .child(new Column().heightRel(1.0f).coverChildrenWidth() + .child(IKey.lang("cover.machine_controller.control").asWidget() + .left(0).height(16).marginBottom(2)) + .child(modeButton(controllerModeValue, ControllerMode.MACHINE).left(0))) + .child(modeColumn(controllerModeValue, ControllerMode.COVER_UP, IKey.str("U")) + .right(100)) + .child(modeColumn(controllerModeValue, ControllerMode.COVER_DOWN, IKey.str("D")) + .right(80)) + .child(modeColumn(controllerModeValue, ControllerMode.COVER_NORTH, IKey.str("N")) + .right(60)) + .child(modeColumn(controllerModeValue, ControllerMode.COVER_SOUTH, IKey.str("S")) + .right(40)) + .child(modeColumn(controllerModeValue, ControllerMode.COVER_EAST, IKey.str("E")) + .right(20)) + .child(modeColumn(controllerModeValue, ControllerMode.COVER_WEST, IKey.str("W")) + .right(0)))); + } + + private Column modeColumn(EnumSyncValue syncValue, ControllerMode mode, IKey title) { + return new Column().coverChildrenHeight().width(18) + .child(title.asWidget().size(16).marginBottom(2).alignment(Alignment.Center)) + .child(modeButton(syncValue, mode)); + } + + private Widget modeButton(EnumSyncValue syncValue, ControllerMode mode) { + IControllable controllable = getControllable(mode); + if (controllable == null) { + // Nothing to control, put a placeholder widget + // 3 states possible here: + IKey detail; + if (mode.side == getAttachedSide()) { + // our own side, we can't control ourselves + detail = IKey.lang("cover.machine_controller.this_cover"); + } else if (mode.side != null) { + // some potential cover that either doesn't exist or isn't controllable + detail = IKey.lang("cover.machine_controller.cover_not_controllable"); + } else { + // cover holder is not controllable + detail = IKey.lang("cover.machine_controller.machine_not_controllable"); + } + + return GTGuiTextures.MC_BUTTON.asWidget().size(18) + .overlay(GTGuiTextures.BUTTON_CROSS) + .tooltip(t -> t.addLine(IKey.lang(mode.localeName)).addLine(detail)); + } + + ItemStack stack; + if (mode == ControllerMode.MACHINE) { + stack = getCoverableView().getStackForm(); + } else { + // this can't be null because we already checked IControllable, and it was not null + // noinspection ConstantConditions + stack = getCoverableView().getCoverAtSide(mode.side).getDefinition().getDropItemStack(); + } + + return new ToggleButton().size(18) + .value(boolValueOf(syncValue, mode)) + .overlay(new ItemDrawable(stack).asIcon().size(16)) + .tooltip(t -> t.addLine(IKey.lang(mode.localeName)) + .addLine(IKey.str(TextFormatting.GRAY + stack.getDisplayName()))); } @Override @@ -163,20 +244,8 @@ public void onRedstoneInputSignalChange(int newSignalStrength) { updateRedstoneStatus(); } - private void updateDisplayInventory() { - EnumFacing controlledSide = getControllerMode().side; - ItemStack resultStack = ItemStack.EMPTY; - if (controlledSide != null) { - Cover cover = getCoverableView().getCoverAtSide(controlledSide); - if (cover != null) { - resultStack = cover.getDefinition().getDropItemStack(); - } - } - this.displayInventory.setStackInSlot(0, resultStack); - } - - private @Nullable IControllable getControllable() { - EnumFacing side = controllerMode.side; + private @Nullable IControllable getControllable(ControllerMode mode) { + EnumFacing side = mode.side; if (side == null) { return getCoverableView().getCapability(GregtechTileCapabilities.CAPABILITY_CONTROLLABLE, getAttachedSide()); @@ -190,24 +259,22 @@ private void updateDisplayInventory() { } private void resetCurrentControllable() { - IControllable controllable = getControllable(); + IControllable controllable = getControllable(controllerMode); if (controllable != null) { controllable.setWorkingEnabled(doesOtherAllowingWork()); } } private void updateRedstoneStatus() { - IControllable controllable = getControllable(); + IControllable controllable = getControllable(controllerMode); if (controllable != null) { controllable.setWorkingEnabled(shouldAllowWorking() && doesOtherAllowingWork()); } } private boolean shouldAllowWorking() { - boolean shouldAllowWorking = getCoverableView().getInputRedstoneSignal(getAttachedSide(), true) < - minRedstoneStrength; - // noinspection SimplifiableConditionalExpression - return isInverted ? !shouldAllowWorking : shouldAllowWorking; + int inputSignal = getCoverableView().getInputRedstoneSignal(getAttachedSide(), true); + return isInverted ? inputSignal > 0 : inputSignal == 0; } private boolean doesOtherAllowingWork() { @@ -228,7 +295,6 @@ private boolean doesOtherAllowingWork() { @Override public void writeToNBT(@NotNull NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); - tagCompound.setInteger("MinRedstoneStrength", minRedstoneStrength); tagCompound.setBoolean("Inverted", isInverted); tagCompound.setInteger("ControllerMode", controllerMode.ordinal()); } @@ -236,9 +302,22 @@ public void writeToNBT(@NotNull NBTTagCompound tagCompound) { @Override public void readFromNBT(@NotNull NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); - this.minRedstoneStrength = tagCompound.getInteger("MinRedstoneStrength"); this.isInverted = tagCompound.getBoolean("Inverted"); - this.controllerMode = ControllerMode.values()[tagCompound.getInteger("ControllerMode")]; + this.controllerMode = ControllerMode.VALUES[tagCompound.getInteger("ControllerMode")]; + } + + @Override + public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.writeInitialSyncData(packetBuffer); + packetBuffer.writeBoolean(isInverted); + packetBuffer.writeShort(controllerMode.ordinal()); + } + + @Override + public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.readInitialSyncData(packetBuffer); + this.isInverted = packetBuffer.readBoolean(); + this.controllerMode = ControllerMode.VALUES[packetBuffer.readShort()]; } public enum ControllerMode implements IStringSerializable { @@ -254,6 +333,8 @@ public enum ControllerMode implements IStringSerializable { public final String localeName; public final EnumFacing side; + public static final ControllerMode[] VALUES = values(); + ControllerMode(String localeName, EnumFacing side) { this.localeName = localeName; this.side = side; diff --git a/src/main/java/gregtech/common/covers/CoverPump.java b/src/main/java/gregtech/common/covers/CoverPump.java index 961e349be6b..2fdb55e2cdd 100644 --- a/src/main/java/gregtech/common/covers/CoverPump.java +++ b/src/main/java/gregtech/common/covers/CoverPump.java @@ -1,6 +1,5 @@ package gregtech.common.covers; -import gregtech.api.GTValues; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IControllable; @@ -9,14 +8,8 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverWithUI; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.CycleButtonWidget; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.IncrementButtonWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.TextFieldWidget2; -import gregtech.api.gui.widgets.WidgetGroup; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; import gregtech.api.util.GTTransferUtils; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleSidedCubeRenderer; @@ -47,13 +40,25 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; -import com.google.common.math.IntMath; +import com.cleanroommc.modularui.api.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; +import com.cleanroommc.modularui.utils.MouseData; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.IntSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.ButtonWidget; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.function.Function; -import java.util.function.IntSupplier; - public class CoverPump extends CoverBase implements CoverWithUI, ITickable, IControllable { public final int tier; @@ -65,7 +70,7 @@ public class CoverPump extends CoverBase implements CoverWithUI, ITickable, ICon protected int fluidLeftToTransferLastSecond; private CoverableFluidHandlerWrapper fluidHandlerWrapper; protected boolean isWorkingAllowed = true; - protected FluidFilterContainer fluidFilter; + protected FluidFilterContainer fluidFilterContainer; protected BucketMode bucketMode = BucketMode.MILLI_BUCKET; public CoverPump(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, @@ -75,25 +80,35 @@ public CoverPump(@NotNull CoverDefinition definition, @NotNull CoverableView cov this.maxFluidTransferRate = mbPerTick; this.transferRate = mbPerTick; this.fluidLeftToTransferLastSecond = transferRate; - this.fluidFilter = new FluidFilterContainer(this, this::shouldShowTip); + this.fluidFilterContainer = new FluidFilterContainer(this); + } + + public void setStringTransferRate(String s) { + this.fluidFilterContainer.setTransferSize( + getBucketMode() == BucketMode.MILLI_BUCKET ? + Integer.parseInt(s) : + Integer.parseInt(s) * 1000); } - protected boolean shouldShowTip() { - return false; + public String getStringTransferRate() { + return String.valueOf(getBucketMode() == BucketMode.MILLI_BUCKET ? + this.fluidFilterContainer.getTransferSize() : + this.fluidFilterContainer.getTransferSize() / 1000); } public void setTransferRate(int transferRate) { - this.transferRate = transferRate; + if (bucketMode == BucketMode.BUCKET) transferRate *= 1000; + this.transferRate = MathHelper.clamp(transferRate, 1, maxFluidTransferRate); markDirty(); } public int getTransferRate() { - return transferRate; + return bucketMode == BucketMode.BUCKET ? transferRate / 1000 : transferRate; } protected void adjustTransferRate(int amount) { amount *= this.bucketMode == BucketMode.BUCKET ? 1000 : 1; - setTransferRate(MathHelper.clamp(transferRate + amount, 1, maxFluidTransferRate)); + setTransferRate(this.transferRate + amount); } public void setPumpMode(PumpMode pumpMode) { @@ -127,7 +142,7 @@ protected void setManualImportExportMode(ManualImportExportMode manualImportExpo } public FluidFilterContainer getFluidFilterContainer() { - return fluidFilter; + return fluidFilterContainer; } @Override @@ -157,100 +172,131 @@ protected int doTransferFluidsInternal(IFluidHandler myFluidHandler, IFluidHandl int transferLimit) { if (pumpMode == PumpMode.IMPORT) { return GTTransferUtils.transferFluids(fluidHandler, myFluidHandler, transferLimit, - fluidFilter::testFluidStack); + fluidFilterContainer::test); } else if (pumpMode == PumpMode.EXPORT) { return GTTransferUtils.transferFluids(myFluidHandler, fluidHandler, transferLimit, - fluidFilter::testFluidStack); + fluidFilterContainer::test); } return 0; } protected boolean checkInputFluid(FluidStack fluidStack) { - return fluidFilter.testFluidStack(fluidStack); + return fluidFilterContainer.test(fluidStack); } - protected ModularUI buildUI(ModularUI.Builder builder, EntityPlayer player) { - return builder.build(this, player); + @Override + public boolean usesMui2() { + return true; } - protected String getUITitle() { - return "cover.pump.title"; + @Override + public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager) { + var panel = GTGuis.createPanel(this, 176, 192); + + getFluidFilterContainer().setMaxTransferSize(getMaxTransferRate()); + + return panel.child(CoverWithUI.createTitleRow(getPickItem())) + .child(createUI(panel, guiSyncManager)) + .bindPlayerInventory(); + } + + protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager syncManager) { + var manualIOmode = new EnumSyncValue<>(ManualImportExportMode.class, + this::getManualImportExportMode, this::setManualImportExportMode); + manualIOmode.updateCacheFromSource(true); + + var throughput = new IntSyncValue(this::getTransferRate, this::setTransferRate); + throughput.updateCacheFromSource(true); + + var throughputString = new StringSyncValue( + throughput::getStringValue, + throughput::setStringValue); + throughputString.updateCacheFromSource(true); + + var pumpMode = new EnumSyncValue<>(PumpMode.class, this::getPumpMode, this::setPumpMode); + pumpMode.updateCacheFromSource(true); + + syncManager.syncValue("manual_io", manualIOmode); + syncManager.syncValue("pump_mode", pumpMode); + syncManager.syncValue("throughput", throughput); + + var column = new Column().top(24).margin(7, 0) + .widthRel(1f).coverChildrenHeight(); + + if (createThroughputRow()) + column.child(new Row().coverChildrenHeight() + .marginBottom(2).widthRel(1f) + .child(new ButtonWidget<>() + .left(0).width(18) + .onMousePressed(mouseButton -> { + int val = throughput.getValue() - getIncrementValue(MouseData.create(mouseButton)); + throughput.setValue(val, true, true); + Interactable.playButtonClickSound(); + return true; + }) + .onUpdateListener(w -> w.overlay(createAdjustOverlay(false)))) + .child(new TextFieldWidget() + .left(18).right(18) + .setTextColor(Color.WHITE.darker(1)) + .setNumbers(1, maxFluidTransferRate) + .value(throughputString) + .background(GTGuiTextures.DISPLAY)) + .child(new ButtonWidget<>() + .right(0).width(18) + .onMousePressed(mouseButton -> { + int val = throughput.getValue() + getIncrementValue(MouseData.create(mouseButton)); + throughput.setValue(val, true, true); + Interactable.playButtonClickSound(); + return true; + }) + .onUpdateListener(w -> w.overlay(createAdjustOverlay(true))))); + + if (createFilterRow()) + column.child(getFluidFilterContainer() + .initUI(mainPanel, syncManager)); + + if (createManualIOModeRow()) + column.child(new EnumRowBuilder<>(ManualImportExportMode.class) + .value(manualIOmode) + .lang("cover.generic.manual_io") + .overlay(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()) + column.child(new EnumRowBuilder<>(PumpMode.class) + .value(pumpMode) + .lang("cover.pump.mode") + .overlay(GTGuiTextures.CONVEYOR_MODE_OVERLAY) // todo pump mode overlays + .build()); + + return column; + } + + protected boolean createThroughputRow() { + return true; } - @SuppressWarnings("UnstableApiUsage") - @Override - public ModularUI createUI(EntityPlayer player) { - WidgetGroup primaryGroup = new WidgetGroup(); - primaryGroup.addWidget(new LabelWidget(10, 5, getUITitle(), GTValues.VN[tier])); - - primaryGroup.addWidget(new ImageWidget(44, 20, 62, 20, GuiTextures.DISPLAY)); - - primaryGroup.addWidget(new IncrementButtonWidget(136, 20, 30, 20, 1, 10, 100, 1000, this::adjustTransferRate) - .setDefaultTooltip() - .setShouldClientCallback(false)); - primaryGroup.addWidget(new IncrementButtonWidget(10, 20, 34, 20, -1, -10, -100, -1000, this::adjustTransferRate) - .setDefaultTooltip() - .setShouldClientCallback(false)); - - TextFieldWidget2 textField = new TextFieldWidget2(45, 26, 60, 20, () -> bucketMode == BucketMode.BUCKET ? - Integer.toString(transferRate / 1000) : Integer.toString(transferRate), val -> { - if (val != null && !val.isEmpty()) { - int amount = Integer.parseInt(val); - if (this.bucketMode == BucketMode.BUCKET) { - amount = IntMath.saturatedMultiply(amount, 1000); - } - setTransferRate(amount); - } - }) - .setCentered(true) - .setNumbersOnly(1, - bucketMode == BucketMode.BUCKET ? maxFluidTransferRate / 1000 : maxFluidTransferRate) - .setMaxLength(8); - primaryGroup.addWidget(textField); - - primaryGroup.addWidget(new CycleButtonWidget(106, 20, 30, 20, - BucketMode.class, this::getBucketMode, mode -> { - if (mode != bucketMode) { - setBucketMode(mode); - } - })); - - primaryGroup.addWidget(new CycleButtonWidget(10, 43, 75, 18, - PumpMode.class, this::getPumpMode, this::setPumpMode)); - - primaryGroup.addWidget(new CycleButtonWidget(7, 160, 116, 20, - ManualImportExportMode.class, this::getManualImportExportMode, this::setManualImportExportMode) - .setTooltipHoverString("cover.universal.manual_import_export.mode.description")); - - this.fluidFilter.initUI(88, primaryGroup::addWidget); - - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, 184 + 82) - .widget(primaryGroup) - .bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 184); - return buildUI(builder, player); - } - - public static Function getTextFieldValidator(IntSupplier maxSupplier) { - int min = 1; - return val -> { - if (val.isEmpty()) { - return String.valueOf(min); - } - int max = maxSupplier.getAsInt(); - int num; - try { - num = Integer.parseInt(val); - } catch (NumberFormatException ignored) { - return String.valueOf(max); - } - if (num < min) { - return String.valueOf(min); - } - if (num > max) { - return String.valueOf(max); - } - return val; - }; + protected boolean createFilterRow() { + return true; + } + + protected boolean createManualIOModeRow() { + return true; + } + + protected boolean createPumpModeRow() { + return true; + } + + protected int getMaxTransferRate() { + return 1; } @Override @@ -274,13 +320,15 @@ public void readCustomData(int discriminator, @NotNull PacketBuffer buf) { @Override public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { super.writeInitialSyncData(packetBuffer); - packetBuffer.writeEnumValue(pumpMode); + packetBuffer.writeByte(pumpMode.ordinal()); + getFluidFilterContainer().writeInitialSyncData(packetBuffer); } @Override public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { super.readInitialSyncData(packetBuffer); - this.pumpMode = packetBuffer.readEnumValue(PumpMode.class); + this.pumpMode = PumpMode.VALUES[packetBuffer.readByte()]; + getFluidFilterContainer().readInitialSyncData(packetBuffer); } @Override @@ -295,7 +343,7 @@ public boolean canInteractWithOutputSide() { @Override public void onRemoval() { - dropInventoryContents(fluidFilter.getFilterInventory()); + dropInventoryContents(fluidFilterContainer); } @Override @@ -344,18 +392,24 @@ public void writeToNBT(@NotNull NBTTagCompound tagCompound) { tagCompound.setInteger("DistributionMode", distributionMode.ordinal()); tagCompound.setBoolean("WorkingAllowed", isWorkingAllowed); tagCompound.setInteger("ManualImportExportMode", manualImportExportMode.ordinal()); - tagCompound.setTag("Filter", fluidFilter.serializeNBT()); + tagCompound.setInteger("BucketMode", bucketMode.ordinal()); + tagCompound.setTag("Filter", fluidFilterContainer.serializeNBT()); } @Override public void readFromNBT(@NotNull NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); this.transferRate = tagCompound.getInteger("TransferRate"); - this.pumpMode = PumpMode.values()[tagCompound.getInteger("PumpMode")]; - this.distributionMode = DistributionMode.values()[tagCompound.getInteger("DistributionMode")]; + this.pumpMode = PumpMode.VALUES[tagCompound.getInteger("PumpMode")]; + this.distributionMode = DistributionMode.VALUES[tagCompound.getInteger("DistributionMode")]; this.isWorkingAllowed = tagCompound.getBoolean("WorkingAllowed"); - this.manualImportExportMode = ManualImportExportMode.values()[tagCompound.getInteger("ManualImportExportMode")]; - this.fluidFilter.deserializeNBT(tagCompound.getCompoundTag("Filter")); + this.manualImportExportMode = ManualImportExportMode.VALUES[tagCompound.getInteger("ManualImportExportMode")]; + this.bucketMode = BucketMode.VALUES[tagCompound.getInteger("BucketMode")]; + var filterTag = tagCompound.getCompoundTag("Filter"); + if (filterTag.hasKey("IsBlacklist")) + this.fluidFilterContainer.handleLegacyNBT(filterTag); + else + this.fluidFilterContainer.deserializeNBT(filterTag); } @Override @@ -369,6 +423,7 @@ public enum PumpMode implements IStringSerializable, IIOMode { IMPORT("cover.pump.mode.import"), EXPORT("cover.pump.mode.export"); + public static final PumpMode[] VALUES = values(); public final String localeName; PumpMode(String localeName) { @@ -392,6 +447,7 @@ public enum BucketMode implements IStringSerializable { BUCKET("cover.bucket.mode.bucket"), MILLI_BUCKET("cover.bucket.mode.milli_bucket"); + public static final BucketMode[] VALUES = values(); public final String localeName; BucketMode(String localeName) { diff --git a/src/main/java/gregtech/common/covers/CoverRoboticArm.java b/src/main/java/gregtech/common/covers/CoverRoboticArm.java index 902ffcd62f4..22047e6db2e 100644 --- a/src/main/java/gregtech/common/covers/CoverRoboticArm.java +++ b/src/main/java/gregtech/common/covers/CoverRoboticArm.java @@ -1,27 +1,34 @@ package gregtech.common.covers; +import gregtech.api.capability.GregtechDataCodes; import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.ModularUI.Builder; -import gregtech.api.gui.widgets.*; +import gregtech.api.mui.GTGuiTextures; import gregtech.client.renderer.texture.Textures; import gregtech.common.covers.filter.SmartItemFilter; import gregtech.common.pipelike.itempipe.net.ItemNetHandler; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.MathHelper; import net.minecraftforge.items.IItemHandler; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; import java.util.Iterator; @@ -36,7 +43,7 @@ public CoverRoboticArm(@NotNull CoverDefinition definition, @NotNull CoverableVi @NotNull EnumFacing attachedSide, int tier, int itemsPerSecond) { super(definition, coverableView, attachedSide, tier, itemsPerSecond); this.transferMode = TransferMode.TRANSFER_ANY; - this.itemFilterContainer.setMaxStackSize(1); + this.itemFilterContainer.setMaxTransferSize(1); } @Override @@ -72,16 +79,17 @@ protected int doTransferExact(IItemHandler itemHandler, IItemHandler myItemHandl while (iterator.hasNext()) { TypeItemInfo sourceInfo = sourceItemAmount.get(iterator.next()); int itemAmount = sourceInfo.totalCount; - int itemToMoveAmount = itemFilterContainer.getSlotTransferLimit(sourceInfo.filterSlot); + int itemToMoveAmount = itemFilterContainer.getTransferLimit(sourceInfo.itemStack); - // if smart item filter - if (itemFilterContainer.getFilterWrapper().getItemFilter() instanceof SmartItemFilter) { - if (itemFilterContainer.getTransferStackSize() > 1 && itemToMoveAmount * 2 <= itemAmount) { + // if smart item filter and whitelist + if (itemFilterContainer.getFilter() instanceof SmartItemFilter && + !itemFilterContainer.isBlacklistFilter()) { + if (itemFilterContainer.getTransferSize() > 1 && itemToMoveAmount * 2 <= itemAmount) { // get the max we can extract from the item filter variable int maxMultiplier = Math.floorDiv(maxTransferAmount, itemToMoveAmount); // multiply up to the total count of all the items - itemToMoveAmount *= Math.min(itemFilterContainer.getTransferStackSize(), maxMultiplier); + itemToMoveAmount *= Math.min(itemFilterContainer.getTransferSize(), maxMultiplier); } } @@ -115,24 +123,24 @@ protected int doTransferExact(IItemHandler itemHandler, IItemHandler myItemHandl } protected int doKeepExact(IItemHandler itemHandler, IItemHandler myItemHandler, int maxTransferAmount) { - Map currentItemAmount = doCountDestinationInventoryItemsByMatchIndex(itemHandler, + Map currentItemAmount = doCountDestinationInventoryItemsByMatchIndex(itemHandler, myItemHandler); - Map sourceItemAmounts = doCountDestinationInventoryItemsByMatchIndex(myItemHandler, + Map sourceItemAmounts = doCountDestinationInventoryItemsByMatchIndex(myItemHandler, itemHandler); - Iterator iterator = sourceItemAmounts.keySet().iterator(); + Iterator iterator = sourceItemAmounts.keySet().iterator(); while (iterator.hasNext()) { - Object filterSlotIndex = iterator.next(); + int filterSlotIndex = iterator.next(); GroupItemInfo sourceInfo = sourceItemAmounts.get(filterSlotIndex); - int itemToKeepAmount = itemFilterContainer.getSlotTransferLimit(sourceInfo.filterSlot); + int itemToKeepAmount = itemFilterContainer.getTransferLimit(sourceInfo.filterSlot); // only run multiplier for smart item - if (itemFilterContainer.getFilterWrapper().getItemFilter() instanceof SmartItemFilter) { - if (itemFilterContainer.getTransferStackSize() > 1 && itemToKeepAmount * 2 <= sourceInfo.totalCount) { + if (itemFilterContainer.getFilter() instanceof SmartItemFilter) { + if (itemFilterContainer.getTransferSize() > 1 && itemToKeepAmount * 2 <= sourceInfo.totalCount) { // get the max we can keep from the item filter variable int maxMultiplier = Math.floorDiv(sourceInfo.totalCount, itemToKeepAmount); // multiply up to the total count of all the items - itemToKeepAmount *= Math.min(itemFilterContainer.getTransferStackSize(), maxMultiplier); + itemToKeepAmount *= Math.min(itemFilterContainer.getTransferSize(), maxMultiplier); } } @@ -163,9 +171,13 @@ public void clearBuffer() { } public void setTransferMode(TransferMode transferMode) { - this.transferMode = transferMode; - this.getCoverableView().markDirty(); - this.itemFilterContainer.setMaxStackSize(transferMode.maxStackSize); + if (this.transferMode != transferMode) { + this.transferMode = transferMode; + this.getCoverableView().markDirty(); + this.itemFilterContainer.setMaxTransferSize(transferMode.maxStackSize); + writeCustomData(GregtechDataCodes.UPDATE_TRANSFER_MODE, + buffer -> buffer.writeByte(this.transferMode.ordinal())); + } } public TransferMode getTransferMode() { @@ -180,44 +192,60 @@ private boolean shouldDisplayAmountSlider() { } @Override - protected String getUITitle() { - return "cover.robotic_arm.title"; + public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager) { + return super.buildUI(guiData, guiSyncManager).height(192 + 36 + 18 + 2); + } + + @Override + protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager guiSyncManager) { + EnumSyncValue transferMode = new EnumSyncValue<>(TransferMode.class, this::getTransferMode, + this::setTransferMode); + guiSyncManager.syncValue("transfer_mode", transferMode); + + var filterTransferSize = new StringSyncValue( + () -> String.valueOf(this.itemFilterContainer.getTransferSize()), + s -> this.itemFilterContainer.setTransferSize(Integer.parseInt(s))); + filterTransferSize.updateCacheFromSource(true); + + return super.createUI(mainPanel, guiSyncManager) + .child(new EnumRowBuilder<>(TransferMode.class) + .value(transferMode) + .lang("cover.generic.transfer_mode") + .overlay(GTGuiTextures.TRANSFER_MODE_OVERLAY) + .build()) + .child(new Row().right(0).coverChildrenHeight() + .child(new TextFieldWidget().widthRel(0.5f).right(0) + .setEnabledIf(w -> shouldDisplayAmountSlider()) + .setNumbers(0, Integer.MAX_VALUE) + .value(filterTransferSize) + .setTextColor(Color.WHITE.darker(1)))); + } + + @Override + protected int getMaxStackSize() { + return getTransferMode().maxStackSize; } @Override - protected ModularUI buildUI(Builder builder, EntityPlayer player) { - WidgetGroup primaryGroup = new WidgetGroup(); - primaryGroup.addWidget(new CycleButtonWidget(91, 45, 75, 20, - TransferMode.class, this::getTransferMode, this::setTransferMode) - .setTooltipHoverString("cover.robotic_arm.transfer_mode.description")); - - ServerWidgetGroup stackSizeGroup = new ServerWidgetGroup(this::shouldDisplayAmountSlider); - stackSizeGroup.addWidget(new ImageWidget(111, 70, 35, 20, GuiTextures.DISPLAY)); - - stackSizeGroup.addWidget( - new IncrementButtonWidget(146, 70, 20, 20, 1, 8, 64, 512, itemFilterContainer::adjustTransferStackSize) - .setDefaultTooltip() - .setTextScale(0.7f) - .setShouldClientCallback(false)); - stackSizeGroup.addWidget(new IncrementButtonWidget(91, 70, 20, 20, -1, -8, -64, -512, - itemFilterContainer::adjustTransferStackSize) - .setDefaultTooltip() - .setTextScale(0.7f) - .setShouldClientCallback(false)); - - stackSizeGroup.addWidget(new TextFieldWidget2(113, 77, 31, 20, - () -> String.valueOf(itemFilterContainer.getTransferStackSize()), val -> { - if (val != null && !val.isEmpty()) - itemFilterContainer.setTransferStackSize( - MathHelper.clamp(Integer.parseInt(val), 1, transferMode.maxStackSize)); - }) - .setNumbersOnly(1, transferMode.maxStackSize) - .setMaxLength(4) - .setScale(0.9f)); - - primaryGroup.addWidget(stackSizeGroup); - - return super.buildUI(builder.widget(primaryGroup), player); + public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.writeInitialSyncData(packetBuffer); + packetBuffer.writeByte(this.transferMode.ordinal()); + } + + @Override + public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.readInitialSyncData(packetBuffer); + this.transferMode = TransferMode.VALUES[packetBuffer.readByte()]; + this.itemFilterContainer.setMaxTransferSize(this.transferMode.maxStackSize); + } + + @Override + public void readCustomData(int discriminator, @NotNull PacketBuffer buf) { + super.readCustomData(discriminator, buf); + if (discriminator == GregtechDataCodes.UPDATE_TRANSFER_MODE) { + this.transferMode = TransferMode.VALUES[buf.readByte()]; + this.itemFilterContainer.setMaxTransferSize(this.transferMode.maxStackSize); + } } @Override @@ -228,7 +256,8 @@ public void writeToNBT(NBTTagCompound tagCompound) { @Override public void readFromNBT(NBTTagCompound tagCompound) { + this.transferMode = TransferMode.VALUES[tagCompound.getInteger("TransferMode")]; + this.itemFilterContainer.setMaxTransferSize(this.transferMode.maxStackSize); super.readFromNBT(tagCompound); - this.transferMode = TransferMode.values()[tagCompound.getInteger("TransferMode")]; } } diff --git a/src/main/java/gregtech/common/covers/CoverSolarPanel.java b/src/main/java/gregtech/common/covers/CoverSolarPanel.java index 7e2e750439a..e972ef560ad 100644 --- a/src/main/java/gregtech/common/covers/CoverSolarPanel.java +++ b/src/main/java/gregtech/common/covers/CoverSolarPanel.java @@ -13,7 +13,6 @@ import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -50,10 +49,9 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra public void update() { CoverableView coverable = getCoverableView(); World world = coverable.getWorld(); - BlockPos blockPos = coverable.getPos(); - if (GTUtility.canSeeSunClearly(world, blockPos)) { + if (GTUtility.canSeeSunClearly(world, coverable.getPos())) { IEnergyContainer energyContainer = coverable.getCapability(GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER, - null); + getAttachedSide()); if (energyContainer != null) { energyContainer.acceptEnergyFromNetwork(null, EUt, 1); } diff --git a/src/main/java/gregtech/common/covers/CoverStorage.java b/src/main/java/gregtech/common/covers/CoverStorage.java index a63fe3cbd56..f9bb45f788c 100644 --- a/src/main/java/gregtech/common/covers/CoverStorage.java +++ b/src/main/java/gregtech/common/covers/CoverStorage.java @@ -26,7 +26,7 @@ import com.cleanroommc.modularui.api.widget.IWidget; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; -import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandlers; import com.cleanroommc.modularui.widgets.ItemSlot; import com.cleanroommc.modularui.widgets.layout.Grid; @@ -88,7 +88,7 @@ public boolean usesMui2() { } @Override - public ModularPanel buildUI(SidedPosGuiData guiData, GuiSyncManager guiSyncManager) { + public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager) { guiSyncManager.registerSlotGroup("item_inv", this.storageHandler.getSlots()); int rowSize = this.storageHandler.getSlots(); diff --git a/src/main/java/gregtech/common/covers/DistributionMode.java b/src/main/java/gregtech/common/covers/DistributionMode.java index 24268bdc6a0..c704d045b18 100644 --- a/src/main/java/gregtech/common/covers/DistributionMode.java +++ b/src/main/java/gregtech/common/covers/DistributionMode.java @@ -10,6 +10,7 @@ public enum DistributionMode implements IStringSerializable { ROUND_ROBIN_PRIO("cover.conveyor.distribution.round_robin"), INSERT_FIRST("cover.conveyor.distribution.first_insert"); + public static final DistributionMode[] VALUES = values(); public final String localeName; DistributionMode(String localeName) { diff --git a/src/main/java/gregtech/common/covers/FluidFilterMode.java b/src/main/java/gregtech/common/covers/FluidFilterMode.java index ee372ff8b09..e26c6192e8b 100644 --- a/src/main/java/gregtech/common/covers/FluidFilterMode.java +++ b/src/main/java/gregtech/common/covers/FluidFilterMode.java @@ -1,11 +1,14 @@ package gregtech.common.covers; -public enum FluidFilterMode implements IFilterMode { +import net.minecraft.util.IStringSerializable; + +public enum FluidFilterMode implements IStringSerializable { FILTER_FILL("cover.fluid_filter.mode.filter_fill"), FILTER_DRAIN("cover.fluid_filter.mode.filter_drain"), FILTER_BOTH("cover.fluid_filter.mode.filter_both"); + public static final FluidFilterMode[] VALUES = values(); public final String localeName; FluidFilterMode(String localeName) { diff --git a/src/main/java/gregtech/common/covers/IFilterMode.java b/src/main/java/gregtech/common/covers/IFilterMode.java deleted file mode 100644 index ecc0fde802f..00000000000 --- a/src/main/java/gregtech/common/covers/IFilterMode.java +++ /dev/null @@ -1,6 +0,0 @@ -package gregtech.common.covers; - -public interface IFilterMode { - - String getName(); -} diff --git a/src/main/java/gregtech/common/covers/ItemFilterMode.java b/src/main/java/gregtech/common/covers/ItemFilterMode.java index 2a871e2984e..6d612915161 100644 --- a/src/main/java/gregtech/common/covers/ItemFilterMode.java +++ b/src/main/java/gregtech/common/covers/ItemFilterMode.java @@ -1,11 +1,14 @@ package gregtech.common.covers; -public enum ItemFilterMode implements IFilterMode { +import net.minecraft.util.IStringSerializable; + +public enum ItemFilterMode implements IStringSerializable { FILTER_INSERT("cover.filter.mode.filter_insert"), FILTER_EXTRACT("cover.filter.mode.filter_extract"), FILTER_BOTH("cover.filter.mode.filter_both"); + public static final ItemFilterMode[] VALUES = values(); public final String localeName; ItemFilterMode(String localeName) { diff --git a/src/main/java/gregtech/common/covers/ManualImportExportMode.java b/src/main/java/gregtech/common/covers/ManualImportExportMode.java index d044322425c..df3942d7163 100644 --- a/src/main/java/gregtech/common/covers/ManualImportExportMode.java +++ b/src/main/java/gregtech/common/covers/ManualImportExportMode.java @@ -10,6 +10,7 @@ public enum ManualImportExportMode implements IStringSerializable { FILTERED("cover.universal.manual_import_export.mode.filtered"), UNFILTERED("cover.universal.manual_import_export.mode.unfiltered"); + public static final ManualImportExportMode[] VALUES = values(); public final String localeName; ManualImportExportMode(String localeName) { diff --git a/src/main/java/gregtech/common/covers/TransferMode.java b/src/main/java/gregtech/common/covers/TransferMode.java index ebf708dfdf4..2f278c88ce4 100644 --- a/src/main/java/gregtech/common/covers/TransferMode.java +++ b/src/main/java/gregtech/common/covers/TransferMode.java @@ -8,8 +8,9 @@ public enum TransferMode implements IStringSerializable { TRANSFER_ANY("cover.robotic_arm.transfer_mode.transfer_any", 1), TRANSFER_EXACT("cover.robotic_arm.transfer_mode.transfer_exact", 1024), - KEEP_EXACT("cover.robotic_arm.transfer_mode.keep_exact", 1024); + KEEP_EXACT("cover.robotic_arm.transfer_mode.keep_exact", Integer.MAX_VALUE); + public static final TransferMode[] VALUES = values(); public final String localeName; public final int maxStackSize; diff --git a/src/main/java/gregtech/common/covers/VoidingMode.java b/src/main/java/gregtech/common/covers/VoidingMode.java index 48aa9d0b8de..b7e85666f65 100644 --- a/src/main/java/gregtech/common/covers/VoidingMode.java +++ b/src/main/java/gregtech/common/covers/VoidingMode.java @@ -7,8 +7,9 @@ public enum VoidingMode implements IStringSerializable { VOID_ANY("cover.voiding.voiding_mode.void_any", 1), - VOID_OVERFLOW("cover.voiding.voiding_mode.void_overflow", 1024); + VOID_OVERFLOW("cover.voiding.voiding_mode.void_overflow", Integer.MAX_VALUE); + public static final VoidingMode[] VALUES = values(); public final String localeName; public final int maxStackSize; diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorFluidAdvanced.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorFluidAdvanced.java index 32239be9036..56d7eb246c9 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorFluidAdvanced.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorFluidAdvanced.java @@ -92,7 +92,7 @@ public ModularUI createUI(EntityPlayer player) { // "cover.generic.advanced_detector.invert_label")); group.addWidget( new CycleButtonWidget(10, 3 * (SIZE + PADDING), 4 * SIZE, SIZE, this::isInverted, this::setInverted, - "cover.machine_controller.normal", "cover.machine_controller.inverted") + "cover.advanced_energy_detector.normal", "cover.advanced_energy_detector.inverted") .setTooltipHoverString("cover.generic.advanced_detector.invert_tooltip")); group.addWidget( new CycleButtonWidget(94, 3 * (SIZE + PADDING), 4 * SIZE, SIZE, this::isLatched, this::setLatched, @@ -145,7 +145,7 @@ public void update() { for (IFluidTankProperties properties : tankProperties) { FluidStack contents = properties.getContents(); - if (contents != null && fluidFilter.testFluidStack(contents)) + if (contents != null && fluidFilter.test(contents)) storedFluid += contents.amount; } diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorItemAdvanced.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorItemAdvanced.java index 7d992674a93..e2475756fd5 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorItemAdvanced.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorItemAdvanced.java @@ -78,7 +78,7 @@ public ModularUI createUI(EntityPlayer player) { // "cover.generic.advanced_detector.invert_label")); group.addWidget( new CycleButtonWidget(10, 3 * (SIZE + PADDING), 4 * SIZE, SIZE, this::isInverted, this::setInverted, - "cover.machine_controller.normal", "cover.machine_controller.inverted") + "cover.advanced_energy_detector.normal", "cover.advanced_energy_detector.inverted") .setTooltipHoverString("cover.generic.advanced_detector.invert_tooltip")); // group.addWidget(new LabelWidget(10, 5 + 4 * (SIZE + PADDING), // "cover.generic.advanced_detector.latch_label")); @@ -151,7 +151,7 @@ public void update() { int storedItems = 0; for (int i = 0; i < itemHandler.getSlots(); i++) { - if (itemFilter.testItemStack(itemHandler.getStackInSlot(i))) + if (itemFilter.test(itemHandler.getStackInSlot(i))) storedItems += itemHandler.getStackInSlot(i).getCount(); } diff --git a/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java b/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java new file mode 100644 index 00000000000..eb5c6a81d9d --- /dev/null +++ b/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java @@ -0,0 +1,513 @@ +package gregtech.common.covers.ender; + +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.capability.IControllable; +import gregtech.api.cover.CoverBase; +import gregtech.api.cover.CoverDefinition; +import gregtech.api.cover.CoverWithUI; +import gregtech.api.cover.CoverableView; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; +import gregtech.api.util.virtualregistry.EntryTypes; +import gregtech.api.util.virtualregistry.VirtualEnderRegistry; +import gregtech.api.util.virtualregistry.VirtualEntry; +import gregtech.common.mui.widget.InteractableText; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.ITickable; + +import codechicken.lib.raytracer.CuboidRayTraceResult; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.api.widget.IWidget; +import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.drawable.DynamicDrawable; +import com.cleanroommc.modularui.drawable.GuiTextures; +import com.cleanroommc.modularui.drawable.Rectangle; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.network.NetworkUtils; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncHandler; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.widgets.ButtonWidget; +import com.cleanroommc.modularui.widgets.ListWidget; +import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import java.util.regex.Pattern; + +@SuppressWarnings("SameParameterValue") +public abstract class CoverAbstractEnderLink extends CoverBase + implements CoverWithUI, ITickable, IControllable { + + protected static final Pattern COLOR_INPUT_PATTERN = Pattern.compile("[0-9a-fA-F]*"); + public static final int UPDATE_PRIVATE = GregtechDataCodes.assignId(); + + protected T activeEntry = null; + protected String color = VirtualEntry.DEFAULT_COLOR; + protected UUID playerUUID = null; + private boolean isPrivate = false; + private boolean workingEnabled = true; + private boolean ioEnabled = false; + + public CoverAbstractEnderLink(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, + @NotNull EnumFacing attachedSide) { + super(definition, coverableView, attachedSide); + updateLink(); + } + + protected void updateLink() { + this.activeEntry = VirtualEnderRegistry.getOrCreateEntry(getOwner(), getType(), createName()); + this.activeEntry.setColor(this.color); + markDirty(); + } + + protected abstract EntryTypes getType(); + + public String getColorStr() { + return this.color; + } + + protected final String createName() { + return identifier() + this.color; + } + + protected abstract String identifier(); + + protected final UUID getOwner() { + return isPrivate ? playerUUID : null; + } + + @Override + public void readCustomData(int discriminator, @NotNull PacketBuffer buf) { + super.readCustomData(discriminator, buf); + if (discriminator == UPDATE_PRIVATE) { + setPrivate(buf.readBoolean()); + updateLink(); + } + } + + @Override + public @NotNull EnumActionResult onScrewdriverClick(@NotNull EntityPlayer playerIn, @NotNull EnumHand hand, + @NotNull CuboidRayTraceResult hitResult) { + if (!getWorld().isRemote) { + openUI((EntityPlayerMP) playerIn); + } + return EnumActionResult.SUCCESS; + } + + @Override + public void onAttachment(@NotNull CoverableView coverableView, @NotNull EnumFacing side, + @Nullable EntityPlayer player, @NotNull ItemStack itemStack) { + super.onAttachment(coverableView, side, player, itemStack); + if (player != null) { + this.playerUUID = player.getUniqueID(); + } + } + + public void updateColor(String str) { + if (str.length() == 8) { + this.color = str.toUpperCase(); + updateLink(); + } + } + + @Override + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager) { + var panel = GTGuis.createPanel(this, 176, 192); + + return panel.child(CoverWithUI.createTitleRow(getPickItem())) + .child(createWidgets(panel, guiSyncManager)) + .bindPlayerInventory(); + } + + protected Column createWidgets(ModularPanel panel, PanelSyncManager syncManager) { + var name = new StringSyncValue(this::getColorStr, this::updateColor); + + var entrySelectorSH = createEntrySelector(panel); + syncManager.syncValue("entry_selector", entrySelectorSH); + + return new Column().coverChildrenHeight().top(24) + .margin(7, 0).widthRel(1f) + .child(new Row().marginBottom(2) + .coverChildrenHeight() + .child(createPrivateButton()) + .child(createColorIcon()) + .child(new TextFieldWidget() + .height(18) + .value(name) + .setPattern(COLOR_INPUT_PATTERN) + .widthRel(0.5f) + .marginRight(2)) + .child(createEntrySlot()) + .child(new ButtonWidget<>() + .overlay(GTGuiTextures.MENU_OVERLAY) + .background(GTGuiTextures.MC_BUTTON) + .disableHoverBackground() + .addTooltipLine(IKey.lang("cover.generic.ender.open_selector")) + .onMousePressed(i -> { + if (entrySelectorSH.isPanelOpen()) { + entrySelectorSH.closePanel(); + } else { + entrySelectorSH.openPanel(); + } + Interactable.playButtonClickSound(); + return true; + }))) + .child(createIoRow()); + } + + protected abstract PanelSyncHandler createEntrySelector(ModularPanel panel); + + protected abstract IWidget createEntrySlot(); + + protected IWidget createColorIcon() { + // todo color selector popup panel + return new DynamicDrawable(() -> new Rectangle() + .setColor(this.activeEntry.getColor()) + .asIcon().size(16)) + .asWidget() + .background(GTGuiTextures.SLOT) + .size(18) + .marginRight(2); + } + + protected IWidget createPrivateButton() { + var isPrivate = new BooleanSyncValue(this::isPrivate, this::setPrivate); + isPrivate.updateCacheFromSource(true); + + return new ToggleButton() + .tooltip(tooltip -> tooltip.setAutoUpdate(true)) + .background(GTGuiTextures.PRIVATE_MODE_BUTTON[0]) + .hoverBackground(GTGuiTextures.PRIVATE_MODE_BUTTON[0]) + .selectedBackground(GTGuiTextures.PRIVATE_MODE_BUTTON[1]) + .selectedHoverBackground(GTGuiTextures.PRIVATE_MODE_BUTTON[1]) + .tooltipBuilder(tooltip -> tooltip.addLine(IKey.lang(this.isPrivate ? + "cover.ender_fluid_link.private.tooltip.enabled" : + "cover.ender_fluid_link.private.tooltip.disabled"))) + .marginRight(2) + .value(isPrivate); + } + + protected IWidget createIoRow() { + var ioEnabled = new BooleanSyncValue(this::isIoEnabled, this::setIoEnabled); + + return new Row().marginBottom(2) + .coverChildrenHeight() + .child(new ToggleButton() + .value(ioEnabled) + .overlay(IKey.dynamic(() -> IKey.lang(this.ioEnabled ? + "behaviour.soft_hammer.enabled" : + "behaviour.soft_hammer.disabled").get()) + .color(Color.WHITE.darker(1))) + .widthRel(0.6f) + .left(0)); + } + + @Override + public boolean isWorkingEnabled() { + return workingEnabled; + } + + @Override + public void setWorkingEnabled(boolean isActivationAllowed) { + this.workingEnabled = isActivationAllowed; + } + + public boolean isIoEnabled() { + return ioEnabled; + } + + protected void setIoEnabled(boolean ioEnabled) { + this.ioEnabled = ioEnabled; + } + + private boolean isPrivate() { + return isPrivate; + } + + private void setPrivate(boolean isPrivate) { + this.isPrivate = isPrivate; + updateLink(); + writeCustomData(UPDATE_PRIVATE, buffer -> buffer.writeBoolean(this.isPrivate)); + } + + @Override + public void writeInitialSyncData(PacketBuffer packetBuffer) { + packetBuffer.writeString(this.playerUUID == null ? "null" : this.playerUUID.toString()); + } + + @Override + public void readInitialSyncData(PacketBuffer packetBuffer) { + // does client even need uuid info? just in case + String uuidStr = packetBuffer.readString(36); + this.playerUUID = uuidStr.equals("null") ? null : UUID.fromString(uuidStr); + } + + @Override + public void readFromNBT(@NotNull NBTTagCompound nbt) { + super.readFromNBT(nbt); + this.ioEnabled = nbt.getBoolean("IOAllowed"); + this.isPrivate = nbt.getBoolean("Private"); + this.workingEnabled = nbt.getBoolean("WorkingAllowed"); + this.playerUUID = UUID.fromString(nbt.getString("PlacedUUID")); + int color = nbt.getInteger("Frequency"); + this.color = Integer.toHexString(color).toUpperCase(); + updateLink(); + } + + @Override + public void writeToNBT(@NotNull NBTTagCompound nbt) { + super.writeToNBT(nbt); + nbt.setBoolean("IOAllowed", ioEnabled); + nbt.setBoolean("Private", isPrivate); + nbt.setBoolean("WorkingAllowed", workingEnabled); + nbt.setString("PlacedUUID", playerUUID.toString()); + nbt.setInteger("Frequency", activeEntry.getColor()); + } + + protected abstract class EntrySelectorSH extends PanelSyncHandler { + + private static final int TRACK_SUBPANELS = 3; + private static final int DELETE_ENTRY = 1; + private final EntryTypes type; + private final ModularPanel mainPanel; + private static final String PANEL_NAME = "entry_selector"; + private final Set opened = new HashSet<>(); + protected UUID playerUUID; + + protected EntrySelectorSH(ModularPanel mainPanel, EntryTypes type) { + super(mainPanel, EntrySelectorSH::defaultPanel); + this.type = type; + this.mainPanel = mainPanel; + } + + @Override + public void init(String key, PanelSyncManager syncManager) { + super.init(key, syncManager); + this.playerUUID = syncManager.getPlayer().getUniqueID(); + } + + private static ModularPanel defaultPanel(PanelSyncManager syncManager, PanelSyncHandler syncHandler) { + return GTGuis.createPopupPanel(PANEL_NAME, 168, 112); + } + + public UUID getPlayerUUID() { + return isPrivate ? playerUUID : null; + } + + @Override + public ModularPanel createUI(PanelSyncManager syncManager) { + List names = new ArrayList<>(VirtualEnderRegistry.getEntryNames(getPlayerUUID(), type)); + return super.createUI(syncManager) + .child(IKey.lang("cover.generic.ender.known_channels") + .color(UI_TITLE_COLOR).asWidget() + .top(6) + .left(4)) + .child(ListWidget.builder(names, name -> createRow(name, this.mainPanel, syncManager)) + .background(GTGuiTextures.DISPLAY.asIcon() + .width(168 - 8) + .height(112 - 20)) + .paddingTop(1) + .size(168 - 12, 112 - 24) + .left(4) + .bottom(6)); + } + + protected IWidget createRow(String name, ModularPanel mainPanel, PanelSyncManager syncManager) { + T entry = VirtualEnderRegistry.getEntry(getPlayerUUID(), this.type, name); + String key = String.format("entry#%s_description", entry.getColorStr()); + var entryDescriptionSH = new EntryDescriptionSH(mainPanel, key, entry); + syncManager.syncValue(key, isPrivate ? 1 : 0, entryDescriptionSH); + + return new Row() + .left(4) + .marginBottom(2) + .height(18) + .widthRel(0.98f) + .setEnabledIf(row -> VirtualEnderRegistry.hasEntry(getOwner(), this.type, name)) + .child(new Rectangle() + .setColor(entry.getColor()) + .asWidget() + .marginRight(4) + .size(16) + .background(GTGuiTextures.SLOT.asIcon().size(18)) + .top(1)) + .child(new InteractableText<>(entry, CoverAbstractEnderLink.this::updateColor) + .tooltip(tooltip -> tooltip.setAutoUpdate(true)) + .tooltipBuilder(tooltip -> { + String desc = entry.getDescription(); + if (!desc.isEmpty()) + tooltip.addLine(desc); + }) + .width(64) + .height(16) + .top(1) + .marginRight(4)) + .child(new ButtonWidget<>() + .overlay(GuiTextures.GEAR) + .addTooltipLine(IKey.lang("cover.generic.ender.set_description.tooltip")) + .onMousePressed(i -> { + // open entry settings + if (entryDescriptionSH.isPanelOpen()) { + entryDescriptionSH.closePanel(); + } else { + entryDescriptionSH.openPanel(); + } + Interactable.playButtonClickSound(); + return true; + })) + .child(createSlotWidget(entry)) + .child(new ButtonWidget<>() + .overlay(GTGuiTextures.BUTTON_CROSS) + .setEnabledIf(w -> !Objects.equals(entry.getColor(), activeEntry.getColor())) + .addTooltipLine(IKey.lang("cover.generic.ender.delete_entry")) + .onMousePressed(i -> { + // todo option to force delete, maybe as a popup? + deleteEntry(getPlayerUUID(), name); + syncToServer(1, buffer -> { + NetworkUtils.writeStringSafe(buffer, getPlayerUUID().toString()); + NetworkUtils.writeStringSafe(buffer, name); + }); + Interactable.playButtonClickSound(); + return true; + })); + } + + @Override + public void closePanel() { + var manager = getSyncManager().getModularSyncManager().getPanelSyncManager(PANEL_NAME); + for (var key : opened) { + if (manager.getSyncHandler(key) instanceof PanelSyncHandler psh) { + psh.closePanel(); + } + } + super.closePanel(); + } + + @Override + @SuppressWarnings("UnstableApiUsage") + public void closePanelInternal() { + var manager = getSyncManager().getModularSyncManager().getPanelSyncManager(PANEL_NAME); + for (var key : opened) { + if (manager.getSyncHandler(key) instanceof PanelSyncHandler psh) { + psh.closePanel(); + } + } + super.closePanelInternal(); + } + + @Override + public void readOnClient(int i, PacketBuffer packetBuffer) throws IOException { + if (i == TRACK_SUBPANELS) { + handleTracking(packetBuffer); + } + super.readOnClient(i, packetBuffer); + } + + @Override + public void readOnServer(int i, PacketBuffer packetBuffer) throws IOException { + if (i == TRACK_SUBPANELS) { + handleTracking(packetBuffer); + } + super.readOnServer(i, packetBuffer); + if (i == DELETE_ENTRY) { + UUID uuid = UUID.fromString(NetworkUtils.readStringSafe(packetBuffer)); + String name = NetworkUtils.readStringSafe(packetBuffer); + deleteEntry(uuid, name); + } + } + + private void handleTracking(PacketBuffer buffer) { + boolean add = buffer.readBoolean(); + String key = NetworkUtils.readStringSafe(buffer); + if (key != null) { + if (add) opened.add(key); + else opened.remove(key); + } + } + + private class EntryDescriptionSH extends PanelSyncHandler { + + /** + * Creates a PanelSyncHandler + * + * @param mainPanel the main panel of the current GUI + */ + public EntryDescriptionSH(ModularPanel mainPanel, String key, VirtualEntry entry) { + super(mainPanel, (syncManager, syncHandler) -> defaultPanel(syncHandler, key, entry)); + } + + private static ModularPanel defaultPanel(@NotNull PanelSyncHandler syncHandler, String key, + VirtualEntry entry) { + return GTGuis.createPopupPanel(key, 168, 36 + 6) + .child(IKey.lang("cover.generic.ender.set_description.title", entry.getColorStr()) + .color(UI_TITLE_COLOR) + .asWidget() + .left(4) + .top(6)) + .child(new TextFieldWidget() + .setTextColor(Color.WHITE.darker(1)) + .widthRel(0.95f) + .height(18) + .value(new StringSyncValue(entry::getDescription, string -> { + entry.setDescription(string); + if (syncHandler.isPanelOpen()) { + syncHandler.closePanel(); + } + })) + .alignX(0.5f) + .bottom(6)); + } + + @Override + public void openPanel() { + opened.add(getKey()); + EntrySelectorSH.this.sync(3, buffer -> { + buffer.writeBoolean(true); + NetworkUtils.writeStringSafe(buffer, getKey()); + }); + super.openPanel(); + } + + @Override + public void closePanel() { + opened.remove(getKey()); + EntrySelectorSH.this.sync(3, buffer -> { + buffer.writeBoolean(false); + NetworkUtils.writeStringSafe(buffer, getKey()); + }); + super.closePanel(); + } + } + + protected abstract IWidget createSlotWidget(T entry); + + protected abstract void deleteEntry(UUID player, String name); + } +} diff --git a/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java b/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java new file mode 100644 index 00000000000..27c338154b1 --- /dev/null +++ b/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java @@ -0,0 +1,193 @@ +package gregtech.common.covers.ender; + +import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IControllable; +import gregtech.api.cover.CoverDefinition; +import gregtech.api.cover.CoverWithUI; +import gregtech.api.cover.CoverableView; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.util.FluidTankSwitchShim; +import gregtech.api.util.GTTransferUtils; +import gregtech.api.util.virtualregistry.EntryTypes; +import gregtech.api.util.virtualregistry.VirtualEnderRegistry; +import gregtech.api.util.virtualregistry.entries.VirtualTank; +import gregtech.client.renderer.texture.Textures; +import gregtech.common.covers.CoverPump; +import gregtech.common.covers.filter.FluidFilterContainer; +import gregtech.common.mui.widget.GTFluidSlot; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ITickable; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandler; + +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.IVertexOperation; +import codechicken.lib.vec.Cuboid6; +import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.widget.IWidget; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncHandler; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widgets.layout.Column; +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; + +public class CoverEnderFluidLink extends CoverAbstractEnderLink + implements CoverWithUI, ITickable, IControllable { + + public static final int TRANSFER_RATE = 8000; // mB/t + + protected CoverPump.PumpMode pumpMode = CoverPump.PumpMode.IMPORT; + private final FluidTankSwitchShim linkedTank; + protected final FluidFilterContainer fluidFilter; + + public CoverEnderFluidLink(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, + @NotNull EnumFacing attachedSide) { + super(definition, coverableView, attachedSide); + this.linkedTank = new FluidTankSwitchShim(this.activeEntry); + this.fluidFilter = new FluidFilterContainer(this); + } + + @Override + protected void updateLink() { + super.updateLink(); + if (this.linkedTank != null) + this.linkedTank.changeTank(this.activeEntry); + } + + @Override + protected EntryTypes getType() { + return EntryTypes.ENDER_FLUID; + } + + @Override + protected String identifier() { + return "EFLink#"; + } + + public FluidFilterContainer getFluidFilterContainer() { + return this.fluidFilter; + } + + @Override + public boolean canAttach(@NotNull CoverableView coverable, @NotNull EnumFacing side) { + return coverable.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side); + } + + @Override + public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 translation, + IVertexOperation[] pipeline, @NotNull Cuboid6 plateBox, @NotNull BlockRenderLayer layer) { + Textures.ENDER_FLUID_LINK.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); + } + + @Override + public void onRemoval() { + dropInventoryContents(fluidFilter); + } + + @Override + public void update() { + if (isWorkingEnabled() && isIoEnabled()) { + transferFluids(); + } + } + + protected void transferFluids() { + IFluidHandler fluidHandler = getCoverableView().getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, + getAttachedSide()); + if (fluidHandler == null) return; + if (pumpMode == CoverPump.PumpMode.IMPORT) { + GTTransferUtils.transferFluids(fluidHandler, activeEntry, TRANSFER_RATE, fluidFilter::test); + } else if (pumpMode == CoverPump.PumpMode.EXPORT) { + GTTransferUtils.transferFluids(activeEntry, fluidHandler, TRANSFER_RATE, fluidFilter::test); + } + } + + public void setPumpMode(CoverPump.PumpMode pumpMode) { + this.pumpMode = pumpMode; + markDirty(); + } + + public CoverPump.PumpMode getPumpMode() { + return pumpMode; + } + + @Override + protected PanelSyncHandler createEntrySelector(ModularPanel panel) { + return new EntrySelectorSH(panel, EntryTypes.ENDER_FLUID) { + + @Override + protected IWidget createSlotWidget(VirtualTank entry) { + var fluidTank = GTFluidSlot.sync(entry) + .canFillSlot(false) + .canDrainSlot(false); + + return new GTFluidSlot() + .size(18) + .background(GTGuiTextures.FLUID_SLOT) + .syncHandler(fluidTank) + .marginRight(2); + } + + @Override + protected void deleteEntry(UUID uuid, String name) { + VirtualEnderRegistry.deleteEntry(uuid, getType(), name, tank -> tank.getFluidAmount() == 0); + } + }; + } + + @Override + protected IWidget createEntrySlot() { + return new GTFluidSlot() + .size(18) + .background(GTGuiTextures.FLUID_SLOT) + .syncHandler(this.linkedTank) + .marginRight(2); + } + + protected Column createWidgets(ModularPanel panel, PanelSyncManager syncManager) { + getFluidFilterContainer().setMaxTransferSize(1); + + var pumpMode = new EnumSyncValue<>(CoverPump.PumpMode.class, this::getPumpMode, this::setPumpMode); + syncManager.syncValue("pump_mode", pumpMode); + pumpMode.updateCacheFromSource(true); + + return super.createWidgets(panel, syncManager) + .child(getFluidFilterContainer().initUI(panel, syncManager)) + .child(new EnumRowBuilder<>(CoverPump.PumpMode.class) + .value(pumpMode) + .overlay(GTGuiTextures.CONVEYOR_MODE_OVERLAY) + .lang("cover.pump.mode") + .build()); + } + + @Override + public void writeToNBT(NBTTagCompound tagCompound) { + super.writeToNBT(tagCompound); + tagCompound.setInteger("PumpMode", pumpMode.ordinal()); + tagCompound.setTag("Filter", fluidFilter.serializeNBT()); + } + + @Override + public void readFromNBT(NBTTagCompound tagCompound) { + super.readFromNBT(tagCompound); + this.pumpMode = CoverPump.PumpMode.values()[tagCompound.getInteger("PumpMode")]; + this.fluidFilter.deserializeNBT(tagCompound.getCompoundTag("Filter")); + } + + public T getCapability(Capability capability, T defaultValue) { + if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) { + return CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY.cast(this.activeEntry); + } + if (capability == GregtechTileCapabilities.CAPABILITY_CONTROLLABLE) { + return GregtechTileCapabilities.CAPABILITY_CONTROLLABLE.cast(this); + } + return defaultValue; + } +} diff --git a/src/main/java/gregtech/common/covers/filter/BaseFilter.java b/src/main/java/gregtech/common/covers/filter/BaseFilter.java new file mode 100644 index 00000000000..27f6a56bccb --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/BaseFilter.java @@ -0,0 +1,183 @@ +package gregtech.common.covers.filter; + +import gregtech.api.items.metaitem.MetaItem; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; +import gregtech.api.util.IDirtyNotifiable; +import gregtech.common.covers.filter.readers.BaseFilterReader; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fluids.FluidStack; + +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.api.widget.IWidget; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.CycleButtonWidget; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public abstract class BaseFilter implements IFilter { + + public static final BaseFilter ERROR_FILTER = new BaseFilter() { + + private final BaseFilterReader filterReader = new BaseFilterReader(ItemStack.EMPTY, 0); + + @Override + public BaseFilterReader getFilterReader() { + return this.filterReader; + } + + @Override + public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager) { + return GTGuis.createPopupPanel("error", 100, 100) + .child(createWidgets(syncManager)); + } + + @Override + public @NotNull ModularPanel createPanel(PanelSyncManager syncManager) { + return GTGuis.createPanel("error", 100, 100) + .child(createWidgets(syncManager)); + } + + @Override + public @NotNull Widget createWidgets(PanelSyncManager syncManager) { + return IKey.lang("INVALID FILTER").alignment(Alignment.Center).asWidget(); + } + + @Override + public FilterType getType() { + return FilterType.ITEM; + } + }; + protected IDirtyNotifiable dirtyNotifiable; + + public abstract BaseFilterReader getFilterReader(); + + public final ItemStack getContainerStack() { + return this.getFilterReader().getContainer(); + } + + public static @Nullable BaseFilter getFilterFromStack(ItemStack stack) { + if (stack.getItem() instanceof MetaItemmetaItem) { + var metaValueItem = metaItem.getItem(stack); + var factory = metaValueItem == null ? null : metaValueItem.getFilterFactory(); + if (factory != null) + return factory.create(stack); + } + return null; + } + + public final void setBlacklistFilter(boolean blacklistFilter) { + this.getFilterReader().setBlacklistFilter(blacklistFilter); + markDirty(); + } + + @Override + public final MatchResult match(Object toMatch) { + if (toMatch instanceof ItemStack stack) { + return matchItem(stack); + } else if (toMatch instanceof FluidStack stack) { + return matchFluid(stack); + } + return MatchResult.NONE; + } + + public MatchResult matchFluid(FluidStack fluidStack) { + return MatchResult.NONE; + } + + public MatchResult matchItem(ItemStack itemStack) { + return MatchResult.NONE; + } + + @Override + public final boolean test(Object toTest) { + boolean b = false; + if (toTest instanceof ItemStack stack) { + b = testItem(stack); + } else if (toTest instanceof FluidStack stack) { + b = testFluid(stack); + } + return b != isBlacklistFilter(); + } + + public boolean testFluid(FluidStack toTest) { + return false; + } + + public boolean testItem(ItemStack toTest) { + return false; + } + + @Override + public final int getTransferLimit(Object o, int transferSize) { + if (o instanceof ItemStack stack) { + return getTransferLimit(stack, transferSize); + } else if (o instanceof FluidStack stack) { + return getTransferLimit(stack, transferSize); + } + return 0; + } + + public int getTransferLimit(FluidStack stack, int transferSize) { + return 0; + } + + public int getTransferLimit(ItemStack stack, int transferSize) { + return 0; + } + + public final boolean isBlacklistFilter() { + return getFilterReader().isBlacklistFilter(); + } + + public IWidget createBlacklistUI() { + return new ParentWidget<>().coverChildren() + .child(new CycleButtonWidget() + .value(new BooleanSyncValue( + this::isBlacklistFilter, + this::setBlacklistFilter)) + .textureGetter(state -> GTGuiTextures.BUTTON_BLACKLIST[state]) + .addTooltip(0, IKey.lang("cover.filter.blacklist.disabled")) + .addTooltip(1, IKey.lang("cover.filter.blacklist.enabled"))); + } + + public final int getMaxTransferSize() { + return this.getFilterReader().getMaxTransferRate(); + } + + public final void setMaxTransferSize(int maxStackSize) { + this.getFilterReader().setMaxTransferRate(maxStackSize); + } + + public boolean showGlobalTransferLimitSlider() { + return isBlacklistFilter(); + } + + public final void setDirtyNotifiable(IDirtyNotifiable dirtyNotifiable) { + this.dirtyNotifiable = dirtyNotifiable; + this.getFilterReader().setDirtyNotifiable(dirtyNotifiable); + } + + public final void markDirty() { + if (dirtyNotifiable != null) { + dirtyNotifiable.markAsDirty(); + } + } + + public void readFromNBT(NBTTagCompound tag) { + this.getFilterReader().deserializeNBT(tag); + markDirty(); + } + + public void writeInitialSyncData(PacketBuffer packetBuffer) {} + + public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) {} +} diff --git a/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java b/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java new file mode 100644 index 00000000000..38867b542bf --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java @@ -0,0 +1,272 @@ +package gregtech.common.covers.filter; + +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.util.IDirtyNotifiable; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.items.ItemStackHandler; + +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.api.widget.IWidget; +import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.drawable.GuiTextures; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.value.sync.PanelSyncHandler; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widgets.ButtonWidget; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.layout.Row; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; + +public abstract class BaseFilterContainer extends ItemStackHandler { + + private int maxTransferSize = 1; + private int transferSize; + private @Nullable BaseFilter currentFilter; + private @Nullable Runnable onFilterInstanceChange; + private final IDirtyNotifiable dirtyNotifiable; + + protected BaseFilterContainer(IDirtyNotifiable dirtyNotifiable) { + super(); + this.dirtyNotifiable = dirtyNotifiable; + } + + public boolean test(Object toTest) { + return !hasFilter() || getFilter().test(toTest); + } + + public MatchResult match(Object toMatch) { + if (!hasFilter()) + return MatchResult.create(true, toMatch, -1); + + return getFilter().match(toMatch); + } + + public int getTransferLimit(Object stack) { + if (!hasFilter() || isBlacklistFilter()) { + return getTransferSize(); + } + return getFilter().getTransferLimit(stack, getTransferSize()); + } + + @Override + public int getSlotLimit(int slot) { + return 1; + } + + public void onFilterInstanceChange() { + dirtyNotifiable.markAsDirty(); + if (onFilterInstanceChange != null) { + onFilterInstanceChange.run(); + } + } + + public void setOnFilterInstanceChange(@Nullable Runnable onFilterInstanceChange) { + this.onFilterInstanceChange = onFilterInstanceChange; + } + + public final @NotNull ItemStack getFilterStack() { + return this.getStackInSlot(0); + } + + @Override + public void setStackInSlot(int slot, @NotNull ItemStack stack) { + if (ItemStack.areItemStacksEqual(stack, getFilterStack())) + return; + + if (stack.isEmpty()) { + setFilter(null); + } else if (isItemValid(stack)) { + setFilter(BaseFilter.getFilterFromStack(stack)); + } + + super.setStackInSlot(slot, stack); + } + + @Override + public boolean isItemValid(int slot, @NotNull ItemStack stack) { + return isItemValid(stack); + } + + protected abstract boolean isItemValid(ItemStack stack); + + protected abstract String getFilterName(); + + @Override + public @NotNull ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + if (!isItemValid(stack)) return stack; + var remainder = super.insertItem(slot, stack, simulate); + if (!simulate) setFilter(BaseFilter.getFilterFromStack(stack)); + return remainder; + } + + @Override + public @NotNull ItemStack extractItem(int slot, int amount, boolean simulate) { + var extracted = super.extractItem(slot, amount, simulate); + if (!extracted.isEmpty()) { + setFilter(null); + } + return extracted; + } + + public final void setFilterStack(ItemStack stack) { + setStackInSlot(0, stack); + } + + public int getMaxTransferSize() { + return !showGlobalTransferLimitSlider() && hasFilter() ? currentFilter.getMaxTransferSize() : + this.maxTransferSize; + } + + public void setMaxTransferSize(int maxTransferSize) { + this.maxTransferSize = MathHelper.clamp(maxTransferSize, 1, Integer.MAX_VALUE); + this.transferSize = MathHelper.clamp(this.transferSize, 1, this.maxTransferSize); + if (hasFilter()) currentFilter.setMaxTransferSize(this.maxTransferSize); + } + + public final boolean hasFilter() { + return currentFilter != null; + } + + public final @Nullable BaseFilter getFilter() { + return currentFilter; + } + + public final void setFilter(@Nullable BaseFilter newFilter) { + this.currentFilter = newFilter; + if (hasFilter()) { + this.currentFilter.setDirtyNotifiable(this.dirtyNotifiable); + this.currentFilter.setMaxTransferSize(this.maxTransferSize); + } + if (onFilterInstanceChange != null) { + this.onFilterInstanceChange.run(); + } + } + + public boolean showGlobalTransferLimitSlider() { + return this.maxTransferSize > 0 && (!hasFilter() || getFilter().showGlobalTransferLimitSlider()); + } + + public void setBlacklistFilter(boolean blacklistFilter) { + if (hasFilter()) getFilter().setBlacklistFilter(blacklistFilter); + onFilterInstanceChange(); + } + + public final boolean isBlacklistFilter() { + return hasFilter() && getFilter().isBlacklistFilter(); + } + + public int getTransferSize() { + if (!showGlobalTransferLimitSlider()) { + return getMaxTransferSize(); + } + return this.transferSize; + } + + public int getTransferLimit(int slotIndex) { + if (isBlacklistFilter() || !hasFilter()) { + return getTransferSize(); + } + return this.currentFilter.getTransferLimit(slotIndex, getTransferSize()); + } + + public void setTransferSize(int transferSize) { + this.transferSize = MathHelper.clamp(transferSize, 1, getMaxTransferSize()); + onFilterInstanceChange(); + } + + @Override + public NBTTagCompound serializeNBT() { + NBTTagCompound tagCompound = new NBTTagCompound(); + tagCompound.setTag("FilterInventory", super.serializeNBT()); + tagCompound.setInteger("TransferStackSize", getTransferSize()); + return tagCompound; + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + super.deserializeNBT(nbt.getCompoundTag("FilterInventory")); + setFilter(BaseFilter.getFilterFromStack(getFilterStack())); + if (nbt.hasKey("TransferStackSize")) + this.transferSize = nbt.getInteger("TransferStackSize"); + } + + public void handleLegacyNBT(NBTTagCompound nbt) { + // for filters as covers, the stack is set manually, and "FilterInventory" doesn't exist to be deserialized + // also, ItemStackHandler's deserialization doesn't use setStackInSlot, so I have to do that manually here + if (nbt.hasKey("FilterInventory")) { + super.deserializeNBT(nbt.getCompoundTag("FilterInventory")); + setFilter(BaseFilter.getFilterFromStack(getFilterStack())); + } + + if (hasFilter()) + getFilter().getFilterReader().handleLegacyNBT(nbt); + } + + /** Uses Cleanroom MUI */ + public IWidget initUI(ModularPanel main, PanelSyncManager manager) { + PanelSyncHandler panel = manager.panel("filter_panel", main, (syncManager, syncHandler) -> { + var filter = hasFilter() ? getFilter() : BaseFilter.ERROR_FILTER; + filter.setMaxTransferSize(getMaxTransferSize()); + return filter.createPopupPanel(syncManager); + }); + + var filterButton = new ButtonWidget<>(); + filterButton.setEnabled(hasFilter()); + + return new Row().coverChildrenHeight() + .marginBottom(2).widthRel(1f) + .child(new ItemSlot() + .slot(SyncHandlers.itemSlot(this, 0) + .filter(this::isItemValid) + .singletonSlotGroup(101) + .changeListener((newItem, onlyAmountChanged, client, init) -> { + if (!isItemValid(newItem) && panel.isPanelOpen()) { + panel.closePanel(); + } + })) + .size(18).marginRight(2) + .background(GTGuiTextures.SLOT, GTGuiTextures.FILTER_SLOT_OVERLAY.asIcon().size(16))) + .child(filterButton + .background(GTGuiTextures.MC_BUTTON, GTGuiTextures.FILTER_SETTINGS_OVERLAY.asIcon().size(16)) + .hoverBackground(GuiTextures.MC_BUTTON_HOVERED, + GTGuiTextures.FILTER_SETTINGS_OVERLAY.asIcon().size(16)) + .setEnabledIf(w -> hasFilter()) + .onMousePressed(i -> { + if (!panel.isPanelOpen()) { + panel.openPanel(); + } else { + panel.closePanel(); + } + Interactable.playButtonClickSound(); + return true; + })) + .child(IKey.dynamic(this::getFilterName) + .alignment(Alignment.CenterRight).asWidget() + .left(36).right(0).height(18)); + } + + public void writeInitialSyncData(PacketBuffer packetBuffer) { + packetBuffer.writeItemStack(this.getFilterStack()); + packetBuffer.writeInt(this.maxTransferSize); + packetBuffer.writeInt(this.transferSize); + } + + public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { + var stack = ItemStack.EMPTY; + try { + stack = packetBuffer.readItemStack(); + } catch (IOException ignore) {} + this.setFilterStack(stack); + this.setMaxTransferSize(packetBuffer.readInt()); + this.setTransferSize(packetBuffer.readInt()); + } +} diff --git a/src/main/java/gregtech/common/covers/filter/FilterTypeRegistry.java b/src/main/java/gregtech/common/covers/filter/FilterTypeRegistry.java deleted file mode 100644 index 633242b05d2..00000000000 --- a/src/main/java/gregtech/common/covers/filter/FilterTypeRegistry.java +++ /dev/null @@ -1,103 +0,0 @@ -package gregtech.common.covers.filter; - -import gregtech.api.unification.stack.ItemAndMetadata; -import gregtech.api.util.GTLog; -import gregtech.common.items.MetaItems; - -import net.minecraft.item.ItemStack; - -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; - -import java.util.Map; - -public class FilterTypeRegistry { - - private static final Map itemFilterIdByStack = new Object2IntOpenHashMap<>(); - private static final Map fluidFilterIdByStack = new Object2IntOpenHashMap<>(); - private static final BiMap> itemFilterById = HashBiMap.create(); - private static final BiMap> fluidFilterById = HashBiMap.create(); - - public static void init() { - registerFluidFilter(1, SimpleFluidFilter.class, MetaItems.FLUID_FILTER.getStackForm()); - registerItemFilter(2, SimpleItemFilter.class, MetaItems.ITEM_FILTER.getStackForm()); - registerItemFilter(3, OreDictionaryItemFilter.class, MetaItems.ORE_DICTIONARY_FILTER.getStackForm()); - registerItemFilter(4, SmartItemFilter.class, MetaItems.SMART_FILTER.getStackForm()); - } - - public static void registerFluidFilter(int id, Class fluidFilterClass, ItemStack itemStack) { - if (fluidFilterById.containsKey(id)) { - throw new IllegalArgumentException("Id is already occupied: " + id); - } - fluidFilterIdByStack.put(new ItemAndMetadata(itemStack), id); - fluidFilterById.put(id, fluidFilterClass); - } - - public static void registerItemFilter(int id, Class itemFilterClass, ItemStack itemStack) { - if (itemFilterById.containsKey(id)) { - throw new IllegalArgumentException("Id is already occupied: " + id); - } - itemFilterIdByStack.put(new ItemAndMetadata(itemStack), id); - itemFilterById.put(id, itemFilterClass); - } - - public static int getIdForItemFilter(ItemFilter itemFilter) { - Integer filterId = itemFilterById.inverse().get(itemFilter.getClass()); - if (filterId == null) { - throw new IllegalArgumentException("Unknown filter type " + itemFilter.getClass()); - } - return filterId; - } - - public static int getIdForFluidFilter(FluidFilter fluidFilter) { - Integer filterId = fluidFilterById.inverse().get(fluidFilter.getClass()); - if (filterId == null) { - throw new IllegalArgumentException("Unknown filter type " + fluidFilter.getClass()); - } - return filterId; - } - - public static ItemFilter createItemFilterById(int filterId) { - Class filterClass = itemFilterById.get(filterId); - if (filterClass == null) { - throw new IllegalArgumentException("Unknown filter id: " + filterId); - } - return createNewFilterInstance(filterClass); - } - - public static FluidFilter createFluidFilterById(int filterId) { - Class filterClass = fluidFilterById.get(filterId); - if (filterClass == null) { - throw new IllegalArgumentException("Unknown filter id: " + filterId); - } - return createNewFilterInstance(filterClass); - } - - public static ItemFilter getItemFilterForStack(ItemStack itemStack) { - Integer filterId = itemFilterIdByStack.get(new ItemAndMetadata(itemStack)); - if (filterId == null) { - return null; - } - Class filterClass = itemFilterById.get(filterId); - return createNewFilterInstance(filterClass); - } - - public static FluidFilter getFluidFilterForStack(ItemStack itemStack) { - Integer filterId = fluidFilterIdByStack.get(new ItemAndMetadata(itemStack)); - if (filterId == null) { - return null; - } - Class filterClass = fluidFilterById.get(filterId); - return createNewFilterInstance(filterClass); - } - - private static T createNewFilterInstance(Class filterClass) { - try { - return filterClass.newInstance(); - } catch (ReflectiveOperationException exception) { - GTLog.logger.error("Failed to create filter instance for class {}", filterClass, exception); - return null; - } - } -} diff --git a/src/main/java/gregtech/common/covers/filter/FluidFilter.java b/src/main/java/gregtech/common/covers/filter/FluidFilter.java deleted file mode 100644 index 6d6dc23254b..00000000000 --- a/src/main/java/gregtech/common/covers/filter/FluidFilter.java +++ /dev/null @@ -1,41 +0,0 @@ -package gregtech.common.covers.filter; - -import gregtech.api.gui.Widget; -import gregtech.api.util.IDirtyNotifiable; - -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.fluids.FluidStack; - -import java.util.function.Consumer; - -public abstract class FluidFilter { - - private IDirtyNotifiable dirtyNotifiable; - boolean showTip; - - public abstract boolean testFluid(FluidStack fluidStack); - - public abstract int getFluidTransferLimit(FluidStack fluidStack); - - public abstract int getMaxOccupiedHeight(); - - public abstract void initUI(Consumer widgetGroup); - - public abstract void writeToNBT(NBTTagCompound tagCompound); - - public abstract void readFromNBT(NBTTagCompound tagCompound); - - public final void setDirtyNotifiable(IDirtyNotifiable dirtyNotifiable) { - this.dirtyNotifiable = dirtyNotifiable; - } - - public abstract void configureFilterTanks(int amount); - - public abstract void setMaxConfigurableFluidSize(int maxStackSize); - - public final void markDirty() { - if (dirtyNotifiable != null) { - dirtyNotifiable.markAsDirty(); - } - } -} diff --git a/src/main/java/gregtech/common/covers/filter/FluidFilterContainer.java b/src/main/java/gregtech/common/covers/filter/FluidFilterContainer.java index 41beb67b6d6..a3793c0ffed 100644 --- a/src/main/java/gregtech/common/covers/filter/FluidFilterContainer.java +++ b/src/main/java/gregtech/common/covers/filter/FluidFilterContainer.java @@ -1,128 +1,64 @@ package gregtech.common.covers.filter; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.SlotWidget; import gregtech.api.util.IDirtyNotifiable; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.common.util.INBTSerializable; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.items.ItemStackHandler; -import org.jetbrains.annotations.NotNull; +import com.cleanroommc.modularui.api.drawable.IKey; +import org.jetbrains.annotations.ApiStatus; +import java.util.function.BooleanSupplier; import java.util.function.Consumer; -import java.util.function.Supplier; -public class FluidFilterContainer implements INBTSerializable { - - private final ItemStackHandler filterInventory; - private final FluidFilterWrapper filterWrapper; - - public FluidFilterContainer(IDirtyNotifiable dirtyNotifiable, int capacity) { - this.filterWrapper = new FluidFilterWrapper(dirtyNotifiable, capacity); - this.filterInventory = new ItemStackHandler(1) { - - @Override - public boolean isItemValid(int slot, @NotNull ItemStack stack) { - return FilterTypeRegistry.getFluidFilterForStack(stack) != null; - } - - @Override - public int getSlotLimit(int slot) { - return 1; - } - - @Override - protected void onLoad() { - onFilterSlotChange(false); - } - - @Override - protected void onContentsChanged(int slot) { - onFilterSlotChange(true); - } - }; - } - - public FluidFilterContainer(IDirtyNotifiable dirtyNotifiable, Supplier showTip, int maxSize) { - this(dirtyNotifiable, maxSize); - filterWrapper.setTipSupplier(showTip); - } - - public FluidFilterContainer(IDirtyNotifiable dirtyNotifiable, Supplier showTip) { - this(dirtyNotifiable, 1000); - filterWrapper.setTipSupplier(showTip); - } +public class FluidFilterContainer extends BaseFilterContainer { public FluidFilterContainer(IDirtyNotifiable dirtyNotifiable) { - this(dirtyNotifiable, 1000); - filterWrapper.setTipSupplier(() -> false); - } - - public ItemStackHandler getFilterInventory() { - return filterInventory; - } - - public FluidFilterWrapper getFilterWrapper() { - return filterWrapper; - } - - public void initUI(int y, Consumer widgetGroup) { - widgetGroup.accept(new LabelWidget(10, y, "cover.pump.fluid_filter.title")); - widgetGroup.accept(new SlotWidget(filterInventory, 0, 10, y + 15) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.FILTER_SLOT_OVERLAY)); - - this.filterWrapper.initUI(y + 15, widgetGroup); - this.filterWrapper.blacklistUI(y + 15, widgetGroup, () -> true); + super(dirtyNotifiable); } - protected void onFilterSlotChange(boolean notify) { - ItemStack filterStack = filterInventory.getStackInSlot(0); - FluidFilter newFluidFilter = FilterTypeRegistry.getFluidFilterForStack(filterStack); - FluidFilter currentFluidFilter = filterWrapper.getFluidFilter(); - if (newFluidFilter == null) { - if (currentFluidFilter != null) { - filterWrapper.setFluidFilter(null); - if (notify) filterWrapper.onFilterInstanceChange(); - } - } else if (currentFluidFilter == null || - newFluidFilter.getClass() != currentFluidFilter.getClass()) { - filterWrapper.setFluidFilter(newFluidFilter); - if (notify) filterWrapper.onFilterInstanceChange(); - } + /** @deprecated uses old builtin MUI */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.10") + public void initUI(int y, Consumer widgetGroup) { + widgetGroup.accept(new gregtech.api.gui.widgets.LabelWidget(10, y, "cover.pump.fluid_filter.title")); + widgetGroup.accept(new gregtech.api.gui.widgets.SlotWidget(this, 0, 10, y + 15) + .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT, + gregtech.api.gui.GuiTextures.FILTER_SLOT_OVERLAY)); + + this.initFilterUI(y + 15, widgetGroup); + this.blacklistUI(y + 15, widgetGroup, () -> true); } - public boolean testFluidStack(FluidStack fluidStack) { - return filterWrapper.testFluidStack(fluidStack); + /** @deprecated uses old builtin MUI */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.10") + public void initFilterUI(int y, Consumer widgetGroup) { + widgetGroup.accept(new WidgetGroupFluidFilter(y, this::getFilter, this::showGlobalTransferLimitSlider)); } - public boolean testFluidStack(FluidStack fluidStack, Boolean whitelist) { - return filterWrapper.testFluidStack(fluidStack, whitelist); + /** @deprecated uses old builtin MUI */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.10") + public void blacklistUI(int y, Consumer widgetGroup, BooleanSupplier showBlacklistButton) { + gregtech.api.gui.widgets.ServerWidgetGroup blacklistButton = new gregtech.api.gui.widgets.ServerWidgetGroup( + this::hasFilter); + blacklistButton.addWidget(new gregtech.api.gui.widgets.ToggleButtonWidget(144, y, 18, 18, + gregtech.api.gui.GuiTextures.BUTTON_BLACKLIST, + this::isBlacklistFilter, this::setBlacklistFilter).setPredicate(showBlacklistButton) + .setTooltipText("cover.filter.blacklist")); + widgetGroup.accept(blacklistButton); } @Override - public NBTTagCompound serializeNBT() { - NBTTagCompound tagCompound = new NBTTagCompound(); - tagCompound.setTag("FilterInventory", filterInventory.serializeNBT()); - tagCompound.setBoolean("IsBlacklist", filterWrapper.isBlacklistFilter()); - if (filterWrapper.getFluidFilter() != null) { - NBTTagCompound filterInventory = new NBTTagCompound(); - filterWrapper.getFluidFilter().writeToNBT(filterInventory); - tagCompound.setTag("Filter", filterInventory); - } - return tagCompound; + protected boolean isItemValid(ItemStack stack) { + var filter = BaseFilter.getFilterFromStack(stack); + return filter != null && filter.getType() == IFilter.FilterType.FLUID; } @Override - public void deserializeNBT(NBTTagCompound tagCompound) { - this.filterInventory.deserializeNBT(tagCompound.getCompoundTag("FilterInventory")); - this.filterWrapper.setBlacklistFilter(tagCompound.getBoolean("IsBlacklist")); - if (filterWrapper.getFluidFilter() != null) { - this.filterWrapper.getFluidFilter().readFromNBT(tagCompound.getCompoundTag("Filter")); - } + protected String getFilterName() { + return hasFilter() ? + getFilterStack().getDisplayName() : + IKey.lang("metaitem.fluid_filter.name").get(); } } diff --git a/src/main/java/gregtech/common/covers/filter/FluidFilterWrapper.java b/src/main/java/gregtech/common/covers/filter/FluidFilterWrapper.java deleted file mode 100644 index 2ef1f76a32e..00000000000 --- a/src/main/java/gregtech/common/covers/filter/FluidFilterWrapper.java +++ /dev/null @@ -1,98 +0,0 @@ -package gregtech.common.covers.filter; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.ServerWidgetGroup; -import gregtech.api.gui.widgets.ToggleButtonWidget; -import gregtech.api.util.IDirtyNotifiable; - -import net.minecraftforge.fluids.FluidStack; - -import java.util.function.BooleanSupplier; -import java.util.function.Consumer; -import java.util.function.Supplier; - -public class FluidFilterWrapper { - - private final IDirtyNotifiable dirtyNotifiable; - private boolean isBlacklistFilter = false; - private FluidFilter currentFluidFilter; - private Supplier showTipSupplier; - private int maxSize = 1000; - - public FluidFilterWrapper(IDirtyNotifiable dirtyNotifiable, int maxSize) { - this.dirtyNotifiable = dirtyNotifiable; - this.maxSize = maxSize; - } - - public FluidFilterWrapper(IDirtyNotifiable dirtyNotifiable) { - this.dirtyNotifiable = dirtyNotifiable; - } - - public void initUI(int y, Consumer widgetGroup) { - widgetGroup.accept(new WidgetGroupFluidFilter(y, this::getFluidFilter, shouldShowTip())); - } - - public void blacklistUI(int y, Consumer widgetGroup, BooleanSupplier showBlacklistButton) { - ServerWidgetGroup blacklistButton = new ServerWidgetGroup(() -> getFluidFilter() != null); - blacklistButton.addWidget(new ToggleButtonWidget(144, y, 18, 18, GuiTextures.BUTTON_BLACKLIST, - this::isBlacklistFilter, this::setBlacklistFilter).setPredicate(showBlacklistButton) - .setTooltipText("cover.filter.blacklist")); - widgetGroup.accept(blacklistButton); - } - - public void setFluidFilter(FluidFilter fluidFilter) { - this.currentFluidFilter = fluidFilter; - if (currentFluidFilter != null) { - currentFluidFilter.setDirtyNotifiable(dirtyNotifiable); - currentFluidFilter.setMaxConfigurableFluidSize(maxSize); - } - } - - private Supplier shouldShowTip() { - return showTipSupplier; - } - - protected void setTipSupplier(Supplier supplier) { - this.showTipSupplier = supplier; - } - - public FluidFilter getFluidFilter() { - return currentFluidFilter; - } - - public void onFilterInstanceChange() { - dirtyNotifiable.markAsDirty(); - } - - public void setBlacklistFilter(boolean blacklistFilter) { - isBlacklistFilter = blacklistFilter; - dirtyNotifiable.markAsDirty(); - } - - public boolean isBlacklistFilter() { - return isBlacklistFilter; - } - - public boolean testFluidStack(FluidStack fluidStack, boolean whitelist) { - boolean result = true; - if (currentFluidFilter != null) { - result = currentFluidFilter.testFluid(fluidStack); - } - if (!whitelist) { - result = !result; - } - return result; - } - - public boolean testFluidStack(FluidStack fluidStack) { - boolean result = true; - if (currentFluidFilter != null) { - result = currentFluidFilter.testFluid(fluidStack); - } - if (isBlacklistFilter) { - result = !result; - } - return result; - } -} diff --git a/src/main/java/gregtech/common/covers/filter/IFilter.java b/src/main/java/gregtech/common/covers/filter/IFilter.java new file mode 100644 index 00000000000..05441442eb0 --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/IFilter.java @@ -0,0 +1,77 @@ +package gregtech.common.covers.filter; + +import gregtech.api.items.metaitem.stats.IItemComponent; +import gregtech.api.util.IDirtyNotifiable; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widget.Widget; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Consumer; + +public interface IFilter { + + @Deprecated + default void initUI(Consumer widgetGroup) {} + + /** Uses Cleanroom MUI */ + @NotNull + ModularPanel createPopupPanel(PanelSyncManager syncManager); + + /** Uses Cleanroom MUI */ + @NotNull + ModularPanel createPanel(PanelSyncManager syncManager); + + /** Uses Cleanroom MUI - Creates the widgets standalone so that they can be put into their own panel */ + + @NotNull + Widget createWidgets(PanelSyncManager syncManager); + + ItemStack getContainerStack(); + + void setDirtyNotifiable(@Nullable IDirtyNotifiable dirtyNotifiable); + + void markDirty(); + + int getMaxTransferSize(); + + void setMaxTransferSize(int maxTransferSize); + + boolean showGlobalTransferLimitSlider(); + + MatchResult match(Object toMatch); + + boolean test(Object toTest); + + int getTransferLimit(Object stack, int transferSize); + + default int getTransferLimit(int slot, int transferSize) { + return transferSize; + } + + void readFromNBT(NBTTagCompound tagCompound); + + FilterType getType(); + + enum FilterType { + ITEM, + FLUID + } + + // this only exists so i can pass in the constructor reference as a metaitem componant + static Factory factory(Factory factory) { + return factory; + } + + @FunctionalInterface + interface Factory extends IItemComponent { + + @NotNull + BaseFilter create(@NotNull ItemStack stack); + } +} diff --git a/src/main/java/gregtech/common/covers/filter/ItemFilter.java b/src/main/java/gregtech/common/covers/filter/ItemFilter.java deleted file mode 100644 index a5b350da33d..00000000000 --- a/src/main/java/gregtech/common/covers/filter/ItemFilter.java +++ /dev/null @@ -1,50 +0,0 @@ -package gregtech.common.covers.filter; - -import gregtech.api.gui.Widget; -import gregtech.api.util.IDirtyNotifiable; - -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; - -import java.util.function.Consumer; - -public abstract class ItemFilter { - - private IDirtyNotifiable dirtyNotifiable; - private int maxStackSize = Integer.MAX_VALUE; - - public final int getMaxStackSize() { - return maxStackSize; - } - - public final void setMaxStackSize(int maxStackSize) { - this.maxStackSize = maxStackSize; - onMaxStackSizeChange(); - } - - protected void onMaxStackSizeChange() {} - - public abstract boolean showGlobalTransferLimitSlider(); - - public abstract int getSlotTransferLimit(Object matchSlot, int globalTransferLimit); - - public abstract Object matchItemStack(ItemStack itemStack); - - public abstract int getTotalOccupiedHeight(); - - public abstract void initUI(Consumer widgetGroup); - - public abstract void writeToNBT(NBTTagCompound tagCompound); - - public abstract void readFromNBT(NBTTagCompound tagCompound); - - final void setDirtyNotifiable(IDirtyNotifiable dirtyNotifiable) { - this.dirtyNotifiable = dirtyNotifiable; - } - - public final void markDirty() { - if (dirtyNotifiable != null) { - dirtyNotifiable.markAsDirty(); - } - } -} diff --git a/src/main/java/gregtech/common/covers/filter/ItemFilterContainer.java b/src/main/java/gregtech/common/covers/filter/ItemFilterContainer.java index 71be9ff14d3..d282595253d 100644 --- a/src/main/java/gregtech/common/covers/filter/ItemFilterContainer.java +++ b/src/main/java/gregtech/common/covers/filter/ItemFilterContainer.java @@ -1,165 +1,65 @@ package gregtech.common.covers.filter; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.Widget; import gregtech.api.gui.widgets.LabelWidget; +import gregtech.api.gui.widgets.ServerWidgetGroup; import gregtech.api.gui.widgets.SlotWidget; +import gregtech.api.gui.widgets.ToggleButtonWidget; import gregtech.api.util.IDirtyNotifiable; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.math.MathHelper; -import net.minecraftforge.common.util.INBTSerializable; -import net.minecraftforge.items.ItemStackHandler; -import org.jetbrains.annotations.NotNull; +import com.cleanroommc.modularui.api.drawable.IKey; +import org.jetbrains.annotations.ApiStatus; +import java.util.function.BooleanSupplier; import java.util.function.Consumer; -public class ItemFilterContainer implements INBTSerializable { - - private final ItemStackHandler filterInventory; - private final ItemFilterWrapper filterWrapper; - private int maxStackSizeLimit = 1; - private int transferStackSize; +public class ItemFilterContainer extends BaseFilterContainer { public ItemFilterContainer(IDirtyNotifiable dirtyNotifiable) { - this.filterWrapper = new ItemFilterWrapper(dirtyNotifiable); - this.filterWrapper.setOnFilterInstanceChange(this::onFilterInstanceChange); - this.filterInventory = new ItemStackHandler(1) { - - @Override - public boolean isItemValid(int slot, @NotNull ItemStack stack) { - return FilterTypeRegistry.getItemFilterForStack(stack) != null; - } - - @Override - public int getSlotLimit(int slot) { - return 1; - } - - @Override - protected void onLoad() { - onFilterSlotChange(false); - } - - @Override - protected void onContentsChanged(int slot) { - onFilterSlotChange(true); - } - }; - } - - public ItemStackHandler getFilterInventory() { - return filterInventory; - } - - public ItemFilterWrapper getFilterWrapper() { - return filterWrapper; - } - - private void onFilterInstanceChange() { - this.filterWrapper.setMaxStackSize(getTransferStackSize()); - } - - public int getMaxStackSize() { - return maxStackSizeLimit; - } - - public int getTransferStackSize() { - if (!showGlobalTransferLimitSlider()) { - return getMaxStackSize(); - } - return transferStackSize; + super(dirtyNotifiable); } - public void setTransferStackSize(int transferStackSize) { - this.transferStackSize = MathHelper.clamp(transferStackSize, 1, getMaxStackSize()); - this.filterWrapper.setMaxStackSize(getTransferStackSize()); - } - - public void adjustTransferStackSize(int amount) { - setTransferStackSize(transferStackSize + amount); - } - - public void initUI(int y, Consumer widgetGroup) { + /** @deprecated uses old builtin MUI */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.10") + public void initUI(int y, Consumer widgetGroup) { widgetGroup.accept(new LabelWidget(10, y, "cover.conveyor.item_filter.title")); - widgetGroup.accept(new SlotWidget(filterInventory, 0, 10, y + 15) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.FILTER_SLOT_OVERLAY)); - - this.filterWrapper.initUI(y + 38, widgetGroup); - this.filterWrapper.blacklistUI(y + 38, widgetGroup, () -> true); - } - - protected void onFilterSlotChange(boolean notify) { - ItemStack filterStack = filterInventory.getStackInSlot(0); - ItemFilter newItemFilter = FilterTypeRegistry.getItemFilterForStack(filterStack); - ItemFilter currentItemFilter = filterWrapper.getItemFilter(); - if (newItemFilter == null) { - if (currentItemFilter != null) { - filterWrapper.setItemFilter(null); - filterWrapper.setBlacklistFilter(false); - if (notify) filterWrapper.onFilterInstanceChange(); - } - } else if (currentItemFilter == null || - newItemFilter.getClass() != currentItemFilter.getClass()) { - filterWrapper.setItemFilter(newItemFilter); - if (notify) filterWrapper.onFilterInstanceChange(); - } - } - - public void setMaxStackSize(int maxStackSizeLimit) { - this.maxStackSizeLimit = maxStackSizeLimit; - setTransferStackSize(transferStackSize); - } - - public boolean showGlobalTransferLimitSlider() { - return getMaxStackSize() > 1 && filterWrapper.showGlobalTransferLimitSlider(); - } - - public int getSlotTransferLimit(Object slotIndex) { - return filterWrapper.getSlotTransferLimit(slotIndex, getTransferStackSize()); - } - - public Object matchItemStack(ItemStack itemStack) { - return filterWrapper.matchItemStack(itemStack); - } + widgetGroup.accept(new SlotWidget(this, 0, 10, y + 15) + .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT, + gregtech.api.gui.GuiTextures.FILTER_SLOT_OVERLAY)); - public Object matchItemStack(ItemStack itemStack, boolean whitelist) { - return filterWrapper.matchItemStack(itemStack, whitelist); + this.initFilterUI(y + 38, widgetGroup); } - public boolean testItemStack(ItemStack itemStack) { - return matchItemStack(itemStack) != null; + /** @deprecated uses old builtin MUI */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.10") + public void initFilterUI(int y, Consumer widgetGroup) { + widgetGroup.accept(new WidgetGroupItemFilter(y, this::getFilter)); } - public boolean testItemStack(ItemStack itemStack, boolean whitelist) { - return matchItemStack(itemStack, whitelist) != null; + /** @deprecated uses old builtin MUI */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.10") + public void blacklistUI(int y, Consumer widgetGroup, BooleanSupplier showBlacklistButton) { + ServerWidgetGroup blacklistButton = new ServerWidgetGroup(this::hasFilter); + blacklistButton.addWidget(new ToggleButtonWidget(144, y, 20, 20, gregtech.api.gui.GuiTextures.BUTTON_BLACKLIST, + this::isBlacklistFilter, this::setBlacklistFilter).setPredicate(showBlacklistButton) + .setTooltipText("cover.filter.blacklist")); + widgetGroup.accept(blacklistButton); } @Override - public NBTTagCompound serializeNBT() { - NBTTagCompound tagCompound = new NBTTagCompound(); - tagCompound.setTag("FilterInventory", filterInventory.serializeNBT()); - tagCompound.setBoolean("IsBlacklist", filterWrapper.isBlacklistFilter()); - tagCompound.setInteger("MaxStackSize", maxStackSizeLimit); - tagCompound.setInteger("TransferStackSize", transferStackSize); - if (filterWrapper.getItemFilter() != null) { - NBTTagCompound filterInventory = new NBTTagCompound(); - filterWrapper.getItemFilter().writeToNBT(filterInventory); - tagCompound.setTag("Filter", filterInventory); - } - return tagCompound; + protected boolean isItemValid(ItemStack stack) { + var filter = BaseFilter.getFilterFromStack(stack); + return filter != null && filter.getType() == IFilter.FilterType.ITEM; } @Override - public void deserializeNBT(NBTTagCompound tagCompound) { - this.filterInventory.deserializeNBT(tagCompound.getCompoundTag("FilterInventory")); - this.filterWrapper.setBlacklistFilter(tagCompound.getBoolean("IsBlacklist")); - setMaxStackSize(tagCompound.getInteger("MaxStackSize")); - setTransferStackSize(tagCompound.getInteger("TransferStackSize")); - if (filterWrapper.getItemFilter() != null) { - this.filterWrapper.getItemFilter().readFromNBT(tagCompound.getCompoundTag("Filter")); - } + protected String getFilterName() { + return hasFilter() ? + getFilterStack().getDisplayName() : + IKey.lang("metaitem.item_filter.name").get(); } } diff --git a/src/main/java/gregtech/common/covers/filter/ItemFilterWrapper.java b/src/main/java/gregtech/common/covers/filter/ItemFilterWrapper.java deleted file mode 100644 index d11905e00b5..00000000000 --- a/src/main/java/gregtech/common/covers/filter/ItemFilterWrapper.java +++ /dev/null @@ -1,132 +0,0 @@ -package gregtech.common.covers.filter; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.ServerWidgetGroup; -import gregtech.api.gui.widgets.ToggleButtonWidget; -import gregtech.api.util.IDirtyNotifiable; - -import net.minecraft.item.ItemStack; - -import java.util.function.BooleanSupplier; -import java.util.function.Consumer; - -public class ItemFilterWrapper { - - private static final Object MATCH_RESULT_TRUE = new Object(); - private final IDirtyNotifiable dirtyNotifiable; - private boolean isBlacklistFilter = false; - private int maxStackSize = 1; - private ItemFilter currentItemFilter; - private Runnable onFilterInstanceChange; - - public ItemFilterWrapper(IDirtyNotifiable dirtyNotifiable) { - this.dirtyNotifiable = dirtyNotifiable; - } - - public void initUI(int y, Consumer widgetGroup) { - widgetGroup.accept(new WidgetGroupItemFilter(y, this::getItemFilter)); - } - - public void blacklistUI(int y, Consumer widgetGroup, BooleanSupplier showBlacklistButton) { - ServerWidgetGroup blacklistButton = new ServerWidgetGroup(() -> getItemFilter() != null); - blacklistButton.addWidget(new ToggleButtonWidget(144, y, 20, 20, GuiTextures.BUTTON_BLACKLIST, - this::isBlacklistFilter, this::setBlacklistFilter).setPredicate(showBlacklistButton) - .setTooltipText("cover.filter.blacklist")); - widgetGroup.accept(blacklistButton); - } - - public void setItemFilter(ItemFilter itemFilter) { - this.currentItemFilter = itemFilter; - if (currentItemFilter != null) { - currentItemFilter.setDirtyNotifiable(dirtyNotifiable); - } - if (onFilterInstanceChange != null) { - this.onFilterInstanceChange.run(); - } - } - - public ItemFilter getItemFilter() { - return currentItemFilter; - } - - public void setOnFilterInstanceChange(Runnable onFilterInstanceChange) { - this.onFilterInstanceChange = onFilterInstanceChange; - } - - public void onFilterInstanceChange() { - if (currentItemFilter != null) { - currentItemFilter.setMaxStackSize(getInternalMaxStackSize()); - } - dirtyNotifiable.markAsDirty(); - } - - public void setMaxStackSize(int maxStackSize) { - this.maxStackSize = maxStackSize; - onFilterInstanceChange(); - dirtyNotifiable.markAsDirty(); - } - - public void setBlacklistFilter(boolean blacklistFilter) { - isBlacklistFilter = blacklistFilter; - onFilterInstanceChange(); - dirtyNotifiable.markAsDirty(); - } - - public boolean isBlacklistFilter() { - return isBlacklistFilter; - } - - public int getMaxStackSize() { - return maxStackSize; - } - - private int getInternalMaxStackSize() { - if (isBlacklistFilter()) { - return 1; - } else { - return getMaxStackSize(); - } - } - - public boolean showGlobalTransferLimitSlider() { - return isBlacklistFilter() || currentItemFilter == null || currentItemFilter.showGlobalTransferLimitSlider(); - } - - public int getSlotTransferLimit(Object matchSlot, int globalTransferLimit) { - if (isBlacklistFilter() || currentItemFilter == null) { - return globalTransferLimit; - } - return currentItemFilter.getSlotTransferLimit(matchSlot, globalTransferLimit); - } - - public Object matchItemStack(ItemStack itemStack) { - Object originalResult; - if (currentItemFilter == null) { - originalResult = MATCH_RESULT_TRUE; - } else { - originalResult = currentItemFilter.matchItemStack(itemStack); - } - if (isBlacklistFilter()) { - originalResult = originalResult == null ? MATCH_RESULT_TRUE : null; - } - return originalResult; - } - - public Object matchItemStack(ItemStack itemStack, boolean whitelist) { - Object originalResult; - if (currentItemFilter == null) { - originalResult = MATCH_RESULT_TRUE; - } else { - originalResult = currentItemFilter.matchItemStack(itemStack); - } - if (!whitelist) { - originalResult = originalResult == null ? MATCH_RESULT_TRUE : null; - } - return originalResult; - } - - public boolean testItemStack(ItemStack itemStack) { - return matchItemStack(itemStack) != null; - } -} diff --git a/src/main/java/gregtech/common/covers/filter/MatchResult.java b/src/main/java/gregtech/common/covers/filter/MatchResult.java new file mode 100644 index 00000000000..028da359cb3 --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/MatchResult.java @@ -0,0 +1,46 @@ +package gregtech.common.covers.filter; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class MatchResult { + + public static final MatchResult NONE = new MatchResult(false, null, -1); + public static final MatchResult ANY = new MatchResult(true, null, -1); + private final boolean matched; + private final Object matchedObject; + private final int filterIndex; + + private MatchResult(boolean matched, Object matchedObject, int filterIndex) { + this.matched = matched; + this.matchedObject = matchedObject; + this.filterIndex = filterIndex; + } + + public boolean isMatched() { + return matched; + } + + public Object getMatchedObject() { + return matchedObject; + } + + public @NotNull ItemStack getItemStack() { + return matchedObject instanceof ItemStack stack ? stack : ItemStack.EMPTY; + } + + public @Nullable FluidStack getFluidStack() { + return matchedObject instanceof FluidStack stack ? stack : null; + } + + public int getFilterIndex() { + return filterIndex; + } + + public static MatchResult create(boolean matched, Object matchedStack, int filterIndex) { + return new MatchResult(matched, matchedStack, filterIndex); + } +} diff --git a/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java b/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java index 1db9a6087e3..0eec589f555 100644 --- a/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java @@ -1,78 +1,69 @@ package gregtech.common.covers.filter; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.TextureArea; -import gregtech.api.gui.widgets.DrawableWidget; -import gregtech.api.gui.widgets.ImageCycleButtonWidget; -import gregtech.api.gui.widgets.ImageWidget; +import gregtech.api.cover.CoverWithUI; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.stack.ItemVariantMap; import gregtech.api.unification.stack.MultiItemVariantMap; import gregtech.api.unification.stack.SingleItemVariantMap; -import gregtech.api.util.function.BooleanConsumer; -import gregtech.api.util.oreglob.OreGlob; import gregtech.api.util.oreglob.OreGlobCompileResult; -import gregtech.common.covers.filter.oreglob.impl.ImpossibleOreGlob; -import gregtech.common.gui.widget.HighlightedTextField; -import gregtech.common.gui.widget.orefilter.ItemOreFilterTestSlot; -import gregtech.common.gui.widget.orefilter.OreGlobCompileStatusWidget; +import gregtech.common.covers.filter.readers.OreDictFilterReader; +import gregtech.common.mui.widget.HighlightedTextField; +import gregtech.common.mui.widget.orefilter.OreFilterTestSlot; +import net.minecraft.client.resources.I18n; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.PacketBuffer; import net.minecraft.util.text.TextFormatting; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.drawable.UITexture; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.screen.Tooltip; +import com.cleanroommc.modularui.utils.BooleanConsumer; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.CycleButtonWidget; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.BooleanSupplier; import java.util.function.Consumer; -public class OreDictionaryItemFilter extends ItemFilter { +public class OreDictionaryItemFilter extends BaseFilter { private final Map> matchCache = new Object2ObjectOpenHashMap<>(); private final SingleItemVariantMap noOreDictMatch = new SingleItemVariantMap<>(); + private final OreDictFilterReader filterReader; - protected String expression = ""; - - private OreGlob glob = ImpossibleOreGlob.getInstance(); - private boolean error; - - private boolean caseSensitive; - /** - * {@code false} requires any of the entry to be match in order for the match to be success, {@code true} requires - * all entries to match - */ - private boolean matchAll; + public OreDictionaryItemFilter(ItemStack stack) { + this.filterReader = new OreDictFilterReader(stack); + recompile(); + } - @NotNull - public String getExpression() { - return expression; + @Override + public OreDictFilterReader getFilterReader() { + return filterReader; } @NotNull - public OreGlob getGlob() { - return this.glob; + public String getExpression() { + return this.filterReader.getExpression(); } - protected void recompile(@Nullable Consumer<@Nullable OreGlobCompileResult> callback) { + protected void recompile() { clearCache(); - String expr = this.expression; - if (!expr.isEmpty()) { - OreGlobCompileResult result = OreGlob.compile(expr, !this.caseSensitive); - this.glob = result.getInstance(); - this.error = result.hasError(); - if (callback != null) callback.accept(result); - } else { - this.glob = ImpossibleOreGlob.getInstance(); - this.error = true; - if (callback != null) callback.accept(null); - } + this.filterReader.recompile(); } protected void clearCache() { @@ -81,106 +72,211 @@ protected void clearCache() { } @Override - public void initUI(Consumer widgetGroup) { - ItemOreFilterTestSlot[] testSlot = new ItemOreFilterTestSlot[5]; - for (int i = 0; i < testSlot.length; i++) { - ItemOreFilterTestSlot slot = new ItemOreFilterTestSlot(20 + 22 * i, 0); - slot.setGlob(getGlob()); - slot.setMatchAll(this.matchAll); - widgetGroup.accept(slot); - testSlot[i] = slot; - } - OreGlobCompileStatusWidget compilationStatus = new OreGlobCompileStatusWidget(10, 10); + public void initUI(Consumer widgetGroup) {} - Consumer<@Nullable OreGlobCompileResult> compileCallback = result -> { - compilationStatus.setCompileResult(result); - for (ItemOreFilterTestSlot slot : testSlot) { - slot.setGlob(getGlob()); + @Override + public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager) { + return GTGuis.createPopupPanel("ore_dict_filter", 188, 76) + .padding(7) + .child(CoverWithUI.createTitleRow(getContainerStack())) + .child(createWidgets(syncManager).top(22)); + } + + @Override + public @NotNull ModularPanel createPanel(PanelSyncManager syncManager) { + return GTGuis.createPanel("ore_dict_filter", 100, 100); + } + + @Override + public @NotNull Widget createWidgets(PanelSyncManager syncManager) { + List oreSlots = new ArrayList<>(); + var expression = new StringSyncValue(this.filterReader::getExpression, this.filterReader::setExpression); + + BooleanConsumer setCaseSensitive = b -> { + this.filterReader.setCaseSensitive(b); + if (!syncManager.isClient()) return; + for (var slot : oreSlots) { + slot.updatePreview(); } }; - HighlightedTextField textField = new HighlightedTextField(14, 26, 152, 14, () -> this.expression, - s -> { - if (s.equals(this.expression)) return; - this.expression = s; - markDirty(); - recompile(compileCallback); - }); - compilationStatus.setTextField(textField); - - widgetGroup.accept(new ImageWidget(10, 0, 7, 7, GuiTextures.ORE_FILTER_INFO) - .setTooltip("cover.ore_dictionary_filter.info")); - widgetGroup.accept(compilationStatus); - widgetGroup.accept(new DrawableWidget(10, 22, 156, 16) - .setBackgroundDrawer((mouseX, mouseY, partialTicks, context, widget) -> { - Widget.drawGradientRect(widget.getPosition().x, widget.getPosition().y, - widget.getSize().width, widget.getSize().height, - 0xFF808080, 0xFF808080, false); - Widget.drawGradientRect(widget.getPosition().x + 1, widget.getPosition().y + 1, - widget.getSize().width - 2, widget.getSize().height - 2, - 0xFF000000, 0xFF000000, false); - })); - widgetGroup.accept(textField - .setHighlightRule(h -> { - String t = h.getOriginalText(); - for (int i = 0; i < t.length(); i++) { - switch (t.charAt(i)) { - case '|', '&', '^', '(', ')' -> h.format(i, TextFormatting.GOLD); - case '*', '?' -> h.format(i, TextFormatting.GREEN); - case '!' -> h.format(i, TextFormatting.RED); - case '\\' -> h.format(i++, TextFormatting.YELLOW); - case '$' -> { // TODO: remove this switch case in 2.9 - h.format(i, TextFormatting.DARK_GREEN); - for (; i < t.length(); i++) { - switch (t.charAt(i)) { - case ' ', '\t', '\n', '\r' -> {} - case '\\' -> { - i++; - continue; - } - default -> { - continue; - } - } - break; - } + BooleanConsumer setMatchAll = b -> { + this.clearCache(); + this.filterReader.setMatchAll(b); + if (!syncManager.isClient()) return; + for (var slot : oreSlots) { + slot.setMatchAll(b); + } + }; + + var caseSensitive = new BooleanSyncValue(this.filterReader::isCaseSensitive, setCaseSensitive); + var matchAll = new BooleanSyncValue(this.filterReader::shouldMatchAll, setMatchAll); + + return new Column().widthRel(1f).coverChildrenHeight() + .child(new HighlightedTextField() + .setHighlightRule(this::highlightRule) + .onUnfocus(() -> { + for (var slot : oreSlots) { + slot.updatePreview(); + } + }) + .setTextColor(Color.WHITE.darker(1)) + .value(expression).marginBottom(4) + .height(18).widthRel(1f)) + .child(new Row().coverChildrenHeight() + .widthRel(1f) + .child(new Column().height(18) + .coverChildrenWidth().marginRight(2) + .child(GTGuiTextures.OREDICT_INFO.asWidget() + .size(8).top(0) + .addTooltipLine(IKey.lang("cover.ore_dictionary_filter.info"))) + .child(new Widget<>() + .size(8).bottom(0) + .onUpdateListener(this::getStatusIcon) + .tooltipBuilder(this::createStatusTooltip) + .tooltip(tooltip -> tooltip.setAutoUpdate(true)))) + .child(SlotGroupWidget.builder() + .row("XXXXX") + .key('X', i -> { + var slot = new OreFilterTestSlot() + .setGlobSupplier(this.filterReader::getGlob); + slot.setMatchAll(this.filterReader.shouldMatchAll()); + oreSlots.add(slot); + return slot; + }) + .build().marginRight(2)) + .child(new CycleButtonWidget() + .size(18).value(caseSensitive) + .marginRight(2) + .textureGetter(state -> GTGuiTextures.BUTTON_CASE_SENSITIVE[state]) + .addTooltip(0, + IKey.lang("cover.ore_dictionary_filter.button.case_sensitive.disabled")) + .addTooltip(1, + IKey.lang("cover.ore_dictionary_filter.button.case_sensitive.enabled"))) + .child(new CycleButtonWidget() + .size(18).value(matchAll) + .marginRight(2) + .textureGetter(state -> GTGuiTextures.BUTTON_MATCH_ALL[state]) + .addTooltip(0, + IKey.lang("cover.ore_dictionary_filter.button.match_all.disabled")) + .addTooltip(1, + IKey.lang("cover.ore_dictionary_filter.button.match_all.enabled"))) + .child(createBlacklistUI())); + } + + protected void getStatusIcon(Widget widget) { + UITexture texture; + var result = this.filterReader.getResult(); + + if (result == null) { + texture = GTGuiTextures.OREDICT_WAITING; + } else if (result.getReports().length == 0) { + texture = GTGuiTextures.OREDICT_SUCCESS; + } else if (result.hasError()) { + texture = GTGuiTextures.OREDICT_ERROR; + } else { + texture = GTGuiTextures.OREDICT_WARN; + } + widget.background(texture); + } + + protected void createStatusTooltip(Tooltip tooltip) { + var result = this.filterReader.getResult(); + if (result == null) return; + List list = new ArrayList<>(); + + int error = 0, warn = 0; + for (OreGlobCompileResult.Report report : result.getReports()) { + if (report.isError()) error++; + else warn++; + list.add((report.isError() ? TextFormatting.RED : TextFormatting.GOLD) + report.toString()); + } + if (error > 0) { + if (warn > 0) { + list.add(0, I18n.format("cover.ore_dictionary_filter.status.err_warn", error, warn)); + } else { + list.add(0, I18n.format("cover.ore_dictionary_filter.status.err", error)); + } + } else { + if (warn > 0) { + list.add(0, I18n.format("cover.ore_dictionary_filter.status.warn", warn)); + } else { + list.add(I18n.format("cover.ore_dictionary_filter.status.no_issues")); + } + list.add(""); + list.add(I18n.format("cover.ore_dictionary_filter.status.explain")); + list.add(""); + list.addAll(result.getInstance().toFormattedString()); + } + tooltip.addStringLines(list); + } + + protected String highlightRule(String text) { + StringBuilder builder = new StringBuilder(text); + for (int i = 0; i < builder.length(); i++) { + switch (builder.charAt(i)) { + case '|', '&', '^', '(', ')' -> { + builder.insert(i, TextFormatting.GOLD); + i += 2; + } + case '*', '?' -> { + builder.insert(i, TextFormatting.GREEN); + i += 2; + } + case '!' -> { + builder.insert(i, TextFormatting.RED); + i += 2; + } + case '\\' -> { + builder.insert(i++, TextFormatting.YELLOW); + i += 2; + } + case '$' -> { // TODO: remove this switch case in 2.9 + builder.insert(i, TextFormatting.DARK_GREEN); + for (; i < builder.length(); i++) { + switch (builder.charAt(i)) { + case ' ', '\t', '\n', '\r' -> {} + case '\\' -> { + i++; + continue; } default -> { continue; } } - h.format(i + 1, TextFormatting.RESET); - } - }).setMaxLength(64)); - widgetGroup.accept(new ForcedInitialSyncImageCycleButtonWidget(130, 38, 18, 18, - GuiTextures.ORE_FILTER_BUTTON_CASE_SENSITIVE, () -> this.caseSensitive, caseSensitive -> { - if (this.caseSensitive == caseSensitive) return; - this.caseSensitive = caseSensitive; - markDirty(); - recompile(compileCallback); - }).setTooltipHoverString( - i -> "cover.ore_dictionary_filter.button.case_sensitive." + (i == 0 ? "disabled" : "enabled"))); - widgetGroup.accept(new ForcedInitialSyncImageCycleButtonWidget(148, 38, 18, 18, - GuiTextures.ORE_FILTER_BUTTON_MATCH_ALL, () -> this.matchAll, matchAll -> { - if (this.matchAll == matchAll) return; - this.matchAll = matchAll; - markDirty(); - clearCache(); - for (ItemOreFilterTestSlot slot : testSlot) { - slot.setMatchAll(matchAll); + break; } - }).setTooltipHoverString( - i -> "cover.ore_dictionary_filter.button.match_all." + (i == 0 ? "disabled" : "enabled"))); + } + default -> { + continue; + } + } + builder.insert(i + 1, TextFormatting.RESET); + } + return builder.toString(); + } + + @Override + public MatchResult matchItem(ItemStack itemStack) { + // "wtf is this system?? i can put any non null object here and it i will work??? $arch" + // not anymore :thanosdaddy: -ghzdude + var match = matchesItemStack(itemStack); + return MatchResult.create(match != isBlacklistFilter(), match ? itemStack.copy() : ItemStack.EMPTY, -1); + } + + @Override + public boolean testItem(ItemStack toTest) { + return matchesItemStack(toTest); } @Override - public Object matchItemStack(ItemStack itemStack) { - return matchesItemStack(itemStack) ? - "wtf is this system?? i can put any non null object here and it i will work??? $arch" : null; + public FilterType getType() { + return FilterType.ITEM; } public boolean matchesItemStack(@NotNull ItemStack itemStack) { - if (this.error) return false; + var result = this.filterReader.getResult(); + if (result == null || result.hasError()) return false; Item item = itemStack.getItem(); ItemVariantMap> oreDictEntry = OreDictUnifier.getOreDictionaryEntry(item); @@ -188,7 +284,7 @@ public boolean matchesItemStack(@NotNull ItemStack itemStack) { // no oredict entries associated Boolean cached = this.noOreDictMatch.getEntry(); if (cached == null) { - cached = this.glob.matches(""); + cached = this.filterReader.getGlob().matches(""); } this.matchCache.put(item, this.noOreDictMatch); return cached; @@ -205,7 +301,7 @@ public boolean matchesItemStack(@NotNull ItemStack itemStack) { // no oredict entries associated Boolean cached = this.noOreDictMatch.getEntry(); if (cached == null) { - cached = this.glob.matches(""); + cached = this.filterReader.getGlob().matches(""); this.noOreDictMatch.put(cached); } this.matchCache.put(item, this.noOreDictMatch); @@ -217,64 +313,15 @@ public boolean matchesItemStack(@NotNull ItemStack itemStack) { } this.matchCache.put(item, cacheEntry); } - boolean matches = this.matchAll ? this.glob.matchesAll(itemStack) : this.glob.matchesAny(itemStack); + boolean matches = this.filterReader.shouldMatchAll() ? + this.filterReader.getGlob().matchesAll(itemStack) : + this.filterReader.getGlob().matchesAny(itemStack); cacheEntry.put(itemStack, matches); return matches; } - @Override - public int getSlotTransferLimit(Object matchSlot, int globalTransferLimit) { - return globalTransferLimit; - } - @Override public boolean showGlobalTransferLimitSlider() { return true; } - - @Override - public int getTotalOccupiedHeight() { - return 37; - } - - @Override - public void writeToNBT(NBTTagCompound tag) { - tag.setString("OreDictionaryFilter", expression); - if (this.caseSensitive) tag.setBoolean("caseSensitive", true); - if (this.matchAll) tag.setBoolean("matchAll", true); - } - - @Override - public void readFromNBT(NBTTagCompound tag) { - this.expression = tag.getString("OreDictionaryFilter"); - this.caseSensitive = tag.getBoolean("caseSensitive"); - this.matchAll = tag.getBoolean("matchAll"); - recompile(null); - } - - public static class ForcedInitialSyncImageCycleButtonWidget extends ImageCycleButtonWidget { - - private final BooleanConsumer updater; - - public ForcedInitialSyncImageCycleButtonWidget(int xPosition, int yPosition, int width, int height, - TextureArea buttonTexture, BooleanSupplier supplier, - BooleanConsumer updater) { - super(xPosition, yPosition, width, height, buttonTexture, supplier, updater); - this.currentOption = 0; - this.updater = updater; - } - - @Override - public void readUpdateInfo(int id, PacketBuffer buffer) { - if (id == 1) { - int currentOptionCache = this.currentOption; - super.readUpdateInfo(id, buffer); - if (this.currentOption != currentOptionCache) { - this.updater.apply(currentOption >= 1); // call updater to apply necessary state changes - } - } else { - super.readUpdateInfo(id, buffer); - } - } - } } diff --git a/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java b/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java index c3abb86898e..ed2b3a40eaf 100644 --- a/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java +++ b/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java @@ -1,118 +1,119 @@ package gregtech.common.covers.filter; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.PhantomFluidWidget; +import gregtech.api.cover.CoverWithUI; +import gregtech.api.mui.GTGuis; +import gregtech.api.mui.sync.FixedFluidSlotSH; +import gregtech.common.covers.filter.readers.SimpleFluidFilterReader; -import net.minecraft.nbt.NBTBase; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; +import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTank; -import org.jetbrains.annotations.Nullable; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.FluidSlot; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.layout.Row; +import org.jetbrains.annotations.NotNull; import java.util.function.Consumer; -public class SimpleFluidFilter extends FluidFilter { +public class SimpleFluidFilter extends BaseFilter { private static final int MAX_FLUID_SLOTS = 9; - protected final FluidTank[] fluidFilterTanks = new FluidTank[MAX_FLUID_SLOTS]; + private final SimpleFluidFilterReader filterReader; - public SimpleFluidFilter() { - for (int i = 0; i < MAX_FLUID_SLOTS; ++i) { - fluidFilterTanks[i] = new FluidTank(1000) { - - @Override - public void setFluid(@Nullable FluidStack fluid) { - super.setFluid(fluid); - SimpleFluidFilter.this.markDirty(); - } - }; - } + public SimpleFluidFilter(ItemStack stack) { + filterReader = new SimpleFluidFilterReader(stack, MAX_FLUID_SLOTS); } @Override + public SimpleFluidFilterReader getFilterReader() { + return filterReader; + } + public void configureFilterTanks(int amount) { - for (FluidTank fluidTank : fluidFilterTanks) { - if (fluidTank.getFluid() != null) - fluidTank.getFluid().amount = amount; - } + this.filterReader.setFluidAmounts(amount); this.markDirty(); } @Override - public void setMaxConfigurableFluidSize(int maxSize) { - for (FluidTank fluidTank : fluidFilterTanks) { - fluidTank.setCapacity(maxSize); - } + public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager) { + return GTGuis.createPopupPanel("simple_fluid_filter", 98, 81) + .padding(4) + .child(CoverWithUI.createTitleRow(getContainerStack())) + .child(createWidgets(syncManager).top(22)); } @Override - public boolean testFluid(FluidStack fluidStack) { - return checkInputFluid(fluidFilterTanks, fluidStack); + public @NotNull ModularPanel createPanel(PanelSyncManager syncManager) { + return GTGuis.createPanel(getContainerStack(), 176, 168); } @Override - public int getMaxOccupiedHeight() { - return 36; + public @NotNull Widget createWidgets(PanelSyncManager syncManager) { + return new Row().coverChildrenHeight().widthRel(1f) + .child(SlotGroupWidget.builder() + .matrix("FFF", + "FFF", + "FFF") + .key('F', i -> new FluidSlot() + .syncHandler(new FixedFluidSlotSH(filterReader.getFluidTank(i)).phantom(true))) + .build().marginRight(4)) + .child(createBlacklistUI()); } @Override - public void initUI(Consumer widgetGroup) { - for (int i = 0; i < 9; ++i) { - widgetGroup.accept((new PhantomFluidWidget(10 + 18 * (i % 3), 18 * (i / 3), 18, 18, - this.fluidFilterTanks[i])) - .setBackgroundTexture(GuiTextures.SLOT).showTipSupplier(this::shouldShowTip)); + public MatchResult matchFluid(FluidStack fluidStack) { + int index = -1; + FluidStack returnable = null; + for (int i = 0; i < filterReader.getSize(); i++) { + var fluid = filterReader.getFluidStack(i); + if (fluid != null && fluid.isFluidEqual(fluidStack)) { + index = i; + returnable = fluid.copy(); + break; + } } + return MatchResult.create(index != -1, returnable, index); } - private boolean shouldShowTip() { - return showTip; - } - - public void writeToNBT(NBTTagCompound tagCompound) { - NBTTagList filterSlots = new NBTTagList(); - for (int i = 0; i < this.fluidFilterTanks.length; ++i) { - FluidTank fluidTank = this.fluidFilterTanks[i]; - if (fluidTank.getFluid() != null) { - NBTTagCompound stackTag = new NBTTagCompound(); - fluidTank.getFluid().writeToNBT(stackTag); - stackTag.setInteger("Slot", i); - filterSlots.appendTag(stackTag); + @Override + public boolean testFluid(FluidStack toTest) { + for (int i = 0; i < filterReader.getSize(); i++) { + var fluid = filterReader.getFluidStack(i); + if (fluid != null && fluid.isFluidEqual(toTest)) { + return true; } } - tagCompound.setTag("FluidFilter", filterSlots); + return false; } - public void readFromNBT(NBTTagCompound tagCompound) { - NBTTagList filterSlots = tagCompound.getTagList("FluidFilter", 10); - for (NBTBase nbtBase : filterSlots) { - NBTTagCompound stackTag = (NBTTagCompound) nbtBase; - FluidStack fluidStack = FluidStack.loadFluidStackFromNBT(stackTag); - this.fluidFilterTanks[stackTag.getInteger("Slot")].setFluid(fluidStack); + @Override + public void initUI(Consumer widgetGroup) { + for (int i = 0; i < 9; ++i) { + widgetGroup.accept((new gregtech.api.gui.widgets.PhantomFluidWidget(10 + 18 * (i % 3), 18 * (i / 3), 18, 18, + filterReader.getFluidTank(i))) + .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT)); } } - public static boolean checkInputFluid(FluidTank[] fluidFilterTanks, FluidStack fluidStack) { - for (FluidTank fluidTank : fluidFilterTanks) { - if (fluidTank.getFluid() != null && fluidTank.getFluid().isFluidEqual(fluidStack)) { - return true; + @Override + public int getTransferLimit(FluidStack fluidStack, int transferSize) { + int limit = 0; + + for (int i = 0; i < this.filterReader.getSize(); i++) { + var fluid = this.filterReader.getFluidStack(i); + if (fluid != null && fluid.isFluidEqual(fluidStack)) { + limit = fluid.amount; } } - return false; + return isBlacklistFilter() ? transferSize : limit; } @Override - public int getFluidTransferLimit(FluidStack fluidStack) { - int limit = 0; - for (FluidTank fluidTank : fluidFilterTanks) { - if (fluidTank.getFluid() != null && fluidTank.getFluid().isFluidEqual(fluidStack)) { - limit = fluidTank.getFluid().amount; - break; - } - } - return limit; + public FilterType getType() { + return FilterType.FLUID; } } diff --git a/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java b/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java index 864986ca805..4eaf4ffc865 100644 --- a/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java @@ -1,119 +1,167 @@ package gregtech.common.covers.filter; +import gregtech.api.cover.CoverWithUI; import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.Widget; import gregtech.api.gui.widgets.PhantomSlotWidget; import gregtech.api.gui.widgets.ToggleButtonWidget; -import gregtech.api.util.LargeStackSizeItemStackHandler; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; +import gregtech.api.util.TextFormattingUtil; +import gregtech.common.covers.CoverItemVoidingAdvanced; +import gregtech.common.covers.CoverRoboticArm; +import gregtech.common.covers.TransferMode; +import gregtech.common.covers.VoidingMode; +import gregtech.common.covers.filter.readers.SimpleItemFilterReader; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.items.IItemHandler; -import net.minecraftforge.items.ItemStackHandler; + +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.CycleButtonWidget; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.slot.SlotGroup; +import org.jetbrains.annotations.NotNull; import java.util.function.Consumer; -public class SimpleItemFilter extends ItemFilter { +public class SimpleItemFilter extends BaseFilter { private static final int MAX_MATCH_SLOTS = 9; + private final SimpleItemFilterReader filterReader; - protected final ItemStackHandler itemFilterSlots; - protected boolean ignoreDamage = true; - protected boolean ignoreNBT = true; - - public SimpleItemFilter() { - this.itemFilterSlots = new LargeStackSizeItemStackHandler(MAX_MATCH_SLOTS) { - - @Override - public int getSlotLimit(int slot) { - return getMaxStackSize(); - } - }; + public SimpleItemFilter(ItemStack stack) { + filterReader = new SimpleItemFilterReader(stack, MAX_MATCH_SLOTS); } @Override - protected void onMaxStackSizeChange() { - for (int i = 0; i < itemFilterSlots.getSlots(); i++) { - ItemStack itemStack = itemFilterSlots.getStackInSlot(i); - if (!itemStack.isEmpty()) { - itemStack.setCount(Math.min(itemStack.getCount(), getMaxStackSize())); - } - } - } - - public ItemStackHandler getItemFilterSlots() { - return itemFilterSlots; + public SimpleItemFilterReader getFilterReader() { + return filterReader; } - public boolean isIgnoreDamage() { - return ignoreDamage; - } - - public boolean isIgnoreNBT() { - return ignoreNBT; - } - - protected void setIgnoreDamage(boolean ignoreDamage) { - this.ignoreDamage = ignoreDamage; - markDirty(); - } - - protected void setIgnoreNBT(boolean ignoreNBT) { - this.ignoreNBT = ignoreNBT; - markDirty(); + @Override + public MatchResult matchItem(ItemStack itemStack) { + int matchedSlot = itemFilterMatch(filterReader, filterReader.isIgnoreDamage(), filterReader.isIgnoreNBT(), + itemStack); + return MatchResult.create(matchedSlot != -1 == !isBlacklistFilter(), + filterReader.getStackInSlot(matchedSlot), matchedSlot); } @Override - public Integer matchItemStack(ItemStack itemStack) { - int itemFilterMatchIndex = itemFilterMatch(getItemFilterSlots(), isIgnoreDamage(), isIgnoreNBT(), itemStack); - return itemFilterMatchIndex == -1 ? null : itemFilterMatchIndex; + public boolean testItem(ItemStack toTest) { + int matchedSlot = itemFilterMatch(filterReader, filterReader.isIgnoreDamage(), filterReader.isIgnoreNBT(), + toTest); + return matchedSlot != -1; } @Override - public int getSlotTransferLimit(Object matchSlot, int globalTransferLimit) { - Integer matchSlotIndex = (Integer) matchSlot; - ItemStack stackInFilterSlot = itemFilterSlots.getStackInSlot(matchSlotIndex); - return Math.min(stackInFilterSlot.getCount(), globalTransferLimit); + public int getTransferLimit(int matchSlot, int transferSize) { + ItemStack stackInFilterSlot = filterReader.getStackInSlot(matchSlot); + return Math.min(stackInFilterSlot.getCount(), transferSize); } @Override - public boolean showGlobalTransferLimitSlider() { - return false; + public FilterType getType() { + return FilterType.ITEM; } @Override - public int getTotalOccupiedHeight() { - return 36; + public int getTransferLimit(ItemStack stack, int transferSize) { + int matchedSlot = itemFilterMatch(filterReader, filterReader.isIgnoreDamage(), filterReader.isIgnoreNBT(), + stack); + return getTransferLimit(matchedSlot, transferSize); } @Override - public void initUI(Consumer widgetGroup) { + public void initUI(Consumer widgetGroup) { for (int i = 0; i < 9; i++) { - widgetGroup.accept(new PhantomSlotWidget(itemFilterSlots, i, 10 + 18 * (i % 3), 18 * (i / 3)) + widgetGroup.accept(new PhantomSlotWidget(filterReader, i, 10 + 18 * (i % 3), 18 * (i / 3)) .setBackgroundTexture(GuiTextures.SLOT)); } widgetGroup.accept(new ToggleButtonWidget(74, 0, 20, 20, GuiTextures.BUTTON_FILTER_DAMAGE, - () -> ignoreDamage, this::setIgnoreDamage).setTooltipText("cover.item_filter.ignore_damage")); + filterReader::isIgnoreDamage, filterReader::setIgnoreDamage) + .setTooltipText("cover.item_filter.ignore_damage")); widgetGroup.accept(new ToggleButtonWidget(99, 0, 20, 20, GuiTextures.BUTTON_FILTER_NBT, - () -> ignoreNBT, this::setIgnoreNBT).setTooltipText("cover.item_filter.ignore_nbt")); + filterReader::isIgnoreNBT, filterReader::setIgnoreNBT).setTooltipText("cover.item_filter.ignore_nbt")); } @Override - public void writeToNBT(NBTTagCompound tagCompound) { - tagCompound.setTag("ItemFilter", itemFilterSlots.serializeNBT()); - tagCompound.setBoolean("IgnoreDamage", ignoreDamage); - tagCompound.setBoolean("IgnoreNBT", ignoreNBT); + public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager) { + return GTGuis.createPopupPanel("simple_item_filter", 98, 81) + .child(CoverWithUI.createTitleRow(getContainerStack())) + .child(createWidgets(syncManager).top(22).left(4)); } @Override - public void readFromNBT(NBTTagCompound tagCompound) { - this.itemFilterSlots.deserializeNBT(tagCompound.getCompoundTag("ItemFilter")); - this.ignoreDamage = tagCompound.getBoolean("IgnoreDamage"); - this.ignoreNBT = tagCompound.getBoolean("IgnoreNBT"); + public @NotNull ModularPanel createPanel(PanelSyncManager syncManager) { + return GTGuis.createPanel("simple_item_filter", 176, 166); } - public static int itemFilterMatch(IItemHandler filterSlots, boolean ignoreDamage, boolean ignoreNBTData, - ItemStack itemStack) { + @SuppressWarnings("UnstableApiUsage") + @Override + public @NotNull Widget createWidgets(PanelSyncManager syncManager) { + SlotGroup filterInventory = new SlotGroup("filter_inv", 3, 1000, true); + var ignoreDamage = new BooleanSyncValue(this.filterReader::isIgnoreDamage, this.filterReader::setIgnoreDamage); + var ignoreNBT = new BooleanSyncValue(this.filterReader::isIgnoreNBT, this.filterReader::setIgnoreNBT); + + syncManager.registerSlotGroup(filterInventory); + + return new Row().coverChildren() + .child(SlotGroupWidget.builder() + .matrix("XXX", + "XXX", + "XXX") + .key('X', index -> new ItemSlot() + .tooltip(tooltip -> { + tooltip.setAutoUpdate(true); + tooltip.textColor(Color.GREY.main); + }) + .tooltipBuilder(tooltip -> { + if (dirtyNotifiable instanceof CoverRoboticArm coverArm && + coverArm.getTransferMode() != TransferMode.TRANSFER_ANY || + dirtyNotifiable instanceof CoverItemVoidingAdvanced coverItem && + coverItem.getVoidingMode() != VoidingMode.VOID_ANY) { + tooltip.addLine(IKey.lang("cover.item_filter.config_amount")); + int count = this.filterReader.getTagAt(index) + .getInteger(SimpleItemFilterReader.COUNT); + if (count > 0) + tooltip.addLine( + IKey.format("Count: %s", TextFormattingUtil.formatNumbers(count))); + } + }) + .slot(SyncHandlers.phantomItemSlot(this.filterReader, index) + .ignoreMaxStackSize(true) + .slotGroup(filterInventory) + .changeListener((newItem, onlyAmountChanged, client, init) -> { + if (onlyAmountChanged && !init) { + markDirty(); + } + }))) + .build().marginRight(4)) + .child(new Column().width(18).coverChildren() + .child(createBlacklistUI()) + .child(new CycleButtonWidget() + .value(ignoreDamage) + .textureGetter(state -> GTGuiTextures.BUTTON_IGNORE_DAMAGE[state]) + .addTooltip(0, IKey.lang("cover.item_filter.ignore_damage.disabled")) + .addTooltip(1, IKey.lang("cover.item_filter.ignore_damage.enabled"))) + .child(new CycleButtonWidget() + .value(ignoreNBT) + .textureGetter(state -> GTGuiTextures.BUTTON_IGNORE_NBT[state]) + .addTooltip(0, IKey.lang("cover.item_filter.ignore_nbt.disabled")) + .addTooltip(1, IKey.lang("cover.item_filter.ignore_nbt.enabled")))); + } + + public static int itemFilterMatch(IItemHandler filterSlots, boolean ignoreDamage, + boolean ignoreNBTData, ItemStack itemStack) { for (int i = 0; i < filterSlots.getSlots(); i++) { ItemStack filterStack = filterSlots.getStackInSlot(i); if (!filterStack.isEmpty() && areItemsEqual(ignoreDamage, ignoreNBTData, filterStack, itemStack)) { @@ -123,8 +171,8 @@ public static int itemFilterMatch(IItemHandler filterSlots, boolean ignoreDamage return -1; } - private static boolean areItemsEqual(boolean ignoreDamage, boolean ignoreNBTData, ItemStack filterStack, - ItemStack itemStack) { + private static boolean areItemsEqual(boolean ignoreDamage, boolean ignoreNBTData, + ItemStack filterStack, ItemStack itemStack) { if (ignoreDamage) { if (!filterStack.isItemEqualIgnoreDurability(itemStack)) { return false; diff --git a/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java b/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java index a655d22f732..425189b7de2 100644 --- a/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java @@ -1,95 +1,144 @@ package gregtech.common.covers.filter; -import gregtech.api.gui.Widget; +import gregtech.api.cover.CoverWithUI; import gregtech.api.gui.widgets.CycleButtonWidget; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.RecipeMaps; import gregtech.api.recipes.ingredients.GTRecipeInput; import gregtech.api.unification.stack.ItemAndMetadata; +import gregtech.common.covers.filter.readers.SmartItemFilterReader; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.IStringSerializable; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.BoolValue; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.jetbrains.annotations.NotNull; import java.util.Collections; -import java.util.Map; import java.util.function.Consumer; -public class SmartItemFilter extends ItemFilter { +public class SmartItemFilter extends BaseFilter { - private SmartFilteringMode filteringMode = SmartFilteringMode.ELECTROLYZER; + private final SmartItemFilterReader filterReader; - public SmartFilteringMode getFilteringMode() { - return filteringMode; + public SmartItemFilter(ItemStack stack) { + filterReader = new SmartItemFilterReader(stack); } - public void setFilteringMode(SmartFilteringMode filteringMode) { - this.filteringMode = filteringMode; - markDirty(); + @Override + public SmartItemFilterReader getFilterReader() { + return filterReader; } - @Override - public int getSlotTransferLimit(Object matchSlot, int globalTransferLimit) { - ItemAndMetadataAndStackSize itemAndMetadata = (ItemAndMetadataAndStackSize) matchSlot; - return itemAndMetadata.transferStackSize; + public SmartFilteringMode getFilteringMode() { + return this.filterReader.getFilteringMode(); } @Override - public Object matchItemStack(ItemStack itemStack) { - ItemAndMetadata itemAndMetadata = new ItemAndMetadata(itemStack); - Integer cachedTransferRateValue = filteringMode.transferStackSizesCache.get(itemAndMetadata); + public int getTransferLimit(ItemStack stack, int globalTransferLimit) { + ItemAndMetadata itemAndMetadata = new ItemAndMetadata(stack); + var filterMode = this.filterReader.getFilteringMode(); + int cachedTransferRateValue = filterMode.transferStackSizesCache.getOrDefault(itemAndMetadata, -1); - if (cachedTransferRateValue == null) { - ItemStack infinitelyBigStack = itemStack.copy(); + if (cachedTransferRateValue == -1) { + ItemStack infinitelyBigStack = stack.copy(); infinitelyBigStack.setCount(Integer.MAX_VALUE); - Recipe recipe = filteringMode.recipeMap.findRecipe(Long.MAX_VALUE, + Recipe recipe = filterMode.recipeMap.findRecipe(Long.MAX_VALUE, Collections.singletonList(infinitelyBigStack), Collections.emptyList()); if (recipe == null) { - filteringMode.transferStackSizesCache.put(itemAndMetadata, 0); + filterMode.transferStackSizesCache.put(itemAndMetadata, 0); cachedTransferRateValue = 0; } else { GTRecipeInput inputIngredient = recipe.getInputs().iterator().next(); - filteringMode.transferStackSizesCache.put(itemAndMetadata, inputIngredient.getAmount()); + filterMode.transferStackSizesCache.put(itemAndMetadata, inputIngredient.getAmount()); cachedTransferRateValue = inputIngredient.getAmount(); } } - if (cachedTransferRateValue == 0) { - return null; - } - return new ItemAndMetadataAndStackSize(itemAndMetadata, cachedTransferRateValue); + return cachedTransferRateValue; + } + + @Override + public MatchResult matchItem(ItemStack itemStack) { + var stack = itemStack.copy(); + stack.setCount(getTransferLimit(itemStack, Integer.MAX_VALUE)); + return MatchResult.create(stack.getCount() > 0 != isBlacklistFilter(), stack, + this.getFilteringMode().ordinal()); + } + + @Override + public boolean testItem(ItemStack toTest) { + return getTransferLimit(toTest, Integer.MAX_VALUE) > 0; } @Override - public void initUI(Consumer widgetGroup) { + public FilterType getType() { + return FilterType.ITEM; + } + + @Override + public void initUI(Consumer widgetGroup) { widgetGroup.accept(new CycleButtonWidget(10, 0, 75, 20, - SmartFilteringMode.class, this::getFilteringMode, this::setFilteringMode) + SmartFilteringMode.class, filterReader::getFilteringMode, filterReader::setFilteringMode) .setTooltipHoverString("cover.smart_item_filter.filtering_mode.description")); } @Override - public int getTotalOccupiedHeight() { - return 20; + public @NotNull ModularPanel createPopupPanel(PanelSyncManager syncManager) { + return GTGuis.createPopupPanel("smart_item_filter", 98 + 27, 81) + .child(CoverWithUI.createTitleRow(getContainerStack())) + .child(createWidgets(syncManager).top(22).left(4)); } @Override - public boolean showGlobalTransferLimitSlider() { - return true; + public @NotNull ModularPanel createPanel(PanelSyncManager syncManager) { + return GTGuis.createPanel("smart_item_filter", 100, 100).padding(7); } @Override - public void writeToNBT(NBTTagCompound tagCompound) { - tagCompound.setInteger("FilterMode", filteringMode.ordinal()); + public @NotNull Widget createWidgets(PanelSyncManager syncManager) { + var filterMode = new EnumSyncValue<>(SmartFilteringMode.class, filterReader::getFilteringMode, + filterReader::setFilteringMode); + syncManager.syncValue("filter_mode", filterMode); + + return new Row().coverChildren() + .child(new Column().coverChildren().marginRight(4) + .child(createFilterModeButton(filterMode, SmartFilteringMode.ELECTROLYZER)) + .child(createFilterModeButton(filterMode, SmartFilteringMode.CENTRIFUGE)) + .child(createFilterModeButton(filterMode, SmartFilteringMode.SIFTER))) + .child(createBlacklistUI()); + } + + private Widget createFilterModeButton(EnumSyncValue value, + SmartFilteringMode mode) { + return new ToggleButton().height(18).width(18 * 5) + .value(boolValueOf(value, mode)) + .background(GTGuiTextures.MC_BUTTON) + .selectedBackground(GTGuiTextures.MC_BUTTON_DISABLED) + .overlay(IKey.lang(mode.getName()).color(Color.WHITE.darker(1))); + } + + protected > BoolValue.Dynamic boolValueOf(EnumSyncValue syncValue, T value) { + return new BoolValue.Dynamic(() -> syncValue.getValue() == value, $ -> syncValue.setValue(value)); } @Override - public void readFromNBT(NBTTagCompound tagCompound) { - this.filteringMode = SmartFilteringMode.values()[tagCompound.getInteger("FilterMode")]; + public boolean showGlobalTransferLimitSlider() { + return true; } private static class ItemAndMetadataAndStackSize { @@ -122,7 +171,8 @@ public enum SmartFilteringMode implements IStringSerializable { CENTRIFUGE("cover.smart_item_filter.filtering_mode.centrifuge", RecipeMaps.CENTRIFUGE_RECIPES), SIFTER("cover.smart_item_filter.filtering_mode.sifter", RecipeMaps.SIFTER_RECIPES); - private final Map transferStackSizesCache = new Object2IntOpenHashMap<>(); + public static final SmartFilteringMode[] VALUES = values(); + private final Object2IntOpenHashMap transferStackSizesCache = new Object2IntOpenHashMap<>(); public final String localeName; public final RecipeMap recipeMap; diff --git a/src/main/java/gregtech/common/covers/filter/WidgetGroupFluidFilter.java b/src/main/java/gregtech/common/covers/filter/WidgetGroupFluidFilter.java index f2c08f856b3..c43d7487467 100644 --- a/src/main/java/gregtech/common/covers/filter/WidgetGroupFluidFilter.java +++ b/src/main/java/gregtech/common/covers/filter/WidgetGroupFluidFilter.java @@ -1,19 +1,29 @@ package gregtech.common.covers.filter; import gregtech.api.gui.widgets.AbstractWidgetGroup; +import gregtech.api.util.GTLog; import gregtech.api.util.Position; +import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; +import org.jetbrains.annotations.ApiStatus; + +import java.io.IOException; import java.util.function.Supplier; +/** + * @deprecated in favor of new MUI + */ +@Deprecated +@ApiStatus.ScheduledForRemoval(inVersion = "2.10") public class WidgetGroupFluidFilter extends AbstractWidgetGroup { - private final Supplier fluidFilterSupplier; + private final Supplier fluidFilterSupplier; private final Supplier showTipSupplier; - private FluidFilter fluidFilter; + private BaseFilter fluidFilter; - public WidgetGroupFluidFilter(int yPosition, Supplier fluidFilterSupplier, + public WidgetGroupFluidFilter(int yPosition, Supplier fluidFilterSupplier, Supplier showTipSupplier) { super(new Position(18 + 5, yPosition)); this.fluidFilterSupplier = fluidFilterSupplier; @@ -23,7 +33,7 @@ public WidgetGroupFluidFilter(int yPosition, Supplier fluidFilterSu @Override public void detectAndSendChanges() { super.detectAndSendChanges(); - FluidFilter newFluidFilter = fluidFilterSupplier.get(); + BaseFilter newFluidFilter = fluidFilterSupplier.get(); if (fluidFilter != newFluidFilter) { clearAllWidgets(); this.fluidFilter = newFluidFilter; @@ -33,17 +43,16 @@ public void detectAndSendChanges() { writeUpdateInfo(2, buffer -> { if (fluidFilter != null) { buffer.writeBoolean(true); - int filterId = FilterTypeRegistry.getIdForFluidFilter(fluidFilter); - buffer.writeVarInt(filterId); + buffer.writeItemStack(fluidFilter.getContainerStack()); } else { buffer.writeBoolean(false); } }); } - if (fluidFilter != null && showTipSupplier != null && fluidFilter.showTip != showTipSupplier.get()) { - fluidFilter.showTip = showTipSupplier.get(); - writeUpdateInfo(3, buffer -> buffer.writeBoolean(fluidFilter.showTip)); - } + // if (fluidFilter != null && showTipSupplier != null && fluidFilter.showTip != showTipSupplier.get()) { + // fluidFilter.showTip = showTipSupplier.get(); + // writeUpdateInfo(3, buffer -> buffer.writeBoolean(fluidFilter.showTip)); + // } } @Override @@ -52,12 +61,18 @@ public void readUpdateInfo(int id, PacketBuffer buffer) { if (id == 2) { clearAllWidgets(); if (buffer.readBoolean()) { - int filterId = buffer.readVarInt(); - this.fluidFilter = FilterTypeRegistry.createFluidFilterById(filterId); + ItemStack stack; + try { + stack = buffer.readItemStack(); + } catch (IOException e) { + GTLog.logger.warn(e); + return; + } + this.fluidFilter = BaseFilter.getFilterFromStack(stack); this.fluidFilter.initUI(this::addWidget); } } else if (id == 3) { - fluidFilter.showTip = buffer.readBoolean(); + // fluidFilter.showTip = buffer.readBoolean(); } } } diff --git a/src/main/java/gregtech/common/covers/filter/WidgetGroupItemFilter.java b/src/main/java/gregtech/common/covers/filter/WidgetGroupItemFilter.java index d5601f2b2ab..9f26302fb2f 100644 --- a/src/main/java/gregtech/common/covers/filter/WidgetGroupItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/WidgetGroupItemFilter.java @@ -5,15 +5,23 @@ import net.minecraft.network.PacketBuffer; +import org.jetbrains.annotations.ApiStatus; + +import java.io.IOException; import java.util.function.Supplier; +/** + * @deprecated in favor of new MUI + */ +@Deprecated +@ApiStatus.ScheduledForRemoval(inVersion = "2.10") public class WidgetGroupItemFilter extends AbstractWidgetGroup { - private final Supplier itemFilterSupplier; - private ItemFilter itemFilter; + private final Supplier itemFilterSupplier; + private BaseFilter itemFilter; private int maxStackSize = 1; - public WidgetGroupItemFilter(int yPosition, Supplier itemFilterSupplier) { + public WidgetGroupItemFilter(int yPosition, Supplier itemFilterSupplier) { super(new Position(0, yPosition)); this.itemFilterSupplier = itemFilterSupplier; } @@ -21,7 +29,7 @@ public WidgetGroupItemFilter(int yPosition, Supplier itemFilterSuppl @Override public void detectAndSendChanges() { super.detectAndSendChanges(); - ItemFilter newItemFilter = itemFilterSupplier.get(); + BaseFilter newItemFilter = itemFilterSupplier.get(); if (itemFilter != newItemFilter) { clearAllWidgets(); this.itemFilter = newItemFilter; @@ -31,14 +39,13 @@ public void detectAndSendChanges() { writeUpdateInfo(2, buffer -> { if (itemFilter != null) { buffer.writeBoolean(true); - int filterId = FilterTypeRegistry.getIdForItemFilter(itemFilter); - buffer.writeVarInt(filterId); + buffer.writeItemStack(itemFilter.getContainerStack()); } else { buffer.writeBoolean(false); } }); } - int newMaxStackSize = itemFilter == null ? 1 : itemFilter.getMaxStackSize(); + int newMaxStackSize = itemFilter == null ? 1 : itemFilter.getMaxTransferSize(); if (maxStackSize != newMaxStackSize) { this.maxStackSize = newMaxStackSize; writeUpdateInfo(3, buffer -> buffer.writeVarInt(maxStackSize)); @@ -51,15 +58,19 @@ public void readUpdateInfo(int id, PacketBuffer buffer) { if (id == 2) { clearAllWidgets(); if (buffer.readBoolean()) { - int filterId = buffer.readVarInt(); - this.itemFilter = FilterTypeRegistry.createItemFilterById(filterId); - this.itemFilter.initUI(this::addWidget); - this.itemFilter.setMaxStackSize(maxStackSize); + // int filterId = buffer.readVarInt(); + try { + this.itemFilter = BaseFilter.getFilterFromStack(buffer.readItemStack()); + this.itemFilter.initUI(this::addWidget); + this.itemFilter.setMaxTransferSize(maxStackSize); + } catch (IOException e) { + throw new RuntimeException(e); + } } } else if (id == 3) { this.maxStackSize = buffer.readVarInt(); if (itemFilter != null) { - itemFilter.setMaxStackSize(maxStackSize); + itemFilter.setMaxTransferSize(maxStackSize); } } } diff --git a/src/main/java/gregtech/common/covers/filter/readers/BaseFilterReader.java b/src/main/java/gregtech/common/covers/filter/readers/BaseFilterReader.java new file mode 100644 index 00000000000..eee6a16a52a --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/readers/BaseFilterReader.java @@ -0,0 +1,124 @@ +package gregtech.common.covers.filter.readers; + +import gregtech.api.util.IDirtyNotifiable; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.common.util.INBTSerializable; + +import org.jetbrains.annotations.NotNull; + +public class BaseFilterReader implements FilterReader, INBTSerializable { + + protected ItemStack container; + private IDirtyNotifiable dirtyNotifiable; + private final int size; + private int maxTransferRate = 1; + protected static final String BLACKLIST = "IsBlacklist"; + protected static final String FILTER_CONTENTS = "FilterSlots"; + protected static final String KEY_LEGACY_FILTER = "Filter"; + + public BaseFilterReader(ItemStack container, int slots) { + this.container = container; + this.size = slots; + } + + @Override + public ItemStack getContainer() { + return this.container; + } + + @Override + public void readStack(@NotNull ItemStack stack) { + this.container = stack; + } + + public @NotNull NBTTagList getInventoryNbt() { + var nbt = getStackTag(); + if (!nbt.hasKey(FILTER_CONTENTS)) { + NBTTagList list = new NBTTagList(); + for (int i = 0; i < getSize(); i++) { + list.appendTag(new NBTTagCompound()); + } + nbt.setTag(FILTER_CONTENTS, list); + } + return nbt.getTagList(FILTER_CONTENTS, Constants.NBT.TAG_COMPOUND); + } + + public @NotNull NBTTagCompound getStackTag() { + NBTTagCompound nbt = this.container.getTagCompound(); + if (nbt == null) { + nbt = new NBTTagCompound(); + this.container.setTagCompound(nbt); + } + return nbt; + } + + @Override + public int getSize() { + return this.size; + } + + public final void setDirtyNotifiable(IDirtyNotifiable dirtyNotifiable) { + this.dirtyNotifiable = dirtyNotifiable; + } + + public final void markDirty() { + if (dirtyNotifiable != null) { + dirtyNotifiable.markAsDirty(); + } + } + + public void onTransferRateChange() {} + + public final void setBlacklistFilter(boolean blacklistFilter) { + if (getStackTag().getBoolean(BLACKLIST) != blacklistFilter) { + if (blacklistFilter) + getStackTag().setBoolean(BLACKLIST, true); + else + getStackTag().removeTag(BLACKLIST); + onTransferRateChange(); + markDirty(); + } + } + + public final boolean isBlacklistFilter() { + return getStackTag().getBoolean(BLACKLIST); + } + + public void setMaxTransferRate(int transferRate) { + transferRate = MathHelper.clamp(transferRate, 1, Integer.MAX_VALUE); + if (this.maxTransferRate != transferRate) { + this.maxTransferRate = transferRate; + onTransferRateChange(); + } + } + + public int getMaxTransferRate() { + return isBlacklistFilter() ? 1 : this.maxTransferRate; + } + + @Override + public boolean validateSlotIndex(int slot) { + return slot >= 0 && slot < getSize(); + } + + @Override + public NBTTagCompound serializeNBT() { + return getStackTag(); + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + if (nbt.hasKey(BLACKLIST)) + setBlacklistFilter(nbt.getBoolean(BLACKLIST)); + } + + public void handleLegacyNBT(NBTTagCompound tag) { + if (tag.hasKey(BLACKLIST)) + setBlacklistFilter(tag.getBoolean(BLACKLIST)); + } +} diff --git a/src/main/java/gregtech/common/covers/filter/readers/FilterReader.java b/src/main/java/gregtech/common/covers/filter/readers/FilterReader.java new file mode 100644 index 00000000000..34efe945268 --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/readers/FilterReader.java @@ -0,0 +1,32 @@ +package gregtech.common.covers.filter.readers; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; + +import org.jetbrains.annotations.NotNull; + +public interface FilterReader { + + ItemStack getContainer(); + + void readStack(ItemStack stack); + + @NotNull + NBTTagList getInventoryNbt(); + + @NotNull + NBTTagCompound getStackTag(); + + int getSize(); + + boolean validateSlotIndex(int slot); + + @NotNull + default NBTTagCompound getTagAt(int i) { + if (validateSlotIndex(i)) { + return getInventoryNbt().getCompoundTagAt(i); + } + return new NBTTagCompound(); + } +} diff --git a/src/main/java/gregtech/common/covers/filter/readers/OreDictFilterReader.java b/src/main/java/gregtech/common/covers/filter/readers/OreDictFilterReader.java new file mode 100644 index 00000000000..070ec7fe764 --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/readers/OreDictFilterReader.java @@ -0,0 +1,123 @@ +package gregtech.common.covers.filter.readers; + +import gregtech.api.util.oreglob.OreGlob; +import gregtech.api.util.oreglob.OreGlobCompileResult; +import gregtech.common.covers.filter.oreglob.impl.ImpossibleOreGlob; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import org.jetbrains.annotations.NotNull; + +public class OreDictFilterReader extends SimpleItemFilterReader { + + private static final String EXPRESSION = "OreDictionaryFilter"; + private static final String CASE_SENSITIVE = "caseSensitive"; + private static final String MATCH_ALL = "matchAll"; + + private OreGlob glob = ImpossibleOreGlob.getInstance(); + private OreGlobCompileResult result; + + public OreDictFilterReader(ItemStack container) { + super(container, 0); + } + + public void setExpression(String expression) { + if (getStackTag().getString(EXPRESSION).equals(expression)) + return; + + getStackTag().setString(EXPRESSION, expression); + recompile(); + markDirty(); + } + + public String getExpression() { + return getStackTag().getString(EXPRESSION); + } + + public void setCaseSensitive(boolean caseSensitive) { + if (isCaseSensitive() == caseSensitive) + return; + + if (!caseSensitive) + getStackTag().setBoolean(CASE_SENSITIVE, false); + else + getStackTag().removeTag(CASE_SENSITIVE); + recompile(); + markDirty(); + } + + public boolean isCaseSensitive() { + return !getStackTag().hasKey(CASE_SENSITIVE); + } + + public void setMatchAll(boolean matchAll) { + if (shouldMatchAll() == matchAll) + return; + + if (!matchAll) + getStackTag().setBoolean(MATCH_ALL, false); + else + getStackTag().removeTag(MATCH_ALL); + + markDirty(); + } + + /** + * {@code false} requires any of the entry to be match in order for the match to be success, {@code true} + * requires + * all entries to match + */ + public boolean shouldMatchAll() { + return !getStackTag().hasKey(MATCH_ALL); + } + + @NotNull + public OreGlob getGlob() { + return this.glob; + } + + public OreGlobCompileResult getResult() { + return this.result; + } + + public void recompile() { + String expr = getExpression(); + if (!expr.isEmpty()) { + result = OreGlob.compile(expr, !isCaseSensitive()); + this.glob = result.getInstance(); + } else { + this.glob = ImpossibleOreGlob.getInstance(); + result = null; + } + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + super.deserializeNBT(nbt); + + if (nbt.hasKey(EXPRESSION)) + this.setExpression(nbt.getString(EXPRESSION)); + + if (nbt.hasKey(CASE_SENSITIVE)) + this.setCaseSensitive(nbt.getBoolean(CASE_SENSITIVE)); + + if (nbt.hasKey(MATCH_ALL)) + this.setMatchAll(nbt.getBoolean(MATCH_ALL)); + } + + @Override + public void handleLegacyNBT(NBTTagCompound tag) { + super.handleLegacyNBT(tag); + + var legacyFilter = tag.getCompoundTag(KEY_LEGACY_FILTER); + if (legacyFilter.hasKey(EXPRESSION)) + this.setExpression(legacyFilter.getString(EXPRESSION)); + + if (legacyFilter.hasKey(CASE_SENSITIVE)) + this.setCaseSensitive(legacyFilter.getBoolean(CASE_SENSITIVE)); + + if (legacyFilter.hasKey(MATCH_ALL)) + this.setMatchAll(legacyFilter.getBoolean(MATCH_ALL)); + } +} diff --git a/src/main/java/gregtech/common/covers/filter/readers/SimpleFluidFilterReader.java b/src/main/java/gregtech/common/covers/filter/readers/SimpleFluidFilterReader.java new file mode 100644 index 00000000000..ea38dafd569 --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/readers/SimpleFluidFilterReader.java @@ -0,0 +1,181 @@ +package gregtech.common.covers.filter.readers; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTank; + +import org.jetbrains.annotations.Nullable; + +public class SimpleFluidFilterReader extends BaseFilterReader { + + protected WritableFluidTank[] fluidTanks; + protected static final String CAPACITY = "Capacity"; + + protected static final String LEGACY_FLUIDFILTER_KEY = "FluidFilter"; + + public SimpleFluidFilterReader(ItemStack container, int slots) { + super(container, slots); + fluidTanks = new WritableFluidTank[slots]; + for (int i = 0; i < fluidTanks.length; i++) { + fluidTanks[i] = new WritableFluidTank(this, getInventoryNbt().getCompoundTagAt(i)); + } + setCapacity(getStackTag().hasKey(CAPACITY) ? getCapacity() : 1000); + } + + public final boolean shouldShowAmount() { + return getMaxTransferRate() > 1; + } + + @Nullable + public FluidStack getFluidStack(int i) { + return getFluidTank(i).getFluid(); + } + + public void setCapacity(int capacity) { + getStackTag().setInteger(CAPACITY, capacity); + markDirty(); + } + + public int getCapacity() { + return getStackTag().getInteger(CAPACITY); + } + + public WritableFluidTank getFluidTank(int i) { + return fluidTanks[i]; + } + + public void setFluidAmounts(int amount) { + for (int i = 0; i < getSize(); i++) { + getFluidTank(i).setFluidAmount(amount); + } + } + + @Override + public void onTransferRateChange() { + for (int i = 0; i < getSize(); i++) { + var stack = getFluidStack(i); + if (stack == null) continue; + getFluidTank(i).setFluidAmount(Math.min(stack.amount, getMaxTransferRate())); + } + setCapacity(getMaxTransferRate()); + } + + @Override + public void handleLegacyNBT(NBTTagCompound tag) { + super.handleLegacyNBT(tag); + NBTTagCompound legacyFilter = tag.getCompoundTag(KEY_LEGACY_FILTER); + + NBTTagList filterSlots = legacyFilter.getTagList(LEGACY_FLUIDFILTER_KEY, Constants.NBT.TAG_COMPOUND); + for (int i = 0; i < filterSlots.tagCount(); i++) { + NBTTagCompound stackTag = filterSlots.getCompoundTagAt(i); + FluidStack fluidStack = FluidStack.loadFluidStackFromNBT(stackTag); + if (fluidStack == null) continue; + int slot = stackTag.getInteger("Slot"); + getFluidTank(slot).setFluid(fluidStack); + } + } + + public class WritableFluidTank extends FluidTank { + + private final NBTTagCompound fluidTank; + private final SimpleFluidFilterReader filterReader; + protected static final String FLUID_AMOUNT = "Amount"; + protected static final String FLUID = "Fluid"; + protected static final String EMPTY = "Empty"; + + protected WritableFluidTank(SimpleFluidFilterReader filterReader, NBTTagCompound fluidTank) { + super(0); + this.filterReader = filterReader; + this.fluidTank = fluidTank; + } + + public void setFluidAmount(int amount) { + if (amount <= 0) { + setFluid(null); + } else if (this.fluidTank.hasKey(FLUID)) { + this.fluidTank + .getCompoundTag(FLUID) + .setInteger(FLUID_AMOUNT, amount); + markDirty(); + } + } + + public boolean isEmpty() { + return !this.fluidTank.hasKey(FLUID); + } + + protected @Nullable NBTTagCompound getFluidTag() { + if (isEmpty()) { + return null; + } + + return this.fluidTank.getCompoundTag(FLUID); + } + + @Override + public @Nullable FluidStack getFluid() { + return FluidStack.loadFluidStackFromNBT(getFluidTag()); + } + + @Override + public void setFluid(@Nullable FluidStack stack) { + if (stack == null) { + this.fluidTank.removeTag(FLUID); + } else { + this.fluidTank.setTag(FLUID, stack.writeToNBT(new NBTTagCompound())); + } + markDirty(); + } + + public boolean showAmount() { + return this.filterReader.shouldShowAmount(); + } + + @Override + public int getFluidAmount() { + return this.fluidTank + .getCompoundTag(FLUID) + .getInteger(FLUID_AMOUNT); + } + + @Override + public int getCapacity() { + return this.filterReader.getCapacity(); + } + + // getFluid() is checked for nullability, suppress + @SuppressWarnings("DataFlowIssue") + @Override + public int fill(FluidStack resource, boolean doFill) { + if (isEmpty() || !getFluid().isFluidEqual(resource)) { + setFluid(resource); + if (!showAmount()) setFluidAmount(1); + return resource.amount; + } else if (showAmount()) { + var fluid = getFluid(); + int accepted = Math.min(resource.amount, getCapacity() - fluid.amount); + fluid.amount += accepted; + setFluid(fluid); + return accepted; + } + return 0; + } + + // getFluid() is checked for nullability, suppress + @SuppressWarnings("DataFlowIssue") + @Override + public FluidStack drain(int maxDrain, boolean doDrain) { + if (isEmpty()) return null; + FluidStack fluid = getFluid(); + + fluid.amount -= Math.min(fluid.amount, maxDrain); + + setFluidAmount(fluid.amount); + markDirty(); + return fluid; + } + } +} diff --git a/src/main/java/gregtech/common/covers/filter/readers/SimpleItemFilterReader.java b/src/main/java/gregtech/common/covers/filter/readers/SimpleItemFilterReader.java new file mode 100644 index 00000000000..84a66fe90b2 --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/readers/SimpleItemFilterReader.java @@ -0,0 +1,194 @@ +package gregtech.common.covers.filter.readers; + +import gregtech.api.util.GTUtility; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraftforge.items.IItemHandlerModifiable; +import net.minecraftforge.items.ItemHandlerHelper; +import net.minecraftforge.items.ItemStackHandler; + +import org.jetbrains.annotations.NotNull; + +public class SimpleItemFilterReader extends BaseFilterReader implements IItemHandlerModifiable { + + public static final String COUNT = "Count"; + protected static final String LEGACY_ITEM_KEY = "ItemFilter"; + protected static final String LEGACY_STACK_SIZE = "BigStackSize"; + public static final String RESPECT_NBT = "IgnoreNBT"; + public static final String RESPECT_DAMAGE = "IgnoreDamage"; + + public SimpleItemFilterReader(ItemStack container, int slots) { + super(container, slots); + } + + public void setIgnoreDamage(boolean ignoreDamage) { + if (!getStackTag().getBoolean(RESPECT_DAMAGE) == ignoreDamage) + return; + + if (ignoreDamage) + getStackTag().removeTag(RESPECT_DAMAGE); + else + getStackTag().setBoolean(RESPECT_DAMAGE, true); + markDirty(); + } + + @Override + public int getSlots() { + return getSize(); + } + + public void setIgnoreNBT(boolean ignoreNBT) { + if (!getStackTag().getBoolean(RESPECT_NBT) == ignoreNBT) + return; + + if (ignoreNBT) + getStackTag().removeTag(RESPECT_NBT); + else + getStackTag().setBoolean(RESPECT_NBT, true); + markDirty(); + } + + public boolean isIgnoreDamage() { + return !getStackTag().getBoolean(RESPECT_DAMAGE); + } + + public boolean isIgnoreNBT() { + return !getStackTag().getBoolean(RESPECT_NBT); + } + + @Override + public int getSlotLimit(int slot) { + return getMaxTransferRate(); + } + + @NotNull + @Override + public ItemStack getStackInSlot(int slot) { + if (validateSlotIndex(slot)) { + NBTTagCompound item = getTagAt(slot); + return item.isEmpty() ? ItemStack.EMPTY : new ItemStack(item); + } + return ItemStack.EMPTY; + } + + @Override + public void setStackInSlot(int slot, ItemStack stack) { + if (validateSlotIndex(slot)) { + if (!stack.isEmpty()) { + stack.setCount(Math.min(stack.getCount(), isBlacklistFilter() ? 1 : getMaxTransferRate())); + } + NBTTagList list = getInventoryNbt(); + list.set(slot, stack.isEmpty() ? new NBTTagCompound() : stack.serializeNBT()); + markDirty(); + } + } + + @NotNull + @Override + public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + if (stack.isEmpty()) return stack; + ItemStack existing = getStackInSlot(slot); + + int limit = getStackLimit(slot, stack); + + if (!existing.isEmpty()) { + if (!ItemHandlerHelper.canItemStacksStack(stack, existing)) + return stack; + + limit -= existing.getCount(); + } + + if (limit <= 0) return stack; + + boolean reachedLimit = stack.getCount() > limit; + + if (!simulate) { + if (existing.isEmpty()) { + setStackInSlot(slot, reachedLimit ? ItemHandlerHelper.copyStackWithSize(stack, limit) : stack); + } else { + existing.grow(reachedLimit ? limit : stack.getCount()); + setStackInSlot(slot, existing); + } + } + + return reachedLimit ? GTUtility.copy(stack.getCount() - limit, stack) : ItemStack.EMPTY; + } + + @NotNull + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (amount == 0) return ItemStack.EMPTY; + + ItemStack existing = getStackInSlot(slot); + if (existing.isEmpty()) return ItemStack.EMPTY; + + int toExtract = Math.min(amount, existing.getMaxStackSize()); + + if (existing.getCount() <= toExtract) { + if (!simulate) { + setStackInSlot(slot, ItemStack.EMPTY); + } + return existing; + } else { + if (!simulate) { + setStackInSlot(slot, ItemHandlerHelper.copyStackWithSize(existing, existing.getCount() - toExtract)); + } + + return GTUtility.copy(toExtract, existing); + } + } + + protected int getStackLimit(int slot, @NotNull ItemStack stack) { + return Math.min(getSlotLimit(slot), stack.getMaxStackSize()); + } + + @Override + public void onTransferRateChange() { + for (int i = 0; i < getSlots(); i++) { + ItemStack itemStack = getStackInSlot(i); + if (!itemStack.isEmpty()) { + itemStack.setCount(Math.min(itemStack.getCount(), isBlacklistFilter() ? 1 : getMaxTransferRate())); + setStackInSlot(i, itemStack); + } + } + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + super.deserializeNBT(nbt); + + if (nbt.hasKey(RESPECT_DAMAGE)) + this.setIgnoreDamage(nbt.getBoolean(RESPECT_DAMAGE)); + + if (nbt.hasKey(RESPECT_NBT)) + this.setIgnoreNBT(nbt.getBoolean(RESPECT_NBT)); + } + + @Override + public void handleLegacyNBT(NBTTagCompound tag) { + super.handleLegacyNBT(tag); + NBTTagCompound legacyFilter = tag.getCompoundTag(KEY_LEGACY_FILTER); + + if (legacyFilter.hasKey(LEGACY_ITEM_KEY)) { + var temp = new ItemStackHandler(); + var legacyTag = legacyFilter.getCompoundTag(LEGACY_ITEM_KEY); + var stackSizes = legacyTag.getCompoundTag(LEGACY_STACK_SIZE); + + temp.deserializeNBT(legacyTag); + for (int i = 0; i < temp.getSlots(); i++) { + var stack = temp.getStackInSlot(i); + if (stack.isEmpty()) + continue; + + if (stackSizes.hasKey(String.valueOf(i))) + stack.setCount(stackSizes.getInteger(String.valueOf(i))); + + var stackTag = stack.serializeNBT(); + stackTag.setInteger(COUNT, stack.getCount()); + getInventoryNbt().set(i, stackTag); + } + } + } +} diff --git a/src/main/java/gregtech/common/covers/filter/readers/SmartItemFilterReader.java b/src/main/java/gregtech/common/covers/filter/readers/SmartItemFilterReader.java new file mode 100644 index 00000000000..ca96ed549c2 --- /dev/null +++ b/src/main/java/gregtech/common/covers/filter/readers/SmartItemFilterReader.java @@ -0,0 +1,40 @@ +package gregtech.common.covers.filter.readers; + +import gregtech.common.covers.filter.SmartItemFilter; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +public class SmartItemFilterReader extends SimpleItemFilterReader { + + private static final String FILTER_MODE = "FilterMode"; + + public SmartItemFilterReader(ItemStack container) { + super(container, 0); + } + + public SmartItemFilter.SmartFilteringMode getFilteringMode() { + if (!getStackTag().hasKey(FILTER_MODE)) + setFilteringMode(SmartItemFilter.SmartFilteringMode.ELECTROLYZER); + + return SmartItemFilter.SmartFilteringMode.VALUES[getStackTag().getInteger(FILTER_MODE)]; + } + + public void setFilteringMode(SmartItemFilter.SmartFilteringMode filteringMode) { + getStackTag().setInteger(FILTER_MODE, filteringMode.ordinal()); + markDirty(); + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + super.deserializeNBT(nbt); + this.setFilteringMode(SmartItemFilter.SmartFilteringMode.VALUES[nbt.getInteger(FILTER_MODE)]); + } + + @Override + public void handleLegacyNBT(NBTTagCompound tag) { + super.handleLegacyNBT(tag); + var legacyFilter = tag.getCompoundTag(KEY_LEGACY_FILTER); + this.setFilteringMode(SmartItemFilter.SmartFilteringMode.VALUES[legacyFilter.getInteger(FILTER_MODE)]); + } +} diff --git a/src/main/java/gregtech/common/creativetab/GTCreativeTabs.java b/src/main/java/gregtech/common/creativetab/GTCreativeTabs.java new file mode 100644 index 00000000000..95d308dde3e --- /dev/null +++ b/src/main/java/gregtech/common/creativetab/GTCreativeTabs.java @@ -0,0 +1,34 @@ +package gregtech.common.creativetab; + +import gregtech.api.GTValues; +import gregtech.api.creativetab.BaseCreativeTab; +import gregtech.api.unification.OreDictUnifier; +import gregtech.api.unification.material.Materials; +import gregtech.api.unification.ore.OrePrefix; +import gregtech.common.blocks.BlockWarningSign; +import gregtech.common.blocks.MetaBlocks; +import gregtech.common.items.MetaItems; +import gregtech.common.items.ToolItems; +import gregtech.common.metatileentities.MetaTileEntities; + +public final class GTCreativeTabs { + + public static final BaseCreativeTab TAB_GREGTECH = new BaseCreativeTab(GTValues.MODID + ".main", + () -> MetaItems.LOGO.getStackForm(), true); + public static final BaseCreativeTab TAB_GREGTECH_MACHINES = new BaseCreativeTab(GTValues.MODID + ".machines", + () -> MetaTileEntities.ELECTRIC_BLAST_FURNACE.getStackForm(), true); + public static final BaseCreativeTab TAB_GREGTECH_CABLES = new BaseCreativeTab(GTValues.MODID + ".cables", + () -> OreDictUnifier.get(OrePrefix.cableGtDouble, Materials.Aluminium), true); + public static final BaseCreativeTab TAB_GREGTECH_PIPES = new BaseCreativeTab(GTValues.MODID + ".pipes", + () -> OreDictUnifier.get(OrePrefix.pipeNormalFluid, Materials.Aluminium), true); + public static final BaseCreativeTab TAB_GREGTECH_TOOLS = new BaseCreativeTab(GTValues.MODID + ".tools", + () -> ToolItems.HARD_HAMMER.get(Materials.Aluminium), true); + public static final BaseCreativeTab TAB_GREGTECH_MATERIALS = new BaseCreativeTab(GTValues.MODID + ".materials", + () -> OreDictUnifier.get(OrePrefix.ingot, Materials.Aluminium), true); + public static final BaseCreativeTab TAB_GREGTECH_ORES = new BaseCreativeTab(GTValues.MODID + ".ores", + () -> OreDictUnifier.get(OrePrefix.ore, Materials.Aluminium), true); + public static final BaseCreativeTab TAB_GREGTECH_DECORATIONS = new BaseCreativeTab(GTValues.MODID + ".decorations", + () -> MetaBlocks.WARNING_SIGN.getItemVariant(BlockWarningSign.SignType.YELLOW_STRIPES), true); + + private GTCreativeTabs() {} +} diff --git a/src/main/java/gregtech/common/entities/EntityGTExplosive.java b/src/main/java/gregtech/common/entities/EntityGTExplosive.java new file mode 100644 index 00000000000..70233d7f17b --- /dev/null +++ b/src/main/java/gregtech/common/entities/EntityGTExplosive.java @@ -0,0 +1,136 @@ +package gregtech.common.entities; + +import gregtech.api.util.BlockUtility; +import gregtech.api.util.GregFakePlayer; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.MoverType; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.item.EntityTNTPrimed; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; + +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; + +public abstract class EntityGTExplosive extends EntityTNTPrimed { + + public EntityGTExplosive(World world, double x, double y, double z, EntityLivingBase exploder) { + super(world, x, y, z, exploder); + } + + @SuppressWarnings("unused") + public EntityGTExplosive(World world) { + super(world); + } + + /** + * @return The strength of the explosive. + */ + protected abstract float getStrength(); + + /** + * @return Whether to drop all blocks, or use default logic + */ + public abstract boolean dropsAllBlocks(); + + /** + * @return The range of the explosive, if {@link #dropsAllBlocks} is true. + */ + protected int getRange() { + return 2; + } + + /** + * @return The block state of the block this explosion entity is created by. + */ + public abstract @NotNull IBlockState getExplosiveState(); + + @Override + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + if (!this.hasNoGravity()) { + this.motionY -= 0.03999999910593033D; + } + + this.move(MoverType.SELF, this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9800000190734863D; + this.motionY *= 0.9800000190734863D; + this.motionZ *= 0.9800000190734863D; + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + this.motionY *= -0.5D; + } + + setFuse(this.getFuse() - 1); + if (this.getFuse() <= 0) { + this.setDead(); + if (!this.world.isRemote) { + this.explodeTNT(); + } + } else { + this.handleWaterMovement(); + this.world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, + 0.0D); + } + } + + protected void explodeTNT() { + this.world.createExplosion(this, this.posX, this.posY + (double) (this.height / 16.0F), this.posZ, + getStrength(), !dropsAllBlocks()); + + // If we don't drop all blocks, then skip the drop capture logic + if (!dropsAllBlocks()) return; + + // Create the fake explosion but don't destroy any blocks in water, per MC behavior + if (this.inWater) return; + + EntityPlayer player = GregFakePlayer.get((WorldServer) world); + + int range = getRange(); + for (BlockPos pos : BlockPos.getAllInBox(this.getPosition().add(-range, -range, -range), + this.getPosition().add(range, range, range))) { + IBlockState state = world.getBlockState(pos); + + if (state.getMaterial() == Material.AIR) continue; + if (state.getMaterial() == Material.WATER || state.getMaterial() == Material.LAVA) continue; + + float hardness = state.getBlockHardness(world, pos); + float resistance = state.getBlock().getExplosionResistance(player); + + if (hardness >= 0.0f && resistance < 100 && world.isBlockModifiable(player, pos)) { + List drops = attemptBreakBlockAndObtainDrops(pos, state, player); + + for (ItemStack stack : drops) { + EntityItem entity = new EntityItem(world, pos.getX(), pos.getY(), pos.getZ(), stack); + entity.setDefaultPickupDelay(); + world.spawnEntity(entity); + } + } + } + } + + private List attemptBreakBlockAndObtainDrops(BlockPos pos, IBlockState state, EntityPlayer player) { + if (state.getBlock().removedByPlayer(state, world, pos, player, true)) { + world.playEvent(null, 2001, pos, Block.getStateId(state)); + state.getBlock().onPlayerDestroy(world, pos, state); + + BlockUtility.startCaptureDrops(); + state.getBlock().harvestBlock(world, player, pos, state, world.getTileEntity(pos), ItemStack.EMPTY); + return BlockUtility.stopCaptureDrops(); + } + return Collections.emptyList(); + } +} diff --git a/src/main/java/gregtech/common/entities/ITNTEntity.java b/src/main/java/gregtech/common/entities/ITNTEntity.java new file mode 100644 index 00000000000..3fa60cf4860 --- /dev/null +++ b/src/main/java/gregtech/common/entities/ITNTEntity.java @@ -0,0 +1,41 @@ +package gregtech.common.entities; + +import gregtech.common.blocks.MetaBlocks; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; + +public class ITNTEntity extends EntityGTExplosive { + + public ITNTEntity(World world, double x, double y, double z, EntityLivingBase exploder) { + super(world, x, y, z, exploder); + } + + @SuppressWarnings("unused") + public ITNTEntity(World world) { + super(world); + } + + @Override + protected float getStrength() { + return 5.0F; + } + + @Override + public boolean dropsAllBlocks() { + return true; + } + + @Override + protected int getRange() { + return 3; + } + + @Override + public @NotNull IBlockState getExplosiveState() { + return MetaBlocks.ITNT.getDefaultState(); + } +} diff --git a/src/main/java/gregtech/common/entities/PowderbarrelEntity.java b/src/main/java/gregtech/common/entities/PowderbarrelEntity.java new file mode 100644 index 00000000000..39f1ed4df56 --- /dev/null +++ b/src/main/java/gregtech/common/entities/PowderbarrelEntity.java @@ -0,0 +1,36 @@ +package gregtech.common.entities; + +import gregtech.common.blocks.MetaBlocks; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.world.World; + +import org.jetbrains.annotations.NotNull; + +public class PowderbarrelEntity extends EntityGTExplosive { + + public PowderbarrelEntity(World world, double x, double y, double z, EntityLivingBase exploder) { + super(world, x, y, z, exploder); + } + + @SuppressWarnings("unused") + public PowderbarrelEntity(World world) { + super(world); + } + + @Override + protected float getStrength() { + return 3.5F; + } + + @Override + public boolean dropsAllBlocks() { + return true; + } + + @Override + public @NotNull IBlockState getExplosiveState() { + return MetaBlocks.POWDERBARREL.getDefaultState(); + } +} diff --git a/src/main/java/gregtech/common/gui/impl/FakeModularUIContainerClipboard.java b/src/main/java/gregtech/common/gui/impl/FakeModularUIContainerClipboard.java index af569788b80..e7c4b8dad09 100644 --- a/src/main/java/gregtech/common/gui/impl/FakeModularUIContainerClipboard.java +++ b/src/main/java/gregtech/common/gui/impl/FakeModularUIContainerClipboard.java @@ -10,10 +10,8 @@ import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; -import net.minecraft.util.NonNullList; import net.minecraft.util.Tuple; -import com.google.common.collect.Lists; import io.netty.buffer.Unpooled; import java.util.ArrayList; @@ -24,8 +22,8 @@ public class FakeModularUIContainerClipboard extends FakeModularGuiContainer { - private final NonNullList inventoryItemStacks = NonNullList.create(); - public final List inventorySlots = Lists.newArrayList(); + private final List inventoryItemStacks = new ArrayList<>(); + public final List inventorySlots = new ArrayList<>(); public int windowId; public MetaTileEntityClipboard clipboard; diff --git a/src/main/java/gregtech/common/gui/widget/HighlightedTextField.java b/src/main/java/gregtech/common/gui/widget/HighlightedTextField.java deleted file mode 100644 index 8acea5527f7..00000000000 --- a/src/main/java/gregtech/common/gui/widget/HighlightedTextField.java +++ /dev/null @@ -1,127 +0,0 @@ -package gregtech.common.gui.widget; - -import gregtech.api.gui.widgets.TextFieldWidget2; - -import net.minecraft.util.text.TextFormatting; - -import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntList; -import org.jetbrains.annotations.Nullable; - -import java.util.function.Consumer; -import java.util.function.Supplier; - -public class HighlightedTextField extends TextFieldWidget2 { - - @Nullable - private Consumer highlightRule; - @Nullable - private TextHighlighter formatResult; - - public HighlightedTextField(int x, int y, int width, int height, Supplier supplier, - Consumer setter) { - super(x, y, width, height, supplier, setter); - } - - /** - * Text highlighter applied only in rendering text. Only formatting characters can be inserted. - * - * @param highlightRule Consumer for text highlighter - * @return This - */ - public HighlightedTextField setHighlightRule(Consumer highlightRule) { - this.highlightRule = highlightRule; - return this; - } - - @Override - public void setText(String text) { - super.setText(text); - this.formatResult = null; - } - - @Override - protected String getRenderText() { - if (this.formatResult == null) { - if (this.highlightRule == null) { - return getText(); - } - TextHighlighter highlighter = new TextHighlighter(getText()); - this.highlightRule.accept(highlighter); - this.formatResult = highlighter; - return highlighter.getFormattedText(); - } - return this.formatResult.getFormattedText(); - } - - @Override - protected int toOriginalTextIndex(int renderTextIndex) { - return formatResult != null ? formatResult.toOriginalTextIndex(renderTextIndex) : renderTextIndex; - } - - @Override - protected int toRenderTextIndex(int originalTextIndex) { - return formatResult != null ? formatResult.toFormattedTextIndex(originalTextIndex) : originalTextIndex; - } - - public static final class TextHighlighter { - - private final String originalText; - private final StringBuilder formattedTextBuilder; - - private final IntList formatOriginalIndices = new IntArrayList(); - - @Nullable - private String formattedTextCache; - - public TextHighlighter(String originalText) { - this.originalText = originalText; - this.formattedTextBuilder = new StringBuilder(originalText); - } - - public String getOriginalText() { - return this.originalText; - } - - public String getFormattedText() { - if (this.formattedTextCache == null) { - return this.formattedTextCache = this.formattedTextBuilder.toString(); - } - return this.formattedTextCache; - } - - public int toFormattedTextIndex(int originalTextIndex) { - int i = 0; - for (; i < formatOriginalIndices.size(); i++) { - if (formatOriginalIndices.getInt(i) > originalTextIndex) { - break; - } - } - return originalTextIndex + i * 2; - } - - public int toOriginalTextIndex(int formattedTextIndex) { - int i = 0; - for (; i < formatOriginalIndices.size(); i++) { - if (formatOriginalIndices.getInt(i) + i * 2 >= formattedTextIndex) { - break; - } - } - return formattedTextIndex - i * 2; - } - - public void format(int index, TextFormatting format) { - if (index < 0) index = 0; - else if (index > originalText.length()) return; - formattedTextBuilder.insert(toFormattedTextIndex(index), format.toString()); - formattedTextCache = null; - for (int i = 0; i < formatOriginalIndices.size(); i++) { - if (formatOriginalIndices.getInt(i) > index) { - formatOriginalIndices.add(i, index); - return; - } - } - formatOriginalIndices.add(index); - } - } -} diff --git a/src/main/java/gregtech/common/gui/widget/appeng/AEConfigWidget.java b/src/main/java/gregtech/common/gui/widget/appeng/AEConfigWidget.java index 59005459893..1195fa8f34f 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/AEConfigWidget.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/AEConfigWidget.java @@ -6,7 +6,7 @@ import gregtech.api.util.Size; import gregtech.common.gui.widget.appeng.slot.AEConfigSlot; import gregtech.common.gui.widget.appeng.slot.AmountSetSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import appeng.api.storage.data.IAEStack; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; @@ -26,26 +26,34 @@ public abstract class AEConfigWidget> extends AbstractWidg protected Int2ObjectMap> changeMap = new Int2ObjectOpenHashMap<>(); protected IConfigurableSlot[] displayList; protected AmountSetSlot amountSetWidget; + protected final boolean isStocking; protected final static int UPDATE_ID = 1000; - public AEConfigWidget(int x, int y, IConfigurableSlot[] config) { + public AEConfigWidget(int x, int y, IConfigurableSlot[] config, boolean isStocking) { super(new Position(x, y), new Size(config.length * 18, 18 * 2)); + this.isStocking = isStocking; this.config = config; this.init(); - this.amountSetWidget = new AmountSetSlot<>(80, -40, this); - this.addWidget(this.amountSetWidget); - this.addWidget(this.amountSetWidget.getText()); - this.amountSetWidget.setVisible(false); - this.amountSetWidget.getText().setVisible(false); + if (!isStocking()) { + this.amountSetWidget = new AmountSetSlot<>(80, -40, this); + this.addWidget(this.amountSetWidget); + this.addWidget(this.amountSetWidget.getText()); + this.amountSetWidget.setVisible(false); + this.amountSetWidget.getText().setVisible(false); + } } public void enableAmount(int slotIndex) { + // Only allow the amount set widget if not stocking, as amount is useless for stocking + if (isStocking()) return; this.amountSetWidget.setSlotIndex(slotIndex); this.amountSetWidget.setVisible(true); this.amountSetWidget.getText().setVisible(true); } public void disableAmount() { + // Only allow the amount set widget if not stocking, as amount is useless for stocking + if (isStocking()) return; this.amountSetWidget.setSlotIndex(-1); this.amountSetWidget.setVisible(false); this.amountSetWidget.getText().setVisible(false); @@ -53,22 +61,29 @@ public void disableAmount() { @Override public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (this.amountSetWidget.isVisible()) { - if (this.amountSetWidget.getText().mouseClicked(mouseX, mouseY, button)) { - return true; + // Only allow the amount set widget if not stocking, as amount is useless for stocking + if (!isStocking()) { + if (this.amountSetWidget.isVisible()) { + if (this.amountSetWidget.getText().mouseClicked(mouseX, mouseY, button)) { + return true; + } } - } - for (Widget w : this.widgets) { - if (w instanceof AEConfigSlot) { - ((AEConfigSlot) w).setSelect(false); + for (Widget w : this.widgets) { + if (w instanceof AEConfigSlot) { + ((AEConfigSlot) w).setSelect(false); + } } + this.disableAmount(); } - this.disableAmount(); return super.mouseClicked(mouseX, mouseY, button); } abstract void init(); + public boolean isStocking() { + return isStocking; + } + @Override public void detectAndSendChanges() { super.detectAndSendChanges(); diff --git a/src/main/java/gregtech/common/gui/widget/appeng/AEFluidConfigWidget.java b/src/main/java/gregtech/common/gui/widget/appeng/AEFluidConfigWidget.java index 1599217290c..b5f709b0b86 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/AEFluidConfigWidget.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/AEFluidConfigWidget.java @@ -1,39 +1,49 @@ package gregtech.common.gui.widget.appeng; import gregtech.common.gui.widget.appeng.slot.AEFluidConfigSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEInputHatch; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fluids.FluidStack; import appeng.api.storage.data.IAEFluidStack; -/** - * @Author GlodBlock - * @Description Display {@link IAEFluidStack} config - * @Date 2023/4/21-1:45 - */ public class AEFluidConfigWidget extends AEConfigWidget { - public AEFluidConfigWidget(int x, int y, IConfigurableSlot[] config) { - super(x, y, config); + final ExportOnlyAEFluidList fluidList; + + public AEFluidConfigWidget(int x, int y, ExportOnlyAEFluidList fluidList) { + super(x, y, fluidList.getInventory(), fluidList.isStocking()); + this.fluidList = fluidList; } @Override @SuppressWarnings("unchecked") void init() { - int line; + final int size = (int) Math.sqrt(this.config.length); this.displayList = new IConfigurableSlot[this.config.length]; this.cached = new IConfigurableSlot[this.config.length]; - for (int index = 0; index < this.config.length; index++) { - this.displayList[index] = new MetaTileEntityMEInputHatch.ExportOnlyAEFluid(); - this.cached[index] = new MetaTileEntityMEInputHatch.ExportOnlyAEFluid(); - line = index / 8; - this.addWidget(new AEFluidConfigSlot((index - line * 8) * 18, line * (18 * 2 + 2), this, index)); + for (int h = 0; h < size; h++) { + for (int w = 0; w < size; w++) { + final int index = h * size + w; + this.displayList[index] = new ExportOnlyAEFluidSlot(); + this.cached[index] = new ExportOnlyAEFluidSlot(); + this.addWidget(new AEFluidConfigSlot(w * 18, h * 18, this, index)); + } } } + public boolean hasStackInConfig(FluidStack stack) { + return fluidList.hasStackInConfig(stack, true); + } + + public boolean isAutoPull() { + return fluidList.isAutoPull(); + } + @Override public void readUpdateInfo(int id, PacketBuffer buffer) { super.readUpdateInfo(id, buffer); diff --git a/src/main/java/gregtech/common/gui/widget/appeng/AEItemConfigWidget.java b/src/main/java/gregtech/common/gui/widget/appeng/AEItemConfigWidget.java index c3707d4afaf..0f2afe98235 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/AEItemConfigWidget.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/AEItemConfigWidget.java @@ -1,39 +1,49 @@ package gregtech.common.gui.widget.appeng; import gregtech.common.gui.widget.appeng.slot.AEItemConfigSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEInputBus; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; +import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import appeng.api.storage.data.IAEItemStack; -/** - * @Author GlodBlock - * @Description Display {@link IAEItemStack} config - * @Date 2023/4/22-1:02 - */ public class AEItemConfigWidget extends AEConfigWidget { - public AEItemConfigWidget(int x, int y, IConfigurableSlot[] config) { - super(x, y, config); + final ExportOnlyAEItemList itemList; + + public AEItemConfigWidget(int x, int y, ExportOnlyAEItemList itemList) { + super(x, y, itemList.getInventory(), itemList.isStocking()); + this.itemList = itemList; } @Override @SuppressWarnings("unchecked") void init() { - int line; + final int size = (int) Math.sqrt(this.config.length); this.displayList = new IConfigurableSlot[this.config.length]; this.cached = new IConfigurableSlot[this.config.length]; - for (int index = 0; index < this.config.length; index++) { - this.displayList[index] = new MetaTileEntityMEInputBus.ExportOnlyAEItem(); - this.cached[index] = new MetaTileEntityMEInputBus.ExportOnlyAEItem(); - line = index / 8; - this.addWidget(new AEItemConfigSlot((index - line * 8) * 18, line * (18 * 2 + 2), this, index)); + for (int h = 0; h < size; h++) { + for (int w = 0; w < size; w++) { + final int index = h * size + w; + this.displayList[index] = new ExportOnlyAEItemSlot(); + this.cached[index] = new ExportOnlyAEItemSlot(); + this.addWidget(new AEItemConfigSlot(w * 18, h * 18, this, index)); + } } } + public boolean hasStackInConfig(ItemStack stack) { + return itemList.hasStackInConfig(stack, true); + } + + public boolean isAutoPull() { + return itemList.isAutoPull(); + } + @Override public void readUpdateInfo(int id, PacketBuffer buffer) { super.readUpdateInfo(id, buffer); diff --git a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEConfigSlot.java b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEConfigSlot.java index ed1b9145bd7..d663340a451 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEConfigSlot.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEConfigSlot.java @@ -5,7 +5,7 @@ import gregtech.api.util.Position; import gregtech.api.util.Size; import gregtech.common.gui.widget.appeng.AEConfigWidget; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; @@ -17,13 +17,9 @@ import java.util.Collections; import java.util.List; -/** - * @Author GlodBlock - * @Description A configurable slot - * @Date 2023/4/22-0:30 - */ public class AEConfigSlot> extends Widget implements IGhostIngredientTarget { + protected static final int DISPLAY_X_OFFSET = 18 * 5; protected AEConfigWidget parentWidget; protected int index; protected final static int REMOVE_ID = 1000; @@ -43,14 +39,24 @@ public void drawInForeground(int mouseX, int mouseY) { IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); if (slot.getConfig() == null && mouseOverConfig(mouseX, mouseY)) { List hoverStringList = new ArrayList<>(); - hoverStringList.add(I18n.format("gregtech.gui.config_slot")); - hoverStringList.add(I18n.format("gregtech.gui.config_slot.set")); - hoverStringList.add(I18n.format("gregtech.gui.config_slot.scroll")); - hoverStringList.add(I18n.format("gregtech.gui.config_slot.remove")); - drawHoveringText(ItemStack.EMPTY, hoverStringList, -1, mouseX, mouseY); + addHoverText(hoverStringList); + if (!hoverStringList.isEmpty()) { + drawHoveringText(ItemStack.EMPTY, hoverStringList, -1, mouseX, mouseY); + } } } + protected void addHoverText(List hoverText) { + hoverText.add(I18n.format("gregtech.gui.config_slot")); + if (!parentWidget.isStocking()) { + hoverText.add(I18n.format("gregtech.gui.config_slot.set")); + hoverText.add(I18n.format("gregtech.gui.config_slot.scroll")); + } else { + hoverText.add(I18n.format("gregtech.gui.config_slot.set_only")); + } + hoverText.add(I18n.format("gregtech.gui.config_slot.remove")); + } + public void setSelect(boolean val) { this.select = val; } @@ -62,11 +68,15 @@ protected boolean mouseOverConfig(int mouseX, int mouseY) { protected boolean mouseOverStock(int mouseX, int mouseY) { Position position = getPosition(); - return isMouseOver(position.x, position.y + 18, 18, 18, mouseX, mouseY); + return isMouseOver(position.x + DISPLAY_X_OFFSET, position.y, 18, 18, mouseX, mouseY); } @Override public List> getPhantomTargets(Object ingredient) { return Collections.emptyList(); } + + public AEConfigWidget getParentWidget() { + return parentWidget; + } } diff --git a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEFluidConfigSlot.java b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEFluidConfigSlot.java index b4ab7e87beb..2b852fdeb14 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEFluidConfigSlot.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEFluidConfigSlot.java @@ -7,10 +7,11 @@ import gregtech.api.util.Size; import gregtech.api.util.TextFormattingUtil; import gregtech.client.utils.RenderUtil; -import gregtech.common.gui.widget.appeng.AEConfigWidget; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.gui.widget.appeng.AEFluidConfigWidget; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; +import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; @@ -34,27 +35,26 @@ import static gregtech.api.capability.GregtechDataCodes.LOAD_PHANTOM_FLUID_STACK_FROM_NBT; import static gregtech.api.util.GTUtility.getFluidFromContainer; -/** - * @Author GlodBlock - * @Description A configurable slot for {@link IAEFluidStack} - * @Date 2023/4/21-0:50 - */ public class AEFluidConfigSlot extends AEConfigSlot { - public AEFluidConfigSlot(int x, int y, AEConfigWidget widget, int index) { - super(new Position(x, y), new Size(18, 18 * 2), widget, index); + public AEFluidConfigSlot(int x, int y, AEFluidConfigWidget widget, int index) { + super(new Position(x, y), new Size(18 * 6, 18), widget, index); + } + + @Override + public AEFluidConfigWidget getParentWidget() { + return (AEFluidConfigWidget) super.getParentWidget(); } @Override public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { super.drawInBackground(mouseX, mouseY, partialTicks, context); + AEFluidConfigWidget pw = getParentWidget(); Position position = getPosition(); - IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); + IConfigurableSlot slot = pw.getDisplay(this.index); IAEFluidStack config = slot.getConfig(); IAEFluidStack stock = slot.getStock(); - GuiTextures.FLUID_SLOT.draw(position.x, position.y, 18, 18); - GuiTextures.FLUID_SLOT.draw(position.x, position.y + 18, 18, 18); - GuiTextures.CONFIG_ARROW.draw(position.x, position.y, 18, 18); + drawSlots(pw.isAutoPull(), position.x, position.y); if (this.select) { GuiTextures.SELECT_BOX.draw(position.x, position.y, 18, 18); } @@ -62,22 +62,35 @@ public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRender int stackY = position.y + 1; if (config != null) { RenderUtil.drawFluidForGui(config.getFluidStack(), config.getFluidStack().amount, stackX, stackY, 17, 17); - String amountStr = TextFormattingUtil.formatLongToCompactString(config.getStackSize(), 4) + "L"; - drawStringFixedCorner(amountStr, stackX + 17, stackY + 17, 16777215, true, 0.5f); + + if (!pw.isStocking()) { + String amountStr = TextFormattingUtil.formatLongToCompactString(config.getStackSize(), 4) + "L"; + drawStringFixedCorner(amountStr, stackX + 17, stackY + 17, 16777215, true, 0.5f); + } } if (stock != null) { - RenderUtil.drawFluidForGui(stock.getFluidStack(), stock.getFluidStack().amount, stackX, stackY + 18, 17, - 17); + RenderUtil.drawFluidForGui(stock.getFluidStack(), stock.getFluidStack().amount, stackX + DISPLAY_X_OFFSET, + stackY, 17, 17); String amountStr = TextFormattingUtil.formatLongToCompactString(stock.getStackSize(), 4) + "L"; - drawStringFixedCorner(amountStr, stackX + 17, stackY + 18 + 17, 16777215, true, 0.5f); + drawStringFixedCorner(amountStr, stackX + DISPLAY_X_OFFSET + 17, stackY + 17, 16777215, true, 0.5f); } if (mouseOverConfig(mouseX, mouseY)) { drawSelectionOverlay(stackX, stackY, 16, 16); } else if (mouseOverStock(mouseX, mouseY)) { - drawSelectionOverlay(stackX, stackY + 18, 16, 16); + drawSelectionOverlay(stackX + DISPLAY_X_OFFSET, stackY, 16, 16); } } + private void drawSlots(boolean autoPull, int x, int y) { + if (autoPull) { + GuiTextures.SLOT_DARK.draw(x, y, 18, 18); + } else { + GuiTextures.FLUID_SLOT.draw(x, y, 18, 18); + } + GuiTextures.SLOT_DARK.draw(x + DISPLAY_X_OFFSET, y, 18, 18); + GuiTextures.CONFIG_ARROW.draw(x, y, 18, 18); + } + @Override public void drawInForeground(int mouseX, int mouseY) { super.drawInForeground(mouseX, mouseY); @@ -107,13 +120,31 @@ public void drawInForeground(int mouseX, int mouseY) { } } + @Override + protected void addHoverText(List hoverText) { + if (getParentWidget().isAutoPull()) { + hoverText.add(I18n.format("gregtech.gui.config_slot")); + hoverText.add(I18n.format("gregtech.gui.config_slot.auto_pull_managed")); + } else { + super.addHoverText(hoverText); + } + } + @Override public boolean mouseClicked(int mouseX, int mouseY, int button) { + AEFluidConfigWidget pw = getParentWidget(); + if (pw.isAutoPull()) { + return false; + } + if (mouseOverConfig(mouseX, mouseY)) { if (button == 1) { // Right click to clear - this.parentWidget.disableAmount(); writeClientAction(REMOVE_ID, buf -> {}); + + if (!pw.isStocking()) { + this.parentWidget.disableAmount(); + } } else if (button == 0) { // Left click to set/select ItemStack hold = this.gui.entityPlayer.inventory.getItemStack(); @@ -125,8 +156,11 @@ public boolean mouseClicked(int mouseX, int mouseY, int button) { buf.writeVarInt(fluid.amount); }); } - this.parentWidget.enableAmount(this.index); - this.select = true; + + if (!pw.isStocking()) { + this.parentWidget.enableAmount(this.index); + this.select = true; + } } return true; } @@ -145,6 +179,7 @@ public void handleClientAction(int id, PacketBuffer buffer) { if (id == UPDATE_ID) { FluidStack fluid = FluidRegistry.getFluidStack(buffer.readString(Integer.MAX_VALUE / 16), buffer.readVarInt()); + if (!isFluidValidForSlot(fluid)) return; slot.setConfig(WrappedFluidStack.fromFluidStack(fluid)); this.parentWidget.enableAmount(this.index); if (fluid != null) { @@ -198,13 +233,20 @@ public void readUpdateInfo(int id, PacketBuffer buffer) { } } + private boolean isFluidValidForSlot(FluidStack stack) { + if (stack == null) return true; + AEFluidConfigWidget pw = getParentWidget(); + if (!pw.isStocking()) return true; + return !pw.hasStackInConfig(stack); + } + @Override public List> getPhantomTargets(Object ingredient) { if (getFluidFromContainer(ingredient) == null) { return Collections.emptyList(); } Rectangle rectangle = toRectangleBox(); - rectangle.height /= 2; + rectangle.width /= 6; return Lists.newArrayList(new IGhostIngredientHandler.Target<>() { @NotNull @@ -227,9 +269,10 @@ public void accept(@NotNull Object ingredient) { @SideOnly(Side.CLIENT) public boolean mouseWheelMove(int mouseX, int mouseY, int wheelDelta) { + if (parentWidget.isStocking()) return false; IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); Rectangle rectangle = toRectangleBox(); - rectangle.height /= 2; + rectangle.width /= 6; if (slot.getConfig() == null || wheelDelta == 0 || !rectangle.contains(mouseX, mouseY)) { return false; } diff --git a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEItemConfigSlot.java b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEItemConfigSlot.java index 02cad40272b..3dff4140249 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/slot/AEItemConfigSlot.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/slot/AEItemConfigSlot.java @@ -5,10 +5,11 @@ import gregtech.api.util.Position; import gregtech.api.util.Size; import gregtech.api.util.TextFormattingUtil; -import gregtech.common.gui.widget.appeng.AEConfigWidget; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.gui.widget.appeng.AEItemConfigWidget; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; +import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import net.minecraftforge.fml.relauncher.Side; @@ -24,27 +25,26 @@ import java.util.Collections; import java.util.List; -/** - * @Author GlodBlock - * @Description A configurable slot for {@link IAEItemStack} - * @Date 2023/4/22-0:48 - */ public class AEItemConfigSlot extends AEConfigSlot { - public AEItemConfigSlot(int x, int y, AEConfigWidget widget, int index) { - super(new Position(x, y), new Size(18, 18 * 2), widget, index); + public AEItemConfigSlot(int x, int y, AEItemConfigWidget widget, int index) { + super(new Position(x, y), new Size(18 * 6, 18), widget, index); + } + + @Override + public AEItemConfigWidget getParentWidget() { + return (AEItemConfigWidget) super.getParentWidget(); } @Override public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { super.drawInBackground(mouseX, mouseY, partialTicks, context); + AEItemConfigWidget pw = getParentWidget(); Position position = getPosition(); - IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); + IConfigurableSlot slot = pw.getDisplay(this.index); IAEItemStack config = slot.getConfig(); IAEItemStack stock = slot.getStock(); - GuiTextures.SLOT.draw(position.x, position.y, 18, 18); - GuiTextures.SLOT.draw(position.x, position.y + 18, 18, 18); - GuiTextures.CONFIG_ARROW_DARK.draw(position.x, position.y, 18, 18); + drawSlots(pw.isAutoPull(), position.x, position.y); if (this.select) { GuiTextures.SELECT_BOX.draw(position.x, position.y, 18, 18); } @@ -54,28 +54,43 @@ public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRender ItemStack stack = config.createItemStack(); stack.setCount(1); drawItemStack(stack, stackX, stackY, null); - String amountStr = TextFormattingUtil.formatLongToCompactString(config.getStackSize(), 4); - drawStringFixedCorner(amountStr, stackX + 17, stackY + 17, 16777215, true, 0.5f); + + // Only draw the config amount if not stocking, as its meaningless when stocking + if (!pw.isStocking()) { + String amountStr = TextFormattingUtil.formatLongToCompactString(config.getStackSize(), 4); + drawStringFixedCorner(amountStr, stackX + 17, stackY + 17, 16777215, true, 0.5f); + } } if (stock != null) { ItemStack stack = stock.createItemStack(); stack.setCount(1); - drawItemStack(stack, stackX, stackY + 18, null); + drawItemStack(stack, stackX + DISPLAY_X_OFFSET, stackY, null); String amountStr = TextFormattingUtil.formatLongToCompactString(stock.getStackSize(), 4); - drawStringFixedCorner(amountStr, stackX + 17, stackY + 18 + 17, 16777215, true, 0.5f); + drawStringFixedCorner(amountStr, stackX + DISPLAY_X_OFFSET + 17, stackY + 17, 16777215, true, 0.5f); } if (mouseOverConfig(mouseX, mouseY)) { drawSelectionOverlay(stackX, stackY, 16, 16); } else if (mouseOverStock(mouseX, mouseY)) { - drawSelectionOverlay(stackX, stackY + 18, 16, 16); + drawSelectionOverlay(stackX + DISPLAY_X_OFFSET, stackY, 16, 16); } } + private void drawSlots(boolean autoPull, int x, int y) { + if (autoPull) { + GuiTextures.SLOT_DARK.draw(x, y, 18, 18); + GuiTextures.CONFIG_ARROW.draw(x, y, 18, 18); + } else { + GuiTextures.SLOT.draw(x, y, 18, 18); + GuiTextures.CONFIG_ARROW_DARK.draw(x, y, 18, 18); + } + GuiTextures.SLOT_DARK.draw(x + DISPLAY_X_OFFSET, y, 18, 18); + } + @Override public void drawInForeground(int mouseX, int mouseY) { super.drawInForeground(mouseX, mouseY); IAEItemStack item = null; - IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); + IConfigurableSlot slot = this.getParentWidget().getDisplay(this.index); if (mouseOverConfig(mouseX, mouseY)) { item = slot.getConfig(); } else if (mouseOverStock(mouseX, mouseY)) { @@ -86,22 +101,45 @@ public void drawInForeground(int mouseX, int mouseY) { } } + @Override + protected void addHoverText(List hoverText) { + if (getParentWidget().isAutoPull()) { + hoverText.add(I18n.format("gregtech.gui.config_slot")); + hoverText.add(I18n.format("gregtech.gui.config_slot.auto_pull_managed")); + } else { + super.addHoverText(hoverText); + } + } + @Override public boolean mouseClicked(int mouseX, int mouseY, int button) { + AEItemConfigWidget pw = getParentWidget(); + // don't allow manual interaction with config slots when auto pull is enabled + if (pw.isAutoPull()) { + return false; + } + if (mouseOverConfig(mouseX, mouseY)) { if (button == 1) { // Right click to clear - this.parentWidget.disableAmount(); writeClientAction(REMOVE_ID, buf -> {}); + + if (!pw.isStocking()) { + pw.disableAmount(); + } } else if (button == 0) { // Left click to set/select ItemStack item = this.gui.entityPlayer.inventory.getItemStack(); if (!item.isEmpty()) { writeClientAction(UPDATE_ID, buf -> buf.writeItemStack(item)); + return true; + } + + if (!pw.isStocking()) { + pw.enableAmount(this.index); + this.select = true; } - this.parentWidget.enableAmount(this.index); - this.select = true; } return true; } @@ -120,6 +158,7 @@ public void handleClientAction(int id, PacketBuffer buffer) { if (id == UPDATE_ID) { try { ItemStack item = buffer.readItemStack(); + if (!isItemValidForSlot(item)) return; slot.setConfig(WrappedItemStack.fromItemStack(item)); this.parentWidget.enableAmount(this.index); if (!item.isEmpty()) { @@ -157,13 +196,21 @@ public void readUpdateInfo(int id, PacketBuffer buffer) { } } + // Method for server-side validation of an attempted new configured item + private boolean isItemValidForSlot(ItemStack stack) { + if (stack == null || stack.isEmpty()) return true; + AEItemConfigWidget pw = getParentWidget(); + if (!pw.isStocking()) return true; + return !pw.hasStackInConfig(stack); + } + @Override public List> getPhantomTargets(Object ingredient) { if (!(ingredient instanceof ItemStack)) { return Collections.emptyList(); } Rectangle rectangle = toRectangleBox(); - rectangle.height /= 2; + rectangle.width /= 6; return Lists.newArrayList(new IGhostIngredientHandler.Target<>() { @NotNull @@ -183,9 +230,11 @@ public void accept(@NotNull Object ingredient) { @SideOnly(Side.CLIENT) public boolean mouseWheelMove(int mouseX, int mouseY, int wheelDelta) { + // Only allow the amount scrolling if not stocking, as amount is useless for stocking + if (parentWidget.isStocking()) return false; IConfigurableSlot slot = this.parentWidget.getDisplay(this.index); Rectangle rectangle = toRectangleBox(); - rectangle.height /= 2; + rectangle.width /= 6; if (slot.getConfig() == null || wheelDelta == 0 || !rectangle.contains(mouseX, mouseY)) { return false; } diff --git a/src/main/java/gregtech/common/gui/widget/appeng/slot/AmountSetSlot.java b/src/main/java/gregtech/common/gui/widget/appeng/slot/AmountSetSlot.java index ccec8521dd7..35063d5638b 100644 --- a/src/main/java/gregtech/common/gui/widget/appeng/slot/AmountSetSlot.java +++ b/src/main/java/gregtech/common/gui/widget/appeng/slot/AmountSetSlot.java @@ -6,7 +6,7 @@ import gregtech.api.gui.widgets.TextFieldWidget2; import gregtech.api.util.Position; import gregtech.common.gui.widget.appeng.AEConfigWidget; -import gregtech.common.metatileentities.multi.multiblockpart.appeng.IConfigurableSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.IConfigurableSlot; import net.minecraft.network.PacketBuffer; diff --git a/src/main/java/gregtech/common/gui/widget/orefilter/ItemOreFilterTestSlot.java b/src/main/java/gregtech/common/gui/widget/orefilter/ItemOreFilterTestSlot.java deleted file mode 100644 index b30a48cd25d..00000000000 --- a/src/main/java/gregtech/common/gui/widget/orefilter/ItemOreFilterTestSlot.java +++ /dev/null @@ -1,111 +0,0 @@ -package gregtech.common.gui.widget.orefilter; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.ingredient.IGhostIngredientTarget; -import gregtech.api.unification.OreDictUnifier; -import gregtech.api.util.Position; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.RenderHelper; -import net.minecraft.client.renderer.RenderItem; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import com.google.common.collect.Lists; -import mezz.jei.api.gui.IGhostIngredientHandler; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.awt.*; -import java.util.Collections; -import java.util.List; -import java.util.Set; - -public class ItemOreFilterTestSlot extends OreFilterTestSlot implements IGhostIngredientTarget { - - @NotNull - private ItemStack testStack = ItemStack.EMPTY; - - public ItemOreFilterTestSlot(int xPosition, int yPosition) { - super(xPosition, yPosition); - } - - @NotNull - public ItemStack getTestStack() { - return testStack; - } - - public void setTestStack(@NotNull ItemStack testStack) { - this.testStack = testStack; - updatePreview(); - } - - @Nullable - @Override - protected Set getTestCandidates() { - return this.testStack.isEmpty() ? null : OreDictUnifier.getOreDictionaryNames(this.testStack); - } - - @Override - protected void renderSlotContents(float partialTicks, IRenderContext context) { - Position pos = getPosition(); - if (!testStack.isEmpty()) { - GlStateManager.enableDepth(); - RenderHelper.enableGUIStandardItemLighting(); - GlStateManager.pushMatrix(); - RenderItem itemRender = Minecraft.getMinecraft().getRenderItem(); - itemRender.renderItemAndEffectIntoGUI(testStack, pos.x + 1, pos.y + 1); - itemRender.renderItemOverlayIntoGUI(Minecraft.getMinecraft().fontRenderer, testStack, pos.x + 1, pos.y + 1, - null); - GlStateManager.popMatrix(); - RenderHelper.disableStandardItemLighting(); - } - } - - @Override - @SideOnly(Side.CLIENT) - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (isMouseOverElement(mouseX, mouseY)) { - EntityPlayer player = Minecraft.getMinecraft().player; - putItem(player.inventory.getItemStack()); - return true; - } - return false; - } - - private void putItem(ItemStack stack) { - ItemStack testStack = getTestStack(); - if ((stack.isEmpty() ^ testStack.isEmpty()) || !testStack.isItemEqual(stack) || - !ItemStack.areItemStackTagsEqual(testStack, stack)) { - ItemStack copy = stack.copy(); - copy.setCount(1); - setTestStack(copy); - } - } - - @Override - public List> getPhantomTargets(Object ingredient) { - if (!(ingredient instanceof ItemStack)) { - return Collections.emptyList(); - } - Rectangle rectangle = toRectangleBox(); - return Lists.newArrayList(new IGhostIngredientHandler.Target() { - - @NotNull - @Override - public Rectangle getArea() { - return rectangle; - } - - @Override - public void accept(@NotNull Object ingredient) { - if (ingredient instanceof ItemStack) { - putItem((ItemStack) ingredient); - } - } - }); - } -} diff --git a/src/main/java/gregtech/common/gui/widget/orefilter/OreFilterTestSlot.java b/src/main/java/gregtech/common/gui/widget/orefilter/OreFilterTestSlot.java deleted file mode 100644 index fd81e80bcd7..00000000000 --- a/src/main/java/gregtech/common/gui/widget/orefilter/OreFilterTestSlot.java +++ /dev/null @@ -1,202 +0,0 @@ -package gregtech.common.gui.widget.orefilter; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.resources.TextureArea; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.util.LocalizationUtils; -import gregtech.api.util.Position; -import gregtech.api.util.function.BooleanConsumer; -import gregtech.api.util.oreglob.OreGlob; - -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.resources.I18n; -import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import it.unimi.dsi.fastutil.objects.Object2BooleanAVLTreeMap; -import it.unimi.dsi.fastutil.objects.Object2BooleanMap; -import it.unimi.dsi.fastutil.objects.Object2BooleanMaps; -import org.jetbrains.annotations.Nullable; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * @author brachy84 - */ -public abstract class OreFilterTestSlot extends WidgetGroup { - - private final ImageWidget match; - private final ImageWidget noMatch; - - @Nullable - private OreGlob glob; - private boolean expectedResult = true; - - @Nullable - private TextureArea slotIcon = GuiTextures.SLOT; - - @Nullable - private BooleanConsumer onMatchChange; - - private Object2BooleanMap testResult; - private MatchType matchType = MatchType.INVALID; - private boolean matchSuccess; - - private boolean initialized = false; - - private boolean matchAll; - - public OreFilterTestSlot(int xPosition, int yPosition) { - super(xPosition, yPosition, 18, 18); - this.match = new ImageWidget(18 - 5, -3, 9, 6, GuiTextures.ORE_FILTER_MATCH); - this.noMatch = new ImageWidget(18 - 5, -3, 7, 7, GuiTextures.ORE_FILTER_NO_MATCH); - addWidget(this.match); - addWidget(this.noMatch); - } - - @Override - public void initWidget() { - this.initialized = true; - updatePreview(); - super.initWidget(); - } - - public boolean isMatchSuccess() { - return matchSuccess; - } - - public OreFilterTestSlot setSlotIcon(@Nullable TextureArea slotIcon) { - this.slotIcon = slotIcon; - return this; - } - - public OreFilterTestSlot setExpectedResult(boolean expectedResult) { - this.expectedResult = expectedResult; - return this; - } - - public OreFilterTestSlot onMatchChange(@Nullable BooleanConsumer onMatchChange) { - this.onMatchChange = onMatchChange; - return this; - } - - public void setGlob(@Nullable OreGlob glob) { - if (this.glob == glob) return; - this.glob = glob; - updatePreview(); - } - - public void setMatchAll(boolean matchAll) { - if (this.matchAll == matchAll) return; - this.matchAll = matchAll; - updatePreview(); - } - - protected void updatePreview() { - if (!this.initialized) return; - Set oreDicts = getTestCandidates(); - if (oreDicts != null) { - OreGlob glob = this.glob; - if (oreDicts.isEmpty()) { - // no oredict entries - this.testResult = Object2BooleanMaps.singleton("", glob != null && glob.matches("")); - this.matchType = MatchType.NO_ORE_DICT_MATCH; - } else { - this.testResult = new Object2BooleanAVLTreeMap<>(); - for (String oreDict : oreDicts) { - boolean matches = glob != null && glob.matches(oreDict); - this.testResult.put(oreDict, matches); - } - this.matchType = MatchType.ORE_DICT_MATCH; - } - boolean success = this.matchAll; - for (var e : testResult.object2BooleanEntrySet()) { - boolean result = e.getBooleanValue(); - if (result == !this.matchAll) { - success = !this.matchAll; - break; - } - } - updateAndNotifyMatchSuccess(this.expectedResult == success); - this.match.setVisible(this.expectedResult == success); - this.noMatch.setVisible(this.expectedResult != success); - return; - } - this.testResult = Object2BooleanMaps.emptyMap(); - this.matchType = MatchType.INVALID; - updateAndNotifyMatchSuccess(false); - this.match.setVisible(false); - this.noMatch.setVisible(false); - } - - private void updateAndNotifyMatchSuccess(boolean newValue) { - if (this.matchSuccess == newValue) return; - this.matchSuccess = newValue; - if (this.onMatchChange != null) { - this.onMatchChange.apply(newValue); - } - } - - /** - * Get each test candidate for current state of test slot. An empty collection indicates that the match is for items - * without any ore dictionary entry. A {@code null} value indicates that the input state is invalid or empty. - * - * @return each test candidate for current state of test slot - */ - @Nullable - protected abstract Set getTestCandidates(); - - @Override - @SideOnly(Side.CLIENT) - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - Position pos = getPosition(); - if (this.slotIcon != null) { - this.slotIcon.draw(pos.x, pos.y, 18, 18); - } - - renderSlotContents(partialTicks, context); - - if (isActive() && isMouseOverElement(mouseX, mouseY)) { - GlStateManager.disableDepth(); - GlStateManager.colorMask(true, true, true, false); - drawSolidRect(getPosition().x + 1, getPosition().y + 1, 16, 16, 0x80ffffff); - GlStateManager.colorMask(true, true, true, true); - GlStateManager.enableBlend(); - } - - GlStateManager.disableDepth(); - super.drawInBackground(mouseX, mouseY, partialTicks, context); - GlStateManager.enableDepth(); - } - - protected abstract void renderSlotContents(float partialTicks, IRenderContext context); - - @Override - public void drawInForeground(int mouseX, int mouseY) { - if (isActive() && isMouseOverElement(mouseX, mouseY)) { - drawHoveringText(ItemStack.EMPTY, switch (this.matchType) { - case NO_ORE_DICT_MATCH -> Collections.singletonList(I18n.format(this.matchSuccess ? - "cover.ore_dictionary_filter.test_slot.no_oredict.matches" : - "cover.ore_dictionary_filter.test_slot.no_oredict.matches_not")); - case ORE_DICT_MATCH -> this.testResult.object2BooleanEntrySet().stream().map( - e -> I18n.format(e.getBooleanValue() ? - "cover.ore_dictionary_filter.test_slot.matches" : - "cover.ore_dictionary_filter.test_slot.matches_not", e.getKey())) - .collect(Collectors.toList()); - default -> Arrays.asList(LocalizationUtils.formatLines("cover.ore_dictionary_filter.test_slot.info")); - }, 300, mouseX, mouseY); - } - } - - private enum MatchType { - NO_ORE_DICT_MATCH, - ORE_DICT_MATCH, - INVALID - } -} diff --git a/src/main/java/gregtech/common/terminal/app/prospector/ProspectingTexture.java b/src/main/java/gregtech/common/gui/widget/prospector/ProspectingTexture.java similarity index 99% rename from src/main/java/gregtech/common/terminal/app/prospector/ProspectingTexture.java rename to src/main/java/gregtech/common/gui/widget/prospector/ProspectingTexture.java index 4f0070524ec..d0313daf95b 100644 --- a/src/main/java/gregtech/common/terminal/app/prospector/ProspectingTexture.java +++ b/src/main/java/gregtech/common/gui/widget/prospector/ProspectingTexture.java @@ -1,4 +1,4 @@ -package gregtech.common.terminal.app.prospector; +package gregtech.common.gui.widget.prospector; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.stack.MaterialStack; diff --git a/src/main/java/gregtech/common/terminal/app/prospector/ProspectorMode.java b/src/main/java/gregtech/common/gui/widget/prospector/ProspectorMode.java similarity index 93% rename from src/main/java/gregtech/common/terminal/app/prospector/ProspectorMode.java rename to src/main/java/gregtech/common/gui/widget/prospector/ProspectorMode.java index 5de3b24ec9b..0867c6d2a3f 100644 --- a/src/main/java/gregtech/common/terminal/app/prospector/ProspectorMode.java +++ b/src/main/java/gregtech/common/gui/widget/prospector/ProspectorMode.java @@ -1,4 +1,4 @@ -package gregtech.common.terminal.app.prospector; +package gregtech.common.gui.widget.prospector; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/gregtech/common/terminal/app/prospector/widget/WidgetOreList.java b/src/main/java/gregtech/common/gui/widget/prospector/widget/WidgetOreList.java similarity index 91% rename from src/main/java/gregtech/common/terminal/app/prospector/widget/WidgetOreList.java rename to src/main/java/gregtech/common/gui/widget/prospector/widget/WidgetOreList.java index 40435e51b5e..2e774351517 100644 --- a/src/main/java/gregtech/common/terminal/app/prospector/widget/WidgetOreList.java +++ b/src/main/java/gregtech/common/gui/widget/prospector/widget/WidgetOreList.java @@ -1,15 +1,19 @@ -package gregtech.common.terminal.app.prospector.widget; +package gregtech.common.gui.widget.prospector.widget; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.IRenderContext; import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.*; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.terminal.os.TerminalTheme; +import gregtech.api.gui.resources.ColorRectTexture; +import gregtech.api.gui.widgets.ImageWidget; +import gregtech.api.gui.widgets.LabelWidget; +import gregtech.api.gui.widgets.SlotWidget; +import gregtech.api.gui.widgets.TankWidget; +import gregtech.api.gui.widgets.WidgetGroup; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.stack.MaterialStack; import gregtech.api.util.Position; -import gregtech.common.terminal.app.prospector.ProspectorMode; +import gregtech.common.gui.widget.prospector.ProspectorMode; +import gregtech.common.gui.widget.terminal.gui.widgets.DraggableScrollableWidgetGroup; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.item.ItemStack; @@ -23,7 +27,12 @@ import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; -import java.util.*; +import java.awt.*; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.function.Consumer; public class WidgetOreList extends DraggableScrollableWidgetGroup { @@ -39,7 +48,7 @@ public WidgetOreList(int xPosition, int yPosition, int width, int slotSize) { widgetMap = HashBiMap.create(); ores = new HashMap<>(); this.setYScrollBarWidth(5); - this.setYBarStyle(null, TerminalTheme.COLOR_F_1); + this.setYBarStyle(null, new ColorRectTexture(new Color(148, 226, 193))); clear(); } diff --git a/src/main/java/gregtech/common/terminal/app/prospector/widget/WidgetProspectingMap.java b/src/main/java/gregtech/common/gui/widget/prospector/widget/WidgetProspectingMap.java similarity index 96% rename from src/main/java/gregtech/common/terminal/app/prospector/widget/WidgetProspectingMap.java rename to src/main/java/gregtech/common/gui/widget/prospector/widget/WidgetProspectingMap.java index 106b142c66f..f203e1af020 100644 --- a/src/main/java/gregtech/common/terminal/app/prospector/widget/WidgetProspectingMap.java +++ b/src/main/java/gregtech/common/gui/widget/prospector/widget/WidgetProspectingMap.java @@ -1,6 +1,5 @@ -package gregtech.common.terminal.app.prospector.widget; +package gregtech.common.gui.widget.prospector.widget; -import gregtech.api.GTValues; import gregtech.api.gui.IRenderContext; import gregtech.api.gui.Widget; import gregtech.api.unification.OreDictUnifier; @@ -12,8 +11,8 @@ import gregtech.api.worldgen.config.OreDepositDefinition; import gregtech.api.worldgen.config.WorldGenRegistry; import gregtech.api.worldgen.filler.FillerEntry; -import gregtech.common.terminal.app.prospector.ProspectingTexture; -import gregtech.common.terminal.app.prospector.ProspectorMode; +import gregtech.common.gui.widget.prospector.ProspectingTexture; +import gregtech.common.gui.widget.prospector.ProspectorMode; import gregtech.core.network.packets.PacketProspecting; import gregtech.integration.xaero.ColorUtility; @@ -33,7 +32,6 @@ import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -308,8 +306,7 @@ public void drawInForeground(int mouseX, int mouseY) { } } - if (Loader.isModLoaded(GTValues.MODID_JOURNEYMAP) || Loader.isModLoaded(GTValues.MODID_VOXELMAP) || - Loader.isModLoaded(GTValues.MODID_XAERO_MINIMAP)) { + if (Mods.JourneyMap.isModLoaded() || Mods.VoxelMap.isModLoaded() || Mods.XaerosMinimap.isModLoaded()) { tooltips.add(I18n.format("terminal.prospector.waypoint.add")); } this.drawHoveringText(ItemStack.EMPTY, tooltips, 300, mouseX, mouseY); @@ -336,11 +333,11 @@ public boolean mouseClicked(int mouseX, int mouseY, int button) { boolean added = false; trimHoveredNames(); - if (Loader.isModLoaded(GTValues.MODID_JOURNEYMAP)) { + if (Mods.JourneyMap.isModLoaded()) { added = addJourneymapWaypoint(b); - } else if (Loader.isModLoaded(GTValues.MODID_VOXELMAP)) { + } else if (Mods.VoxelMap.isModLoaded()) { added = addVoxelMapWaypoint(b); - } else if (Loader.isModLoaded(GTValues.MODID_XAERO_MINIMAP)) { + } else if (Mods.XaerosMinimap.isModLoaded()) { added = addXaeroMapWaypoint(b); } if (added) { @@ -382,7 +379,7 @@ private String createVeinName() { return s.substring(1, s.length() - 1); } - @Optional.Method(modid = GTValues.MODID_JOURNEYMAP) + @Optional.Method(modid = Mods.Names.JOURNEY_MAP) private boolean addJourneymapWaypoint(BlockPos b) { journeymap.client.model.Waypoint journeyMapWaypoint = new journeymap.client.model.Waypoint(createVeinName(), b, @@ -396,7 +393,7 @@ private boolean addJourneymapWaypoint(BlockPos b) { return false; } - @Optional.Method(modid = GTValues.MODID_VOXELMAP) + @Optional.Method(modid = Mods.Names.VOXEL_MAP) private boolean addVoxelMapWaypoint(@NotNull BlockPos b) { Color c = new Color(color); TreeSet world = new TreeSet<>(); @@ -425,7 +422,7 @@ private boolean addVoxelMapWaypoint(@NotNull BlockPos b) { return false; } - @Optional.Method(modid = GTValues.MODID_XAERO_MINIMAP) + @Optional.Method(modid = Mods.Names.XAEROS_MINIMAP) private boolean addXaeroMapWaypoint(@NotNull BlockPos b) { int red = clampColor(color >> 16 & 0xFF); int green = clampColor(color >> 8 & 0xFF); diff --git a/src/main/java/gregtech/common/terminal/component/SearchComponent.java b/src/main/java/gregtech/common/gui/widget/terminal/SearchComponent.java similarity index 94% rename from src/main/java/gregtech/common/terminal/component/SearchComponent.java rename to src/main/java/gregtech/common/gui/widget/terminal/SearchComponent.java index b0b99d8f154..b06bb1ce2f8 100644 --- a/src/main/java/gregtech/common/terminal/component/SearchComponent.java +++ b/src/main/java/gregtech/common/gui/widget/terminal/SearchComponent.java @@ -1,4 +1,4 @@ -package gregtech.common.terminal.component; +package gregtech.common.gui.widget.terminal; import gregtech.api.gui.IRenderContext; import gregtech.api.gui.resources.ColorRectTexture; @@ -6,9 +6,9 @@ import gregtech.api.gui.resources.TextureArea; import gregtech.api.gui.widgets.TextFieldWidget; import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.terminal.os.menu.IMenuComponent; -import gregtech.api.terminal.util.ISearch; -import gregtech.api.terminal.util.SearchEngine; +import gregtech.common.gui.widget.terminal.menu.IMenuComponent; +import gregtech.common.gui.widget.terminal.util.ISearch; +import gregtech.common.gui.widget.terminal.util.SearchEngine; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; diff --git a/src/main/java/gregtech/api/terminal/gui/IDraggable.java b/src/main/java/gregtech/common/gui/widget/terminal/gui/IDraggable.java similarity index 86% rename from src/main/java/gregtech/api/terminal/gui/IDraggable.java rename to src/main/java/gregtech/common/gui/widget/terminal/gui/IDraggable.java index 33b6cf41719..c93e7491f2c 100644 --- a/src/main/java/gregtech/api/terminal/gui/IDraggable.java +++ b/src/main/java/gregtech/common/gui/widget/terminal/gui/IDraggable.java @@ -1,4 +1,4 @@ -package gregtech.api.terminal.gui; +package gregtech.common.gui.widget.terminal.gui; public interface IDraggable { diff --git a/src/main/java/gregtech/api/terminal/gui/widgets/CircleButtonWidget.java b/src/main/java/gregtech/common/gui/widget/terminal/gui/widgets/CircleButtonWidget.java similarity index 98% rename from src/main/java/gregtech/api/terminal/gui/widgets/CircleButtonWidget.java rename to src/main/java/gregtech/common/gui/widget/terminal/gui/widgets/CircleButtonWidget.java index 98d6b27b5ab..953bf457f1b 100644 --- a/src/main/java/gregtech/api/terminal/gui/widgets/CircleButtonWidget.java +++ b/src/main/java/gregtech/common/gui/widget/terminal/gui/widgets/CircleButtonWidget.java @@ -1,4 +1,4 @@ -package gregtech.api.terminal.gui.widgets; +package gregtech.common.gui.widget.terminal.gui.widgets; import gregtech.api.gui.IRenderContext; import gregtech.api.gui.Widget; diff --git a/src/main/java/gregtech/api/terminal/gui/widgets/DraggableScrollableWidgetGroup.java b/src/main/java/gregtech/common/gui/widget/terminal/gui/widgets/DraggableScrollableWidgetGroup.java similarity index 99% rename from src/main/java/gregtech/api/terminal/gui/widgets/DraggableScrollableWidgetGroup.java rename to src/main/java/gregtech/common/gui/widget/terminal/gui/widgets/DraggableScrollableWidgetGroup.java index 7adb35a9e56..339a7f7cdfa 100644 --- a/src/main/java/gregtech/api/terminal/gui/widgets/DraggableScrollableWidgetGroup.java +++ b/src/main/java/gregtech/common/gui/widget/terminal/gui/widgets/DraggableScrollableWidgetGroup.java @@ -1,14 +1,14 @@ -package gregtech.api.terminal.gui.widgets; +package gregtech.common.gui.widget.terminal.gui.widgets; import gregtech.api.gui.IRenderContext; import gregtech.api.gui.Widget; import gregtech.api.gui.resources.IGuiTexture; import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.terminal.gui.IDraggable; import gregtech.api.util.Position; import gregtech.api.util.Size; import gregtech.client.utils.RenderUtil; import gregtech.common.ConfigHolder; +import gregtech.common.gui.widget.terminal.gui.IDraggable; import net.minecraft.util.math.MathHelper; diff --git a/src/main/java/gregtech/api/terminal/gui/widgets/RectButtonWidget.java b/src/main/java/gregtech/common/gui/widget/terminal/gui/widgets/RectButtonWidget.java similarity index 98% rename from src/main/java/gregtech/api/terminal/gui/widgets/RectButtonWidget.java rename to src/main/java/gregtech/common/gui/widget/terminal/gui/widgets/RectButtonWidget.java index d49b5a3c25d..e4f134ff851 100644 --- a/src/main/java/gregtech/api/terminal/gui/widgets/RectButtonWidget.java +++ b/src/main/java/gregtech/common/gui/widget/terminal/gui/widgets/RectButtonWidget.java @@ -1,4 +1,4 @@ -package gregtech.api.terminal.gui.widgets; +package gregtech.common.gui.widget.terminal.gui.widgets; import gregtech.api.gui.IRenderContext; import gregtech.api.gui.resources.IGuiTexture; diff --git a/src/main/java/gregtech/api/terminal/gui/widgets/SelectorWidget.java b/src/main/java/gregtech/common/gui/widget/terminal/gui/widgets/SelectorWidget.java similarity index 98% rename from src/main/java/gregtech/api/terminal/gui/widgets/SelectorWidget.java rename to src/main/java/gregtech/common/gui/widget/terminal/gui/widgets/SelectorWidget.java index c5f35429f01..20e0bf030b5 100644 --- a/src/main/java/gregtech/api/terminal/gui/widgets/SelectorWidget.java +++ b/src/main/java/gregtech/common/gui/widget/terminal/gui/widgets/SelectorWidget.java @@ -1,4 +1,4 @@ -package gregtech.api.terminal.gui.widgets; +package gregtech.common.gui.widget.terminal.gui.widgets; import gregtech.api.gui.resources.IGuiTexture; import gregtech.api.gui.widgets.SimpleTextWidget; diff --git a/src/main/java/gregtech/api/terminal/os/menu/IMenuComponent.java b/src/main/java/gregtech/common/gui/widget/terminal/menu/IMenuComponent.java similarity index 91% rename from src/main/java/gregtech/api/terminal/os/menu/IMenuComponent.java rename to src/main/java/gregtech/common/gui/widget/terminal/menu/IMenuComponent.java index 519d09b2231..6996f8888d5 100644 --- a/src/main/java/gregtech/api/terminal/os/menu/IMenuComponent.java +++ b/src/main/java/gregtech/common/gui/widget/terminal/menu/IMenuComponent.java @@ -1,4 +1,4 @@ -package gregtech.api.terminal.os.menu; +package gregtech.common.gui.widget.terminal.menu; import gregtech.api.gui.Widget; import gregtech.api.gui.resources.ColorRectTexture; diff --git a/src/main/java/gregtech/api/terminal/util/ISearch.java b/src/main/java/gregtech/common/gui/widget/terminal/util/ISearch.java similarity index 79% rename from src/main/java/gregtech/api/terminal/util/ISearch.java rename to src/main/java/gregtech/common/gui/widget/terminal/util/ISearch.java index 2ae8c26569b..0f256ab62c0 100644 --- a/src/main/java/gregtech/api/terminal/util/ISearch.java +++ b/src/main/java/gregtech/common/gui/widget/terminal/util/ISearch.java @@ -1,4 +1,4 @@ -package gregtech.api.terminal.util; +package gregtech.common.gui.widget.terminal.util; import java.util.function.Consumer; diff --git a/src/main/java/gregtech/api/terminal/util/SearchEngine.java b/src/main/java/gregtech/common/gui/widget/terminal/util/SearchEngine.java similarity index 94% rename from src/main/java/gregtech/api/terminal/util/SearchEngine.java rename to src/main/java/gregtech/common/gui/widget/terminal/util/SearchEngine.java index deaff75d2fd..e810dfaca34 100644 --- a/src/main/java/gregtech/api/terminal/util/SearchEngine.java +++ b/src/main/java/gregtech/common/gui/widget/terminal/util/SearchEngine.java @@ -1,4 +1,4 @@ -package gregtech.api.terminal.util; +package gregtech.common.gui.widget.terminal.util; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/gregtech/common/items/MetaItem1.java b/src/main/java/gregtech/common/items/MetaItem1.java index 9620ccaa60b..cdf8d42deda 100644 --- a/src/main/java/gregtech/common/items/MetaItem1.java +++ b/src/main/java/gregtech/common/items/MetaItem1.java @@ -3,11 +3,14 @@ import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.capability.impl.CommonFluidFilters; -import gregtech.api.items.metaitem.*; +import gregtech.api.items.metaitem.ElectricStats; +import gregtech.api.items.metaitem.FilteredFluidStats; +import gregtech.api.items.metaitem.FoodStats; +import gregtech.api.items.metaitem.MusicDiscStats; +import gregtech.api.items.metaitem.StandardMetaItem; import gregtech.api.items.metaitem.stats.IItemComponent; import gregtech.api.items.metaitem.stats.IItemContainerItemProvider; import gregtech.api.items.metaitem.stats.ItemFluidContainer; -import gregtech.api.terminal.hardware.HardwareProvider; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.MarkerMaterial; import gregtech.api.unification.material.MarkerMaterials; @@ -22,8 +25,35 @@ import gregtech.api.util.RandomPotionEffect; import gregtech.common.ConfigHolder; import gregtech.common.blocks.MetaBlocks; +import gregtech.common.covers.filter.IFilter; +import gregtech.common.covers.filter.OreDictionaryItemFilter; +import gregtech.common.covers.filter.SimpleFluidFilter; +import gregtech.common.covers.filter.SimpleItemFilter; +import gregtech.common.covers.filter.SmartItemFilter; +import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.entities.GTBoatEntity.GTBoatType; -import gregtech.common.items.behaviors.*; +import gregtech.common.items.behaviors.ClipboardBehavior; +import gregtech.common.items.behaviors.ColorSprayBehaviour; +import gregtech.common.items.behaviors.DataItemBehavior; +import gregtech.common.items.behaviors.DoorBehavior; +import gregtech.common.items.behaviors.DynamiteBehaviour; +import gregtech.common.items.behaviors.FacadeItem; +import gregtech.common.items.behaviors.FertilizerBehavior; +import gregtech.common.items.behaviors.FoamSprayerBehavior; +import gregtech.common.items.behaviors.GTBoatBehavior; +import gregtech.common.items.behaviors.IntCircuitBehaviour; +import gregtech.common.items.behaviors.ItemMagnetBehavior; +import gregtech.common.items.behaviors.LighterBehaviour; +import gregtech.common.items.behaviors.MultiblockBuilderBehavior; +import gregtech.common.items.behaviors.NanoSaberBehavior; +import gregtech.common.items.behaviors.ProspectorScannerBehavior; +import gregtech.common.items.behaviors.TooltipBehavior; +import gregtech.common.items.behaviors.TricorderBehavior; +import gregtech.common.items.behaviors.TurbineRotorBehavior; +import gregtech.common.items.behaviors.filter.OreDictFilterUIManager; +import gregtech.common.items.behaviors.filter.SimpleFilterUIManager; +import gregtech.common.items.behaviors.filter.SimpleFluidFilterUIManager; +import gregtech.common.items.behaviors.filter.SmartFilterUIManager; import gregtech.common.items.behaviors.monitorplugin.AdvancedMonitorPluginBehavior; import gregtech.common.items.behaviors.monitorplugin.FakeGuiPluginBehavior; import gregtech.common.items.behaviors.monitorplugin.OnlinePicPluginBehavior; @@ -149,53 +179,53 @@ public void registerSubItems() { // out of registry order so it can reference the Empty Spray Can SPRAY_SOLVENT = addItem(60, "spray.solvent").setMaxStackSize(1) .addComponents(new ColorSprayBehaviour(SPRAY_EMPTY.getStackForm(), 1024, -1)) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); for (int i = 0; i < EnumDyeColor.values().length; i++) { SPRAY_CAN_DYES[i] = addItem(62 + i, "spray.can.dyes." + EnumDyeColor.values()[i].getName()) .setMaxStackSize(1) .addComponents(new ColorSprayBehaviour(SPRAY_EMPTY.getStackForm(), 512, i)) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); } // Fluid Cells: ID 78-88 FLUID_CELL = addItem(78, "fluid_cell") .addComponents(new FilteredFluidStats(1000, 1800, true, false, false, false, false), new ItemFluidContainer()) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_UNIVERSAL = addItem(79, "fluid_cell.universal") .addComponents(new FilteredFluidStats(1000, 1800, true, false, false, false, true), new ItemFluidContainer()) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_LARGE_STEEL = addItem(80, "large_fluid_cell.steel") .addComponents(new FilteredFluidStats(8000, Materials.Steel.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, false, false, false, true), new ItemFluidContainer()) .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Steel, M * 4))) // ingot * 4 - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_LARGE_ALUMINIUM = addItem(81, "large_fluid_cell.aluminium") .addComponents(new FilteredFluidStats(32000, Materials.Aluminium.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, false, false, false, true), new ItemFluidContainer()) .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Aluminium, M * 4))) // ingot * 4 - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_LARGE_STAINLESS_STEEL = addItem(82, "large_fluid_cell.stainless_steel") .addComponents(new FilteredFluidStats(64000, Materials.StainlessSteel.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, true, true, false, true), new ItemFluidContainer()) .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.StainlessSteel, M * 6))) // ingot * 6 - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_LARGE_TITANIUM = addItem(83, "large_fluid_cell.titanium") .addComponents(new FilteredFluidStats(128000, Materials.Titanium.getProperty(PropertyKey.FLUID_PIPE).getMaxFluidTemperature(), true, true, false, false, true), new ItemFluidContainer()) .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Titanium, M * 6))) // ingot * 6 - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_LARGE_TUNGSTEN_STEEL = addItem(84, "large_fluid_cell.tungstensteel") .addComponents(new FilteredFluidStats(512000, @@ -203,36 +233,36 @@ public void registerSubItems() { true, false, false, true), new ItemFluidContainer()) .setMaxStackSize(32) .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.TungstenSteel, M * 8))) // ingot * 8 - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); FLUID_CELL_GLASS_VIAL = addItem(85, "fluid_cell.glass_vial") .addComponents(new FilteredFluidStats(1000, 1200, false, true, false, false, true), new ItemFluidContainer()) .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Glass, M / 4))) // small dust - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); // Limited-Use Items: ID 89-95 TOOL_MATCHES = addItem(89, "tool.matches") .addComponents(new LighterBehaviour(false, false, false)) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); TOOL_MATCHBOX = addItem(90, "tool.matchbox") .addComponents(new LighterBehaviour(false, true, false, Items.PAPER, 16)) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); TOOL_LIGHTER_INVAR = addItem(91, "tool.lighter.invar") .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Invar, M * 2))) .addComponents(new LighterBehaviour(GTUtility.gregtechId("lighter_open"), true, true, true)) .addComponents(new FilteredFluidStats(100, true, CommonFluidFilters.LIGHTER_FUEL)) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); TOOL_LIGHTER_PLATINUM = addItem(92, "tool.lighter.platinum") .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Platinum, M * 2))) .addComponents(new LighterBehaviour(GTUtility.gregtechId("lighter_open"), true, true, true)) .addComponents(new FilteredFluidStats(1000, true, CommonFluidFilters.LIGHTER_FUEL)) .setMaxStackSize(1) .setRarity(EnumRarity.UNCOMMON) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BOTTLE_PURPLE_DRINK = addItem(93, "bottle.purple.drink").addComponents(new FoodStats(8, 0.2F, true, true, new ItemStack(Items.GLASS_BOTTLE), new RandomPotionEffect(MobEffects.HASTE, 800, 1, 90))); @@ -247,7 +277,7 @@ public void registerSubItems() { VOLTAGE_COIL_HV = addItem(99, "voltage_coil.hv").setMaterialInfo(new ItemMaterialInfo( new MaterialStack(Materials.BlackSteel, M * 2), new MaterialStack(Materials.SteelMagnetic, M / 2))); VOLTAGE_COIL_EV = addItem(100, "voltage_coil.ev") - .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.TungstenSteel, M * 2), + .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Platinum, M * 2), new MaterialStack(Materials.NeodymiumMagnetic, M / 2))); VOLTAGE_COIL_IV = addItem(101, "voltage_coil.iv").setMaterialInfo(new ItemMaterialInfo( new MaterialStack(Materials.Iridium, M * 2), new MaterialStack(Materials.NeodymiumMagnetic, M / 2))); @@ -556,14 +586,18 @@ public void registerSubItems() { // Filters: ID 290-300 FLUID_FILTER = addItem(290, "fluid_filter") - .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Zinc, M * 2))); + .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Zinc, M * 2))) + .addComponents(new SimpleFluidFilterUIManager(), IFilter.factory(SimpleFluidFilter::new)); ITEM_FILTER = addItem(291, "item_filter") .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Zinc, M * 2), - new MaterialStack(Materials.Steel, M))); + new MaterialStack(Materials.Steel, M))) + .addComponents(new SimpleFilterUIManager(), IFilter.factory(SimpleItemFilter::new)); ORE_DICTIONARY_FILTER = addItem(292, "ore_dictionary_filter") - .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Zinc, M * 2))); + .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Zinc, M * 2))) + .addComponents(new OreDictFilterUIManager(), IFilter.factory(OreDictionaryItemFilter::new)); SMART_FILTER = addItem(293, "smart_item_filter") - .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Zinc, M * 3 / 2))); + .setMaterialInfo(new ItemMaterialInfo(new MaterialStack(Materials.Zinc, M * 3 / 2))) + .addComponents(new SmartFilterUIManager(), IFilter.factory(SmartItemFilter::new)); // Functional Covers: ID 301-330 COVER_MACHINE_CONTROLLER = addItem(301, "cover.controller"); @@ -737,69 +771,68 @@ public void registerSubItems() { // Usable Items: ID 460-490 DYNAMITE = addItem(460, "dynamite") .addComponents(new DynamiteBehaviour()) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); INTEGRATED_CIRCUIT = addItem(461, "circuit.integrated").addComponents(new IntCircuitBehaviour()) .setModelAmount(33); FOAM_SPRAYER = addItem(462, "foam_sprayer").addComponents(new FoamSprayerBehavior()) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); NANO_SABER = addItem(463, "nano_saber").addComponents(ElectricStats.createElectricItem(4_000_000L, GTValues.HV)) .addComponents(new NanoSaberBehavior()) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); NANO_SABER.getMetaItem().addPropertyOverride(NanoSaberBehavior.OVERRIDE_KEY_LOCATION, (stack, worldIn, entityIn) -> NanoSaberBehavior.isItemActive(stack) ? 1.0f : 0.0f); CLIPBOARD = addItem(464, "clipboard") .addComponents(new ClipboardBehavior()) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); TERMINAL = addItem(465, "terminal") - .addComponents(new HardwareProvider(), new TerminalBehaviour()) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); PROSPECTOR_LV = addItem(466, "prospector.lv") .addComponents(ElectricStats.createElectricItem(100_000L, GTValues.LV), new ProspectorScannerBehavior(2, GTValues.LV)) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); PROSPECTOR_HV = addItem(467, "prospector.hv") .addComponents(ElectricStats.createElectricItem(1_600_000L, GTValues.HV), new ProspectorScannerBehavior(3, GTValues.HV)) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); PROSPECTOR_LUV = addItem(468, "prospector.luv") .addComponents(ElectricStats.createElectricItem(1_000_000_000L, GTValues.LuV), new ProspectorScannerBehavior(5, GTValues.LuV)) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); TRICORDER_SCANNER = addItem(469, "tricorder_scanner") .addComponents(ElectricStats.createElectricItem(100_000L, GTValues.MV), new TricorderBehavior(2)) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); DEBUG_SCANNER = addItem(470, "debug_scanner") .addComponents(new TricorderBehavior(3)) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); ITEM_MAGNET_LV = addItem(471, "item_magnet.lv") .addComponents(ElectricStats.createElectricItem(100_000L, GTValues.LV), new ItemMagnetBehavior(8)) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); ITEM_MAGNET_HV = addItem(472, "item_magnet.hv") .addComponents(ElectricStats.createElectricItem(1_600_000L, GTValues.HV), new ItemMagnetBehavior(32)) .setMaxStackSize(1) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); RUBBER_WOOD_BOAT = addItem(473, "rubber_wood_boat") .addComponents(new GTBoatBehavior(GTBoatType.RUBBER_WOOD_BOAT)).setMaxStackSize(1).setBurnValue(400); TREATED_WOOD_BOAT = addItem(474, "treated_wood_boat") .addComponents(new GTBoatBehavior(GTBoatType.TREATED_WOOD_BOAT)).setMaxStackSize(1).setBurnValue(400); RUBBER_WOOD_DOOR = addItem(475, "rubber_wood_door").addComponents(new DoorBehavior(MetaBlocks.RUBBER_WOOD_DOOR)) - .setBurnValue(200).setCreativeTabs(GregTechAPI.TAB_GREGTECH_DECORATIONS); + .setBurnValue(200).setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); TREATED_WOOD_DOOR = addItem(476, "treated_wood_door") .addComponents(new DoorBehavior(MetaBlocks.TREATED_WOOD_DOOR)).setBurnValue(200) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_DECORATIONS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_DECORATIONS); // Misc Crafting Items: ID 491-515 ENERGIUM_DUST = addItem(491, "energium_dust"); @@ -817,7 +850,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); @@ -976,105 +1010,105 @@ public void registerSubItems() { // Batteries: 731-775 BATTERY_ULV_TANTALUM = addItem(731, "battery.re.ulv.tantalum") .addComponents(ElectricStats.createRechargeableBattery(1000, GTValues.ULV)) - .setUnificationData(OrePrefix.battery, Tier.ULV).setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setUnificationData(OrePrefix.battery, Tier.ULV).setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_LV_SODIUM = addItem(732, "battery.re.lv.sodium") .addComponents(ElectricStats.createRechargeableBattery(80000, GTValues.LV)) .setUnificationData(OrePrefix.battery, Tier.LV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_MV_SODIUM = addItem(733, "battery.re.mv.sodium") .addComponents(ElectricStats.createRechargeableBattery(360000, GTValues.MV)) .setUnificationData(OrePrefix.battery, Tier.MV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_HV_SODIUM = addItem(734, "battery.re.hv.sodium") .addComponents(ElectricStats.createRechargeableBattery(1200000, GTValues.HV)) .setUnificationData(OrePrefix.battery, Tier.HV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_LV_LITHIUM = addItem(735, "battery.re.lv.lithium") .addComponents(ElectricStats.createRechargeableBattery(120000, GTValues.LV)) .setUnificationData(OrePrefix.battery, Tier.LV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_MV_LITHIUM = addItem(736, "battery.re.mv.lithium") .addComponents(ElectricStats.createRechargeableBattery(420000, GTValues.MV)) .setUnificationData(OrePrefix.battery, Tier.MV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_HV_LITHIUM = addItem(737, "battery.re.hv.lithium") .addComponents(ElectricStats.createRechargeableBattery(1800000, GTValues.HV)) .setUnificationData(OrePrefix.battery, Tier.HV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_LV_CADMIUM = addItem(738, "battery.re.lv.cadmium") .addComponents(ElectricStats.createRechargeableBattery(100000, GTValues.LV)) .setUnificationData(OrePrefix.battery, Tier.LV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_MV_CADMIUM = addItem(739, "battery.re.mv.cadmium") .addComponents(ElectricStats.createRechargeableBattery(400000, GTValues.MV)) .setUnificationData(OrePrefix.battery, Tier.MV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_HV_CADMIUM = addItem(740, "battery.re.hv.cadmium") .addComponents(ElectricStats.createRechargeableBattery(1600000, GTValues.HV)) .setUnificationData(OrePrefix.battery, Tier.HV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); ENERGIUM_CRYSTAL = addItem(741, "energy_crystal") .addComponents(ElectricStats.createRechargeableBattery(6_400_000L, GTValues.HV)) .setUnificationData(OrePrefix.battery, Tier.HV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); LAPOTRON_CRYSTAL = addItem(742, "lapotron_crystal") .addComponents(ElectricStats.createRechargeableBattery(25_000_000L, GTValues.EV)) .setUnificationData(OrePrefix.battery, Tier.EV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_EV_VANADIUM = addItem(743, "battery.ev.vanadium") .addComponents(ElectricStats.createRechargeableBattery(10_240_000L, GTValues.EV)) .setUnificationData(OrePrefix.battery, Tier.EV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_IV_VANADIUM = addItem(744, "battery.iv.vanadium") .addComponents(ElectricStats.createRechargeableBattery(40_960_000L, GTValues.IV)) .setUnificationData(OrePrefix.battery, Tier.IV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_LUV_VANADIUM = addItem(745, "battery.luv.vanadium") .addComponents(ElectricStats.createRechargeableBattery(163_840_000L, GTValues.LuV)) .setUnificationData(OrePrefix.battery, Tier.LuV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_ZPM_NAQUADRIA = addItem(746, "battery.zpm.naquadria") .addComponents(ElectricStats.createRechargeableBattery(655_360_000L, GTValues.ZPM)) .setUnificationData(OrePrefix.battery, Tier.ZPM).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); BATTERY_UV_NAQUADRIA = addItem(747, "battery.uv.naquadria") .addComponents(ElectricStats.createRechargeableBattery(2_621_440_000L, GTValues.UV)) .setUnificationData(OrePrefix.battery, Tier.UV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); ENERGY_LAPOTRONIC_ORB = addItem(748, "energy.lapotronic_orb") .addComponents(ElectricStats.createRechargeableBattery(250_000_000L, GTValues.IV)) .setUnificationData(OrePrefix.battery, Tier.IV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); ENERGY_LAPOTRONIC_ORB_CLUSTER = addItem(749, "energy.lapotronic_orb_cluster") .addComponents(ElectricStats.createRechargeableBattery(1_000_000_000L, GTValues.LuV)) .setUnificationData(OrePrefix.battery, Tier.LuV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); ENERGY_MODULE = addItem(750, "energy.module") .addComponents( new IItemComponent[] { ElectricStats.createRechargeableBattery(4_000_000_000L, GTValues.ZPM) }) .setUnificationData(OrePrefix.battery, Tier.ZPM).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); ENERGY_CLUSTER = addItem(751, "energy.cluster") .addComponents( new IItemComponent[] { ElectricStats.createRechargeableBattery(20_000_000_000L, GTValues.UV) }) .setUnificationData(OrePrefix.battery, Tier.UV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); ZERO_POINT_MODULE = addItem(752, "zpm") .addComponents(ElectricStats.createBattery(2000000000000L, GTValues.ZPM, true)).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); ULTIMATE_BATTERY = addItem(753, "max.battery") .addComponents(ElectricStats.createRechargeableBattery(Long.MAX_VALUE, GTValues.UHV)) .setUnificationData(OrePrefix.battery, Tier.UHV).setModelAmount(8) - .setCreativeTabs(GregTechAPI.TAB_GREGTECH_TOOLS); + .setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS); POWER_THRUSTER = addItem(776, "power_thruster").setRarity(EnumRarity.UNCOMMON); POWER_THRUSTER_ADVANCED = addItem(777, "power_thruster_advanced").setRarity(EnumRarity.RARE); diff --git a/src/main/java/gregtech/common/items/ToolItems.java b/src/main/java/gregtech/common/items/ToolItems.java index 05e2453846b..5545387ef7c 100644 --- a/src/main/java/gregtech/common/items/ToolItems.java +++ b/src/main/java/gregtech/common/items/ToolItems.java @@ -55,6 +55,9 @@ public final class ToolItems { public static IGTTool BUZZSAW; public static IGTTool SCREWDRIVER_LV; public static IGTTool PLUNGER; + public static IGTTool WIRECUTTER_LV; + public static IGTTool WIRECUTTER_HV; + public static IGTTool WIRECUTTER_IV; private ToolItems() {/**/} @@ -319,6 +322,36 @@ public static void init() { .oreDict(ToolOreDict.toolPlunger) .toolClasses(ToolClasses.PLUNGER) .markerItem(() -> ToolHelper.getAndSetToolData(PLUNGER, Materials.Rubber, 255, 1, 4F, 0F))); + WIRECUTTER_LV = register(ItemGTTool.Builder.of(GTValues.MODID, "wire_cutter_lv") + .toolStats(b -> b.blockBreaking().crafting().damagePerCraftingAction(4) + .efficiencyMultiplier(2.0F) + .attackDamage(-1.0F).attackSpeed(-2.4F) + .brokenStack(ToolHelper.SUPPLY_POWER_UNIT_LV)) + .sound(GTSoundEvents.WIRECUTTER_TOOL, true) + .oreDict(ToolOreDict.toolWireCutter) + .secondaryOreDicts("craftingToolWireCutter") + .toolClasses(ToolClasses.WIRE_CUTTER) + .electric(GTValues.LV)); + WIRECUTTER_HV = register(ItemGTTool.Builder.of(GTValues.MODID, "wire_cutter_hv") + .toolStats(b -> b.blockBreaking().crafting().damagePerCraftingAction(4) + .efficiencyMultiplier(3.0F) + .attackDamage(-1.0F).attackSpeed(-2.4F) + .brokenStack(ToolHelper.SUPPLY_POWER_UNIT_LV)) + .sound(GTSoundEvents.WIRECUTTER_TOOL, true) + .oreDict(ToolOreDict.toolWireCutter) + .secondaryOreDicts("craftingToolWireCutter") + .toolClasses(ToolClasses.WIRE_CUTTER) + .electric(GTValues.HV)); + WIRECUTTER_IV = register(ItemGTTool.Builder.of(GTValues.MODID, "wire_cutter_iv") + .toolStats(b -> b.blockBreaking().crafting().damagePerCraftingAction(4) + .efficiencyMultiplier(4.0F) + .attackDamage(-1.0F).attackSpeed(-2.4F) + .brokenStack(ToolHelper.SUPPLY_POWER_UNIT_LV)) + .sound(GTSoundEvents.WIRECUTTER_TOOL, true) + .oreDict(ToolOreDict.toolWireCutter) + .secondaryOreDicts("craftingToolWireCutter") + .toolClasses(ToolClasses.WIRE_CUTTER) + .electric(GTValues.IV)); } public static IGTTool register(@NotNull ToolBuilder builder) { diff --git a/src/main/java/gregtech/common/items/behaviors/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/ColorSprayBehaviour.java b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java index 6cda26f8ce5..a52777f70d6 100644 --- a/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/ColorSprayBehaviour.java @@ -1,11 +1,11 @@ package gregtech.common.items.behaviors; -import gregtech.api.GTValues; import gregtech.api.items.metaitem.stats.IItemDurabilityManager; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.pipenet.tile.IPipeTile; import gregtech.api.util.GradientUtil; +import gregtech.api.util.Mods; import gregtech.core.sound.GTSoundEvents; import net.minecraft.block.Block; @@ -20,10 +20,13 @@ import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.*; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.SoundCategory; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraftforge.fml.common.Loader; import appeng.api.util.AEColor; import appeng.tile.networking.TileCableBus; @@ -93,7 +96,7 @@ private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos world.setBlockState(pos, newBlockState); return true; } - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { TileEntity te = world.getTileEntity(pos); if (te instanceof TileCableBus) { TileCableBus cable = (TileCableBus) te; @@ -146,7 +149,7 @@ private static boolean tryStripBlockColor(EntityPlayer player, World world, Bloc } // AE2 cable special case - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { if (te instanceof TileCableBus) { TileCableBus cable = (TileCableBus) te; // do not try to strip color if it is already colorless @@ -189,7 +192,9 @@ public void addInformation(ItemStack itemStack, List lines) { lines.add(I18n.format("behaviour.paintspray.solvent.tooltip")); } lines.add(I18n.format("behaviour.paintspray.uses", remainingUses)); - lines.add(I18n.format("behaviour.paintspray.offhand")); + if (color != null) { + lines.add(I18n.format("behaviour.paintspray.offhand")); + } } @Override diff --git a/src/main/java/gregtech/common/items/behaviors/DataItemBehavior.java b/src/main/java/gregtech/common/items/behaviors/DataItemBehavior.java index 7be90f4d9ff..116dca7ee5d 100644 --- a/src/main/java/gregtech/common/items/behaviors/DataItemBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/DataItemBehavior.java @@ -6,11 +6,12 @@ import gregtech.api.recipes.RecipeMaps; import gregtech.api.recipes.machines.IResearchRecipeMap; import gregtech.api.util.AssemblyLineManager; +import gregtech.api.util.ItemStackHashStrategy; import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -41,7 +42,7 @@ public void addInformation(@NotNull ItemStack itemStack, List lines) { .getDataStickEntry(researchId); if (recipes != null && !recipes.isEmpty()) { lines.add(I18n.format("behavior.data_item.assemblyline.title")); - Collection added = new ObjectOpenHashSet<>(); + Collection added = new ObjectOpenCustomHashSet<>(ItemStackHashStrategy.comparingAllButCount()); for (Recipe recipe : recipes) { ItemStack output = recipe.getOutputs().get(0); if (added.add(output)) { diff --git a/src/main/java/gregtech/common/items/behaviors/IntCircuitBehaviour.java b/src/main/java/gregtech/common/items/behaviors/IntCircuitBehaviour.java index 2be3dcbc766..5a7091e838e 100644 --- a/src/main/java/gregtech/common/items/behaviors/IntCircuitBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/IntCircuitBehaviour.java @@ -24,8 +24,8 @@ import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.HandGuiData; import com.cleanroommc.modularui.screen.ModularPanel; -import com.cleanroommc.modularui.value.sync.GuiSyncManager; import com.cleanroommc.modularui.value.sync.InteractionSyncHandler; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widgets.ButtonWidget; import com.cleanroommc.modularui.widgets.layout.Grid; @@ -64,7 +64,7 @@ public ActionResult onItemRightClick(World world, EntityPlayer player } @Override - public ModularPanel buildUI(HandGuiData guiData, GuiSyncManager guiSyncManager) { + public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager) { ItemDrawable circuitPreview = new ItemDrawable(guiData.getUsedItemStack()); for (int i = 0; i <= 32; i++) { int finalI = i; diff --git a/src/main/java/gregtech/common/items/behaviors/ItemMagnetBehavior.java b/src/main/java/gregtech/common/items/behaviors/ItemMagnetBehavior.java index 15a3ebc2599..bd0adea08e7 100644 --- a/src/main/java/gregtech/common/items/behaviors/ItemMagnetBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/ItemMagnetBehavior.java @@ -5,6 +5,8 @@ import gregtech.api.capability.IElectricItem; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.metaitem.stats.IItemBehaviour; +import gregtech.api.util.Mods; +import gregtech.common.ConfigHolder; import gregtech.integration.baubles.BaublesModule; import net.minecraft.client.resources.I18n; @@ -26,7 +28,6 @@ import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.item.ItemTossEvent; import net.minecraftforge.event.entity.player.PlayerPickupXpEvent; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import org.jetbrains.annotations.NotNull; @@ -81,7 +82,7 @@ private static boolean toggleActive(ItemStack stack) { public void onUpdate(ItemStack stack, Entity entity) { // Adapted logic from Draconic Evolution // https://github.com/Draconic-Inc/Draconic-Evolution/blob/1.12.2/src/main/java/com/brandon3055/draconicevolution/items/tools/Magnet.java - if (!entity.isSneaking() && entity.ticksExisted % 10 == 0 && isActive(stack) && + if (!entity.isSneaking() && entity.ticksExisted % ConfigHolder.tools.magnetDelay == 0 && isActive(stack) && entity instanceof EntityPlayer player) { World world = entity.getEntityWorld(); if (!drainEnergy(true, stack, energyDraw)) { @@ -162,7 +163,7 @@ public void onItemToss(@NotNull ItemTossEvent event) { if (event.getPlayer() == null) return; IInventory inventory = event.getPlayer().inventory; - if (Loader.isModLoaded(GTValues.MODID_BAUBLES)) { + if (Mods.Baubles.isModLoaded()) { inventory = BaublesModule.getBaublesWrappedInventory(event.getPlayer()); } diff --git a/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java b/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java index 4e1f14cfa61..66941091218 100644 --- a/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/LighterBehaviour.java @@ -7,6 +7,7 @@ import gregtech.api.unification.material.Materials; import gregtech.api.util.GTUtility; import gregtech.api.util.GradientUtil; +import gregtech.common.blocks.explosive.BlockGTExplosive; import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.block.Block; @@ -24,7 +25,13 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.*; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundCategory; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fluids.FluidStack; @@ -89,34 +96,48 @@ public boolean onLeftClickEntity(ItemStack stack, EntityPlayer player, Entity en } @Override - public EnumActionResult onItemUseFirst(@NotNull EntityPlayer player, @NotNull World world, BlockPos pos, - EnumFacing side, float hitX, float hitY, float hitZ, EnumHand hand) { + public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { ItemStack stack = player.getHeldItem(hand); NBTTagCompound compound = GTUtility.getOrCreateNbtCompound(stack); if (canOpen && player.isSneaking()) { compound.setBoolean(LIGHTER_OPEN, !compound.getBoolean(LIGHTER_OPEN)); stack.setTagCompound(compound); - return EnumActionResult.PASS; } + return ActionResult.newResult(EnumActionResult.PASS, stack); + } + + @Override + public EnumActionResult onItemUseFirst(@NotNull EntityPlayer player, @NotNull World world, BlockPos pos, + EnumFacing side, float hitX, float hitY, float hitZ, EnumHand hand) { + ItemStack stack = player.getHeldItem(hand); + NBTTagCompound compound = GTUtility.getOrCreateNbtCompound(stack); if (!player.canPlayerEdit(pos, side, player.getHeldItem(hand))) return EnumActionResult.FAIL; // If this item does not have opening mechanics, or if it does and is currently open - if ((!canOpen || compound.getBoolean(LIGHTER_OPEN)) && consumeFuel(player, stack)) { + // If the item has opening mechanics, and the player is sneaking, close the item instead + if ((!canOpen || (compound.getBoolean(LIGHTER_OPEN)) && !player.isSneaking()) && consumeFuel(player, stack)) { player.getEntityWorld().playSound(null, player.getPosition(), SoundEvents.ITEM_FLINTANDSTEEL_USE, SoundCategory.PLAYERS, 1.0F, GTValues.RNG.nextFloat() * 0.4F + 0.8F); IBlockState blockState = world.getBlockState(pos); Block block = blockState.getBlock(); - if (block instanceof BlockTNT) { - ((BlockTNT) block).explode(world, pos, blockState.withProperty(BlockTNT.EXPLODE, true), player); + if (block instanceof BlockTNT tnt) { + tnt.explode(world, pos, blockState.withProperty(BlockTNT.EXPLODE, true), player); + world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11); + return EnumActionResult.SUCCESS; + } + if (block instanceof BlockGTExplosive powderbarrel) { + powderbarrel.explode(world, pos, player); world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11); return EnumActionResult.SUCCESS; } BlockPos offset = pos.offset(side); - world.setBlockState(offset, Blocks.FIRE.getDefaultState(), 11); - if (!world.isRemote) { - CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP) player, offset, stack); + if (world.isAirBlock(offset)) { + world.setBlockState(offset, Blocks.FIRE.getDefaultState(), 11); + if (!world.isRemote) { + CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP) player, offset, stack); + } } return EnumActionResult.SUCCESS; } diff --git a/src/main/java/gregtech/common/items/behaviors/ProspectorScannerBehavior.java b/src/main/java/gregtech/common/items/behaviors/ProspectorScannerBehavior.java index ac1e91f3615..eaad7dd7bc2 100644 --- a/src/main/java/gregtech/common/items/behaviors/ProspectorScannerBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/ProspectorScannerBehavior.java @@ -11,10 +11,10 @@ import gregtech.api.items.gui.PlayerInventoryHolder; import gregtech.api.items.metaitem.stats.IItemBehaviour; import gregtech.api.util.GTUtility; -import gregtech.common.terminal.app.prospector.ProspectorMode; -import gregtech.common.terminal.app.prospector.widget.WidgetOreList; -import gregtech.common.terminal.app.prospector.widget.WidgetProspectingMap; -import gregtech.common.terminal.component.SearchComponent; +import gregtech.common.gui.widget.prospector.ProspectorMode; +import gregtech.common.gui.widget.prospector.widget.WidgetOreList; +import gregtech.common.gui.widget.prospector.widget.WidgetProspectingMap; +import gregtech.common.gui.widget.terminal.SearchComponent; import net.minecraft.client.resources.I18n; import net.minecraft.entity.Entity; diff --git a/src/main/java/gregtech/common/items/behaviors/TerminalBehaviour.java b/src/main/java/gregtech/common/items/behaviors/TerminalBehaviour.java deleted file mode 100644 index 6ffc8919a40..00000000000 --- a/src/main/java/gregtech/common/items/behaviors/TerminalBehaviour.java +++ /dev/null @@ -1,144 +0,0 @@ -package gregtech.common.items.behaviors; - -import gregtech.api.capability.GregtechCapabilities; -import gregtech.api.capability.IElectricItem; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.items.gui.ItemUIFactory; -import gregtech.api.items.gui.PlayerInventoryHolder; -import gregtech.api.items.metaitem.stats.IItemBehaviour; -import gregtech.api.items.metaitem.stats.ISubItemHandler; -import gregtech.api.terminal.TerminalRegistry; -import gregtech.api.terminal.hardware.Hardware; -import gregtech.api.terminal.hardware.HardwareProvider; -import gregtech.api.terminal.os.TerminalOSWidget; -import gregtech.common.terminal.hardware.BatteryHardware; - -import net.minecraft.client.resources.I18n; -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTUtil; -import net.minecraft.util.*; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; - -import java.util.List; - -public class TerminalBehaviour implements IItemBehaviour, ItemUIFactory, ISubItemHandler { - - @Override - public EnumActionResult onItemUseFirst(EntityPlayer player, World world, BlockPos pos, EnumFacing side, float hitX, - float hitY, float hitZ, EnumHand hand) { - if (player.isSneaking()) { - ItemStack itemStack = player.getHeldItem(hand); - itemStack.getOrCreateSubCompound("terminal").removeTag("_click"); - if (pos != null) { - itemStack.getOrCreateSubCompound("terminal").setTag("_click", NBTUtil.createPosTag(pos)); - if (!world.isRemote) { - PlayerInventoryHolder holder = new PlayerInventoryHolder(player, hand); - holder.openUI(); - } - return EnumActionResult.SUCCESS; - } - } - return EnumActionResult.PASS; - } - - @Override - public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { - ItemStack itemStack = player.getHeldItem(hand); - itemStack.getOrCreateSubCompound("terminal").removeTag("_click"); - if (!world.isRemote) { - PlayerInventoryHolder holder = new PlayerInventoryHolder(player, hand); - holder.openUI(); - } - return ActionResult.newResult(EnumActionResult.SUCCESS, itemStack); - } - - @Override - public void onUpdate(ItemStack itemStack, Entity entity) { - NBTTagCompound tabletNBT = itemStack.getOrCreateSubCompound("terminal"); - if (entity.ticksExisted % 20 == 0 && tabletNBT.hasKey("_ar")) { - if (entity instanceof EntityLivingBase) { - EntityLivingBase livingBase = (EntityLivingBase) entity; - if (!livingBase.getHeldItemMainhand().isItemEqual(itemStack) && - !livingBase.getHeldItemOffhand().isItemEqual(itemStack)) { - return; - } - } - - String appName = tabletNBT.getString("_ar"); - int tier = TerminalRegistry.getApplication(appName).getMaxTier(); - if (!TerminalBehaviour.isCreative(itemStack)) { - tier = Math.min(tabletNBT.getCompoundTag(appName).getInteger("_tier"), tier); - } - long cost = 0; - for (Hardware hardware : TerminalRegistry.getAppHardwareDemand(appName, tier)) { - if (hardware instanceof BatteryHardware) { - cost = ((BatteryHardware) hardware).getCharge(); - break; - } - } - if (cost > 0) { - IElectricItem electricItem = itemStack.getCapability(GregtechCapabilities.CAPABILITY_ELECTRIC_ITEM, - null); - if (electricItem != null) { - long back = electricItem.discharge(cost, 999, true, false, false); - if (back != cost) { - tabletNBT.removeTag("_ar"); - } - } else { - tabletNBT.removeTag("_ar"); - } - } - } - } - - @Override - public void addInformation(ItemStack itemStack, List lines) { - HardwareProvider provider = itemStack.getCapability(GregtechCapabilities.CAPABILITY_HARDWARE_PROVIDER, null); - if (isCreative(itemStack)) { - lines.add(I18n.format("metaitem.terminal.tooltip.creative")); - } - if (provider != null) { - List hardware = provider.getHardware(); - lines.add(I18n.format("metaitem.terminal.tooltip.hardware", hardware.size())); - for (Hardware hw : hardware) { - String info = hw.addInformation(); - if (info == null) { - lines.add(hw.getLocalizedName()); - } else { - lines.add(String.format("%s (%s)", hw.getLocalizedName(), info)); - } - } - } - } - - @Override - public ModularUI createUI(PlayerInventoryHolder holder, EntityPlayer entityPlayer) { - return ModularUI.builder(IGuiTexture.EMPTY, 380, 256) - .widget(new TerminalOSWidget(12, 11, holder.getCurrentItem())) - .shouldColor(false) - .build(holder, entityPlayer); - } - - public static boolean isCreative(ItemStack itemStack) { - return itemStack != null && itemStack.getOrCreateSubCompound("terminal").getBoolean("_creative"); - } - - @Override - public String getItemSubType(ItemStack itemStack) { - return ""; - } - - @Override - public void getSubItems(ItemStack itemStack, CreativeTabs creativeTab, NonNullList subItems) { - ItemStack copy = itemStack.copy(); - copy.getOrCreateSubCompound("terminal").setBoolean("_creative", true); - subItems.add(copy); - } -} diff --git a/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java b/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java index 344b97231d3..1045603125a 100644 --- a/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java @@ -1,8 +1,13 @@ 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.IQuantumController; +import gregtech.api.capability.IQuantumStorage; +import gregtech.api.capability.IWorkable; import gregtech.api.capability.impl.FluidTankList; import gregtech.api.items.metaitem.stats.IItemBehaviour; import gregtech.api.metatileentity.IDataInfoProvider; @@ -46,6 +51,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.UUID; public class TricorderBehavior implements IItemBehaviour { @@ -63,7 +69,9 @@ public EnumActionResult onItemUseFirst(EntityPlayer player, World world, BlockPo List info = getScannerInfo(player, world, pos); if (player.isCreative() || drainEnergy(player.getHeldItem(hand), energyCost, true)) { - drainEnergy(player.getHeldItem(hand), energyCost, false); + if (!player.isCreative()) { + drainEnergy(player.getHeldItem(hand), energyCost, false); + } for (ITextComponent line : info) { player.sendMessage(line); } @@ -136,11 +144,28 @@ public List getScannerInfo(EntityPlayer player, World world, Blo // name of the machine list.add(new TextComponentTranslation("behavior.tricorder.block_name", - new TextComponentTranslation(LocalizationUtils.format(metaTileEntity.getMetaFullName())) + new TextComponentTranslation(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)))); + + UUID owner = metaTileEntity.getOwner(); + if (owner != null) { + EntityPlayer ownerEntity = metaTileEntity.getWorld().getPlayerEntityByUUID(owner); + if (ownerEntity != null) { + list.add(new TextComponentTranslation("behavior.tricorder.mte_owner", + new TextComponentTranslation(ownerEntity.getName()) + .setStyle(new Style().setColor(TextFormatting.AQUA)))); + } else { + list.add(new TextComponentTranslation("behavior.tricorder.mte_owner_offline") + .setStyle(new Style().setColor(TextFormatting.YELLOW))); + } + } else { + list.add(new TextComponentTranslation("behavior.tricorder.mte_owner_null") + .setStyle(new Style().setColor(TextFormatting.RED))); + } list.add(new TextComponentTranslation("behavior.tricorder.divider")); @@ -261,6 +286,30 @@ else if (metaTileEntity instanceof IDataInfoProvider) list.addAll(provider.getDataInfo()); } + // quantum storage + if (metaTileEntity instanceof IQuantumController quantumController) { + list.add(new TextComponentTranslation("behavior.tricorder.divider")); + long eut = quantumController.getEnergyUsage(); // eu per 10 ticks + int tier = GTUtility.getTierByVoltage(eut / 10); + list.add(new TextComponentTranslation("behavior.tricorder.quantum_controller.usage", + TextFormatting.RED + String.format("%.1f", eut / 10d) + TextFormatting.RESET, + GTValues.VNF[tier])); + var handler = quantumController.getHandler(); + list.add(new TextComponentTranslation("behavior.tricorder.quantum_controller.connected_items", + TextFormatting.RED.toString() + handler.getItemHandlers().getSlots())); + list.add(new TextComponentTranslation("behavior.tricorder.quantum_controller.connected_fluids", + TextFormatting.RED.toString() + handler.getFluidTanks().getTanks())); + } else if (metaTileEntity instanceof IQuantumStoragestorage) { + var qcontrollor = storage.getQuantumController(); + if (qcontrollor != null) { + long eut = qcontrollor.getTypeEnergy(storage); + + list.add(new TextComponentTranslation("behavior.tricorder.divider")); + list.add(new TextComponentTranslation("behavior.tricorder.quantum_storage.usage", + TextFormatting.RED + String.format("%.1f", eut / 10d))); + } + } + } else if (tileEntity instanceof IPipeTile) { // pipes need special name handling IPipeTile pipeTile = (IPipeTile) tileEntity; diff --git a/src/main/java/gregtech/common/items/behaviors/filter/BaseFilterUIManager.java b/src/main/java/gregtech/common/items/behaviors/filter/BaseFilterUIManager.java new file mode 100644 index 00000000000..cbddb18d305 --- /dev/null +++ b/src/main/java/gregtech/common/items/behaviors/filter/BaseFilterUIManager.java @@ -0,0 +1,55 @@ +package gregtech.common.items.behaviors.filter; + +import gregtech.api.cover.CoverWithUI; +import gregtech.api.items.gui.ItemUIFactory; +import gregtech.api.items.metaitem.stats.IItemBehaviour; +import gregtech.api.mui.GTGuiTheme; +import gregtech.api.mui.GTGuis; +import gregtech.api.mui.factory.MetaItemGuiFactory; + +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; +import net.minecraft.world.World; + +import com.cleanroommc.modularui.factory.HandGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; + +import java.util.List; + +public abstract class BaseFilterUIManager implements IItemBehaviour, ItemUIFactory { + + @Override + public final ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { + ItemStack heldItem = player.getHeldItem(hand); + if (!world.isRemote && !player.isSneaking()) { + MetaItemGuiFactory.open(player, hand); + } + if (player.isSneaking() && heldItem.hasTagCompound()) { + heldItem.setTagCompound(null); + } + return ActionResult.newResult(EnumActionResult.SUCCESS, heldItem); + } + + @Override + public abstract ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager); + + protected final ModularPanel createBasePanel(ItemStack stack) { + return GTGuis.createPanel(stack, 176, 188) + .child(CoverWithUI.createTitleRow(stack)); + } + + @Override + public GTGuiTheme getUITheme() { + return GTGuiTheme.COVER; + } + + @Override + public void addInformation(ItemStack itemStack, List lines) { + lines.add(I18n.format("behaviour.filter_ui_manager")); + } +} diff --git a/src/main/java/gregtech/common/items/behaviors/filter/OreDictFilterUIManager.java b/src/main/java/gregtech/common/items/behaviors/filter/OreDictFilterUIManager.java new file mode 100644 index 00000000000..f38182f9f5c --- /dev/null +++ b/src/main/java/gregtech/common/items/behaviors/filter/OreDictFilterUIManager.java @@ -0,0 +1,19 @@ +package gregtech.common.items.behaviors.filter; + +import gregtech.common.covers.filter.BaseFilter; + +import com.cleanroommc.modularui.factory.HandGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; + +public class OreDictFilterUIManager extends BaseFilterUIManager { + + @Override + public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager) { + var filter = BaseFilter.getFilterFromStack(guiData.getUsedItemStack()); + return createBasePanel(filter.getContainerStack()).height(160) + .child(filter.createWidgets(guiSyncManager).top(22).margin(7, 0)) + .child(SlotGroupWidget.playerInventory().bottom(7).left(7)); + } +} diff --git a/src/main/java/gregtech/common/items/behaviors/filter/SimpleFilterUIManager.java b/src/main/java/gregtech/common/items/behaviors/filter/SimpleFilterUIManager.java new file mode 100644 index 00000000000..ee8062618a4 --- /dev/null +++ b/src/main/java/gregtech/common/items/behaviors/filter/SimpleFilterUIManager.java @@ -0,0 +1,19 @@ +package gregtech.common.items.behaviors.filter; + +import gregtech.common.covers.filter.BaseFilter; + +import com.cleanroommc.modularui.factory.HandGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; + +public class SimpleFilterUIManager extends BaseFilterUIManager { + + @Override + public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager) { + var filter = BaseFilter.getFilterFromStack(guiData.getUsedItemStack()); + return createBasePanel(filter.getContainerStack()).padding(4).height(166) + .child(filter.createWidgets(guiSyncManager).top(22).left(7)) + .child(SlotGroupWidget.playerInventory().left(7)); + } +} diff --git a/src/main/java/gregtech/common/items/behaviors/filter/SimpleFluidFilterUIManager.java b/src/main/java/gregtech/common/items/behaviors/filter/SimpleFluidFilterUIManager.java new file mode 100644 index 00000000000..64164c932fd --- /dev/null +++ b/src/main/java/gregtech/common/items/behaviors/filter/SimpleFluidFilterUIManager.java @@ -0,0 +1,19 @@ +package gregtech.common.items.behaviors.filter; + +import gregtech.common.covers.filter.BaseFilter; + +import com.cleanroommc.modularui.factory.HandGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; + +public class SimpleFluidFilterUIManager extends BaseFilterUIManager { + + @Override + public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager) { + var filter = BaseFilter.getFilterFromStack(guiData.getUsedItemStack()); + return createBasePanel(filter.getContainerStack()).padding(4).height(166) + .child(filter.createWidgets(guiSyncManager).top(22).left(7)) + .child(SlotGroupWidget.playerInventory().left(7)); + } +} diff --git a/src/main/java/gregtech/common/items/behaviors/filter/SmartFilterUIManager.java b/src/main/java/gregtech/common/items/behaviors/filter/SmartFilterUIManager.java new file mode 100644 index 00000000000..3fc047deae6 --- /dev/null +++ b/src/main/java/gregtech/common/items/behaviors/filter/SmartFilterUIManager.java @@ -0,0 +1,19 @@ +package gregtech.common.items.behaviors.filter; + +import gregtech.common.covers.filter.BaseFilter; + +import com.cleanroommc.modularui.factory.HandGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; + +public class SmartFilterUIManager extends BaseFilterUIManager { + + @Override + public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager) { + var filter = BaseFilter.getFilterFromStack(guiData.getUsedItemStack()); + return createBasePanel(filter.getContainerStack()).height(166) + .child(filter.createWidgets(guiSyncManager).left(7).top(22)) + .child(SlotGroupWidget.playerInventory().bottom(7).left(7)); + } +} diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index c346ac65e23..dbe94985456 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -13,6 +13,7 @@ import gregtech.api.unification.material.Materials; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.client.particle.VanillaParticleEffects; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; @@ -94,6 +95,8 @@ import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEInputHatch; import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEOutputBus; import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEOutputHatch; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEStockingBus; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.MetaTileEntityMEStockingHatch; import gregtech.common.metatileentities.multi.multiblockpart.hpca.MetaTileEntityHPCABridge; import gregtech.common.metatileentities.multi.multiblockpart.hpca.MetaTileEntityHPCAComputation; import gregtech.common.metatileentities.multi.multiblockpart.hpca.MetaTileEntityHPCACooler; @@ -121,6 +124,9 @@ import gregtech.common.metatileentities.storage.MetaTileEntityCreativeTank; import gregtech.common.metatileentities.storage.MetaTileEntityDrum; import gregtech.common.metatileentities.storage.MetaTileEntityQuantumChest; +import gregtech.common.metatileentities.storage.MetaTileEntityQuantumExtender; +import gregtech.common.metatileentities.storage.MetaTileEntityQuantumProxy; +import gregtech.common.metatileentities.storage.MetaTileEntityQuantumStorageController; import gregtech.common.metatileentities.storage.MetaTileEntityQuantumTank; import gregtech.common.metatileentities.storage.MetaTileEntityWorkbench; import gregtech.common.pipelike.fluidpipe.longdistance.MetaTileEntityLDFluidEndpoint; @@ -128,7 +134,8 @@ import gregtech.integration.jei.multiblock.MultiblockInfoCategory; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.common.Loader; + +import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.Map; @@ -139,91 +146,65 @@ public class MetaTileEntities { + // spotless:off + // HULLS public static final MetaTileEntityHull[] HULL = new MetaTileEntityHull[GTValues.V.length]; - public static final MetaTileEntityTransformer[] TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - 1]; // no - // MAX - public static final MetaTileEntityTransformer[] HI_AMP_TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - - 1]; /// no MAX - public static final MetaTileEntityTransformer[] POWER_TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - - 1]; // no MAX + public static final MetaTileEntityTransformer[] TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - 1]; // no MAX + public static final MetaTileEntityTransformer[] HI_AMP_TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - 1]; /// no MAX + public static final MetaTileEntityTransformer[] POWER_TRANSFORMER = new MetaTileEntityTransformer[GTValues.V.length - 1]; // no MAX public static final MetaTileEntityDiode[] DIODES = new MetaTileEntityDiode[GTValues.V.length]; public static final MetaTileEntityBatteryBuffer[][] BATTERY_BUFFER = new MetaTileEntityBatteryBuffer[3][GTValues.V.length]; public static final MetaTileEntityCharger[] CHARGER = new MetaTileEntityCharger[GTValues.V.length]; + // SIMPLE MACHINES SECTION - public static final SimpleMachineMetaTileEntity[] ELECTRIC_FURNACE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] MACERATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ALLOY_SMELTER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ARC_FURNACE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ASSEMBLER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] AUTOCLAVE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] ELECTRIC_FURNACE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] MACERATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ALLOY_SMELTER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ARC_FURNACE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ASSEMBLER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] AUTOCLAVE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] BENDER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] BREWERY = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] CANNER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] CENTRIFUGE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] CHEMICAL_BATH = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] CHEMICAL_REACTOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] COMPRESSOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] CENTRIFUGE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] CHEMICAL_BATH = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] CHEMICAL_REACTOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] COMPRESSOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] CUTTER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] DISTILLERY = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ELECTROLYZER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] ELECTROMAGNETIC_SEPARATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] EXTRACTOR = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] DISTILLERY = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ELECTROLYZER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] ELECTROMAGNETIC_SEPARATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] EXTRACTOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] EXTRUDER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] FERMENTER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] FLUID_HEATER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] FLUID_SOLIDIFIER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] FORGE_HAMMER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] FORMING_PRESS = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] FERMENTER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] FLUID_HEATER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] FLUID_SOLIDIFIER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] FORGE_HAMMER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] FORMING_PRESS = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] LATHE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] MIXER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] ORE_WASHER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] ORE_WASHER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] PACKER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] UNPACKER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] POLARIZER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - public static final SimpleMachineMetaTileEntity[] LASER_ENGRAVER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] POLARIZER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + public static final SimpleMachineMetaTileEntity[] LASER_ENGRAVER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] SIFTER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] THERMAL_CENTRIFUGE = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] THERMAL_CENTRIFUGE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final SimpleMachineMetaTileEntity[] WIREMILL = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] CIRCUIT_ASSEMBLER = new SimpleMachineMetaTileEntity[GTValues.V.length - - 1]; - // TODO Replication system - // public static final SimpleMachineMetaTileEntity[] MASS_FABRICATOR = new - // SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - // public static final SimpleMachineMetaTileEntity[] REPLICATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - // - 1]; + public static final SimpleMachineMetaTileEntity[] CIRCUIT_ASSEMBLER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; + // public static final SimpleMachineMetaTileEntity[] MASS_FABRICATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; // TODO Replication + // public static final SimpleMachineMetaTileEntity[] REPLICATOR = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; // TODO Replication public static final SimpleMachineMetaTileEntity[] SCANNER = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; - public static final SimpleMachineMetaTileEntity[] GAS_COLLECTOR = new MetaTileEntityGasCollector[GTValues.V.length - - 1]; + public static final SimpleMachineMetaTileEntity[] GAS_COLLECTOR = new MetaTileEntityGasCollector[GTValues.V.length - 1]; public static final MetaTileEntityRockBreaker[] ROCK_BREAKER = new MetaTileEntityRockBreaker[GTValues.V.length - 1]; public static final MetaTileEntityMiner[] MINER = new MetaTileEntityMiner[GTValues.V.length - 1]; + // GENERATORS SECTION public static final SimpleGeneratorMetaTileEntity[] COMBUSTION_GENERATOR = new SimpleGeneratorMetaTileEntity[4]; public static final SimpleGeneratorMetaTileEntity[] STEAM_TURBINE = new SimpleGeneratorMetaTileEntity[4]; public static final SimpleGeneratorMetaTileEntity[] GAS_TURBINE = new SimpleGeneratorMetaTileEntity[4]; + // MULTIBLOCK PARTS SECTION public static final MetaTileEntityItemBus[] ITEM_IMPORT_BUS = new MetaTileEntityItemBus[GTValues.UHV + 1]; // ULV-UHV public static final MetaTileEntityItemBus[] ITEM_EXPORT_BUS = new MetaTileEntityItemBus[GTValues.UHV + 1]; @@ -234,41 +215,19 @@ public class MetaTileEntities { public static final MetaTileEntityMultiFluidHatch[] QUADRUPLE_EXPORT_HATCH = new MetaTileEntityMultiFluidHatch[6]; // EV-UHV public static final MetaTileEntityMultiFluidHatch[] NONUPLE_EXPORT_HATCH = new MetaTileEntityMultiFluidHatch[6]; // EV-UHV public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH = new MetaTileEntityEnergyHatch[GTValues.V.length]; - public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_4A = new MetaTileEntityEnergyHatch[6]; // EV, IV, - // LuV, - // ZPM, - // UV, UHV - public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_16A = new MetaTileEntityEnergyHatch[5]; // IV, - // LuV, - // ZPM, - // UV, - // UHV + public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_4A = new MetaTileEntityEnergyHatch[6]; // EV, IV, LuV, ZPM, UV, UHV + public static final MetaTileEntityEnergyHatch[] ENERGY_INPUT_HATCH_16A = new MetaTileEntityEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH = new MetaTileEntityEnergyHatch[GTValues.V.length]; - public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_4A = new MetaTileEntityEnergyHatch[6]; // EV, - // IV, - // LuV, - // ZPM, - // UV, - // UHV - public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_16A = new MetaTileEntityEnergyHatch[5]; // IV, - // LuV, - // ZPM, - // UV, - // UHV - public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_INPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[5]; // IV, - // LuV, - // ZPM, - // UV, - // UHV - public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_OUTPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[5]; // IV, - // LuV, - // ZPM, - // UV, - // UHV - public static final MetaTileEntityRotorHolder[] ROTOR_HOLDER = new MetaTileEntityRotorHolder[6]; // HV, EV, IV, LuV, - // ZPM, UV + public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_4A = new MetaTileEntityEnergyHatch[6]; // EV, IV, LuV, ZPM, UV, UHV + public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH_16A = new MetaTileEntityEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV + public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_INPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV + public static final MetaTileEntitySubstationEnergyHatch[] SUBSTATION_ENERGY_OUTPUT_HATCH = new MetaTileEntitySubstationEnergyHatch[5]; // IV, LuV, ZPM, UV, UHV + public static final MetaTileEntityRotorHolder[] ROTOR_HOLDER = new MetaTileEntityRotorHolder[6]; // HV, EV, IV, LuV, ZPM, UV public static final MetaTileEntityMufflerHatch[] MUFFLER_HATCH = new MetaTileEntityMufflerHatch[GTValues.UV + 1]; // LV-UV public static final MetaTileEntityFusionReactor[] FUSION_REACTOR = new MetaTileEntityFusionReactor[3]; + public static MetaTileEntityQuantumStorageController QUANTUM_STORAGE_CONTROLLER; + public static MetaTileEntityQuantumProxy QUANTUM_STORAGE_PROXY; + public static MetaTileEntityQuantumExtender QUANTUM_STORAGE_EXTENDER; public static final MetaTileEntityQuantumChest[] QUANTUM_CHEST = new MetaTileEntityQuantumChest[10]; public static final MetaTileEntityQuantumTank[] QUANTUM_TANK = new MetaTileEntityQuantumTank[10]; public static final MetaTileEntityBuffer[] BUFFER = new MetaTileEntityBuffer[3]; @@ -305,6 +264,7 @@ public class MetaTileEntities { // Used for addons if they wish to disable certain tiers of machines private static final Map MID_TIER = new HashMap<>(); private static final Map HIGH_TIER = new HashMap<>(); + // STEAM AGE SECTION public static SteamCoalBoiler STEAM_BOILER_COAL_BRONZE; public static SteamCoalBoiler STEAM_BOILER_COAL_STEEL; @@ -338,6 +298,7 @@ public class MetaTileEntities { public static MetaTileEntityMaintenanceHatch CONFIGURABLE_MAINTENANCE_HATCH; public static MetaTileEntityAutoMaintenanceHatch AUTO_MAINTENANCE_HATCH; public static MetaTileEntityCleaningMaintenanceHatch CLEANING_MAINTENANCE_HATCH; + // MULTIBLOCKS SECTION public static MetaTileEntityPrimitiveBlastFurnace PRIMITIVE_BLAST_FURNACE; public static MetaTileEntityCokeOven COKE_OVEN; @@ -398,6 +359,7 @@ public class MetaTileEntities { public static MetaTileEntityCrate STAINLESS_STEEL_CRATE; public static MetaTileEntityCrate TITANIUM_CRATE; public static MetaTileEntityCrate TUNGSTENSTEEL_CRATE; + // MISC MACHINES SECTION public static MetaTileEntityWorkbench WORKBENCH; public static MetaTileEntityCreativeEnergy CREATIVE_ENERGY; @@ -410,12 +372,16 @@ public class MetaTileEntities { public static MetaTileEntity ITEM_EXPORT_BUS_ME; public static MetaTileEntity FLUID_IMPORT_HATCH_ME; public static MetaTileEntity ITEM_IMPORT_BUS_ME; + public static MetaTileEntity STOCKING_BUS_ME; + public static MetaTileEntity STOCKING_HATCH_ME; public static MetaTileEntityLDItemEndpoint LONG_DIST_ITEM_ENDPOINT; public static MetaTileEntityLDFluidEndpoint LONG_DIST_FLUID_ENDPOINT; public static MetaTileEntityAlarm ALARM; public static MetaTileEntityConverter[][] ENERGY_CONVERTER = new MetaTileEntityConverter[4][GTValues.V.length]; + //spotless:on + public static void init() { GTLog.logger.info("Registering MetaTileEntities"); @@ -641,7 +607,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", @@ -725,7 +691,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)); @@ -1017,6 +983,14 @@ public static void init() { PUMP[2] = registerMetaTileEntity(1532, new MetaTileEntityPump(gregtechId("pump.hv"), 3)); PUMP[3] = registerMetaTileEntity(1533, new MetaTileEntityPump(gregtechId("pump.ev"), 4)); + // Quantum Storage Network 1757 - 1759 + QUANTUM_STORAGE_CONTROLLER = registerMetaTileEntity(1757, + new MetaTileEntityQuantumStorageController(gregtechId("quantum_storage_controller"))); + QUANTUM_STORAGE_PROXY = registerMetaTileEntity(1758, + new MetaTileEntityQuantumProxy(gregtechId("quantum_storage_proxy"))); + QUANTUM_STORAGE_EXTENDER = registerMetaTileEntity(1759, + new MetaTileEntityQuantumExtender(gregtechId("quantum_storage_extender"))); + // Super / Quantum Chests, IDs 1560-1574 for (int i = 0; i < 5; i++) { String voltageName = GTValues.VN[i + 1].toLowerCase(); @@ -1168,8 +1142,8 @@ public static void init() { // IDs 1730-1744 are taken by 4A <-> 16A Transformers. They are grouped with other transformers for // organization. - // ME Hatches, IDs 1745-1748 - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + // ME Hatches, IDs 1745-1748, 1752-1756 + if (Mods.AppliedEnergistics2.isModLoaded()) { FLUID_EXPORT_HATCH_ME = registerMetaTileEntity(1745, new MetaTileEntityMEOutputHatch(gregtechId("me_export_fluid_hatch"))); ITEM_EXPORT_BUS_ME = registerMetaTileEntity(1746, @@ -1178,6 +1152,13 @@ public static void init() { new MetaTileEntityMEInputHatch(gregtechId("me_import_fluid_hatch"))); ITEM_IMPORT_BUS_ME = registerMetaTileEntity(1748, new MetaTileEntityMEInputBus(gregtechId("me_import_item_bus"))); + STOCKING_BUS_ME = registerMetaTileEntity(1752, + new MetaTileEntityMEStockingBus(gregtechId("me_stocking_item_bus"))); + STOCKING_HATCH_ME = registerMetaTileEntity(1753, + new MetaTileEntityMEStockingHatch(gregtechId("me_stocking_fluid_hatch"))); + // 1754: Crafting Input Bus + // 1755: Crafting Input Buffer + // 1756: Crafting Input Slave } LONG_DIST_ITEM_ENDPOINT = registerMetaTileEntity(1749, @@ -1188,6 +1169,8 @@ public static void init() { // Alarm, ID 1751 ALARM = registerMetaTileEntity(1751, new MetaTileEntityAlarm(gregtechId("alarm"))); + // IDs 1752-1756 are taken by AE2 parts + // Multi-Fluid Hatches, IDs 1190, 1191, 1205, 1206, 1780-1799 // EV hatches separate because of old names/IDs QUADRUPLE_IMPORT_HATCH[0] = registerMetaTileEntity(1190, @@ -1286,17 +1269,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 && Loader.isModLoaded(GTValues.MODID_JEI)) { - 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/MetaTileEntityClipboard.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntityClipboard.java index 64ea0d7ffcf..a50a2978aae 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntityClipboard.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntityClipboard.java @@ -42,6 +42,8 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import codechicken.lib.raytracer.CuboidRayTraceResult; import codechicken.lib.raytracer.IndexedCuboid6; @@ -188,7 +190,7 @@ public void createFakeGui() { this.guiContainerCache = fakeModularUIContainer; if (getWorld().isRemote) this.guiCache = new FakeModularGui(ui, fakeModularUIContainer); - this.writeCustomData(CREATE_FAKE_UI, buffer -> {}); + this.writeCustomData(CREATE_FAKE_UI); } catch (Exception e) { GTLog.logger.error(e); } @@ -219,7 +221,7 @@ public void setClipboard(ItemStack stack) { } @Override - public void getDrops(NonNullList dropsList, @Nullable EntityPlayer harvester) { + public void getDrops(@NotNull List<@NotNull ItemStack> dropsList, @Nullable EntityPlayer harvester) { dropsList.clear(); dropsList.add(this.getClipboard()); } @@ -258,7 +260,7 @@ private void breakClipboard(@Nullable EntityPlayer player) { BlockPos pos = this.getPos(); // Saving this for later so it doesn't get mangled World world = this.getWorld(); // Same here - NonNullList drops = NonNullList.create(); + List drops = new ArrayList<>(); getDrops(drops, player); Block.spawnAsEntity(getWorld(), pos, drops.get(0)); @@ -330,6 +332,7 @@ public IndexedCuboid6 getPageCuboid() { } @Override + @SideOnly(Side.CLIENT) public Pair getParticleTexture() { return Pair.of(CLIPBOARD_RENDERER.getParticleTexture(), 0xFFFFFF); } diff --git a/src/main/java/gregtech/common/metatileentities/converter/MetaTileEntityConverter.java b/src/main/java/gregtech/common/metatileentities/converter/MetaTileEntityConverter.java index c19166ac6ef..0f4f7defa7b 100644 --- a/src/main/java/gregtech/common/metatileentities/converter/MetaTileEntityConverter.java +++ b/src/main/java/gregtech/common/metatileentities/converter/MetaTileEntityConverter.java @@ -3,7 +3,6 @@ import gregtech.api.GTValues; import gregtech.api.capability.FeCompat; import gregtech.api.capability.GregtechCapabilities; -import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.TieredMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; @@ -26,6 +25,8 @@ import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.energy.CapabilityEnergy; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import codechicken.lib.raytracer.CuboidRayTraceResult; import codechicken.lib.render.CCRenderState; @@ -155,6 +156,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, } @Override + @SideOnly(Side.CLIENT) public Pair getParticleTexture() { return Pair.of(Textures.VOLTAGE_CASINGS[getTier()].getParticleSprite(), getPaintingColorForRendering()); } @@ -164,11 +166,6 @@ protected boolean openGUIOnRightClick() { return false; } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; - } - @Override public T getCapability(Capability capability, EnumFacing side) { if (capability == GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER) { diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityAlarm.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityAlarm.java index cadf9768286..8e0518fb935 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityAlarm.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityAlarm.java @@ -11,9 +11,9 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.TieredMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.terminal.gui.widgets.SelectorWidget; import gregtech.client.renderer.texture.Textures; import gregtech.common.ConfigHolder; +import gregtech.common.gui.widget.terminal.gui.widgets.SelectorWidget; import gregtech.core.sound.GTSoundEvents; import net.minecraft.client.resources.I18n; @@ -76,15 +76,17 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { return ModularUI.builder(GuiTextures.BACKGROUND, 240, 86) .widget(new LabelWidget(10, 5, getMetaFullName())) .widget(new SelectorWidget(10, 20, 220, 20, - getSounds().stream().map((event) -> event.getSoundName().toString()) + getSounds().stream().map(this::getNameOfSound) .collect(Collectors.toList()), - 0x555555, () -> this.selectedSound.getSoundName().toString(), true).setOnChanged((v) -> { - GregTechAPI.soundManager.stopTileSound(getPos()); + 0x555555, () -> getNameOfSound(this.selectedSound), true).setOnChanged((v) -> { + if (this.getWorld().isRemote) + GregTechAPI.soundManager.stopTileSound(getPos()); SoundEvent newSound = SoundEvent.REGISTRY.getObject(new ResourceLocation(v)); if (this.selectedSound != newSound) { this.selectedSound = SoundEvent.REGISTRY.getObject(new ResourceLocation(v)); this.writeCustomData(GregtechDataCodes.UPDATE_SOUND, - (writer) -> writer.writeResourceLocation(this.selectedSound.getSoundName())); + (writer) -> writer + .writeResourceLocation(getResourceLocationOfSound(this.selectedSound))); } })) .widget(new ImageWidget(10, 54, 220, 20, GuiTextures.DISPLAY)) @@ -168,14 +170,14 @@ public void receiveInitialSyncData(PacketBuffer buf) { public void writeInitialSyncData(PacketBuffer buf) { super.writeInitialSyncData(buf); buf.writeBoolean(this.isActive); - buf.writeResourceLocation(this.selectedSound.getSoundName()); + buf.writeResourceLocation(getResourceLocationOfSound(this.selectedSound)); buf.writeInt(this.radius); } @Override public NBTTagCompound writeToNBT(NBTTagCompound data) { data.setBoolean("isActive", this.isActive); - data.setString("selectedSound", this.selectedSound.getSoundName().toString()); + data.setString("selectedSound", getNameOfSound(this.selectedSound)); data.setInteger("radius", this.radius); return super.writeToNBT(data); } @@ -187,4 +189,12 @@ public void readFromNBT(NBTTagCompound data) { this.radius = data.getInteger("radius"); super.readFromNBT(data); } + + public String getNameOfSound(SoundEvent sound) { + return getResourceLocationOfSound(sound).toString(); + } + + public ResourceLocation getResourceLocationOfSound(SoundEvent sound) { + return SoundEvent.REGISTRY.getNameForObject(sound); + } } diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityDiode.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityDiode.java index 61b53052962..2bbf645a517 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityDiode.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityDiode.java @@ -3,7 +3,6 @@ import gregtech.api.GTValues; import gregtech.api.capability.IEnergyContainer; import gregtech.api.capability.impl.EnergyContainerHandler; -import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; @@ -142,11 +141,6 @@ protected boolean openGUIOnRightClick() { return false; } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; - } - @Override public void addInformation(ItemStack stack, @Nullable World player, @NotNull List tooltip, boolean advanced) { diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityFisher.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityFisher.java index 2b8aa936f42..076cc395674 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityFisher.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityFisher.java @@ -18,7 +18,6 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; -import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -99,8 +98,8 @@ public void update() { } if (waterCount == WATER_CHECK_SIZE) { LootTable table = world.getLootTableManager().getLootTableFromLocation(LootTableList.GAMEPLAY_FISHING); - NonNullList itemStacks = NonNullList.create(); - itemStacks.addAll(table.generateLootForPools(world.rand, new LootContext.Builder(world).build())); + List itemStacks = table.generateLootForPools(world.rand, + new LootContext.Builder(world).build()); if (GTTransferUtils.addItemsToItemHandler(exportItems, true, itemStacks)) { GTTransferUtils.addItemsToItemHandler(exportItems, false, itemStacks); energyContainer.removeEnergy(energyAmountPerFish); diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityGasCollector.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityGasCollector.java index 77bdd3b0485..8300d2b5fc9 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityGasCollector.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityGasCollector.java @@ -1,24 +1,17 @@ package gregtech.common.metatileentities.electric; -import gregtech.api.capability.IEnergyContainer; import gregtech.api.capability.impl.RecipeLogicEnergy; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.SimpleMachineMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.RecipeMaps; -import gregtech.api.recipes.recipeproperties.GasCollectorDimensionProperty; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import net.minecraft.util.ResourceLocation; -import it.unimi.dsi.fastutil.ints.IntLists; -import org.jetbrains.annotations.NotNull; - import java.util.function.Function; -import java.util.function.Supplier; public class MetaTileEntityGasCollector extends SimpleMachineMetaTileEntity { @@ -36,28 +29,6 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { @Override protected RecipeLogicEnergy createWorkable(RecipeMap recipeMap) { - return new GasCollectorRecipeLogic(this, recipeMap, () -> energyContainer); - } - - protected boolean checkRecipe(@NotNull Recipe recipe) { - for (int dimension : recipe.getProperty(GasCollectorDimensionProperty.getInstance(), IntLists.EMPTY_LIST)) { - if (dimension == this.getWorld().provider.getDimension()) { - return true; - } - } - return false; - } - - private static class GasCollectorRecipeLogic extends RecipeLogicEnergy { - - public GasCollectorRecipeLogic(MetaTileEntity metaTileEntity, RecipeMap recipeMap, - Supplier energyContainer) { - super(metaTileEntity, recipeMap, energyContainer); - } - - @Override - public boolean checkRecipe(@NotNull Recipe recipe) { - return ((MetaTileEntityGasCollector) metaTileEntity).checkRecipe(recipe) && super.checkRecipe(recipe); - } + return new RecipeLogicEnergy(this, recipeMap, () -> energyContainer); } } diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java index 926f7386174..328c9d08884 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java @@ -3,23 +3,21 @@ import gregtech.api.GTValues; import gregtech.api.capability.IEnergyContainer; import gregtech.api.capability.impl.EnergyContainerHandler; -import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.IPassthroughHatch; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.util.Mods; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.PipelineUtil; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockPart; import net.minecraft.client.resources.I18n; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional; import appeng.api.util.AECableType; @@ -72,11 +70,6 @@ protected boolean openGUIOnRightClick() { return false; } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; - } - @Override public void addInformation(ItemStack stack, @Nullable World player, List tooltip, boolean advanced) { String tierName = GTValues.VNF[getTier()]; @@ -89,21 +82,21 @@ public void addInformation(ItemStack stack, @Nullable World player, List @Override public void update() { super.update(); - if (isFirstTick() && Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (isFirstTick() && Mods.AppliedEnergistics2.isModLoaded()) { if (getProxy() != null) getProxy().onReady(); } } @NotNull @Override - @Optional.Method(modid = GTValues.MODID_APPENG) + @Optional.Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AECableType getCableConnectionType(@NotNull AEPartLocation part) { return AECableType.SMART; } @Nullable @Override - @Optional.Method(modid = GTValues.MODID_APPENG) + @Optional.Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public AENetworkProxy getProxy() { if (gridProxy == null && getHolder() instanceof MetaTileEntityHolder) { gridProxy = new AENetworkProxy((MetaTileEntityHolder) getHolder(), "proxy", getStackForm(), true); diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityItemCollector.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityItemCollector.java index d49fb520bf1..1128819ff6d 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityItemCollector.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityItemCollector.java @@ -144,7 +144,7 @@ protected void moveItemsInEffectRange() { double distanceX = (areaCenterPos.getX() + 0.5) - entityItem.posX; double distanceZ = (areaCenterPos.getZ() + 0.5) - entityItem.posZ; double distance = MathHelper.sqrt(distanceX * distanceX + distanceZ * distanceZ); - if (!itemFilter.testItemStack(entityItem.getItem())) { + if (!itemFilter.test(entityItem.getItem())) { continue; } if (distance >= 0.7) { diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityMagicEnergyAbsorber.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityMagicEnergyAbsorber.java index 80d49f2219e..1f8de9fa85b 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityMagicEnergyAbsorber.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityMagicEnergyAbsorber.java @@ -1,7 +1,6 @@ package gregtech.common.metatileentities.electric; import gregtech.api.GTValues; -import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.TieredMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; @@ -18,7 +17,6 @@ import net.minecraft.entity.boss.dragon.phase.PhaseChargingPlayer; import net.minecraft.entity.boss.dragon.phase.PhaseList; import net.minecraft.entity.item.EntityEnderCrystal; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import net.minecraft.util.DamageSource; @@ -221,11 +219,6 @@ protected boolean openGUIOnRightClick() { return false; } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; - } - @SideOnly(Side.CLIENT) @Override public void randomDisplayTick() { diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityMiner.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityMiner.java index 91fd07df207..78603f145d1 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityMiner.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityMiner.java @@ -278,7 +278,7 @@ public T getCapability(Capability capability, EnumFacing side) { } @Override - public void clearMachineInventory(NonNullList itemBuffer) { + public void clearMachineInventory(@NotNull List<@NotNull ItemStack> itemBuffer) { super.clearMachineInventory(itemBuffer); clearInventory(itemBuffer, chargerInventory); } diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityTransformer.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityTransformer.java index d54d7c46f46..2ea4f9e8ce1 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityTransformer.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityTransformer.java @@ -2,7 +2,6 @@ import gregtech.api.GTValues; import gregtech.api.capability.impl.EnergyContainerHandler; -import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.TieredMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; @@ -250,11 +249,6 @@ protected boolean openGUIOnRightClick() { return false; } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; - } - @Override public void addInformation(ItemStack stack, @Nullable World player, List tooltip, boolean advanced) { String lowerTierName = GTValues.VNF[getTier()]; diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityWorldAccelerator.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityWorldAccelerator.java index 09c851400ce..30928bf7a92 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityWorldAccelerator.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityWorldAccelerator.java @@ -4,7 +4,6 @@ import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IControllable; import gregtech.api.capability.impl.EnergyContainerHandler; -import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.TieredMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; @@ -29,7 +28,6 @@ import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.fml.common.FMLCommonHandler; import codechicken.lib.raytracer.CuboidRayTraceResult; import codechicken.lib.render.CCRenderState; @@ -57,7 +55,6 @@ public class MetaTileEntityWorldAccelerator extends TieredMetaTileEntity impleme private boolean tileMode = false; private boolean isActive = false; private boolean isPaused = false; - private int lastTick; // Variables for Random Tick mode optimization // limit = ((tier - min) / (max - min)) * 2^tier @@ -67,7 +64,6 @@ public class MetaTileEntityWorldAccelerator extends TieredMetaTileEntity impleme public MetaTileEntityWorldAccelerator(ResourceLocation metaTileEntityId, int tier) { super(metaTileEntityId, tier); - this.lastTick = 0; this.speed = (int) Math.pow(2, tier); this.successLimit = SUCCESS_LIMITS[tier - 1]; initializeInventory(); @@ -124,6 +120,11 @@ protected long getTEModeAmperage() { return 6L; } + @Override + public boolean allowTickAcceleration() { + return false; + } + @Override public void update() { super.update(); @@ -131,15 +132,11 @@ public void update() { if (isPaused && isActive) { setActive(false); } else if (!isPaused) { - int currentTick = FMLCommonHandler.instance().getMinecraftServerInstance().getTickCounter(); - if (currentTick != lastTick) { // Prevent other tick accelerators from accelerating us - lastTick = currentTick; - boolean wasSuccessful = isTEMode() ? handleTEMode() : handleRandomTickMode(); - if (!wasSuccessful) { - setActive(false); - } else if (!isActive) { - setActive(true); - } + boolean wasSuccessful = isTEMode() ? handleTEMode() : handleRandomTickMode(); + if (!wasSuccessful) { + setActive(false); + } else if (!isActive) { + setActive(true); } } } @@ -230,11 +227,6 @@ protected boolean openGUIOnRightClick() { return false; } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; - } - @Override public boolean onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, CuboidRayTraceResult hitResult) { diff --git a/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityCokeOvenHatch.java b/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityCokeOvenHatch.java index 4484f5b9840..acb83429697 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityCokeOvenHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityCokeOvenHatch.java @@ -3,7 +3,6 @@ import gregtech.api.capability.impl.FluidHandlerProxy; import gregtech.api.capability.impl.FluidTankList; import gregtech.api.capability.impl.ItemHandlerProxy; -import gregtech.api.gui.ModularUI; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; @@ -96,11 +95,6 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { return new MetaTileEntityCokeOvenHatch(metaTileEntityId); } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; - } - @Override protected boolean openGUIOnRightClick() { return false; diff --git a/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityPrimitiveWaterPump.java b/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityPrimitiveWaterPump.java index 43cee2ccb2f..0017c750d94 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityPrimitiveWaterPump.java +++ b/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityPrimitiveWaterPump.java @@ -1,6 +1,5 @@ package gregtech.common.metatileentities.multi; -import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockPart; @@ -19,7 +18,6 @@ import gregtech.common.metatileentities.MetaTileEntities; import net.minecraft.client.resources.I18n; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraft.world.WorldProvider; @@ -97,11 +95,6 @@ private int getAmount() { return 100; } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; - } - @Override protected boolean openGUIOnRightClick() { return false; diff --git a/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityTankValve.java b/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityTankValve.java index a645fc753e1..13f9c9657f3 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityTankValve.java +++ b/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityTankValve.java @@ -2,7 +2,6 @@ import gregtech.api.capability.impl.FluidHandlerProxy; import gregtech.api.capability.impl.FluidTankList; -import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; @@ -14,7 +13,6 @@ import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockPart; import net.minecraft.client.resources.I18n; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; @@ -108,11 +106,6 @@ public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { initializeDummyInventory(); } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; - } - @Override protected boolean openGUIOnRightClick() { return false; diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityActiveTransformer.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityActiveTransformer.java index 059ec0264a7..d22e681fad3 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityActiveTransformer.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityActiveTransformer.java @@ -15,6 +15,8 @@ import gregtech.api.pattern.FactoryBlockPattern; import gregtech.api.pattern.PatternMatchContext; import gregtech.api.pattern.TraceabilityPredicate; +import gregtech.api.util.TextComponentUtil; +import gregtech.api.util.TextFormattingUtil; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.TooltipHelper; @@ -30,6 +32,7 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fml.relauncher.Side; @@ -50,6 +53,8 @@ public class MetaTileEntityActiveTransformer extends MultiblockWithDisplayBase i private IEnergyContainer powerOutput; private IEnergyContainer powerInput; private boolean isActive = false; + private long averageIOLastSec; + private long netIOLastSec; public MetaTileEntityActiveTransformer(ResourceLocation metaTileEntityId) { super(metaTileEntityId); @@ -64,10 +69,18 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { @Override protected void updateFormedValid() { - if (isWorkingEnabled()) { - long canDrain = powerInput.getEnergyStored(); - long totalDrained = powerOutput.changeEnergy(canDrain); - powerInput.removeEnergy(totalDrained); + if (!getWorld().isRemote) { + if ((getOffsetTimer() % 20) == 0) { + averageIOLastSec = netIOLastSec / 20; + netIOLastSec = 0; + } + + if (isWorkingEnabled()) { + long canDrain = powerInput.getEnergyStored(); + long totalDrained = powerOutput.changeEnergy(canDrain); + powerInput.removeEnergy(totalDrained); + netIOLastSec += totalDrained; + } } } @@ -159,7 +172,39 @@ protected void addDisplayText(List textList) { "gregtech.multiblock.idling", "gregtech.multiblock.idling", "gregtech.machine.active_transformer.routing") - .addWorkingStatusLine(); + .addWorkingStatusLine() + .addCustom(tl -> { + if (isStructureFormed()) { + // Max input line + ITextComponent maxInputFormatted = TextComponentUtil.stringWithColor( + TextFormatting.WHITE, + TextFormattingUtil.formatNumbers( + powerInput.getInputVoltage() * powerInput.getInputAmperage()) + " EU/t"); + tl.add(TextComponentUtil.translationWithColor( + TextFormatting.GREEN, + "gregtech.multiblock.active_transformer.max_in", + maxInputFormatted)); + + // Max output line + ITextComponent maxOutputFormatted = TextComponentUtil.stringWithColor( + TextFormatting.WHITE, + TextFormattingUtil.formatNumbers( + powerOutput.getOutputVoltage() * powerOutput.getOutputAmperage()) + " EU/t"); + tl.add(TextComponentUtil.translationWithColor( + TextFormatting.RED, + "gregtech.multiblock.active_transformer.max_out", + maxOutputFormatted)); + + // Average I/O line + ITextComponent avgInputFormatted = TextComponentUtil.stringWithColor( + TextFormatting.WHITE, + TextFormattingUtil.formatNumbers(averageIOLastSec) + " EU/t"); + tl.add(TextComponentUtil.translationWithColor( + TextFormatting.AQUA, + "gregtech.multiblock.active_transformer.average_io", + avgInputFormatted)); + } + }); } @Override @@ -255,4 +300,8 @@ public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip.add(I18n.format("gregtech.machine.active_transformer.tooltip3") + TooltipHelper.RAINBOW_SLOW + I18n.format("gregtech.machine.active_transformer.tooltip3.5")); } + + public long getAverageIOLastSec() { + return this.averageIOLastSec; + } } 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..69b648b41cb 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityAssemblyLine.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityAssemblyLine.java @@ -14,7 +14,7 @@ import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMaps; import gregtech.api.recipes.ingredients.GTRecipeInput; -import gregtech.api.recipes.recipeproperties.ResearchProperty; +import gregtech.api.recipes.properties.impl.ResearchProperty; import gregtech.api.util.GTUtility; import gregtech.api.util.RelativeDirection; import gregtech.client.particle.GTLaserBeamParticle; @@ -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 b9fd8ebf60c..22c6909ca35 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCleanroom.java @@ -1,17 +1,36 @@ package gregtech.common.metatileentities.multi.electric; import gregtech.api.GTValues; -import gregtech.api.capability.*; +import gregtech.api.GregTechAPI; +import gregtech.api.block.ICleanroomFilter; +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IEnergyContainer; +import gregtech.api.capability.IMufflerHatch; +import gregtech.api.capability.IWorkable; import gregtech.api.capability.impl.CleanroomLogic; import gregtech.api.capability.impl.EnergyContainerList; import gregtech.api.metatileentity.IDataInfoProvider; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.SimpleGeneratorMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.metatileentity.multiblock.*; -import gregtech.api.pattern.*; +import gregtech.api.metatileentity.multiblock.CleanroomType; +import gregtech.api.metatileentity.multiblock.FuelMultiblockController; +import gregtech.api.metatileentity.multiblock.ICleanroomProvider; +import gregtech.api.metatileentity.multiblock.ICleanroomReceiver; +import gregtech.api.metatileentity.multiblock.IMultiblockPart; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockDisplayText; +import gregtech.api.metatileentity.multiblock.MultiblockWithDisplayBase; +import gregtech.api.pattern.BlockPattern; +import gregtech.api.pattern.FactoryBlockPattern; +import gregtech.api.pattern.MultiblockShapeInfo; +import gregtech.api.pattern.PatternMatchContext; +import gregtech.api.pattern.PatternStringError; +import gregtech.api.pattern.TraceabilityPredicate; import gregtech.api.util.BlockInfo; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.api.util.TextComponentUtil; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; @@ -27,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; @@ -44,11 +62,11 @@ 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; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -57,11 +75,17 @@ 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; -import java.util.*; +import java.util.ArrayList; +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; public class MetaTileEntityCleanroom extends MultiblockWithDisplayBase implements ICleanroomProvider, IWorkable, IDataInfoProvider { @@ -83,6 +107,7 @@ public class MetaTileEntityCleanroom extends MultiblockWithDisplayBase private IEnergyContainer energyContainer; + private ICleanroomFilter cleanroomFilter; private final CleanroomLogic cleanroomLogic; private final Collection cleanroomReceivers = new HashSet<>(); @@ -108,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 @@ -368,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; } @@ -383,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) @@ -431,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); @@ -489,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); } @@ -521,7 +547,7 @@ public void addInformation(ItemStack stack, @Nullable World player, List tooltip.add(I18n.format("gregtech.machine.cleanroom.tooltip.7")); tooltip.add(I18n.format("gregtech.machine.cleanroom.tooltip.8")); tooltip.add(I18n.format("gregtech.machine.cleanroom.tooltip.9")); - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { tooltip.add(I18n.format(AEConfig.instance().isFeatureEnabled(AEFeature.CHANNELS) ? "gregtech.machine.cleanroom.tooltip.ae2.channels" : "gregtech.machine.cleanroom.tooltip.ae2.no_channels")); @@ -571,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 @@ -608,7 +635,8 @@ public int getProgressPercent() { @Override public int getEnergyTier() { if (energyContainer == null) return GTValues.LV; - return Math.max(GTValues.LV, GTUtility.getFloorTierByVoltage(energyContainer.getInputVoltage())); + return Math.min(GTValues.MAX, + Math.max(GTValues.LV, GTUtility.getFloorTierByVoltage(energyContainer.getInputVoltage()))); } @Override @@ -617,7 +645,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()) { @@ -643,6 +671,8 @@ public void receiveCustomData(int dataId, PacketBuffer buf) { if (dataId == GregtechDataCodes.UPDATE_STRUCTURE_SIZE) { this.lDist = buf.readInt(); this.rDist = buf.readInt(); + this.bDist = buf.readInt(); + this.fDist = buf.readInt(); this.hDist = buf.readInt(); } else if (dataId == GregtechDataCodes.WORKABLE_ACTIVE) { this.cleanroomLogic.setActive(buf.readBoolean()); @@ -737,10 +767,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/MetaTileEntityCrackingUnit.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCrackingUnit.java index 64c441fac4d..b1bd30b8574 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCrackingUnit.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityCrackingUnit.java @@ -11,7 +11,8 @@ import gregtech.api.pattern.FactoryBlockPattern; import gregtech.api.pattern.PatternMatchContext; import gregtech.api.recipes.RecipeMaps; -import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage; +import gregtech.api.recipes.logic.OCResult; +import gregtech.api.recipes.properties.RecipePropertyStorage; import gregtech.api.util.GTUtility; import gregtech.api.util.TextComponentUtil; import gregtech.client.renderer.ICubeRenderer; @@ -149,16 +150,15 @@ public CrackingUnitWorkableHandler(RecipeMapMultiblockController tileEntity) { } @Override - protected void modifyOverclockPost(int[] resultOverclock, @NotNull IRecipePropertyStorage storage) { - super.modifyOverclockPost(resultOverclock, storage); + protected void modifyOverclockPost(@NotNull OCResult ocResult, @NotNull RecipePropertyStorage storage) { + super.modifyOverclockPost(ocResult, storage); int coilTier = ((MetaTileEntityCrackingUnit) metaTileEntity).getCoilTier(); if (coilTier <= 0) return; - resultOverclock[0] *= 1.0f - coilTier * 0.1; // each coil above cupronickel (coilTier = 0) uses 10% less - // energy - resultOverclock[0] = Math.max(1, resultOverclock[0]); + // each coil above cupronickel (coilTier = 0) uses 10% less energy + ocResult.setEut(Math.max(1, (long) (ocResult.eut() * (1.0 - coilTier * 0.1)))); } } } 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..2c7eea8410a 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java @@ -1,5 +1,9 @@ package gregtech.common.metatileentities.multi.electric; +import gregtech.api.capability.IDistillationTower; +import gregtech.api.capability.IMultipleTankHandler; +import gregtech.api.capability.impl.DistillationTowerLogicHandler; +import gregtech.api.capability.impl.MultiblockRecipeLogic; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockPart; @@ -7,7 +11,10 @@ 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.GTTransferUtils; import gregtech.api.util.GTUtility; import gregtech.api.util.RelativeDirection; import gregtech.api.util.TextComponentUtil; @@ -15,8 +22,6 @@ 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.core.sound.GTSoundEvents; import net.minecraft.block.state.IBlockState; @@ -36,22 +41,46 @@ import static gregtech.api.util.RelativeDirection.*; -public class MetaTileEntityDistillationTower extends RecipeMapMultiblockController { +public class MetaTileEntityDistillationTower extends RecipeMapMultiblockController implements IDistillationTower { + protected DistillationTowerLogicHandler handler; + + @SuppressWarnings("unused") // backwards compatibility public MetaTileEntityDistillationTower(ResourceLocation metaTileEntityId) { + this(metaTileEntityId, false); + } + + public MetaTileEntityDistillationTower(ResourceLocation metaTileEntityId, boolean useAdvHatchLogic) { super(metaTileEntityId, RecipeMaps.DISTILLATION_RECIPES); + if (useAdvHatchLogic) { + this.recipeMapWorkable = new DistillationTowerRecipeLogic(this); + this.handler = new DistillationTowerLogicHandler(this); + } else this.handler = null; } @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { - return new MetaTileEntityDistillationTower(metaTileEntityId); + return new MetaTileEntityDistillationTower(metaTileEntityId, this.handler != null); } + /** + * Used if MultiblockPart Abilities need to be sorted a certain way, like + * Distillation Tower and Assembly Line.
            + *
            + * There will be consequences if this is changed. Make sure to set the logic handler to one with + * a properly overriden {@link DistillationTowerLogicHandler#determineOrderedFluidOutputs()} + */ @Override 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. Make sure to set the logic handler to one with + * a properly overriden {@link DistillationTowerLogicHandler#determineOrderedFluidOutputs()} + */ @Override public boolean allowsExtendedFacing() { return false; @@ -74,7 +103,21 @@ protected void addDisplayText(List textList) { } @Override - protected BlockPattern createStructurePattern() { + protected void formStructure(PatternMatchContext context) { + super.formStructure(context); + if (this.handler == null || this.structurePattern == null) return; + handler.determineLayerCount(this.structurePattern); + handler.determineOrderedFluidOutputs(); + } + + @Override + public void invalidateStructure() { + super.invalidateStructure(); + if (this.handler != null) handler.invalidate(); + } + + @Override + protected @NotNull BlockPattern createStructurePattern() { return FactoryBlockPattern.start(RIGHT, FRONT, UP) .aisle("YSY", "YYY", "YYY") .aisle("XXX", "X#X", "XXX").setRepeatable(1, 11) @@ -85,18 +128,14 @@ 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(); } @Override - protected boolean allowSameFluidFillForOutputs() { + public boolean allowSameFluidFillForOutputs() { return false; } @@ -124,6 +163,36 @@ protected ICubeRenderer getFrontOverlay() { @Override public int getFluidOutputLimit() { - return getOutputFluidInventory().getTanks(); + if (this.handler != null) return this.handler.getLayerCount(); + else return super.getFluidOutputLimit(); + } + + protected class DistillationTowerRecipeLogic extends MultiblockRecipeLogic { + + public DistillationTowerRecipeLogic(MetaTileEntityDistillationTower tileEntity) { + super(tileEntity); + } + + @Override + protected void outputRecipeOutputs() { + GTTransferUtils.addItemsToItemHandler(getOutputInventory(), false, itemOutputs); + handler.applyFluidToOutputs(fluidOutputs, true); + } + + @Override + protected boolean checkOutputSpaceFluids(@NotNull Recipe recipe, @NotNull IMultipleTankHandler exportFluids) { + // We have already trimmed fluid outputs at this time + if (!metaTileEntity.canVoidRecipeFluidOutputs() && + !handler.applyFluidToOutputs(recipe.getAllFluidOutputs(), false)) { + this.isOutputsFull = true; + return false; + } + return true; + } + + @Override + protected IMultipleTankHandler getOutputTank() { + return handler.getFluidTanks(); + } } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityElectricBlastFurnace.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityElectricBlastFurnace.java index 5e2714e2b98..89c277d7c8d 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityElectricBlastFurnace.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityElectricBlastFurnace.java @@ -17,7 +17,7 @@ import gregtech.api.pattern.PatternMatchContext; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMaps; -import gregtech.api.recipes.recipeproperties.TemperatureProperty; +import gregtech.api.recipes.properties.impl.TemperatureProperty; import gregtech.api.util.GTUtility; import gregtech.api.util.TextComponentUtil; import gregtech.api.util.TextFormattingUtil; @@ -52,6 +52,8 @@ import java.util.Comparator; import java.util.List; +import static gregtech.api.util.RelativeDirection.*; + public class MetaTileEntityElectricBlastFurnace extends RecipeMapMultiblockController implements IHeatingCoil { private int blastFurnaceTemperature; @@ -179,7 +181,7 @@ public SoundEvent getBreakdownSound() { @Override public List getMatchingShapes() { ArrayList shapeInfo = new ArrayList<>(); - MultiblockShapeInfo.Builder builder = MultiblockShapeInfo.builder() + MultiblockShapeInfo.Builder builder = MultiblockShapeInfo.builder(RIGHT, DOWN, FRONT) .aisle("EEM", "CCC", "CCC", "XXX") .aisle("FXD", "C#C", "C#C", "XHX") .aisle("ISO", "CCC", "CCC", "XXX") diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFluidDrill.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFluidDrill.java index a1501dd6f65..dca07a39e5f 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFluidDrill.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFluidDrill.java @@ -184,7 +184,7 @@ protected void addDisplayText(List textList) { TextFormatting.BLUE, TextFormattingUtil.formatNumbers( minerLogic.getFluidToProduce() * 20L / FluidDrillLogic.MAX_PROGRESS) + - " L/t"); + " L/s"); tl.add(TextComponentUtil.translationWithColor( TextFormatting.GRAY, "gregtech.multiblock.fluid_rig.fluid_amount", diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java index 90b8b70886c..b9a918639f3 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityFusionReactor.java @@ -29,8 +29,9 @@ import gregtech.api.pattern.PatternMatchContext; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMaps; -import gregtech.api.recipes.recipeproperties.FusionEUToStartProperty; -import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage; +import gregtech.api.recipes.logic.OCParams; +import gregtech.api.recipes.properties.RecipePropertyStorage; +import gregtech.api.recipes.properties.impl.FusionEUToStartProperty; import gregtech.api.util.RelativeDirection; import gregtech.api.util.TextComponentUtil; import gregtech.api.util.TextFormattingUtil; @@ -83,6 +84,10 @@ import java.util.List; import java.util.function.DoubleSupplier; +import static gregtech.api.recipes.logic.OverclockingLogic.PERFECT_HALF_DURATION_FACTOR; +import static gregtech.api.recipes.logic.OverclockingLogic.PERFECT_HALF_VOLTAGE_FACTOR; +import static gregtech.api.util.RelativeDirection.*; + public class MetaTileEntityFusionReactor extends RecipeMapMultiblockController implements IFastRenderMetaTileEntity, IBloomEffect { @@ -158,7 +163,7 @@ protected BlockPattern createStructurePattern() { public List getMatchingShapes() { List shapeInfos = new ArrayList<>(); - MultiblockShapeInfo.Builder baseBuilder = MultiblockShapeInfo.builder() + MultiblockShapeInfo.Builder baseBuilder = MultiblockShapeInfo.builder(RIGHT, DOWN, FRONT) .aisle("###############", "######WGW######", "###############") .aisle("######DCD######", "####GG###GG####", "######UCU######") .aisle("####CC###CC####", "###w##EGE##s###", "####CC###CC####") @@ -577,13 +582,13 @@ public FusionRecipeLogic(MetaTileEntityFusionReactor tileEntity) { } @Override - protected double getOverclockingDurationDivisor() { - return 2.0D; + protected double getOverclockingDurationFactor() { + return PERFECT_HALF_DURATION_FACTOR; } @Override - protected double getOverclockingVoltageMultiplier() { - return 2.0D; + protected double getOverclockingVoltageFactor() { + return PERFECT_HALF_VOLTAGE_FACTOR; } @Override @@ -632,16 +637,16 @@ public boolean checkRecipe(@NotNull Recipe recipe) { } @Override - protected void modifyOverclockPre(int @NotNull [] values, @NotNull IRecipePropertyStorage storage) { - super.modifyOverclockPre(values, storage); + protected void modifyOverclockPre(@NotNull OCParams ocParams, @NotNull RecipePropertyStorage storage) { + super.modifyOverclockPre(ocParams, storage); // Limit the number of OCs to the difference in fusion reactor MK. // I.e., a MK2 reactor can overclock a MK1 recipe once, and a // MK3 reactor can overclock a MK2 recipe once, or a MK1 recipe twice. - long euToStart = storage.getRecipePropertyValue(FusionEUToStartProperty.getInstance(), 0L); + long euToStart = storage.get(FusionEUToStartProperty.getInstance(), 0L); int fusionTier = FusionEUToStartProperty.getFusionTier(euToStart); - if (fusionTier != 0) fusionTier -= MetaTileEntityFusionReactor.this.tier; - values[2] = Math.min(fusionTier, values[2]); + if (fusionTier != 0) fusionTier = MetaTileEntityFusionReactor.this.tier - fusionTier; + ocParams.setOcAmount(Math.min(fusionTier, ocParams.ocAmount())); } @NotNull @@ -691,18 +696,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 +760,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/MetaTileEntityHPCA.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityHPCA.java index 06f8286d8ff..f1bf2dc9593 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityHPCA.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityHPCA.java @@ -64,6 +64,8 @@ import java.util.Set; import java.util.function.Supplier; +import static gregtech.api.util.RelativeDirection.*; + public class MetaTileEntityHPCA extends MultiblockWithDisplayBase implements IOpticalComputationProvider, IControllable, IProgressBarMultiblock { @@ -167,7 +169,7 @@ protected void updateFormedValid() { } private void consumeEnergy() { - int energyToConsume = hpcaHandler.getCurrentEUt(); + long energyToConsume = hpcaHandler.getCurrentEUt(); boolean hasMaintenance = ConfigHolder.machines.enableMaintenance && hasMaintenanceMechanics(); if (hasMaintenance) { // 10% more energy per maintenance problem @@ -229,7 +231,7 @@ private void consumeEnergy() { @Override public List getMatchingShapes() { List shapeInfo = new ArrayList<>(); - MultiblockShapeInfo.Builder builder = MultiblockShapeInfo.builder() + MultiblockShapeInfo.Builder builder = MultiblockShapeInfo.builder(RIGHT, DOWN, FRONT) .aisle("AA", "EC", "MC", "HC", "AA") .aisle("VA", "6V", "3V", "0V", "VA") .aisle("VA", "7V", "4V", "1V", "VA") @@ -377,7 +379,7 @@ protected ModularUI.Builder createUITemplate(EntityPlayer entityPlayer) { protected void addDisplayText(List textList) { MultiblockDisplayText.builder(textList, isStructureFormed()) .setWorkingStatus(true, hpcaHandler.getAllocatedCWUt() > 0) // transform into two-state system for - // display + // display .setWorkingStatusKeys( "gregtech.multiblock.idling", "gregtech.multiblock.idling", @@ -580,7 +582,7 @@ public static class HPCAGridHandler { // cached gui info // holding these values past the computation clear because GUI is too "late" to read the state in time - private int cachedEUt; + private long cachedEUt; private int cachedCWUt; public HPCAGridHandler(@Nullable MetaTileEntityHPCA controller) { @@ -760,10 +762,10 @@ public int getMaxCWUt() { } /** The current EU/t this HPCA should use, considering passive drain, current computation, etc.. */ - public int getCurrentEUt() { + public long getCurrentEUt() { int maximumCWUt = Math.max(1, getMaxCWUt()); // behavior is no different setting this to 1 if it is 0 - int maximumEUt = getMaxEUt(); - int upkeepEUt = getUpkeepEUt(); + long maximumEUt = getMaxEUt(); + long upkeepEUt = getUpkeepEUt(); if (maximumEUt == upkeepEUt) { return maximumEUt; @@ -775,8 +777,8 @@ public int getCurrentEUt() { } /** The amount of EU/t this HPCA uses just to stay on with 0 output computation. */ - public int getUpkeepEUt() { - int upkeepEUt = 0; + public long getUpkeepEUt() { + long upkeepEUt = 0; for (var component : components) { upkeepEUt += component.getUpkeepEUt(); } @@ -784,8 +786,8 @@ public int getUpkeepEUt() { } /** The maximum EU/t that this HPCA could ever use with the given configuration. */ - public int getMaxEUt() { - int maximumEUt = 0; + public long getMaxEUt() { + long maximumEUt = 0; for (var component : components) { maximumEUt += component.getMaxEUt(); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityLargeChemicalReactor.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityLargeChemicalReactor.java index cb12da25e2b..a15161260ee 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityLargeChemicalReactor.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityLargeChemicalReactor.java @@ -37,6 +37,8 @@ import java.util.ArrayList; import java.util.List; +import static gregtech.api.util.RelativeDirection.*; + public class MetaTileEntityLargeChemicalReactor extends RecipeMapMultiblockController { public MetaTileEntityLargeChemicalReactor(ResourceLocation metaTileEntityId) { @@ -69,7 +71,7 @@ protected BlockPattern createStructurePattern() { @Override public List getMatchingShapes() { ArrayList shapeInfo = new ArrayList<>(); - MultiblockShapeInfo.Builder baseBuilder = MultiblockShapeInfo.builder() + MultiblockShapeInfo.Builder baseBuilder = MultiblockShapeInfo.builder(RIGHT, DOWN, FRONT) .where('S', MetaTileEntities.LARGE_CHEMICAL_REACTOR, EnumFacing.SOUTH) .where('X', MetaBlocks.METAL_CASING.getState(BlockMetalCasing.MetalCasingType.PTFE_INERT_CASING)) .where('P', diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityMultiSmelter.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityMultiSmelter.java index f9936dd4b31..71fca7ba8d4 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityMultiSmelter.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityMultiSmelter.java @@ -4,13 +4,20 @@ import gregtech.api.capability.impl.MultiblockRecipeLogic; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.metatileentity.multiblock.*; +import gregtech.api.metatileentity.multiblock.IMultiblockPart; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockDisplayText; +import gregtech.api.metatileentity.multiblock.ParallelLogicType; +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.RecipeBuilder; import gregtech.api.recipes.RecipeMaps; +import gregtech.api.recipes.logic.OCParams; +import gregtech.api.recipes.logic.OCResult; import gregtech.api.recipes.machines.RecipeMapFurnace; +import gregtech.api.recipes.properties.RecipePropertyStorage; import gregtech.api.util.GTUtility; import gregtech.api.util.TextComponentUtil; import gregtech.api.util.TextFormattingUtil; @@ -24,7 +31,8 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundEvent; -import net.minecraft.util.text.*; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextFormatting; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -32,6 +40,8 @@ import java.util.List; +import static gregtech.api.recipes.logic.OverclockingLogic.standardOC; + public class MetaTileEntityMultiSmelter extends RecipeMapMultiblockController { protected int heatingCoilLevel; @@ -196,6 +206,13 @@ public ParallelLogicType getParallelLogicType() { return ParallelLogicType.APPEND_ITEMS; } + @Override + protected void runOverclockingLogic(@NotNull OCParams ocParams, @NotNull OCResult ocResult, + @NotNull RecipePropertyStorage propertyStorage, long maxVoltage) { + standardOC(ocParams, ocResult, maxVoltage, getOverclockingDurationFactor(), + getOverclockingVoltageFactor()); + } + @Override public void applyParallelBonus(@NotNull RecipeBuilder builder) { builder.EUt(getEUtForParallel(builder.getParallel(), heatingCoilDiscount)) diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java index c6ee87449d2..7814f3dccc9 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPowerSubstation.java @@ -81,8 +81,10 @@ public class MetaTileEntityPowerSubstation extends MultiblockWithDisplayBase private boolean isActive, isWorkingEnabled = true; // Stats tracked for UI display - private long netIOLastSec; - private long averageIOLastSec; + private long netInLastSec; + private long averageInLastSec; + private long netOutLastSec; + private long averageOutLastSec; public MetaTileEntityPowerSubstation(ResourceLocation metaTileEntityId) { super(metaTileEntityId); @@ -138,8 +140,10 @@ public void invalidateStructure() { inputHatches = null; outputHatches = null; passiveDrain = 0; - netIOLastSec = 0; - averageIOLastSec = 0; + netInLastSec = 0; + averageInLastSec = 0; + netOutLastSec = 0; + averageOutLastSec = 0; super.invalidateStructure(); } @@ -149,25 +153,27 @@ protected void updateFormedValid() { if (getOffsetTimer() % 20 == 0) { // active here is just used for rendering setActive(energyBank.hasEnergy()); - averageIOLastSec = netIOLastSec / 20; - netIOLastSec = 0; + averageInLastSec = netInLastSec / 20; + averageOutLastSec = netOutLastSec / 20; + netInLastSec = 0; + netOutLastSec = 0; } if (isWorkingEnabled()) { // Bank from Energy Input Hatches long energyBanked = energyBank.fill(inputHatches.getEnergyStored()); inputHatches.changeEnergy(-energyBanked); - netIOLastSec += energyBanked; + netInLastSec += energyBanked; // Passive drain long energyPassiveDrained = energyBank.drain(getPassiveDrain()); - netIOLastSec -= energyPassiveDrained; + netOutLastSec += energyPassiveDrained; // Debank to Dynamo Hatches long energyDebanked = energyBank .drain(outputHatches.getEnergyCapacity() - outputHatches.getEnergyStored()); outputHatches.changeEnergy(energyDebanked); - netIOLastSec -= energyDebanked; + netOutLastSec += energyDebanked; } } } @@ -359,44 +365,45 @@ protected void addDisplayText(List textList) { "gregtech.multiblock.power_substation.passive_drain", passiveDrain)); - // Average I/O line - TextFormatting averageIOColor = TextFormatting.GRAY; - if (isActive() && isWorkingEnabled() && averageIOLastSec == 0) { - // only set to yellow on zero if the machine is on, avoids a yellow "warning" - // color when the machine is first formed and not yet plugged in. - averageIOColor = TextFormatting.YELLOW; - } else if (averageIOLastSec > 0) { - averageIOColor = TextFormatting.GREEN; - } else if (averageIOLastSec < 0) { - averageIOColor = TextFormatting.RED; - } - - ITextComponent averageIO = TextComponentUtil.stringWithColor( - averageIOColor, - TextFormattingUtil.formatNumbers(averageIOLastSec) + " EU/t"); - + // Average EU IN line + ITextComponent avgValue = TextComponentUtil.stringWithColor( + TextFormatting.GREEN, + TextFormattingUtil.formatNumbers(averageInLastSec) + " EU/t"); ITextComponent base = TextComponentUtil.translationWithColor( TextFormatting.GRAY, - "gregtech.multiblock.power_substation.average_io", - averageIO); - + "gregtech.multiblock.power_substation.average_in", + avgValue); ITextComponent hover = TextComponentUtil.translationWithColor( TextFormatting.GRAY, - "gregtech.multiblock.power_substation.average_io_hover"); + "gregtech.multiblock.power_substation.average_in_hover"); + tl.add(TextComponentUtil.setHover(base, hover)); + + // Average EU OUT line + avgValue = TextComponentUtil.stringWithColor( + TextFormatting.RED, + TextFormattingUtil.formatNumbers(averageOutLastSec) + " EU/t"); + base = TextComponentUtil.translationWithColor( + TextFormatting.GRAY, + "gregtech.multiblock.power_substation.average_out", + avgValue); + hover = TextComponentUtil.translationWithColor( + TextFormatting.GRAY, + "gregtech.multiblock.power_substation.average_out_hover"); tl.add(TextComponentUtil.setHover(base, hover)); // Time to fill/drain line - if (averageIOLastSec > 0) { + if (averageInLastSec > averageOutLastSec) { ITextComponent timeToFill = getTimeToFillDrainText(energyCapacity.subtract(energyStored) - .divide(BigInteger.valueOf(averageIOLastSec * 20))); + .divide(BigInteger.valueOf((averageInLastSec - averageOutLastSec) * 20))); TextComponentUtil.setColor(timeToFill, TextFormatting.GREEN); tl.add(TextComponentUtil.translationWithColor( TextFormatting.GRAY, "gregtech.multiblock.power_substation.time_to_fill", timeToFill)); - } else if (averageIOLastSec < 0) { + } else if (averageInLastSec < averageOutLastSec) { ITextComponent timeToDrain = getTimeToFillDrainText( - energyStored.divide(BigInteger.valueOf(Math.abs(averageIOLastSec) * 20))); + energyStored.divide(BigInteger.valueOf( + (averageOutLastSec - averageInLastSec) * 20))); TextComponentUtil.setColor(timeToDrain, TextFormatting.RED); tl.add(TextComponentUtil.translationWithColor( TextFormatting.GRAY, @@ -412,9 +419,9 @@ protected void addDisplayText(List textList) { protected void addWarningText(List textList) { super.addWarningText(textList); if (isStructureFormed()) { - if (averageIOLastSec < 0) { // decreasing + if (averageInLastSec < averageOutLastSec) { // decreasing BigInteger timeToDrainSeconds = energyBank.getStored() - .divide(BigInteger.valueOf(Math.abs(averageIOLastSec) * 20)); + .divide(BigInteger.valueOf((averageOutLastSec - averageInLastSec) * 20)); if (timeToDrainSeconds.compareTo(BigInteger.valueOf(60 * 60)) < 0) { // less than 1 hour left textList.add(TextComponentUtil.translationWithColor( TextFormatting.YELLOW, @@ -550,8 +557,12 @@ public String getCapacity() { return TextFormattingUtil.formatNumbers(energyBank.getCapacity()); } - public long getAverageIOLastSec() { - return averageIOLastSec; + public long getAverageInLastSec() { + return averageInLastSec; + } + + public long getAverageOutLastSec() { + return averageOutLastSec; } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityProcessingArray.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityProcessingArray.java index be56f1b4170..4759bb1dec7 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityProcessingArray.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityProcessingArray.java @@ -9,13 +9,22 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.metatileentity.multiblock.*; +import gregtech.api.metatileentity.multiblock.DummyCleanroom; +import gregtech.api.metatileentity.multiblock.ICleanroomProvider; +import gregtech.api.metatileentity.multiblock.ICleanroomReceiver; +import gregtech.api.metatileentity.multiblock.IMultiblockPart; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockDisplayText; +import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; import gregtech.api.pattern.BlockPattern; import gregtech.api.pattern.FactoryBlockPattern; import gregtech.api.pattern.PatternMatchContext; import gregtech.api.pattern.TraceabilityPredicate; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMap; +import gregtech.api.recipes.logic.OCParams; +import gregtech.api.recipes.logic.OCResult; +import gregtech.api.recipes.properties.RecipePropertyStorage; import gregtech.api.util.GTUtility; import gregtech.api.util.TextComponentUtil; import gregtech.api.util.TextFormattingUtil; @@ -47,6 +56,7 @@ import java.util.List; import static gregtech.api.GTValues.ULV; +import static gregtech.api.recipes.logic.OverclockingLogic.subTickNonParallelOC; public class MetaTileEntityProcessingArray extends RecipeMapMultiblockController implements IMachineHatchMultiblock { @@ -228,6 +238,14 @@ public int getItemOutputLimit() { return mte == null ? 0 : mte.getItemOutputLimit(); } + @Override + public void setCleanroom(ICleanroomProvider provider) { + super.setCleanroom(provider); + + // Sync Cleanroom Change to Internal Workable MTE + ((ProcessingArrayWorkable) this.recipeMapWorkable).updateCleanroom(); + } + @SuppressWarnings("InnerClassMayBeStatic") protected class ProcessingArrayWorkable extends MultiblockRecipeLogic { @@ -324,15 +342,7 @@ public void findMachineStack() { mte = holder.setMetaTileEntity(mte); holder.setWorld(this.metaTileEntity.getWorld()); - // Set the cleanroom of the MTEs to the PA's cleanroom reference - if (mte instanceof ICleanroomReceiver receiver) { - if (ConfigHolder.machines.cleanMultiblocks) { - receiver.setCleanroom(DUMMY_CLEANROOM); - } else { - ICleanroomProvider provider = controller.getCleanroom(); - if (provider != null) receiver.setCleanroom(provider); - } - } + updateCleanroom(); } // Find the voltage tier of the machine. @@ -343,6 +353,18 @@ public void findMachineStack() { this.currentMachineStack = machine; } + private void updateCleanroom() { + // Set the cleanroom of the MTEs to the PA's cleanroom reference + if (mte instanceof ICleanroomReceiver receiver) { + if (ConfigHolder.machines.cleanMultiblocks) { + receiver.setCleanroom(DUMMY_CLEANROOM); + } else { + ICleanroomProvider provider = ((RecipeMapMultiblockController) metaTileEntity).getCleanroom(); + if (provider != null) receiver.setCleanroom(provider); + } + } + } + @Override public boolean checkRecipe(@NotNull Recipe recipe) { if (mte == null) return false; @@ -377,7 +399,7 @@ public long getMaxVoltage() { } @Override - protected int getNumberOfOCs(int recipeEUt) { + protected int getNumberOfOCs(long recipeEUt) { if (!isAllowOverclocking()) return 0; int recipeTier = Math.max(0, @@ -393,6 +415,13 @@ protected int getNumberOfOCs(int recipeEUt) { return numberOfOCs; } + @Override + protected void runOverclockingLogic(@NotNull OCParams ocParams, @NotNull OCResult ocResult, + @NotNull RecipePropertyStorage propertyStorage, long maxVoltage) { + subTickNonParallelOC(ocParams, ocResult, maxVoltage, getOverclockingDurationFactor(), + getOverclockingVoltageFactor()); + } + private ItemStack getMachineStack() { return currentMachineStack; } 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..b4715563582 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPyrolyseOven.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityPyrolyseOven.java @@ -11,7 +11,8 @@ import gregtech.api.pattern.FactoryBlockPattern; import gregtech.api.pattern.PatternMatchContext; import gregtech.api.recipes.RecipeMaps; -import gregtech.api.recipes.recipeproperties.IRecipePropertyStorage; +import gregtech.api.recipes.logic.OCResult; +import gregtech.api.recipes.properties.RecipePropertyStorage; import gregtech.api.util.GTUtility; import gregtech.api.util.TextComponentUtil; import gregtech.client.renderer.ICubeRenderer; @@ -172,18 +173,20 @@ public PyrolyseOvenWorkableHandler(RecipeMapMultiblockController tileEntity) { } @Override - protected void modifyOverclockPost(int[] resultOverclock, @NotNull IRecipePropertyStorage storage) { - super.modifyOverclockPost(resultOverclock, storage); + protected void modifyOverclockPost(@NotNull OCResult ocResult, @NotNull RecipePropertyStorage storage) { + super.modifyOverclockPost(ocResult, storage); int coilTier = ((MetaTileEntityPyrolyseOven) metaTileEntity).getCoilTier(); if (coilTier == -1) 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 - - resultOverclock[1] = Math.max(1, resultOverclock[1]); + // 75% speed with cupronickel (coilTier = 0) + ocResult.setDuration(Math.max(1, (int) (ocResult.duration() * 4.0 / 3))); + } else { + // each coil above kanthal (coilTier = 1) is 50% faster + ocResult.setDuration(Math.max(1, (int) (ocResult.duration() * 2.0 / (coilTier + 1)))); + } } } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityResearchStation.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityResearchStation.java index 17fafd955ae..50923590e11 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityResearchStation.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityResearchStation.java @@ -45,6 +45,8 @@ import java.util.Collections; import java.util.List; +import static gregtech.api.util.RelativeDirection.*; + public class MetaTileEntityResearchStation extends RecipeMapMultiblockController implements IOpticalComputationReceiver { @@ -143,7 +145,7 @@ protected BlockPattern createStructurePattern() { @Override public List getMatchingShapes() { - return Collections.singletonList(MultiblockShapeInfo.builder() + return Collections.singletonList(MultiblockShapeInfo.builder(RIGHT, DOWN, FRONT) .aisle("XXX", "VVV", "POP", "PEP", "PMP", "VVV", "XXX") .aisle("XXX", "VAV", "AAA", "AAA", "AAA", "VAV", "XXX") .aisle("XXX", "VAV", "XAX", "XSX", "XAX", "VAV", "XXX") @@ -262,12 +264,11 @@ public boolean isAllowOverclocking() { } @Override - protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, - @NotNull IItemHandlerModifiable importInventory) { + protected @Nullable Recipe setupAndConsumeRecipeInputs(@NotNull Recipe recipe, + @NotNull IItemHandlerModifiable importInventory) { // this machine cannot overclock, so don't bother calling it - this.overclockResults = new int[] { recipe.getEUt(), recipe.getDuration() }; - if (!hasEnoughPower(overclockResults)) { - return false; + if (!hasEnoughPower(recipe.getEUt(), recipe.getDuration())) { + return null; } // skip "can fit" checks, it can always fit @@ -275,14 +276,14 @@ protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, // do not consume inputs here, consume them on completion if (recipe.matches(false, importInventory, getInputTank())) { this.metaTileEntity.addNotifiedInput(importInventory); - return true; + return recipe; } - return false; + return null; } // lock the object holder on recipe start @Override - protected void setupRecipe(Recipe recipe) { + protected void setupRecipe(@NotNull Recipe recipe) { IObjectHolder holder = getMetaTileEntity().getObjectHolder(); holder.setLocked(true); super.setupRecipe(recipe); diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java b/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java index a5d37f33c41..0758efb8e70 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java @@ -202,20 +202,69 @@ private void updateProxyPlugin() { } public int getX() { - if (this.getController() != null) { - if (this.getController().getPos().getX() - this.getPos().getX() != 0) { - return Math.abs(this.getController().getPos().getX() - this.getPos().getX()) - 1; - } else { - return Math.abs(this.getController().getPos().getZ() - this.getPos().getZ()) - 1; + MultiblockControllerBase controller = this.getController(); + if (controller != null) { + EnumFacing spin = controller.getUpwardsFacing(); + switch (controller.getFrontFacing().getAxis()) { + case Y -> { + if (spin.getAxis() == EnumFacing.Axis.X) + return Math.abs(this.getController().getPos().getZ() - this.getPos().getZ()) - 1; + else + return Math.abs(this.getController().getPos().getX() - this.getPos().getX()) - 1; + } + case X -> { + if (spin.getAxis() == EnumFacing.Axis.Z) + return Math.abs(this.getController().getPos().getZ() - this.getPos().getZ()) - 1; + else + return Math.abs(this.getController().getPos().getY() - this.getPos().getY()) - 1; + } + default -> { + if (spin.getAxis() == EnumFacing.Axis.Z) + return Math.abs(this.getController().getPos().getX() - this.getPos().getX()) - 1; + else + return Math.abs(this.getController().getPos().getY() - this.getPos().getY()) - 1; + } } } return -1; } public int getY() { - if (this.getController() != null) { - return ((MetaTileEntityCentralMonitor) this.getController()).height - - (this.getPos().getY() + 1 - this.getController().getPos().getY()) - 1; + MultiblockControllerBase controller = this.getController(); + if (controller != null) { + EnumFacing spin = controller.getUpwardsFacing(); + EnumFacing facing = controller.getFrontFacing(); + int height = ((MetaTileEntityCentralMonitor) this.getController()).height; + switch (facing.getAxis()) { + case Y -> { + if (spin.getAxis() == EnumFacing.Axis.X) + return height - + (Math.abs(controller.getPos().getX() - spin.getXOffset() - this.getPos().getX())) - 1; + else + return height - + (Math.abs(controller.getPos().getZ() - spin.getZOffset() - this.getPos().getZ())) - 1; + } + case X -> { + if (spin.getAxis() == EnumFacing.Axis.Z) + return height - + (Math.abs(controller.getPos().getY() + spin.getZOffset() - this.getPos().getY())) - 1; + else + return height - (Math.abs( + controller.getPos().getZ() + spin.getXOffset() * facing.rotateY().getZOffset() - + this.getPos().getZ())) - + 1; + } + default -> { + if (spin.getAxis() == EnumFacing.Axis.Z) + return height - + (Math.abs(controller.getPos().getY() + spin.getZOffset() - this.getPos().getY())) - 1; + else + return height - (Math.abs( + controller.getPos().getX() + spin.getXOffset() * facing.rotateY().getXOffset() - + this.getPos().getX())) - + 1; + } + } } return -1; } @@ -800,6 +849,7 @@ public void addInformation(ItemStack stack, @Nullable World player, List } @Override + @SideOnly(Side.CLIENT) public Pair getParticleTexture() { return Pair.of(null, -1); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java index 482d6c710b5..46edc9619e7 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/LargeTurbineWorkableHandler.java @@ -1,6 +1,7 @@ package gregtech.common.metatileentities.multi.electric.generator; import gregtech.api.GTValues; +import gregtech.api.capability.IMultipleTankHandler; import gregtech.api.capability.IRotorHolder; import gregtech.api.capability.impl.MultiblockFuelRecipeLogic; import gregtech.api.metatileentity.multiblock.FuelMultiblockController; @@ -8,19 +9,27 @@ import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeBuilder; +import gregtech.api.recipes.RecipeMap; +import gregtech.api.util.GTUtility; +import net.minecraft.item.ItemStack; import net.minecraft.util.math.MathHelper; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.IFluidTank; import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.items.IItemHandlerModifiable; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.stream.Collectors; public class LargeTurbineWorkableHandler extends MultiblockFuelRecipeLogic { private final int BASE_EU_OUTPUT; - private int excessVoltage; + private long excessVoltage; public LargeTurbineWorkableHandler(RecipeMapMultiblockController metaTileEntity, int tier) { super(metaTileEntity); @@ -42,7 +51,9 @@ protected void updateRecipeProgress() { public FluidStack getInputFluidStack() { // Previous Recipe is always null on first world load, so try to acquire a new recipe if (previousRecipe == null) { - Recipe recipe = findRecipe(Integer.MAX_VALUE, getInputInventory(), getInputTank()); + // previousRecipe is set whenever a valid recipe is found + // if it's not set, find *any* recipe we have at least the base (non-parallel) inputs for + Recipe recipe = super.findRecipe(Integer.MAX_VALUE, getInputInventory(), getInputTank()); return recipe == null ? null : getInputTank().drain( new FluidStack(recipe.getFluidInputs().get(0).getInputFluidStack().getFluid(), Integer.MAX_VALUE), @@ -73,23 +84,69 @@ protected long boostProduction(long production) { return 0; } + private int getParallel(@NotNull Recipe recipe, double totalHolderEfficiencyCoefficient, long turbineMaxVoltage) { + return MathHelper.ceil((turbineMaxVoltage - this.excessVoltage) / + (recipe.getEUt() * totalHolderEfficiencyCoefficient)); + } + + private boolean canDoRecipeWithParallel(Recipe recipe) { + IRotorHolder rotorHolder = ((MetaTileEntityLargeTurbine) metaTileEntity).getRotorHolder(); + if (rotorHolder == null || !rotorHolder.hasRotor()) + return false; + double totalHolderEfficiencyCoefficient = rotorHolder.getTotalEfficiency() / 100.0; + long turbineMaxVoltage = getMaxVoltage(); + int parallel = getParallel(recipe, totalHolderEfficiencyCoefficient, turbineMaxVoltage); + + FluidStack recipeFluidStack = recipe.getFluidInputs().get(0).getInputFluidStack(); + + // Intentionally not using this.getInputFluidStack because that is locked to the previous recipe + FluidStack inputFluid = getInputTank().drain( + new FluidStack(recipeFluidStack.getFluid(), Integer.MAX_VALUE), + false); + return inputFluid != null && inputFluid.amount >= recipeFluidStack.amount * parallel; + } + @Override - protected boolean prepareRecipe(Recipe recipe) { + protected boolean checkPreviousRecipe() { + return super.checkPreviousRecipe() && canDoRecipeWithParallel(this.previousRecipe); + } + + @Override + protected @Nullable Recipe findRecipe(long maxVoltage, IItemHandlerModifiable inputs, + IMultipleTankHandler fluidInputs) { + RecipeMap map = getRecipeMap(); + if (map == null || !isRecipeMapValid(map)) { + return null; + } + + final List items = GTUtility.itemHandlerToList(inputs).stream().filter(s -> !s.isEmpty()).collect( + Collectors.toList()); + final List fluids = GTUtility.fluidHandlerToList(fluidInputs).stream() + .filter(f -> f != null && f.amount != 0) + .collect(Collectors.toList()); + + return map.find(items, fluids, recipe -> { + if (recipe.getEUt() > maxVoltage) return false; + return recipe.matches(false, inputs, fluidInputs) && this.canDoRecipeWithParallel(recipe); + }); + } + + @Override + public boolean prepareRecipe(Recipe recipe) { IRotorHolder rotorHolder = ((MetaTileEntityLargeTurbine) metaTileEntity).getRotorHolder(); if (rotorHolder == null || !rotorHolder.hasRotor()) return false; - int turbineMaxVoltage = (int) getMaxVoltage(); + long turbineMaxVoltage = getMaxVoltage(); FluidStack recipeFluidStack = recipe.getFluidInputs().get(0).getInputFluidStack(); int parallel = 0; - if (excessVoltage >= turbineMaxVoltage) { - excessVoltage -= turbineMaxVoltage; + if (this.excessVoltage >= turbineMaxVoltage) { + this.excessVoltage -= turbineMaxVoltage; } else { double holderEfficiency = rotorHolder.getTotalEfficiency() / 100.0; // get the amount of parallel required to match the desired output voltage - parallel = MathHelper.ceil((turbineMaxVoltage - excessVoltage) / - (Math.abs(recipe.getEUt()) * holderEfficiency)); + parallel = getParallel(recipe, holderEfficiency, turbineMaxVoltage); // Null check fluid here, since it can return null on first join into world or first form FluidStack inputFluid = getInputFluidStack(); @@ -98,7 +155,7 @@ protected boolean prepareRecipe(Recipe recipe) { } // this is necessary to prevent over-consumption of fuel - excessVoltage += (int) (parallel * Math.abs(recipe.getEUt()) * holderEfficiency - turbineMaxVoltage); + this.excessVoltage += (long) (parallel * recipe.getEUt() * holderEfficiency - turbineMaxVoltage); } // rebuild the recipe and adjust voltage to match the turbine @@ -108,17 +165,20 @@ protected boolean prepareRecipe(Recipe recipe) { applyParallelBonus(recipeBuilder); recipe = recipeBuilder.build().getResult(); - if (recipe != null && setupAndConsumeRecipeInputs(recipe, getInputInventory())) { - setupRecipe(recipe); - return true; + if (recipe != null) { + recipe = setupAndConsumeRecipeInputs(recipe, getInputInventory()); + if (recipe != null) { + setupRecipe(recipe); + return true; + } } return false; } @Override public void invalidate() { - excessVoltage = 0; super.invalidate(); + excessVoltage = 0; } public void updateTanks() { diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java index 4b298f25cd0..5bdd31eafc8 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/generator/MetaTileEntityLargeCombustionEngine.java @@ -10,12 +10,18 @@ import gregtech.api.gui.resources.TextureArea; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.metatileentity.multiblock.*; +import gregtech.api.metatileentity.multiblock.FuelMultiblockController; +import gregtech.api.metatileentity.multiblock.IMultiblockPart; +import gregtech.api.metatileentity.multiblock.IProgressBarMultiblock; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockDisplayText; +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.RecipeMaps; import gregtech.api.unification.material.Materials; +import gregtech.api.util.RelativeDirection; import gregtech.api.util.TextComponentUtil; import gregtech.api.util.TextFormattingUtil; import gregtech.client.renderer.ICubeRenderer; @@ -28,7 +34,6 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.ITextComponent; @@ -192,18 +197,19 @@ protected void formStructure(PatternMatchContext context) { } private boolean checkIntakesObstructed() { - EnumFacing facing = this.getFrontFacing(); - boolean permuteXZ = facing.getAxis() == EnumFacing.Axis.Z; - BlockPos centerPos = this.getPos().offset(facing); - for (int x = -1; x < 2; x++) { - for (int y = -1; y < 2; y++) { - // Skip the controller block itself - if (x == 0 && y == 0) + for (int left = -1; left <= 1; left++) { + for (int up = -1; up <= 1; up++) { + if (left == 0 && up == 0) { + // Skip the controller block itself continue; - BlockPos blockPos = centerPos.add(permuteXZ ? x : 0, y, permuteXZ ? 0 : x); - IBlockState blockState = this.getWorld().getBlockState(blockPos); - if (!blockState.getBlock().isAir(blockState, this.getWorld(), blockPos)) + } + + final BlockPos checkPos = RelativeDirection.offsetPos( + getPos(), getFrontFacing(), getUpwardsFacing(), isFlipped(), up, left, 1); + final IBlockState state = getWorld().getBlockState(checkPos); + if (!state.getBlock().isAir(state, getWorld(), checkPos)) { return true; + } } } return false; @@ -424,8 +430,8 @@ protected long boostProduction(long production) { @Override public void invalidate() { - isOxygenBoosted = false; super.invalidate(); + isOxygenBoosted = false; } } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityAutoMaintenanceHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityAutoMaintenanceHatch.java index 7743303c4ec..c1ac8373b43 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityAutoMaintenanceHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityAutoMaintenanceHatch.java @@ -1,7 +1,6 @@ package gregtech.common.metatileentities.multi.multiblockpart; import gregtech.api.capability.IMaintenanceHatch; -import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; @@ -12,7 +11,6 @@ import net.minecraft.client.resources.I18n; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; @@ -95,11 +93,6 @@ public boolean startWithoutProblems() { return true; } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; - } - @Override protected boolean openGUIOnRightClick() { return false; diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java index 850ea3730be..85c2bc25173 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java @@ -4,7 +4,6 @@ import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IOpticalComputationHatch; import gregtech.api.capability.IOpticalComputationProvider; -import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; @@ -13,10 +12,12 @@ import gregtech.client.renderer.texture.Textures; import gregtech.common.pipelike.optical.tile.TileEntityOpticalPipe; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.client.resources.I18n; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import codechicken.lib.render.CCRenderState; @@ -129,11 +130,6 @@ protected boolean openGUIOnRightClick() { return false; } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; - } - @Override public boolean canPartShare() { return false; @@ -166,4 +162,11 @@ public T getCapability(Capability capability, EnumFacing side) { } return super.getCapability(capability, side); } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + super.addInformation(stack, world, tooltip, advanced); + tooltip.add(I18n.format("gregtech.universal.disabled")); + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java index c925716144e..a50acc06ba0 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java @@ -175,6 +175,11 @@ public void addInformation(ItemStack stack, @Nullable World world, @NotNull List } else { tooltip.add(I18n.format("gregtech.machine.data_access_hatch.tooltip.2", getInventorySize())); } + if (canPartShare()) { + tooltip.add(I18n.format("gregtech.universal.enabled")); + } else { + tooltip.add(I18n.format("gregtech.universal.disabled")); + } } @NotNull @@ -199,7 +204,7 @@ public List getDataInfo() { @Override public boolean canPartShare() { - return false; + return isCreative; } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityEnergyHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityEnergyHatch.java index 1440514f90e..fd79fc8811d 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityEnergyHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityEnergyHatch.java @@ -1,13 +1,17 @@ package gregtech.common.metatileentities.multi.multiblockpart; import gregtech.api.GTValues; +import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.IEnergyContainer; +import gregtech.api.capability.IQuantumController; +import gregtech.api.capability.IQuantumStorage; import gregtech.api.capability.impl.EnergyContainerHandler; -import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.util.GTUtility; +import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; import gregtech.client.utils.PipelineUtil; @@ -15,10 +19,13 @@ import net.minecraft.client.resources.I18n; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import codechicken.lib.render.CCRenderState; @@ -27,15 +34,23 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.lang.ref.WeakReference; import java.util.List; public class MetaTileEntityEnergyHatch extends MetaTileEntityMultiblockPart - implements IMultiblockAbilityPart { + implements IMultiblockAbilityPart, + IQuantumStorage { protected final boolean isExportHatch; protected final int amperage; protected final IEnergyContainer energyContainer; + /** not synced, server only. lazily initialized from pos */ + private WeakReference controller = new WeakReference<>(null); + + /** synced, server and client */ + private BlockPos controllerPos; + public MetaTileEntityEnergyHatch(ResourceLocation metaTileEntityId, int tier, int amperage, boolean isExportHatch) { super(metaTileEntityId, tier); this.isExportHatch = isExportHatch; @@ -110,11 +125,6 @@ protected boolean openGUIOnRightClick() { return false; } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; - } - @Override public void addInformation(ItemStack stack, @Nullable World world, List tooltip, boolean advanced) { String tierName = GTValues.VNF[getTier()]; @@ -204,4 +214,137 @@ public void doExplosion(float explosionPower) { super.doExplosion(explosionPower); } } + + @Override + public void onRemoval() { + if (!getWorld().isRemote && isConnected()) { + IQuantumController controller = getQuantumController(); + if (controller != null) controller.rebuildNetwork(); + } + } + + @Override + public void onPlacement(@Nullable EntityLivingBase placer) { + super.onPlacement(placer); + if (getWorld() == null || getWorld().isRemote || isExportHatch) + return; + + // add to the network if an adjacent block is part of a network + // use whatever we find first, merging networks is not supported + tryFindNetwork(); + } + + @Override + public Type getType() { + return Type.ENERGY; + } + + @Override + public ICubeRenderer getBaseTexture() { + if (isConnected()) { + return Textures.QUANTUM_CASING; + } + return super.getBaseTexture(); + } + + @Override + public void setConnected(IQuantumController controller) { + if (getWorld().isRemote) return; + if (isExportHatch) return; + + if (!controller.getPos().equals(controllerPos)) { + this.controller = new WeakReference<>(controller); + this.controllerPos = controller.getPos(); + writeCustomData(GregtechDataCodes.UPDATE_CONTROLLER_POS, buf -> buf.writeBlockPos(controllerPos)); + markDirty(); + } + } + + @Override + public void setDisconnected() { + if (getWorld().isRemote) return; + + controller.clear(); + controllerPos = null; + writeCustomData(GregtechDataCodes.REMOVE_CONTROLLER, buf -> {}); + markDirty(); + } + + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == GregtechDataCodes.UPDATE_CONTROLLER_POS) { + this.controllerPos = buf.readBlockPos(); + this.controller.clear(); + scheduleRenderUpdate(); + } else if (dataId == GregtechDataCodes.REMOVE_CONTROLLER) { + this.controllerPos = null; + this.controller.clear(); + scheduleRenderUpdate(); + } + } + + @Override + public void writeInitialSyncData(PacketBuffer buf) { + super.writeInitialSyncData(buf); + buf.writeBoolean(controllerPos != null); + if (controllerPos != null) { + buf.writeBlockPos(controllerPos); + } + } + + @Override + public void receiveInitialSyncData(PacketBuffer buf) { + super.receiveInitialSyncData(buf); + if (buf.readBoolean()) { + controllerPos = buf.readBlockPos(); + scheduleRenderUpdate(); + } + } + + // use this to make sure controller is properly initialized + @Override + public final IQuantumController getQuantumController() { + if (isConnected()) { + if (controller.get() != null) return controller.get(); + MetaTileEntity mte = GTUtility.getMetaTileEntity(getWorld(), controllerPos); + if (mte instanceof IQuantumController quantumController) { + controller = new WeakReference<>(quantumController); + return quantumController; + } else { + // controller is no longer there for some reason, need to disconnect + setDisconnected(); + tryFindNetwork(); + } + } + return null; + } + + @Override + public BlockPos getControllerPos() { + return controllerPos; + } + + @Override + public IEnergyContainer getTypeValue() { + return this.energyContainer; + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + NBTTagCompound tagCompound = super.writeToNBT(data); + tagCompound.setBoolean("HasController", controllerPos != null); + if (controllerPos != null) { + tagCompound.setLong("ControllerPos", controllerPos.toLong()); + } + return tagCompound; + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + if (data.getBoolean("HasController")) { + this.controllerPos = BlockPos.fromLong(data.getLong("ControllerPos")); + } + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java index 8eca7ca9111..8cf7c4f2e6a 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java @@ -47,16 +47,16 @@ public class MetaTileEntityFluidHatch extends MetaTileEntityMultiblockNotifiablePart implements IMultiblockAbilityPart, IControllable { - private static final int INITIAL_INVENTORY_SIZE = 8000; + public static final int INITIAL_INVENTORY_SIZE = 8000; // only holding this for convenience - private final HatchFluidTank fluidTank; - private boolean workingEnabled; + protected final HatchFluidTank fluidTank; + protected boolean workingEnabled; // export hatch-only fields - private boolean locked; + protected boolean locked; @Nullable - private FluidStack lockedFluid; + protected FluidStack lockedFluid; public MetaTileEntityFluidHatch(ResourceLocation metaTileEntityId, int tier, boolean isExportHatch) { super(metaTileEntityId, tier, isExportHatch); @@ -176,7 +176,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, } } - private int getInventorySize() { + protected int getInventorySize() { return INITIAL_INVENTORY_SIZE * (1 << Math.min(9, getTier())); } @@ -268,7 +268,7 @@ public ModularUI.Builder createTankUI(IFluidTank fluidTank, String title, Entity .bindPlayerInventory(entityPlayer.inventory); } - private Consumer> getFluidNameText(TankWidget tankWidget) { + protected Consumer> getFluidNameText(TankWidget tankWidget) { return (list) -> { TextComponentTranslation translation = tankWidget.getFluidTextComponent(); // If there is no fluid in the tank, but there is a locked fluid @@ -282,7 +282,7 @@ private Consumer> getFluidNameText(TankWidget tankWidget) { }; } - private Consumer> getFluidAmountText(TankWidget tankWidget) { + protected Consumer> getFluidAmountText(TankWidget tankWidget) { return (list) -> { String fluidAmount = ""; @@ -339,7 +339,7 @@ private void setLocked(boolean locked) { fluidTank.onContentsChanged(); } - private class HatchFluidTank extends NotifiableFluidTank implements IFilteredFluidContainer, IFilter { + protected class HatchFluidTank extends NotifiableFluidTank implements IFilteredFluidContainer, IFilter { public HatchFluidTank(int capacity, MetaTileEntity entityToNotify, boolean isExport) { super(capacity, entityToNotify, isExport); 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..50435231a3b 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java @@ -41,7 +41,7 @@ import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.value.BoolValue; import com.cleanroommc.modularui.value.sync.BooleanSyncValue; -import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandlers; import com.cleanroommc.modularui.widget.Widget; import com.cleanroommc.modularui.widgets.ItemSlot; @@ -265,7 +265,7 @@ public boolean usesMui2() { } @Override - public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { int rowSize = (int) Math.sqrt(getInventorySize()); guiSyncManager.registerSlotGroup("item_inv", rowSize); @@ -278,10 +278,18 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { for (int i = 0; i < rowSize; i++) { widgets.add(new ArrayList<>()); for (int j = 0; j < rowSize; j++) { + int index = i * rowSize + j; + IItemHandlerModifiable handler = isExportHatch ? exportItems : importItems; widgets.get(i) .add(new ItemSlot() - .slot(SyncHandlers.itemSlot(isExportHatch ? exportItems : importItems, i * rowSize + j) + .slot(SyncHandlers.itemSlot(handler, index) .slotGroup("item_inv") + .changeListener((newItem, onlyAmountChanged, client, init) -> { + if (onlyAmountChanged && + handler instanceof GTItemStackHandler gtHandler) { + gtHandler.onContentsChanged(index); + } + }) .accessibility(!isExportHatch, true))); } } @@ -312,9 +320,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/MetaTileEntityLaserHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java index 2f622588c7b..f47d35c0377 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java @@ -3,7 +3,6 @@ import gregtech.api.GTValues; import gregtech.api.capability.ILaserContainer; import gregtech.api.capability.impl.LaserContainerHandler; -import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.IDataInfoProvider; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; @@ -12,7 +11,6 @@ import gregtech.client.renderer.texture.Textures; import net.minecraft.client.resources.I18n; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; @@ -62,21 +60,11 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { return new MetaTileEntityLaserHatch(metaTileEntityId, isOutput, tier, amperage); } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; - } - @Override protected boolean openGUIOnRightClick() { return false; } - @Override - public boolean canPartShare() { - return false; - } - @Override public MultiblockAbility getAbility() { return isOutput ? MultiblockAbility.OUTPUT_LASER : MultiblockAbility.INPUT_LASER; @@ -114,7 +102,7 @@ public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip.add(I18n.format("gregtech.universal.tooltip.amperage_in_till", amperage)); } tooltip.add(I18n.format("gregtech.universal.tooltip.energy_storage_capacity", buffer.getEnergyCapacity())); - tooltip.add(I18n.format("gregtech.universal.disabled")); + tooltip.add(I18n.format("gregtech.universal.enabled")); } @NotNull diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMaintenanceHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMaintenanceHatch.java index dda660e024f..31c87a58251 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMaintenanceHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMaintenanceHatch.java @@ -112,7 +112,7 @@ protected void initializeInventory() { } @Override - public void clearMachineInventory(NonNullList itemBuffer) { + public void clearMachineInventory(@NotNull List<@NotNull ItemStack> itemBuffer) { super.clearMachineInventory(itemBuffer); clearInventory(itemBuffer, itemStackHandler); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java index 5bc07d2e793..4634293686a 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java @@ -24,7 +24,6 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -35,6 +34,7 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -75,7 +75,7 @@ public void update() { } @Override - public void clearMachineInventory(NonNullList itemBuffer) { + public void clearMachineInventory(@NotNull List<@NotNull ItemStack> itemBuffer) { clearInventory(itemBuffer, inventory); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java index cf77abc3bb6..cf053eb8500 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java @@ -122,6 +122,14 @@ public void receiveInitialSyncData(PacketBuffer buf) { this.workingEnabled = buf.readBoolean(); } + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == GregtechDataCodes.WORKING_ENABLED) { + this.workingEnabled = buf.readBoolean(); + } + } + @Override public NBTTagCompound writeToNBT(NBTTagCompound data) { super.writeToNBT(data); diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiblockPart.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiblockPart.java index 04b67b858b2..0a1b098a0b4 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiblockPart.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiblockPart.java @@ -15,6 +15,8 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.ColourMultiplier; @@ -40,6 +42,7 @@ public MetaTileEntityMultiblockPart(ResourceLocation metaTileEntityId, int tier) } @Override + @SideOnly(Side.CLIENT) public Pair getParticleTexture() { return Pair.of(getBaseTexture().getParticleSprite(), getPaintingColorForRendering()); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java index 5658841fcda..c55fcbfeaa8 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java @@ -18,19 +18,21 @@ import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; +import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; -import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; import net.minecraftforge.items.IItemHandler; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -72,7 +74,7 @@ private boolean isSlotBlocked() { } @Override - public void clearMachineInventory(NonNullList itemBuffer) { + public void clearMachineInventory(@NotNull List<@NotNull ItemStack> itemBuffer) { clearInventory(itemBuffer, heldItems); } @@ -207,6 +209,18 @@ public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { heldItems.removeNotifiableMetaTileEntity(controllerBase); } + @Override + public boolean canPartShare() { + return false; + } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + super.addInformation(stack, world, tooltip, advanced); + tooltip.add(I18n.format("gregtech.universal.disabled")); + } + private class ObjectHolderHandler extends NotifiableItemStackHandler { public ObjectHolderHandler(MetaTileEntity metaTileEntity) { diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java index ca4d8d8000c..b86782957d2 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java @@ -4,7 +4,6 @@ import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IDataAccessHatch; import gregtech.api.capability.IOpticalDataAccessHatch; -import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; @@ -14,16 +13,19 @@ import gregtech.client.renderer.texture.Textures; import gregtech.common.pipelike.optical.tile.TileEntityOpticalPipe; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.client.resources.I18n; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.List; @@ -43,11 +45,6 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { return new MetaTileEntityOpticalDataHatch(metaTileEntityId, this.isTransmitter); } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; - } - @Override protected boolean openGUIOnRightClick() { return false; @@ -134,4 +131,11 @@ public MultiblockAbility getAbility() { public void registerAbilities(@NotNull List abilityList) { abilityList.add(this); } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + super.addInformation(stack, world, tooltip, advanced); + tooltip.add(I18n.format("gregtech.universal.disabled")); + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityPassthroughHatchItem.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityPassthroughHatchItem.java index b60a9781bed..febd79c80d6 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityPassthroughHatchItem.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityPassthroughHatchItem.java @@ -18,7 +18,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; -import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; @@ -141,7 +140,7 @@ protected boolean shouldSerializeInventories() { } @Override - public void clearMachineInventory(NonNullList itemBuffer) { + public void clearMachineInventory(@NotNull List<@NotNull ItemStack> itemBuffer) { clearInventory(itemBuffer, itemStackHandler); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java index 9981538731d..e8cf6d7b59b 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java @@ -63,7 +63,6 @@ public void update() { super.update(); if (!getWorld().isRemote) { fillContainerFromInternalTank(fluidTank); - fillInternalTankFromFluidContainer(fluidTank); if (getOffsetTimer() % 20 == 0) { fluidTank.refillWater(); } @@ -129,7 +128,7 @@ public ModularUI.Builder createTankUI(IFluidTank fluidTank, String title, Entity // Add input/output-specific widgets tankWidget = new TankWidget(fluidTank, 69, 52, 18, 18) - .setAlwaysShowFull(true).setDrawHoveringText(false).setContainerClicking(true, true); + .setAlwaysShowFull(true).setDrawHoveringText(false).setContainerClicking(true, false); builder.image(7, 16, 81, 55, GuiTextures.DISPLAY) .widget(new ImageWidget(91, 36, 14, 15, GuiTextures.TANK_ICON)) @@ -180,47 +179,39 @@ public void addToolUsages(ItemStack stack, @Nullable World world, List t private static class InfiniteWaterTank extends NotifiableFluidTank { - private final FluidStack BIG_WATER = new FluidStack(FluidRegistry.WATER, FLUID_AMOUNT); - public InfiniteWaterTank(int capacity, MetaTileEntity entityToNotify) { super(capacity, entityToNotify, false); - setFluid(BIG_WATER); + // start with the full amount + setFluid(new FluidStack(FluidRegistry.WATER, FLUID_AMOUNT)); + // don't allow external callers to fill this tank + setCanFill(false); } private void refillWater() { - if (BIG_WATER.amount != FLUID_AMOUNT) { - BIG_WATER.amount = FLUID_AMOUNT; - onContentsChanged(); + int fillAmount = Math.max(0, FLUID_AMOUNT - getFluidAmount()); + if (fillAmount > 0) { + // call super since our overrides don't allow any kind of filling + super.fillInternal(new FluidStack(FluidRegistry.WATER, fillAmount), true); } } @Override - public FluidStack drainInternal(int maxDrain, boolean doDrain) { - return new FluidStack(BIG_WATER, maxDrain); - } - - @Nullable - @Override - public FluidStack drainInternal(FluidStack resource, boolean doDrain) { - return new FluidStack(BIG_WATER, resource.amount); + public boolean canDrainFluidType(@Nullable FluidStack fluid) { + return fluid != null && fluid.getFluid() == FluidRegistry.WATER; } + // don't allow external filling @Override public int fillInternal(FluidStack resource, boolean doFill) { - return resource.amount; - } - - @Override - public boolean canDrainFluidType(@Nullable FluidStack fluid) { - return fluid != null && fluid.getFluid() == BIG_WATER.getFluid(); + return 0; } @Override public boolean canFillFluidType(FluidStack fluid) { - return fluid.getFluid() == BIG_WATER.getFluid(); + return false; } - // serialization is unnecessary here, it should always have the same amount of fluid + // serialization is unnecessary here, we can always recreate it completely full since it would refill anyway @Override public FluidTank readFromNBT(NBTTagCompound nbt) { return this; diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java index e36b9bb24d4..1fd863b864f 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java @@ -12,6 +12,7 @@ import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.util.RelativeDirection; import gregtech.client.renderer.texture.Textures; import gregtech.common.items.behaviors.AbstractMaterialPartBehavior; import gregtech.common.items.behaviors.TurbineRotorBehavior; @@ -27,7 +28,6 @@ import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; -import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -163,14 +163,17 @@ public boolean isFrontFaceFree() { } private boolean checkTurbineFaceFree() { - EnumFacing facing = getFrontFacing(); - boolean permuteXZ = facing.getAxis() == EnumFacing.Axis.Z; - BlockPos centerPos = getPos().offset(facing); - for (int x = -1; x < 2; x++) { - for (int y = -1; y < 2; y++) { - BlockPos blockPos = centerPos.add(permuteXZ ? x : 0, y, permuteXZ ? 0 : x); - IBlockState blockState = getWorld().getBlockState(blockPos); - if (!blockState.getBlock().isAir(blockState, getWorld(), blockPos)) { + final EnumFacing front = getFrontFacing(); + // this can be anything really, as long as it is not up/down when on Y axis + final EnumFacing upwards = front.getAxis() == EnumFacing.Axis.Y ? EnumFacing.NORTH : EnumFacing.UP; + + for (int left = -1; left <= 1; left++) { + for (int up = -1; up <= 1; up++) { + // flip doesn't affect anything here since we are checking a square anyway + final BlockPos checkPos = RelativeDirection.offsetPos( + getPos(), front, upwards, false, up, left, 1); + final IBlockState state = getWorld().getBlockState(checkPos); + if (!state.getBlock().isAir(state, getWorld(), checkPos)) { return false; } } @@ -291,7 +294,7 @@ public void onLeftClick(EntityPlayer player, EnumFacing facing, CuboidRayTraceRe } @Override - public void clearMachineInventory(NonNullList itemBuffer) { + public void clearMachineInventory(@NotNull List<@NotNull ItemStack> itemBuffer) { super.clearMachineInventory(itemBuffer); clearInventory(itemBuffer, inventory); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java index 7f470e4d0ff..6212144fec7 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityAEHostablePart.java @@ -1,63 +1,58 @@ package gregtech.common.metatileentities.multi.multiblockpart.appeng; -import gregtech.api.GTValues; import gregtech.api.capability.IControllable; -import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; -import gregtech.client.renderer.ICubeRenderer; -import gregtech.client.renderer.texture.Textures; import gregtech.common.ConfigHolder; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockNotifiablePart; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; -import net.minecraft.util.NonNullList; +import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentTranslation; import appeng.api.AEApi; import appeng.api.networking.GridFlags; import appeng.api.networking.security.IActionHost; import appeng.api.networking.security.IActionSource; +import appeng.api.storage.IMEMonitor; import appeng.api.storage.IStorageChannel; -import appeng.api.storage.channels.IFluidStorageChannel; -import appeng.api.storage.channels.IItemStorageChannel; -import appeng.api.storage.data.IAEFluidStack; -import appeng.api.storage.data.IAEItemStack; +import appeng.api.storage.data.IAEStack; import appeng.api.util.AECableType; import appeng.api.util.AEPartLocation; +import appeng.me.GridAccessException; import appeng.me.helpers.AENetworkProxy; import appeng.me.helpers.BaseActionSource; import appeng.me.helpers.IGridProxyable; import appeng.me.helpers.MachineSource; +import codechicken.lib.raytracer.CuboidRayTraceResult; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.util.EnumSet; +import java.util.List; -/** - * @Author GlodBlock - * @Description It can connect to ME network. - * @Date 2023/4/18-23:17 - */ -public abstract class MetaTileEntityAEHostablePart extends MetaTileEntityMultiblockNotifiablePart - implements IControllable { +import static gregtech.api.capability.GregtechDataCodes.UPDATE_ONLINE_STATUS; - protected static final IStorageChannel ITEM_NET = AEApi.instance().storage() - .getStorageChannel(IItemStorageChannel.class); - protected static final IStorageChannel FLUID_NET = AEApi.instance().storage() - .getStorageChannel(IFluidStorageChannel.class); +public abstract class MetaTileEntityAEHostablePart> extends MetaTileEntityMultiblockNotifiablePart + implements IControllable { - private final static int ME_UPDATE_INTERVAL = ConfigHolder.compat.ae2.updateIntervals; + private final Class> storageChannel; private AENetworkProxy aeProxy; private int meUpdateTick; protected boolean isOnline; - private final static int ONLINE_ID = 6666; + private boolean allowExtraConnections; + protected boolean meStatusChanged = false; - public MetaTileEntityAEHostablePart(ResourceLocation metaTileEntityId, int tier, boolean isExportHatch) { + public MetaTileEntityAEHostablePart(ResourceLocation metaTileEntityId, int tier, boolean isExportHatch, + Class> storageChannel) { super(metaTileEntityId, tier, isExportHatch); this.meUpdateTick = 0; + this.storageChannel = storageChannel; + this.allowExtraConnections = false; } @Override @@ -73,9 +68,7 @@ public void update() { * So there is no need to drop them. */ @Override - public void clearMachineInventory(NonNullList itemBuffer) { - // NO-OP - } + public void clearMachineInventory(@NotNull List<@NotNull ItemStack> itemBuffer) {} @Override public void writeInitialSyncData(PacketBuffer buf) { @@ -90,6 +83,7 @@ public void writeInitialSyncData(PacketBuffer buf) { } buf.writeInt(this.meUpdateTick); buf.writeBoolean(this.isOnline); + buf.writeBoolean(this.allowExtraConnections); } @Override @@ -109,36 +103,25 @@ public void receiveInitialSyncData(PacketBuffer buf) { } this.meUpdateTick = buf.readInt(); this.isOnline = buf.readBoolean(); + this.allowExtraConnections = buf.readBoolean(); } @Override public void receiveCustomData(int dataId, PacketBuffer buf) { super.receiveCustomData(dataId, buf); - if (dataId == ONLINE_ID) { - this.isOnline = buf.readBoolean(); - } - } - - @Override - public ICubeRenderer getBaseTexture() { - MultiblockControllerBase controller = getController(); - if (controller != null) { - return this.hatchTexture = controller.getBaseTexture(this); - } else if (this.hatchTexture != null) { - if (hatchTexture != Textures.getInactiveTexture(hatchTexture)) { - return this.hatchTexture = Textures.getInactiveTexture(hatchTexture); + if (dataId == UPDATE_ONLINE_STATUS) { + boolean isOnline = buf.readBoolean(); + if (this.isOnline != isOnline) { + this.isOnline = isOnline; + scheduleRenderUpdate(); } - return this.hatchTexture; - } else { - // Always display as EV casing - return Textures.VOLTAGE_CASINGS[GTValues.EV]; } } @NotNull @Override public AECableType getCableConnectionType(@NotNull AEPartLocation part) { - if (part.getFacing() != this.frontFacing) { + if (part.getFacing() != this.frontFacing && !this.allowExtraConnections) { return AECableType.NONE; } return AECableType.SMART; @@ -159,52 +142,108 @@ public AENetworkProxy getProxy() { @Override public void setFrontFacing(EnumFacing frontFacing) { super.setFrontFacing(frontFacing); - if (this.aeProxy != null) { - this.aeProxy.setValidSides(EnumSet.of(this.getFrontFacing())); - } + updateConnectableSides(); } @Override - public void gridChanged() { - // NO-OP - } + 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) { + 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; + this.meStatusChanged = true; + } else { + this.meStatusChanged = false; + } } - writeCustomData(ONLINE_ID, buf -> buf.writeBoolean(this.isOnline)); return this.isOnline; } protected boolean shouldSyncME() { - return this.meUpdateTick % ME_UPDATE_INTERVAL == 0; + return this.meUpdateTick % ConfigHolder.compat.ae2.updateIntervals == 0; } protected IActionSource getActionSource() { - if (this.getHolder() instanceof IActionHost) { - return new MachineSource((IActionHost) this.getHolder()); + if (this.getHolder() instanceof IActionHost holder) { + return new MachineSource(holder); } return new BaseActionSource(); } @Nullable private AENetworkProxy createProxy() { - if (this.getHolder() instanceof IGridProxyable) { - AENetworkProxy proxy = new AENetworkProxy((IGridProxyable) this.getHolder(), "mte_proxy", - this.getStackForm(), true); + if (this.getHolder() instanceof IGridProxyable holder) { + AENetworkProxy proxy = new AENetworkProxy(holder, "mte_proxy", this.getStackForm(), true); proxy.setFlags(GridFlags.REQUIRE_CHANNEL); proxy.setIdlePowerUsage(ConfigHolder.compat.ae2.meHatchEnergyUsage); - proxy.setValidSides(EnumSet.of(this.getFrontFacing())); + proxy.setValidSides(getConnectableSides()); return proxy; } return null; } + + @NotNull + protected IStorageChannel getStorageChannel() { + return AEApi.instance().storage().getStorageChannel(storageChannel); + } + + @Nullable + protected IMEMonitor getMonitor() { + AENetworkProxy proxy = getProxy(); + if (proxy == null) return null; + + IStorageChannel channel = getStorageChannel(); + + try { + return proxy.getStorage().getInventory(channel); + } catch (GridAccessException ignored) { + return null; + } + } + + public EnumSet getConnectableSides() { + return this.allowExtraConnections ? EnumSet.allOf(EnumFacing.class) : EnumSet.of(getFrontFacing()); + } + + public void updateConnectableSides() { + if (this.aeProxy != null) { + this.aeProxy.setValidSides(getConnectableSides()); + } + } + + @Override + public boolean onWireCutterClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, + CuboidRayTraceResult hitResult) { + this.allowExtraConnections = !this.allowExtraConnections; + updateConnectableSides(); + + if (!getWorld().isRemote) { + playerIn.sendStatusMessage(new TextComponentTranslation(this.allowExtraConnections ? + "gregtech.machine.me.extra_connections.enabled" : "gregtech.machine.me.extra_connections.disabled"), + true); + } + + return true; + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + data.setBoolean("AllowExtraConnections", this.allowExtraConnections); + return data; + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + this.allowExtraConnections = data.getBoolean("AllowExtraConnections"); + } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java index 18a81b7df3d..b1e53f22f4a 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java @@ -3,15 +3,26 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IDataStickIntractable; +import gregtech.api.capability.IGhostSlotConfigurable; +import gregtech.api.capability.INotifiableHandler; +import gregtech.api.capability.impl.GhostCircuitItemStackHandler; +import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.capability.impl.NotifiableItemStackHandler; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.GhostCircuitSlotWidget; +import gregtech.api.gui.widgets.SlotWidget; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; import gregtech.common.gui.widget.appeng.AEItemConfigWidget; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; import net.minecraft.client.resources.I18n; @@ -23,117 +34,160 @@ import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import appeng.api.config.Actionable; import appeng.api.storage.IMEMonitor; +import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.data.IAEItemStack; -import appeng.me.GridAccessException; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; import java.util.List; -import java.util.function.Consumer; -/** - * @Author GlodBlock - * @Description The Input Bus that can auto fetch item ME storage network. - * @Date 2023/4/22-13:34 - */ -public class MetaTileEntityMEInputBus extends MetaTileEntityAEHostablePart - implements IMultiblockAbilityPart { +public class MetaTileEntityMEInputBus extends MetaTileEntityAEHostablePart + implements IMultiblockAbilityPart, + IGhostSlotConfigurable, IDataStickIntractable { public final static String ITEM_BUFFER_TAG = "ItemSlots"; public final static String WORKING_TAG = "WorkingEnabled"; private final static int CONFIG_SIZE = 16; - private boolean workingEnabled; - private ExportOnlyAEItemList aeItemHandler; + private boolean workingEnabled = true; + protected ExportOnlyAEItemList aeItemHandler; + protected GhostCircuitItemStackHandler circuitInventory; + protected NotifiableItemStackHandler extraSlotInventory; + private ItemHandlerList actualImportItems; public MetaTileEntityMEInputBus(ResourceLocation metaTileEntityId) { - super(metaTileEntityId, GTValues.UHV, false); - this.workingEnabled = true; + this(metaTileEntityId, GTValues.EV); + } + + protected MetaTileEntityMEInputBus(ResourceLocation metaTileEntityId, int tier) { + super(metaTileEntityId, tier, false, IItemStorageChannel.class); + } + + protected ExportOnlyAEItemList getAEItemHandler() { + if (aeItemHandler == null) { + aeItemHandler = new ExportOnlyAEItemList(this, CONFIG_SIZE, this.getController()); + } + return aeItemHandler; } @Override protected void initializeInventory() { - this.aeItemHandler = new ExportOnlyAEItemList(this, CONFIG_SIZE, this.getController()); super.initializeInventory(); - } - - protected IItemHandlerModifiable createImportItemHandler() { - return this.aeItemHandler; + this.aeItemHandler = getAEItemHandler(); + this.circuitInventory = new GhostCircuitItemStackHandler(this); + this.circuitInventory.addNotifiableMetaTileEntity(this); + this.extraSlotInventory = new NotifiableItemStackHandler(this, 1, this, false); + this.extraSlotInventory.addNotifiableMetaTileEntity(this); + this.actualImportItems = new ItemHandlerList( + Arrays.asList(this.aeItemHandler, this.circuitInventory, this.extraSlotInventory)); + this.importItems = this.actualImportItems; } public IItemHandlerModifiable getImportItems() { - this.importItems = this.aeItemHandler; - return super.getImportItems(); + return this.actualImportItems; } @Override public void update() { super.update(); - if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME()) { - if (this.updateMEStatus()) { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(ITEM_NET); - for (ExportOnlyAEItem aeSlot : this.aeItemHandler.inventory) { - // Try to clear the wrong item - IAEItemStack exceedItem = aeSlot.exceedStack(); - if (exceedItem != null) { - long total = exceedItem.getStackSize(); - IAEItemStack notInserted = aeNetwork.injectItems(exceedItem, Actionable.MODULATE, - this.getActionSource()); - if (notInserted != null && notInserted.getStackSize() > 0) { - aeSlot.extractItem(0, (int) (total - notInserted.getStackSize()), false); - continue; - } else { - aeSlot.extractItem(0, (int) total, false); - } - } - // Fill it - IAEItemStack reqItem = aeSlot.requestStack(); - if (reqItem != null) { - IAEItemStack extracted = aeNetwork.extractItems(reqItem, Actionable.MODULATE, - this.getActionSource()); - if (extracted != null) { - aeSlot.addStack(extracted); - } - } - } - } catch (GridAccessException ignore) {} - } + if (!getWorld().isRemote && this.workingEnabled && updateMEStatus() && shouldSyncME()) { + syncME(); } } - @Override - public void onRemoval() { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(ITEM_NET); - for (ExportOnlyAEItem aeSlot : this.aeItemHandler.inventory) { - IAEItemStack stock = aeSlot.stock; - if (stock instanceof WrappedItemStack) { - stock = ((WrappedItemStack) stock).getAEStack(); + protected void syncME() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEItemSlot aeSlot : this.getAEItemHandler().getInventory()) { + // Try to clear the wrong item + IAEItemStack exceedItem = aeSlot.exceedStack(); + if (exceedItem != null) { + long total = exceedItem.getStackSize(); + IAEItemStack notInserted = monitor.injectItems(exceedItem, Actionable.MODULATE, this.getActionSource()); + if (notInserted != null && notInserted.getStackSize() > 0) { + aeSlot.extractItem(0, (int) (total - notInserted.getStackSize()), false); + continue; + } else { + aeSlot.extractItem(0, (int) total, false); } - if (stock != null) { - aeNetwork.injectItems(stock, Actionable.MODULATE, this.getActionSource()); + } + // Fill it + IAEItemStack reqItem = aeSlot.requestStack(); + if (reqItem != null) { + IAEItemStack extracted = monitor.extractItems(reqItem, Actionable.MODULATE, this.getActionSource()); + if (extracted != null) { + aeSlot.addStack(extracted); } } - } catch (GridAccessException ignore) {} + } + } + + @Override + public void onRemoval() { + flushInventory(); super.onRemoval(); } + protected void flushInventory() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEItemSlot aeSlot : this.getAEItemHandler().getInventory()) { + IAEItemStack stock = aeSlot.getStock(); + if (stock instanceof WrappedItemStack) { + stock = ((WrappedItemStack) stock).getAEStack(); + } + if (stock != null) { + monitor.injectItems(stock, Actionable.MODULATE, this.getActionSource()); + } + } + } + @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity iGregTechTileEntity) { - return new MetaTileEntityMEInputBus(this.metaTileEntityId); + return new MetaTileEntityMEInputBus(metaTileEntityId); + } + + @Override + public void addToMultiBlock(MultiblockControllerBase controllerBase) { + super.addToMultiBlock(controllerBase); + for (IItemHandler handler : this.actualImportItems.getBackingHandlers()) { + if (handler instanceof INotifiableHandler notifiable) { + notifiable.addNotifiableMetaTileEntity(controllerBase); + notifiable.addToNotifiedList(this, handler, false); + } + } } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { + public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { + super.removeFromMultiBlock(controllerBase); + for (IItemHandler handler : this.actualImportItems.getBackingHandlers()) { + if (handler instanceof INotifiableHandler notifiable) { + notifiable.removeNotifiableMetaTileEntity(controllerBase); + } + } + } + + @Override + protected final ModularUI createUI(EntityPlayer player) { + ModularUI.Builder builder = createUITemplate(player); + return builder.build(this.getHolder(), player); + } + + protected ModularUI.Builder createUITemplate(EntityPlayer player) { ModularUI.Builder builder = ModularUI .builder(GuiTextures.BACKGROUND, 176, 18 + 18 * 4 + 94) .label(10, 5, getMetaFullName()); @@ -141,13 +195,37 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { builder.dynamicLabel(10, 15, () -> this.isOnline ? I18n.format("gregtech.gui.me_network.online") : I18n.format("gregtech.gui.me_network.offline"), - 0xFFFFFFFF); + 0x404040); // Config slots - builder.widget(new AEItemConfigWidget(16, 25, this.aeItemHandler.inventory)); + builder.widget(new AEItemConfigWidget(7, 25, this.getAEItemHandler())); + + // Ghost circuit slot + SlotWidget circuitSlot = new GhostCircuitSlotWidget(circuitInventory, 0, 7 + 18 * 4, 25 + 18 * 3) + .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.INT_CIRCUIT_OVERLAY); + builder.widget(circuitSlot.setConsumer(w -> { + String configString; + if (circuitInventory == null || + circuitInventory.getCircuitValue() == GhostCircuitItemStackHandler.NO_CONFIG) { + configString = new TextComponentTranslation("gregtech.gui.configurator_slot.no_value") + .getFormattedText(); + } else { + configString = String.valueOf(circuitInventory.getCircuitValue()); + } + + w.setTooltipText("gregtech.gui.configurator_slot.tooltip", configString); + })); - builder.bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT, 7, 18 + 18 * 4 + 12); - return builder.build(this.getHolder(), entityPlayer); + // Extra slot + builder.widget(new SlotWidget(extraSlotInventory, 0, 7 + 18 * 4, 25 + 18 * 2) + .setBackgroundTexture(GuiTextures.SLOT) + .setTooltipText("gregtech.gui.me_bus.extra_slot")); + + // Arrow image + builder.image(7 + 18 * 4, 25 + 18, 18, 18, GuiTextures.ARROW_DOUBLE); + + builder.bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 18 + 18 * 4 + 12); + return builder; } @Override @@ -190,13 +268,16 @@ public NBTTagCompound writeToNBT(NBTTagCompound data) { data.setBoolean(WORKING_TAG, this.workingEnabled); NBTTagList slots = new NBTTagList(); for (int i = 0; i < CONFIG_SIZE; i++) { - ExportOnlyAEItem slot = this.aeItemHandler.inventory[i]; + ExportOnlyAEItemSlot slot = this.getAEItemHandler().getInventory()[i]; NBTTagCompound slotTag = new NBTTagCompound(); slotTag.setInteger("slot", i); slotTag.setTag("stack", slot.serializeNBT()); slots.appendTag(slotTag); } data.setTag(ITEM_BUFFER_TAG, slots); + this.circuitInventory.write(data); + // Extra slot inventory + GTUtility.writeItems(this.extraSlotInventory, "ExtraInventory", data); return data; } @@ -210,10 +291,12 @@ public void readFromNBT(NBTTagCompound data) { NBTTagList slots = (NBTTagList) data.getTag(ITEM_BUFFER_TAG); for (NBTBase nbtBase : slots) { NBTTagCompound slotTag = (NBTTagCompound) nbtBase; - ExportOnlyAEItem slot = this.aeItemHandler.inventory[slotTag.getInteger("slot")]; + ExportOnlyAEItemSlot slot = this.getAEItemHandler().getInventory()[slotTag.getInteger("slot")]; slot.deserializeNBT(slotTag.getCompoundTag("stack")); } } + this.circuitInventory.read(data); + GTUtility.readItems(this.extraSlotInventory, "ExtraInventory", data); this.importItems = createImportItemHandler(); } @@ -221,7 +304,11 @@ public void readFromNBT(NBTTagCompound data) { public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { super.renderMetaTileEntity(renderState, translation, pipeline); if (this.shouldRenderOverlay()) { - Textures.ME_INPUT_BUS.renderSided(getFrontFacing(), renderState, translation, pipeline); + if (isOnline) { + Textures.ME_INPUT_BUS_ACTIVE.renderSided(getFrontFacing(), renderState, translation, pipeline); + } else { + Textures.ME_INPUT_BUS.renderSided(getFrontFacing(), renderState, translation, pipeline); + } } } @@ -231,6 +318,9 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.item_bus.import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.item_import.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me_import_item_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.copy_paste.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.extra_connections.tooltip")); tooltip.add(I18n.format("gregtech.universal.enabled")); } @@ -241,197 +331,79 @@ public MultiblockAbility getAbility() { @Override public void registerAbilities(List list) { - list.add(this.aeItemHandler); + list.add(this.actualImportItems); } - private static class ExportOnlyAEItemList extends NotifiableItemStackHandler { - - ExportOnlyAEItem[] inventory; - - public ExportOnlyAEItemList(MetaTileEntity holder, int slots, MetaTileEntity entityToNotify) { - super(holder, slots, entityToNotify, false); - this.inventory = new ExportOnlyAEItem[CONFIG_SIZE]; - for (int i = 0; i < CONFIG_SIZE; i++) { - this.inventory[i] = new ExportOnlyAEItem(null, null); - } - for (ExportOnlyAEItem slot : this.inventory) { - slot.trigger = this::onContentsChanged; - } - } - - @Override - public void deserializeNBT(NBTTagCompound nbt) { - for (int index = 0; index < CONFIG_SIZE; index++) { - if (nbt.hasKey("#" + index)) { - NBTTagCompound slotTag = nbt.getCompoundTag("#" + index); - this.inventory[index].deserializeNBT(slotTag); - } - } - } - - @Override - public NBTTagCompound serializeNBT() { - NBTTagCompound nbt = new NBTTagCompound(); - for (int index = 0; index < CONFIG_SIZE; index++) { - NBTTagCompound slot = this.inventory[index].serializeNBT(); - nbt.setTag("#" + index, slot); - } - return nbt; - } - - @Override - public void setStackInSlot(int slot, @NotNull ItemStack stack) { - // NO-OP - } - - @Override - public int getSlots() { - return MetaTileEntityMEInputBus.CONFIG_SIZE; - } - - @NotNull - @Override - public ItemStack getStackInSlot(int slot) { - if (slot >= 0 && slot < CONFIG_SIZE) { - return this.inventory[slot].getStackInSlot(0); - } - return ItemStack.EMPTY; - } - - @NotNull - @Override - public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { - return stack; - } - - @NotNull - @Override - public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (slot >= 0 && slot < CONFIG_SIZE) { - return this.inventory[slot].extractItem(0, amount, simulate); - } - return ItemStack.EMPTY; - } - - @Override - public int getSlotLimit(int slot) { - return Integer.MAX_VALUE; - } - - @Override - protected int getStackLimit(int slot, @NotNull ItemStack stack) { - return Integer.MAX_VALUE; - } + @Override + public boolean hasGhostCircuitInventory() { + return true; } - public static class ExportOnlyAEItem extends ExportOnlyAESlot implements IItemHandlerModifiable { - - private Consumer trigger; - - public ExportOnlyAEItem(IAEItemStack config, IAEItemStack stock) { - super(config, stock); - } - - public ExportOnlyAEItem() { - super(); - } - - @Override - public void deserializeNBT(NBTTagCompound nbt) { - if (nbt.hasKey(CONFIG_TAG)) { - this.config = WrappedItemStack.fromNBT(nbt.getCompoundTag(CONFIG_TAG)); - } - if (nbt.hasKey(STOCK_TAG)) { - this.stock = WrappedItemStack.fromNBT(nbt.getCompoundTag(STOCK_TAG)); - } - } - - @Override - public ExportOnlyAEItem copy() { - return new ExportOnlyAEItem( - this.config == null ? null : this.config.copy(), - this.stock == null ? null : this.stock.copy()); + @Override + public void setGhostCircuitConfig(int config) { + if (this.circuitInventory.getCircuitValue() == config) { + return; } - - @Override - public void setStackInSlot(int slot, @NotNull ItemStack stack) { - // NO-OP + this.circuitInventory.setCircuitValue(config); + if (!getWorld().isRemote) { + markDirty(); } + } - @Override - public int getSlots() { - return 1; - } + @Override + public final void onDataStickLeftClick(EntityPlayer player, ItemStack dataStick) { + NBTTagCompound tag = new NBTTagCompound(); + tag.setTag("MEInputBus", writeConfigToTag()); + dataStick.setTagCompound(tag); + dataStick.setTranslatableName("gregtech.machine.me.item_import.data_stick.name"); + player.sendStatusMessage(new TextComponentTranslation("gregtech.machine.me.import_copy_settings"), true); + } - @NotNull - @Override - public ItemStack getStackInSlot(int slot) { - if (slot == 0 && this.stock != null) { - return this.stock.getDefinition(); + protected NBTTagCompound writeConfigToTag() { + NBTTagCompound tag = new NBTTagCompound(); + NBTTagCompound configStacks = new NBTTagCompound(); + tag.setTag("ConfigStacks", configStacks); + for (int i = 0; i < CONFIG_SIZE; i++) { + var slot = this.aeItemHandler.getInventory()[i]; + IAEItemStack config = slot.getConfig(); + if (config == null) { + continue; } - return ItemStack.EMPTY; + NBTTagCompound stackNbt = new NBTTagCompound(); + config.getDefinition().writeToNBT(stackNbt); + configStacks.setTag(Integer.toString(i), stackNbt); } + tag.setByte("GhostCircuit", (byte) this.circuitInventory.getCircuitValue()); + return tag; + } - @NotNull - @Override - public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { - return stack; + @Override + public final boolean onDataStickRightClick(EntityPlayer player, ItemStack dataStick) { + NBTTagCompound tag = dataStick.getTagCompound(); + if (tag == null || !tag.hasKey("MEInputBus")) { + return false; } + readConfigFromTag(tag.getCompoundTag("MEInputBus")); + syncME(); + player.sendStatusMessage(new TextComponentTranslation("gregtech.machine.me.import_paste_settings"), true); + return true; + } - @NotNull - @Override - public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (slot == 0 && this.stock != null) { - int extracted = (int) Math.min(this.stock.getStackSize(), amount); - ItemStack result = this.stock.createItemStack(); - result.setCount(extracted); - if (!simulate) { - this.stock.decStackSize(extracted); - if (this.stock.getStackSize() == 0) { - this.stock = null; - } - } - if (this.trigger != null) { - this.trigger.accept(0); + protected void readConfigFromTag(NBTTagCompound tag) { + if (tag.hasKey("ConfigStacks")) { + NBTTagCompound configStacks = tag.getCompoundTag("ConfigStacks"); + for (int i = 0; i < CONFIG_SIZE; i++) { + String key = Integer.toString(i); + if (configStacks.hasKey(key)) { + NBTTagCompound configTag = configStacks.getCompoundTag(key); + this.aeItemHandler.getInventory()[i].setConfig(WrappedItemStack.fromNBT(configTag)); + } else { + this.aeItemHandler.getInventory()[i].setConfig(null); } - return result; } - return ItemStack.EMPTY; } - - @Override - public IAEItemStack requestStack() { - IAEItemStack result = super.requestStack(); - if (result instanceof WrappedItemStack) { - return ((WrappedItemStack) result).getAEStack(); - } else { - return result; - } - } - - @Override - public IAEItemStack exceedStack() { - IAEItemStack result = super.exceedStack(); - if (result instanceof WrappedItemStack) { - return ((WrappedItemStack) result).getAEStack(); - } else { - return result; - } - } - - @Override - public void addStack(IAEItemStack stack) { - if (this.stock == null) { - this.stock = WrappedItemStack.fromItemStack(stack.createItemStack()); - } else { - this.stock.add(stack); - } - this.trigger.accept(0); - } - - @Override - public int getSlotLimit(int slot) { - return Integer.MAX_VALUE; + if (tag.hasKey("GhostCircuit")) { + this.setGhostCircuitConfig(tag.getByte("GhostCircuit")); } } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java index 9a6dfa4f6aa..2bcdc10f542 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java @@ -3,16 +3,19 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.GregtechTileCapabilities; -import gregtech.api.capability.INotifiableHandler; +import gregtech.api.capability.IDataStickIntractable; import gregtech.api.capability.impl.FluidTankList; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.ImageWidget; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.client.renderer.texture.Textures; import gregtech.common.gui.widget.appeng.AEFluidConfigWidget; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidSlot; import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; import net.minecraft.client.resources.I18n; @@ -24,122 +27,129 @@ import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidTank; -import net.minecraftforge.fluids.capability.FluidTankProperties; -import net.minecraftforge.fluids.capability.IFluidHandler; -import net.minecraftforge.fluids.capability.IFluidTankProperties; import appeng.api.config.Actionable; import appeng.api.storage.IMEMonitor; +import appeng.api.storage.channels.IFluidStorageChannel; import appeng.api.storage.data.IAEFluidStack; -import appeng.me.GridAccessException; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; -/** - * @Author GlodBlock - * @Description The Input Hatch that can auto fetch fluid ME storage network. - * @Date 2023/4/20-21:21 - */ -public class MetaTileEntityMEInputHatch extends MetaTileEntityAEHostablePart - implements IMultiblockAbilityPart { +public class MetaTileEntityMEInputHatch extends MetaTileEntityAEHostablePart + implements IMultiblockAbilityPart, IDataStickIntractable { public final static String FLUID_BUFFER_TAG = "FluidTanks"; public final static String WORKING_TAG = "WorkingEnabled"; private final static int CONFIG_SIZE = 16; - private boolean workingEnabled; - private ExportOnlyAEFluid[] aeFluidTanks; + private boolean workingEnabled = true; + protected ExportOnlyAEFluidList aeFluidHandler; public MetaTileEntityMEInputHatch(ResourceLocation metaTileEntityId) { - super(metaTileEntityId, GTValues.UHV, false); - this.workingEnabled = true; + this(metaTileEntityId, GTValues.EV); + } + + protected MetaTileEntityMEInputHatch(ResourceLocation metaTileEntityId, int tier) { + super(metaTileEntityId, tier, false, IFluidStorageChannel.class); + } + + protected ExportOnlyAEFluidList getAEFluidHandler() { + if (aeFluidHandler == null) { + aeFluidHandler = new ExportOnlyAEFluidList(this, CONFIG_SIZE, this.getController()); + } + return aeFluidHandler; } @Override protected void initializeInventory() { - this.aeFluidTanks = new ExportOnlyAEFluid[CONFIG_SIZE]; - for (int i = 0; i < CONFIG_SIZE; i++) { - this.aeFluidTanks[i] = new ExportOnlyAEFluid(this, null, null, this.getController()); - } + getAEFluidHandler(); // initialize it super.initializeInventory(); } @Override protected FluidTankList createImportFluidHandler() { - return new FluidTankList(false, this.aeFluidTanks); + return new FluidTankList(false, getAEFluidHandler().getInventory()); } @Override public void update() { super.update(); - if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME()) { - if (this.updateMEStatus()) { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(FLUID_NET); - for (ExportOnlyAEFluid aeTank : this.aeFluidTanks) { - // Try to clear the wrong fluid - IAEFluidStack exceedFluid = aeTank.exceedStack(); - if (exceedFluid != null) { - long total = exceedFluid.getStackSize(); - IAEFluidStack notInserted = aeNetwork.injectItems(exceedFluid, Actionable.MODULATE, - this.getActionSource()); - if (notInserted != null && notInserted.getStackSize() > 0) { - aeTank.drain((int) (total - notInserted.getStackSize()), true); - continue; - } else { - aeTank.drain((int) total, true); - } - } - // Fill it - IAEFluidStack reqFluid = aeTank.requestStack(); - if (reqFluid != null) { - IAEFluidStack extracted = aeNetwork.extractItems(reqFluid, Actionable.MODULATE, - this.getActionSource()); - if (extracted != null) { - aeTank.addStack(extracted); - } - } - } - } catch (GridAccessException ignore) {} - } + if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME() && updateMEStatus()) { + syncME(); } } - @Override - public void onRemoval() { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(FLUID_NET); - for (ExportOnlyAEFluid aeTank : this.aeFluidTanks) { - IAEFluidStack stock = aeTank.stock; - if (stock instanceof WrappedFluidStack) { - stock = ((WrappedFluidStack) stock).getAEStack(); + protected void syncME() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEFluidSlot aeTank : this.getAEFluidHandler().getInventory()) { + // Try to clear the wrong fluid + IAEFluidStack exceedFluid = aeTank.exceedStack(); + if (exceedFluid != null) { + long total = exceedFluid.getStackSize(); + IAEFluidStack notInserted = monitor.injectItems(exceedFluid, Actionable.MODULATE, + this.getActionSource()); + if (notInserted != null && notInserted.getStackSize() > 0) { + aeTank.drain((int) (total - notInserted.getStackSize()), true); + continue; + } else { + aeTank.drain((int) total, true); } - if (stock != null) { - aeNetwork.injectItems(stock, Actionable.MODULATE, this.getActionSource()); + } + // Fill it + IAEFluidStack reqFluid = aeTank.requestStack(); + if (reqFluid != null) { + IAEFluidStack extracted = monitor.extractItems(reqFluid, Actionable.MODULATE, this.getActionSource()); + if (extracted != null) { + aeTank.addStack(extracted); } } - } catch (GridAccessException ignore) {} + } + } + + @Override + public void onRemoval() { + flushInventory(); super.onRemoval(); } + protected void flushInventory() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEFluidSlot aeTank : this.getAEFluidHandler().getInventory()) { + IAEFluidStack stock = aeTank.getStock(); + if (stock instanceof WrappedFluidStack) { + stock = ((WrappedFluidStack) stock).getAEStack(); + } + if (stock != null) { + monitor.injectItems(stock, Actionable.MODULATE, this.getActionSource()); + } + } + } + @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity iGregTechTileEntity) { return new MetaTileEntityMEInputHatch(this.metaTileEntityId); } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { + protected final ModularUI createUI(EntityPlayer player) { + ModularUI.Builder builder = createUITemplate(player); + return builder.build(this.getHolder(), player); + } + + protected ModularUI.Builder createUITemplate(EntityPlayer player) { ModularUI.Builder builder = ModularUI .builder(GuiTextures.BACKGROUND, 176, 18 + 18 * 4 + 94) .label(10, 5, getMetaFullName()); @@ -147,13 +157,21 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { builder.dynamicLabel(10, 15, () -> this.isOnline ? I18n.format("gregtech.gui.me_network.online") : I18n.format("gregtech.gui.me_network.offline"), - 0xFFFFFFFF); + 0x404040); // Config slots - builder.widget(new AEFluidConfigWidget(16, 25, this.aeFluidTanks)); + builder.widget(new AEFluidConfigWidget(7, 25, this.getAEFluidHandler())); + + // Arrow image + builder.image(7 + 18 * 4, 25 + 18, 18, 18, GuiTextures.ARROW_DOUBLE); - builder.bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT, 7, 18 + 18 * 4 + 12); - return builder.build(this.getHolder(), entityPlayer); + // GT Logo, cause there's some free real estate + builder.widget(new ImageWidget(7 + 18 * 4, 25 + 18 * 3, 17, 17, + GTValues.XMAS.get() ? GuiTextures.GREGTECH_LOGO_XMAS : GuiTextures.GREGTECH_LOGO) + .setIgnoreColor(true)); + + builder.bindPlayerInventory(player.inventory, GuiTextures.SLOT, 7, 18 + 18 * 4 + 12); + return builder; } @Override @@ -196,7 +214,7 @@ public NBTTagCompound writeToNBT(NBTTagCompound data) { data.setBoolean(WORKING_TAG, this.workingEnabled); NBTTagList tanks = new NBTTagList(); for (int i = 0; i < CONFIG_SIZE; i++) { - ExportOnlyAEFluid tank = this.aeFluidTanks[i]; + ExportOnlyAEFluidSlot tank = this.getAEFluidHandler().getInventory()[i]; NBTTagCompound tankTag = new NBTTagCompound(); tankTag.setInteger("slot", i); tankTag.setTag("tank", tank.serializeNBT()); @@ -216,7 +234,7 @@ public void readFromNBT(NBTTagCompound data) { NBTTagList tanks = (NBTTagList) data.getTag(FLUID_BUFFER_TAG); for (NBTBase nbtBase : tanks) { NBTTagCompound tankTag = (NBTTagCompound) nbtBase; - ExportOnlyAEFluid tank = this.aeFluidTanks[tankTag.getInteger("slot")]; + ExportOnlyAEFluidSlot tank = this.getAEFluidHandler().getInventory()[tankTag.getInteger("slot")]; tank.deserializeNBT(tankTag.getCompoundTag("tank")); } } @@ -226,7 +244,11 @@ public void readFromNBT(NBTTagCompound data) { public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { super.renderMetaTileEntity(renderState, translation, pipeline); if (this.shouldRenderOverlay()) { - Textures.ME_INPUT_HATCH.renderSided(getFrontFacing(), renderState, translation, pipeline); + if (isOnline) { + Textures.ME_INPUT_HATCH_ACTIVE.renderSided(getFrontFacing(), renderState, translation, pipeline); + } else { + Textures.ME_INPUT_HATCH.renderSided(getFrontFacing(), renderState, translation, pipeline); + } } } @@ -236,6 +258,9 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.fluid_hatch.import.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.fluid_import.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me_import_fluid_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.copy_paste.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.extra_connections.tooltip")); tooltip.add(I18n.format("gregtech.universal.enabled")); } @@ -246,157 +271,59 @@ public MultiblockAbility getAbility() { @Override public void registerAbilities(List list) { - list.addAll(Arrays.asList(this.aeFluidTanks)); + list.addAll(Arrays.asList(this.getAEFluidHandler().getInventory())); } - public static class ExportOnlyAEFluid extends ExportOnlyAESlot - implements IFluidTank, INotifiableHandler, IFluidHandler { - - private final List notifiableEntities = new ArrayList<>(); - private MetaTileEntity holder; - - public ExportOnlyAEFluid(MetaTileEntity holder, IAEFluidStack config, IAEFluidStack stock, MetaTileEntity mte) { - super(config, stock); - this.holder = holder; - this.notifiableEntities.add(mte); - } - - public ExportOnlyAEFluid() { - super(); - } - - @Override - public IAEFluidStack requestStack() { - IAEFluidStack result = super.requestStack(); - if (result instanceof WrappedFluidStack) { - return ((WrappedFluidStack) result).getAEStack(); - } else { - return result; - } - } - - @Override - public IAEFluidStack exceedStack() { - IAEFluidStack result = super.exceedStack(); - if (result instanceof WrappedFluidStack) { - return ((WrappedFluidStack) result).getAEStack(); - } else { - return result; - } - } - - @Override - public void addStack(IAEFluidStack stack) { - if (this.stock == null) { - this.stock = WrappedFluidStack.fromFluidStack(stack.getFluidStack()); - } else { - this.stock.add(stack); - } - trigger(); - } - - @Override - public void deserializeNBT(NBTTagCompound nbt) { - if (nbt.hasKey(CONFIG_TAG)) { - this.config = WrappedFluidStack.fromNBT(nbt.getCompoundTag(CONFIG_TAG)); - } - if (nbt.hasKey(STOCK_TAG)) { - this.stock = WrappedFluidStack.fromNBT(nbt.getCompoundTag(STOCK_TAG)); - } - } - - @Nullable - @Override - public FluidStack getFluid() { - if (this.stock != null && this.stock instanceof WrappedFluidStack) { - return ((WrappedFluidStack) this.stock).getDelegate(); - } - return null; - } - - @Override - public int getFluidAmount() { - return this.stock != null ? (int) this.stock.getStackSize() : 0; - } - - @Override - public int getCapacity() { - // Its capacity is always 0. - return 0; - } - - @Override - public FluidTankInfo getInfo() { - return new FluidTankInfo(this); - } - - @Override - public IFluidTankProperties[] getTankProperties() { - return new IFluidTankProperties[] { - new FluidTankProperties(this.getFluid(), 0) - }; - } - - @Override - public int fill(FluidStack resource, boolean doFill) { - return 0; - } - - @Nullable - @Override - public FluidStack drain(FluidStack resource, boolean doDrain) { - if (this.getFluid() != null && this.getFluid().isFluidEqual(resource)) { - return this.drain(resource.amount, doDrain); - } - return null; - } + @Override + public final void onDataStickLeftClick(EntityPlayer player, ItemStack dataStick) { + NBTTagCompound tag = new NBTTagCompound(); + tag.setTag("MEInputHatch", writeConfigToTag()); + dataStick.setTagCompound(tag); + dataStick.setTranslatableName("gregtech.machine.me.fluid_import.data_stick.name"); + player.sendStatusMessage(new TextComponentTranslation("gregtech.machine.me.import_copy_settings"), true); + } - @Nullable - @Override - public FluidStack drain(int maxDrain, boolean doDrain) { - if (this.stock == null) { - return null; - } - int drained = (int) Math.min(this.stock.getStackSize(), maxDrain); - FluidStack result = new FluidStack(this.stock.getFluid(), drained); - if (doDrain) { - this.stock.decStackSize(drained); - if (this.stock.getStackSize() == 0) { - this.stock = null; - } - trigger(); + protected NBTTagCompound writeConfigToTag() { + NBTTagCompound tag = new NBTTagCompound(); + NBTTagCompound configStacks = new NBTTagCompound(); + tag.setTag("ConfigStacks", configStacks); + for (int i = 0; i < CONFIG_SIZE; i++) { + var slot = this.aeFluidHandler.getInventory()[i]; + IAEFluidStack config = slot.getConfig(); + if (config == null) { + continue; } - return result; - } - - @Override - public void addNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { - this.notifiableEntities.add(metaTileEntity); + NBTTagCompound stackNbt = new NBTTagCompound(); + config.writeToNBT(stackNbt); + configStacks.setTag(Integer.toString(i), stackNbt); } + return tag; + } - @Override - public void removeNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { - this.notifiableEntities.remove(metaTileEntity); + @Override + public final boolean onDataStickRightClick(EntityPlayer player, ItemStack dataStick) { + NBTTagCompound tag = dataStick.getTagCompound(); + if (tag == null || !tag.hasKey("MEInputHatch")) { + return false; } + readConfigFromTag(tag.getCompoundTag("MEInputHatch")); + syncME(); + player.sendStatusMessage(new TextComponentTranslation("gregtech.machine.me.import_paste_settings"), true); + return true; + } - private void trigger() { - for (MetaTileEntity metaTileEntity : this.notifiableEntities) { - if (metaTileEntity != null && metaTileEntity.isValid()) { - this.addToNotifiedList(metaTileEntity, this, false); + protected void readConfigFromTag(NBTTagCompound tag) { + if (tag.hasKey("ConfigStacks")) { + NBTTagCompound configStacks = tag.getCompoundTag("ConfigStacks"); + for (int i = 0; i < CONFIG_SIZE; i++) { + String key = Integer.toString(i); + if (configStacks.hasKey(key)) { + NBTTagCompound configTag = configStacks.getCompoundTag(key); + this.aeFluidHandler.getInventory()[i].setConfig(WrappedFluidStack.fromNBT(configTag)); + } else { + this.aeFluidHandler.getInventory()[i].setConfig(null); } } - if (holder != null) { - holder.markDirty(); - } - } - - @Override - public ExportOnlyAEFluid copy() { - return new ExportOnlyAEFluid( - this.holder, - this.config == null ? null : this.config.copy(), - this.stock == null ? null : this.stock.copy(), - null); } } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java index 92277985603..9e008b857e3 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java @@ -30,9 +30,9 @@ import appeng.api.config.Actionable; import appeng.api.storage.IMEMonitor; +import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IItemList; -import appeng.me.GridAccessException; import appeng.util.item.AEItemStack; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; @@ -43,22 +43,16 @@ import java.util.ArrayList; import java.util.List; -/** - * @Author GlodBlock - * @Description The Output Bus that can directly send its contents to ME storage network. - * @Date 2023/4/19-20:37 - */ -public class MetaTileEntityMEOutputBus extends MetaTileEntityAEHostablePart +public class MetaTileEntityMEOutputBus extends MetaTileEntityAEHostablePart implements IMultiblockAbilityPart { public final static String ITEM_BUFFER_TAG = "ItemBuffer"; public final static String WORKING_TAG = "WorkingEnabled"; - private boolean workingEnabled; + private boolean workingEnabled = true; private SerializableItemList internalBuffer; public MetaTileEntityMEOutputBus(ResourceLocation metaTileEntityId) { - super(metaTileEntityId, GTValues.UHV, true); - this.workingEnabled = true; + super(metaTileEntityId, GTValues.EV, true, IItemStorageChannel.class); } @Override @@ -70,21 +64,18 @@ protected void initializeInventory() { @Override public void update() { super.update(); - if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME()) { - if (this.updateMEStatus()) { - if (!this.internalBuffer.isEmpty()) { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(ITEM_NET); - for (IAEItemStack item : this.internalBuffer) { - IAEItemStack notInserted = aeNetwork.injectItems(item.copy(), Actionable.MODULATE, - this.getActionSource()); - if (notInserted != null && notInserted.getStackSize() > 0) { - item.setStackSize(notInserted.getStackSize()); - } else { - item.reset(); - } - } - } catch (GridAccessException ignore) {} + if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME() && this.updateMEStatus()) { + if (this.internalBuffer.isEmpty()) return; + + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (IAEItemStack item : this.internalBuffer) { + IAEItemStack notInserted = monitor.injectItems(item.copy(), Actionable.MODULATE, getActionSource()); + if (notInserted != null && notInserted.getStackSize() > 0) { + item.setStackSize(notInserted.getStackSize()); + } else { + item.reset(); } } } @@ -92,12 +83,12 @@ public void update() { @Override public void onRemoval() { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(ITEM_NET); + IMEMonitor monitor = getMonitor(); + if (monitor != null) { for (IAEItemStack item : this.internalBuffer) { - aeNetwork.injectItems(item.copy(), Actionable.MODULATE, this.getActionSource()); + monitor.injectItems(item.copy(), Actionable.MODULATE, this.getActionSource()); } - } catch (GridAccessException ignore) {} + } super.onRemoval(); } @@ -115,7 +106,7 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { builder.dynamicLabel(10, 15, () -> this.isOnline ? I18n.format("gregtech.gui.me_network.online") : I18n.format("gregtech.gui.me_network.offline"), - 0xFFFFFFFF); + 0x404040); builder.label(10, 25, "gregtech.gui.waiting_list", 0xFFFFFFFF); builder.widget(new AEItemGridWidget(10, 35, 3, this.internalBuffer)); @@ -180,7 +171,11 @@ public void readFromNBT(NBTTagCompound data) { public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { super.renderMetaTileEntity(renderState, translation, pipeline); if (this.shouldRenderOverlay()) { - Textures.ME_OUTPUT_BUS.renderSided(getFrontFacing(), renderState, translation, pipeline); + if (isOnline) { + Textures.ME_OUTPUT_BUS_ACTIVE.renderSided(getFrontFacing(), renderState, translation, pipeline); + } else { + Textures.ME_OUTPUT_BUS.renderSided(getFrontFacing(), renderState, translation, pipeline); + } } } @@ -190,7 +185,8 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.item_bus.export.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.item_export.tooltip")); - tooltip.add(I18n.format("gregtech.machine.me.export.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.item_export.tooltip.2")); + tooltip.add(I18n.format("gregtech.machine.me.extra_connections.tooltip")); tooltip.add(I18n.format("gregtech.universal.enabled")); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java index c19e7e1bb51..26a8fcc7947 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java @@ -32,10 +32,10 @@ import appeng.api.config.Actionable; import appeng.api.storage.IMEMonitor; +import appeng.api.storage.channels.IFluidStorageChannel; import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IItemList; import appeng.fluids.util.AEFluidStack; -import appeng.me.GridAccessException; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; @@ -45,22 +45,16 @@ import java.util.ArrayList; import java.util.List; -/** - * @Author GlodBlock - * @Description The Output Hatch that can directly send its contents to ME storage network. - * @Date 2023/4/19-1:18 - */ -public class MetaTileEntityMEOutputHatch extends MetaTileEntityAEHostablePart +public class MetaTileEntityMEOutputHatch extends MetaTileEntityAEHostablePart implements IMultiblockAbilityPart { public final static String FLUID_BUFFER_TAG = "FluidBuffer"; public final static String WORKING_TAG = "WorkingEnabled"; - private boolean workingEnabled; + private boolean workingEnabled = true; private SerializableFluidList internalBuffer; public MetaTileEntityMEOutputHatch(ResourceLocation metaTileEntityId) { - super(metaTileEntityId, GTValues.UHV, true); - this.workingEnabled = true; + super(metaTileEntityId, GTValues.EV, true, IFluidStorageChannel.class); } @Override @@ -72,21 +66,18 @@ protected void initializeInventory() { @Override public void update() { super.update(); - if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME()) { - if (this.updateMEStatus()) { - if (!this.internalBuffer.isEmpty()) { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(FLUID_NET); - for (IAEFluidStack fluid : this.internalBuffer) { - IAEFluidStack notInserted = aeNetwork.injectItems(fluid.copy(), Actionable.MODULATE, - this.getActionSource()); - if (notInserted != null && notInserted.getStackSize() > 0) { - fluid.setStackSize(notInserted.getStackSize()); - } else { - fluid.reset(); - } - } - } catch (GridAccessException ignore) {} + if (!getWorld().isRemote && this.workingEnabled && this.shouldSyncME() && updateMEStatus()) { + if (this.internalBuffer.isEmpty()) return; + + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (IAEFluidStack fluid : this.internalBuffer) { + IAEFluidStack notInserted = monitor.injectItems(fluid.copy(), Actionable.MODULATE, getActionSource()); + if (notInserted != null && notInserted.getStackSize() > 0) { + fluid.setStackSize(notInserted.getStackSize()); + } else { + fluid.reset(); } } } @@ -94,12 +85,12 @@ public void update() { @Override public void onRemoval() { - try { - IMEMonitor aeNetwork = this.getProxy().getStorage().getInventory(FLUID_NET); - for (IAEFluidStack fluid : this.internalBuffer) { - aeNetwork.injectItems(fluid.copy(), Actionable.MODULATE, this.getActionSource()); - } - } catch (GridAccessException ignore) {} + IMEMonitor monitor = getMonitor(); + if (monitor == null) return; + + for (IAEFluidStack fluid : this.internalBuffer) { + monitor.injectItems(fluid.copy(), Actionable.MODULATE, this.getActionSource()); + } super.onRemoval(); } @@ -117,7 +108,7 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { builder.dynamicLabel(10, 15, () -> this.isOnline ? I18n.format("gregtech.gui.me_network.online") : I18n.format("gregtech.gui.me_network.offline"), - 0xFFFFFFFF); + 0x404040); builder.label(10, 25, "gregtech.gui.waiting_list", 0xFFFFFFFF); builder.widget(new AEFluidGridWidget(10, 35, 3, this.internalBuffer)); @@ -182,7 +173,11 @@ public void readFromNBT(NBTTagCompound data) { public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { super.renderMetaTileEntity(renderState, translation, pipeline); if (this.shouldRenderOverlay()) { - Textures.ME_OUTPUT_HATCH.renderSided(getFrontFacing(), renderState, translation, pipeline); + if (isOnline) { + Textures.ME_OUTPUT_HATCH_ACTIVE.renderSided(getFrontFacing(), renderState, translation, pipeline); + } else { + Textures.ME_OUTPUT_HATCH.renderSided(getFrontFacing(), renderState, translation, pipeline); + } } } @@ -192,7 +187,8 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.fluid_hatch.export.tooltip")); tooltip.add(I18n.format("gregtech.machine.me.fluid_export.tooltip")); - tooltip.add(I18n.format("gregtech.machine.me.export.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.fluid_export.tooltip.2")); + tooltip.add(I18n.format("gregtech.machine.me.extra_connections.tooltip")); tooltip.add(I18n.format("gregtech.universal.enabled")); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java new file mode 100644 index 00000000000..70fb8de03c3 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingBus.java @@ -0,0 +1,456 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng; + +import gregtech.api.GTValues; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.ImageCycleButtonWidget; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEItemSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; + +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.world.World; + +import appeng.api.config.Actionable; +import appeng.api.storage.IMEMonitor; +import appeng.api.storage.data.IAEItemStack; +import appeng.api.storage.data.IItemList; +import codechicken.lib.raytracer.CuboidRayTraceResult; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.function.Predicate; + +import static gregtech.api.capability.GregtechDataCodes.UPDATE_AUTO_PULL; + +public class MetaTileEntityMEStockingBus extends MetaTileEntityMEInputBus { + + private static final int CONFIG_SIZE = 16; + private boolean autoPull; + private Predicate autoPullTest; + + public MetaTileEntityMEStockingBus(ResourceLocation metaTileEntityId) { + super(metaTileEntityId, GTValues.LuV); + this.autoPullTest = $ -> false; + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MetaTileEntityMEStockingBus(metaTileEntityId); + } + + @Override + protected ExportOnlyAEStockingItemList getAEItemHandler() { + if (this.aeItemHandler == null) { + this.aeItemHandler = new ExportOnlyAEStockingItemList(this, CONFIG_SIZE, getController()); + } + return (ExportOnlyAEStockingItemList) this.aeItemHandler; + } + + @Override + public void update() { + super.update(); + if (!getWorld().isRemote) { + if (isWorkingEnabled() && autoPull && getOffsetTimer() % 100 == 0) { + refreshList(); + syncME(); + } + + // Immediately clear cached items if the status changed, to prevent running recipes while offline + if (this.meStatusChanged && !this.isOnline) { + if (autoPull) { + clearInventory(0); + } else { + for (int i = 0; i < CONFIG_SIZE; i++) { + getAEItemHandler().getInventory()[i].setStack(null); + } + } + } + } + } + + // Update the visual display for the fake items. This also is important for the item handler's + // getStackInSlot() method, as it uses the cached items set here. + @Override + protected void syncME() { + IMEMonitor monitor = super.getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEStockingItemSlot slot : this.getAEItemHandler().getInventory()) { + if (slot.getConfig() == null) { + slot.setStack(null); + } else { + // Try to fill the slot + IAEItemStack request; + if (slot.getConfig() instanceof WrappedItemStack wis) { + request = wis.getAEStack(); + } else { + request = slot.getConfig().copy(); + } + request.setStackSize(Integer.MAX_VALUE); + IAEItemStack result = monitor.extractItems(request, Actionable.SIMULATE, getActionSource()); + slot.setStack(result); + } + } + } + + @Override + protected void flushInventory() { + // no-op, nothing to send back to the network + } + + @Override + public void addToMultiBlock(MultiblockControllerBase controllerBase) { + super.addToMultiBlock(controllerBase); + // ensure that no other stocking bus on this multiblock is configured to hold the same item. + // that we have in our own bus. + this.autoPullTest = stack -> !this.testConfiguredInOtherBus(stack); + // also ensure that our current config is valid given other inputs + validateConfig(); + } + + @Override + public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { + // block auto-pull from working when not in a formed multiblock + this.autoPullTest = $ -> false; + if (this.autoPull) { + // may as well clear if we are auto-pull, no reason to preserve the config + this.getAEItemHandler().clearConfig(); + } + super.removeFromMultiBlock(controllerBase); + } + + @Override + public void onDistinctChange(boolean newValue) { + super.onDistinctChange(newValue); + if (!getWorld().isRemote && !newValue) { + // Ensure that our configured items won't match any other buses in the multiblock. + // Needed since we allow duplicates in distinct mode on, but not off + validateConfig(); + } + } + + /** + * Test for if any of our configured items are in another stocking bus on the multi + * we are attached to. Prevents dupes in certain situations. + */ + private void validateConfig() { + for (var slot : this.getAEItemHandler().getInventory()) { + if (slot.getConfig() != null) { + ItemStack configuredStack = slot.getConfig().createItemStack(); + if (testConfiguredInOtherBus(configuredStack)) { + slot.setConfig(null); + slot.setStock(null); + } + } + } + } + + /** + * @return True if the passed stack is found as a configuration in any other stocking buses on the multiblock. + */ + private boolean testConfiguredInOtherBus(ItemStack stack) { + if (stack == null || stack.isEmpty()) return false; + MultiblockControllerBase controller = getController(); + if (controller == null) return false; + + // In distinct mode, we don't need to check other buses since only one bus can run a recipe at a time. + if (!(controller instanceof RecipeMapMultiblockController rmmc) || !rmmc.isDistinct()) { + // Otherwise, we need to test for if the item is configured + // in any stocking bus in the multi (besides ourselves). + var abilityList = controller.getAbilities(MultiblockAbility.IMPORT_ITEMS); + for (var ability : abilityList) { + if (ability instanceof ExportOnlyAEStockingItemList aeList) { + // We don't need to check for ourselves, as this case is handled elsewhere. + if (aeList == this.aeItemHandler) continue; + if (aeList.hasStackInConfig(stack, false)) { + return true; + } + } + } + } + return false; + } + + private void setAutoPull(boolean autoPull) { + this.autoPull = autoPull; + markDirty(); + if (!getWorld().isRemote) { + if (!this.autoPull) { + this.getAEItemHandler().clearConfig(); + } else if (updateMEStatus()) { + this.refreshList(); + syncME(); + } + writeCustomData(UPDATE_AUTO_PULL, buf -> buf.writeBoolean(this.autoPull)); + } + } + + /** + * Refresh the configuration list in auto-pull mode. + * Sets the config to the first 16 valid items found in the network. + */ + private void refreshList() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) { + clearInventory(0); + return; + } + + IItemList storageList = monitor.getStorageList(); + if (storageList == null) { + clearInventory(0); + return; + } + + int index = 0; + for (IAEItemStack stack : storageList) { + if (index >= CONFIG_SIZE) break; + if (stack.getStackSize() == 0) continue; + stack = monitor.extractItems(stack, Actionable.SIMULATE, getActionSource()); + if (stack == null || stack.getStackSize() == 0) continue; + + ItemStack itemStack = stack.createItemStack(); + if (itemStack == null || itemStack.isEmpty()) continue; + // Ensure that it is valid to configure with this stack + if (autoPullTest != null && !autoPullTest.test(itemStack)) continue; + IAEItemStack selectedStack = WrappedItemStack.fromItemStack(itemStack); + if (selectedStack == null) continue; + IAEItemStack configStack = selectedStack.copy().setStackSize(1); + var slot = this.getAEItemHandler().getInventory()[index]; + slot.setConfig(configStack); + slot.setStack(selectedStack); + index++; + } + + clearInventory(index); + } + + private void clearInventory(int startIndex) { + for (int i = startIndex; i < CONFIG_SIZE; i++) { + var slot = this.getAEItemHandler().getInventory()[i]; + slot.setConfig(null); + slot.setStack(null); + } + } + + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == UPDATE_AUTO_PULL) { + this.autoPull = buf.readBoolean(); + } + } + + @Override + protected ModularUI.Builder createUITemplate(EntityPlayer player) { + ModularUI.Builder builder = super.createUITemplate(player); + builder.widget(new ImageCycleButtonWidget(7 + 18 * 4 + 1, 26, 16, 16, GuiTextures.BUTTON_AUTO_PULL, + () -> autoPull, this::setAutoPull).setTooltipHoverString("gregtech.gui.me_bus.auto_pull_button")); + return builder; + } + + @Override + public boolean onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, + CuboidRayTraceResult hitResult) { + if (!getWorld().isRemote) { + setAutoPull(!autoPull); + if (autoPull) { + playerIn.sendStatusMessage( + new TextComponentTranslation("gregtech.machine.me.stocking_auto_pull_enabled"), false); + } else { + playerIn.sendStatusMessage( + new TextComponentTranslation("gregtech.machine.me.stocking_auto_pull_disabled"), false); + } + } + return true; + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + data.setBoolean("AutoPull", autoPull); + return data; + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + this.autoPull = data.getBoolean("AutoPull"); + } + + @Override + public void writeInitialSyncData(PacketBuffer buf) { + super.writeInitialSyncData(buf); + buf.writeBoolean(autoPull); + } + + @Override + public void receiveInitialSyncData(PacketBuffer buf) { + super.receiveInitialSyncData(buf); + this.autoPull = buf.readBoolean(); + } + + private static class ExportOnlyAEStockingItemSlot extends ExportOnlyAEItemSlot { + + private final MetaTileEntityMEStockingBus holder; + + public ExportOnlyAEStockingItemSlot(IAEItemStack config, IAEItemStack stock, + MetaTileEntityMEStockingBus holder) { + super(config, stock); + this.holder = holder; + } + + public ExportOnlyAEStockingItemSlot(MetaTileEntityMEStockingBus holder) { + super(); + this.holder = holder; + } + + @Override + public ExportOnlyAEStockingItemSlot copy() { + return new ExportOnlyAEStockingItemSlot( + this.config == null ? null : this.config.copy(), + this.stock == null ? null : this.stock.copy(), + this.holder); + } + + @Override + public @NotNull ItemStack extractItem(int slot, int amount, boolean simulate) { + if (slot == 0 && this.stock != null) { + if (this.config != null) { + // Extract the items from the real net to either validate (simulate) + // or extract (modulate) when this is called + IMEMonitor monitor = holder.getMonitor(); + if (monitor == null) return ItemStack.EMPTY; + + Actionable action = simulate ? Actionable.SIMULATE : Actionable.MODULATE; + IAEItemStack request; + if (this.config instanceof WrappedItemStack wis) { + request = wis.getAEStack(); + } else { + request = this.config.copy(); + } + request.setStackSize(amount); + + IAEItemStack result = monitor.extractItems(request, action, holder.getActionSource()); + if (result != null) { + int extracted = (int) Math.min(result.getStackSize(), amount); + this.stock.decStackSize(extracted); // may as well update the display here + if (this.trigger != null) { + this.trigger.accept(0); + } + if (extracted != 0) { + ItemStack resultStack = this.config.createItemStack(); + resultStack.setCount(extracted); + return resultStack; + } + } + } + } + return ItemStack.EMPTY; + } + } + + @Override + public void addInformation(ItemStack stack, @Nullable World player, @NotNull List tooltip, + boolean advanced) { + tooltip.add(I18n.format("gregtech.machine.item_bus.import.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.stocking_item.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me_import_item_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.copy_paste.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.stocking_item.tooltip.2")); + tooltip.add(I18n.format("gregtech.machine.me.extra_connections.tooltip")); + tooltip.add(I18n.format("gregtech.universal.enabled")); + } + + @Override + protected NBTTagCompound writeConfigToTag() { + if (!autoPull) { + NBTTagCompound tag = super.writeConfigToTag(); + tag.setBoolean("AutoPull", false); + return tag; + } + // if in auto-pull, no need to write actual configured slots, but still need to write the ghost circuit + NBTTagCompound tag = new NBTTagCompound(); + tag.setBoolean("AutoPull", true); + tag.setByte("GhostCircuit", (byte) this.circuitInventory.getCircuitValue()); + return tag; + } + + @Override + protected void readConfigFromTag(NBTTagCompound tag) { + if (tag.getBoolean("AutoPull")) { + // if being set to auto-pull, no need to read the configured slots + this.setAutoPull(true); + this.setGhostCircuitConfig(tag.getByte("GhostCircuit")); + return; + } + // set auto pull first to avoid issues with clearing the config after reading from the data stick + this.setAutoPull(false); + super.readConfigFromTag(tag); + } + + private static class ExportOnlyAEStockingItemList extends ExportOnlyAEItemList { + + private final MetaTileEntityMEStockingBus holder; + + public ExportOnlyAEStockingItemList(MetaTileEntityMEStockingBus holder, int slots, + MetaTileEntity entityToNotify) { + super(holder, slots, entityToNotify); + this.holder = holder; + } + + @Override + protected void createInventory(MetaTileEntity holder) { + if (!(holder instanceof MetaTileEntityMEStockingBus stocking)) { + throw new IllegalArgumentException("Cannot create Stocking Item List for nonstocking MetaTileEntity!"); + } + this.inventory = new ExportOnlyAEStockingItemSlot[size]; + for (int i = 0; i < size; i++) { + this.inventory[i] = new ExportOnlyAEStockingItemSlot(stocking); + } + for (ExportOnlyAEItemSlot slot : this.inventory) { + slot.setTrigger(this::onContentsChanged); + } + } + + @Override + public ExportOnlyAEStockingItemSlot[] getInventory() { + return (ExportOnlyAEStockingItemSlot[]) super.getInventory(); + } + + @Override + public boolean isStocking() { + return true; + } + + @Override + public boolean isAutoPull() { + return holder.autoPull; + } + + @Override + public boolean hasStackInConfig(ItemStack stack, boolean checkExternal) { + boolean inThisBus = super.hasStackInConfig(stack, false); + if (inThisBus) return true; + if (checkExternal) { + return holder.testConfiguredInOtherBus(stack); + } + return false; + } + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java new file mode 100644 index 00000000000..f751a05a7a3 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEStockingHatch.java @@ -0,0 +1,415 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng; + +import gregtech.api.GTValues; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.ImageCycleButtonWidget; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidList; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.slot.ExportOnlyAEFluidSlot; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; + +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidStack; + +import appeng.api.config.Actionable; +import appeng.api.storage.IMEMonitor; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IItemList; +import codechicken.lib.raytracer.CuboidRayTraceResult; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.function.Predicate; + +import static gregtech.api.capability.GregtechDataCodes.UPDATE_AUTO_PULL; + +public class MetaTileEntityMEStockingHatch extends MetaTileEntityMEInputHatch { + + private static final int CONFIG_SIZE = 16; + private boolean autoPull; + private Predicate autoPullTest; + + public MetaTileEntityMEStockingHatch(ResourceLocation metaTileEntityId) { + super(metaTileEntityId, GTValues.LuV); + this.autoPullTest = $ -> false; + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity iGregTechTileEntity) { + return new MetaTileEntityMEStockingHatch(metaTileEntityId); + } + + @Override + protected ExportOnlyAEStockingFluidList getAEFluidHandler() { + if (this.aeFluidHandler == null) { + this.aeFluidHandler = new ExportOnlyAEStockingFluidList(this, CONFIG_SIZE, getController()); + } + return (ExportOnlyAEStockingFluidList) this.aeFluidHandler; + } + + @Override + public void update() { + super.update(); + if (!getWorld().isRemote) { + if (isWorkingEnabled() && autoPull && getOffsetTimer() % 100 == 0) { + refreshList(); + syncME(); + } + + // Immediately clear cached fluids if the status changed, to prevent running recipes while offline + if (this.meStatusChanged && !this.isOnline) { + if (autoPull) { + this.getAEFluidHandler().clearConfig(); + } else { + for (int i = 0; i < CONFIG_SIZE; i++) { + getAEFluidHandler().getInventory()[i].setStack(null); + } + } + } + } + } + + @Override + protected void syncME() { + IMEMonitor monitor = super.getMonitor(); + if (monitor == null) return; + + for (ExportOnlyAEStockingFluidSlot slot : this.getAEFluidHandler().getInventory()) { + if (slot.getConfig() == null) { + slot.setStack(null); + } else { + // Try to fill the slot + IAEFluidStack request; + if (slot.getConfig() instanceof WrappedFluidStack wfs) { + request = wfs.getAEStack(); + } else { + request = slot.getConfig().copy(); + } + request.setStackSize(Integer.MAX_VALUE); + IAEFluidStack result = monitor.extractItems(request, Actionable.SIMULATE, getActionSource()); + slot.setStack(result); + } + } + } + + @Override + protected void flushInventory() { + // no-op, nothing to send back to the network + } + + @Override + public void addToMultiBlock(MultiblockControllerBase controllerBase) { + super.addToMultiBlock(controllerBase); + this.autoPullTest = stack -> !this.testConfiguredInOtherHatch(stack); + validateConfig(); + } + + @Override + public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { + this.autoPullTest = $ -> false; + if (this.autoPull) { + this.getAEFluidHandler().clearConfig(); + } + super.removeFromMultiBlock(controllerBase); + } + + private void validateConfig() { + for (var slot : this.getAEFluidHandler().getInventory()) { + if (slot.getConfig() != null) { + FluidStack configuredStack = slot.getConfig().getFluidStack(); + if (testConfiguredInOtherHatch(configuredStack)) { + slot.setConfig(null); + slot.setStock(null); + } + } + } + } + + private boolean testConfiguredInOtherHatch(FluidStack stack) { + if (stack == null) return false; + MultiblockControllerBase controller = getController(); + if (controller == null) return false; + + var abilityList = controller.getAbilities(MultiblockAbility.IMPORT_FLUIDS); + for (var ability : abilityList) { + if (ability instanceof ExportOnlyAEStockingFluidSlot aeSlot) { + if (aeSlot.getConfig() == null) continue; + if (getAEFluidHandler().ownsSlot(aeSlot)) continue; + if (aeSlot.getConfig().getFluid().equals(stack.getFluid())) { + return true; + } + } + } + return false; + } + + private void setAutoPull(boolean autoPull) { + this.autoPull = autoPull; + markDirty(); + if (!getWorld().isRemote) { + if (!this.autoPull) { + this.getAEFluidHandler().clearConfig(); + } else if (updateMEStatus()) { + this.refreshList(); + syncME(); + } + writeCustomData(UPDATE_AUTO_PULL, buf -> buf.writeBoolean(this.autoPull)); + } + } + + private void refreshList() { + IMEMonitor monitor = getMonitor(); + if (monitor == null) { + clearInventory(0); + return; + } + + IItemList storageList = monitor.getStorageList(); + if (storageList == null) { + clearInventory(0); + return; + } + + int index = 0; + for (IAEFluidStack stack : storageList) { + if (index >= CONFIG_SIZE) break; + if (stack.getStackSize() == 0) continue; + stack = monitor.extractItems(stack, Actionable.SIMULATE, getActionSource()); + if (stack == null || stack.getStackSize() == 0) continue; + + FluidStack fluidStack = stack.getFluidStack(); + if (fluidStack == null) continue; + if (autoPullTest != null && !autoPullTest.test(fluidStack)) continue; + IAEFluidStack selectedStack = WrappedFluidStack.fromFluidStack(fluidStack); + IAEFluidStack configStack = selectedStack.copy().setStackSize(1); + var slot = this.getAEFluidHandler().getInventory()[index]; + slot.setConfig(configStack); + slot.setStack(selectedStack); + index++; + } + + clearInventory(index); + } + + private void clearInventory(int startIndex) { + for (int i = startIndex; i < CONFIG_SIZE; i++) { + var slot = this.getAEFluidHandler().getInventory()[i]; + slot.setConfig(null); + slot.setStack(null); + } + } + + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == UPDATE_AUTO_PULL) { + this.autoPull = buf.readBoolean(); + } + } + + @Override + protected ModularUI.Builder createUITemplate(EntityPlayer player) { + ModularUI.Builder builder = super.createUITemplate(player); + builder.widget(new ImageCycleButtonWidget(7 + 18 * 4 + 1, 26, 16, 16, GuiTextures.BUTTON_AUTO_PULL, + () -> autoPull, this::setAutoPull).setTooltipHoverString("gregtech.gui.me_bus.auto_pull_button")); + return builder; + } + + @Override + public boolean onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, + CuboidRayTraceResult hitResult) { + if (!getWorld().isRemote) { + setAutoPull(!autoPull); + if (autoPull) { + playerIn.sendStatusMessage( + new TextComponentTranslation("gregtech.machine.me.stocking_auto_pull_enabled"), false); + } else { + playerIn.sendStatusMessage( + new TextComponentTranslation("gregtech.machine.me.stocking_auto_pull_disabled"), false); + } + } + return true; + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + data.setBoolean("AutoPull", autoPull); + return data; + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + this.autoPull = data.getBoolean("AutoPull"); + } + + @Override + public void writeInitialSyncData(PacketBuffer buf) { + super.writeInitialSyncData(buf); + buf.writeBoolean(autoPull); + } + + @Override + public void receiveInitialSyncData(PacketBuffer buf) { + super.receiveInitialSyncData(buf); + this.autoPull = buf.readBoolean(); + } + + @Override + public void addInformation(ItemStack stack, @Nullable World player, @NotNull List tooltip, + boolean advanced) { + tooltip.add(I18n.format("gregtech.machine.fluid_hatch.import.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.stocking_fluid.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me_import_fluid_hatch.configs.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.copy_paste.tooltip")); + tooltip.add(I18n.format("gregtech.machine.me.stocking_fluid.tooltip.2")); + tooltip.add(I18n.format("gregtech.machine.me.extra_connections.tooltip")); + tooltip.add(I18n.format("gregtech.universal.enabled")); + } + + @Override + protected NBTTagCompound writeConfigToTag() { + if (!autoPull) { + NBTTagCompound tag = super.writeConfigToTag(); + tag.setBoolean("AutoPull", false); + return tag; + } + // if in auto-pull, no need to write actual configured slots, but still need to write the ghost circuit + NBTTagCompound tag = new NBTTagCompound(); + tag.setBoolean("AutoPull", true); + return tag; + } + + @Override + protected void readConfigFromTag(NBTTagCompound tag) { + if (tag.getBoolean("AutoPull")) { + // if being set to auto-pull, no need to read the configured slots + this.setAutoPull(true); + return; + } + // set auto pull first to avoid issues with clearing the config after reading from the data stick + this.setAutoPull(false); + super.readConfigFromTag(tag); + } + + private static class ExportOnlyAEStockingFluidSlot extends ExportOnlyAEFluidSlot { + + public ExportOnlyAEStockingFluidSlot(MetaTileEntityMEStockingHatch holder, IAEFluidStack config, + IAEFluidStack stock, MetaTileEntity entityToNotify) { + super(holder, config, stock, entityToNotify); + } + + public ExportOnlyAEStockingFluidSlot(MetaTileEntityMEStockingHatch holder, MetaTileEntity entityToNotify) { + super(holder, entityToNotify); + } + + @Override + protected MetaTileEntityMEStockingHatch getHolder() { + return (MetaTileEntityMEStockingHatch) super.getHolder(); + } + + @Override + public ExportOnlyAEFluidSlot copy() { + return new ExportOnlyAEStockingFluidSlot( + this.getHolder(), + this.config == null ? null : this.config.copy(), + this.stock == null ? null : this.stock.copy(), + null); + } + + @Override + public @Nullable FluidStack drain(int maxDrain, boolean doDrain) { + if (this.stock == null) { + return null; + } + if (this.config != null) { + IMEMonitor monitor = getHolder().getMonitor(); + if (monitor == null) return null; + + Actionable action = doDrain ? Actionable.MODULATE : Actionable.SIMULATE; + IAEFluidStack request; + if (this.config instanceof WrappedFluidStack wfs) { + request = wfs.getAEStack(); + } else { + request = this.config.copy(); + } + request.setStackSize(maxDrain); + + IAEFluidStack result = monitor.extractItems(request, action, getHolder().getActionSource()); + if (result != null) { + int extracted = (int) Math.min(result.getStackSize(), maxDrain); + this.stock.decStackSize(extracted); + trigger(); + if (extracted != 0) { + FluidStack resultStack = this.config.getFluidStack(); + resultStack.amount = extracted; + return resultStack; + } + } + } + return null; + } + } + + private static class ExportOnlyAEStockingFluidList extends ExportOnlyAEFluidList { + + private final MetaTileEntityMEStockingHatch holder; + + public ExportOnlyAEStockingFluidList(MetaTileEntityMEStockingHatch holder, int slots, + MetaTileEntity entityToNotify) { + super(holder, slots, entityToNotify); + this.holder = holder; + } + + @Override + protected void createInventory(MetaTileEntity holder, MetaTileEntity entityToNotify) { + if (!(holder instanceof MetaTileEntityMEStockingHatch stocking)) { + throw new IllegalArgumentException("Cannot create Stocking Fluid List for nonstocking MetaTileEntity!"); + } + this.inventory = new ExportOnlyAEStockingFluidSlot[size]; + for (int i = 0; i < size; i++) { + this.inventory[i] = new ExportOnlyAEStockingFluidSlot(stocking, entityToNotify); + } + } + + @Override + public ExportOnlyAEStockingFluidSlot[] getInventory() { + return (ExportOnlyAEStockingFluidSlot[]) super.getInventory(); + } + + @Override + public boolean isStocking() { + return true; + } + + @Override + public boolean isAutoPull() { + return holder.autoPull; + } + + @Override + public boolean hasStackInConfig(FluidStack stack, boolean checkExternal) { + boolean inThisHatch = super.hasStackInConfig(stack, false); + if (inThisHatch) return true; + if (checkExternal) { + return holder.testConfiguredInOtherHatch(stack); + } + return false; + } + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidList.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidList.java new file mode 100644 index 00000000000..fd4b40ea7e5 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidList.java @@ -0,0 +1,64 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; + +import gregtech.api.metatileentity.MetaTileEntity; + +import net.minecraftforge.fluids.FluidStack; + +import appeng.api.storage.data.IAEFluidStack; + +public class ExportOnlyAEFluidList { + + protected final int size; + protected ExportOnlyAEFluidSlot[] inventory; + + public ExportOnlyAEFluidList(MetaTileEntity holder, int slots, MetaTileEntity entityToNotify) { + this.size = slots; + createInventory(holder, entityToNotify); + } + + protected void createInventory(MetaTileEntity holder, MetaTileEntity entityToNotify) { + this.inventory = new ExportOnlyAEFluidSlot[size]; + for (int i = 0; i < size; i++) { + this.inventory[i] = new ExportOnlyAEFluidSlot(holder, entityToNotify); + } + } + + public ExportOnlyAEFluidSlot[] getInventory() { + return inventory; + } + + public void clearConfig() { + for (var slot : inventory) { + slot.setConfig(null); + slot.setStock(null); + } + } + + public boolean hasStackInConfig(FluidStack stack, boolean checkExternal) { + if (stack == null) return false; + for (ExportOnlyAEFluidSlot slot : inventory) { + IAEFluidStack config = slot.getConfig(); + if (config != null && config.getFluid().equals(stack.getFluid())) { + return true; + } + } + return false; + } + + public boolean isAutoPull() { + return false; + } + + public boolean isStocking() { + return false; + } + + public boolean ownsSlot(ExportOnlyAEFluidSlot testSlot) { + for (var slot : inventory) { + if (slot == testSlot) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidSlot.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidSlot.java new file mode 100644 index 00000000000..73ad45f9ac4 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEFluidSlot.java @@ -0,0 +1,192 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; + +import gregtech.api.capability.INotifiableHandler; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedFluidStack; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.FluidTankProperties; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.IFluidTankProperties; + +import appeng.api.storage.data.IAEFluidStack; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public class ExportOnlyAEFluidSlot extends ExportOnlyAESlot + implements IFluidTank, INotifiableHandler, IFluidHandler { + + private final List notifiableEntities = new ArrayList<>(); + private MetaTileEntity holder; + + public ExportOnlyAEFluidSlot(MetaTileEntity holder, IAEFluidStack config, IAEFluidStack stock, MetaTileEntity mte) { + super(config, stock); + this.holder = holder; + this.notifiableEntities.add(mte); + } + + public ExportOnlyAEFluidSlot(MetaTileEntity holder, MetaTileEntity entityToNotify) { + this(holder, null, null, entityToNotify); + } + + public ExportOnlyAEFluidSlot() { + super(); + } + + @Override + public IAEFluidStack requestStack() { + IAEFluidStack result = super.requestStack(); + if (result instanceof WrappedFluidStack) { + return ((WrappedFluidStack) result).getAEStack(); + } else { + return result; + } + } + + @Override + public IAEFluidStack exceedStack() { + IAEFluidStack result = super.exceedStack(); + if (result instanceof WrappedFluidStack) { + return ((WrappedFluidStack) result).getAEStack(); + } else { + return result; + } + } + + @Override + public void addStack(IAEFluidStack stack) { + if (this.stock == null) { + this.stock = WrappedFluidStack.fromFluidStack(stack.getFluidStack()); + } else { + this.stock.add(stack); + } + trigger(); + } + + @Override + public void setStack(IAEFluidStack stack) { + if (this.stock == null && stack == null) { + return; + } else if (stack == null) { + this.stock = null; + } else if (this.stock == null || this.stock.getFluid() != stack.getFluid()) { + this.stock = WrappedFluidStack.fromFluidStack(stack.getFluidStack()); + } else if (this.stock.getStackSize() != stack.getStackSize()) { + this.stock.setStackSize(stack.getStackSize()); + } else return; + trigger(); + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + if (nbt.hasKey(CONFIG_TAG)) { + this.config = WrappedFluidStack.fromNBT(nbt.getCompoundTag(CONFIG_TAG)); + } + if (nbt.hasKey(STOCK_TAG)) { + this.stock = WrappedFluidStack.fromNBT(nbt.getCompoundTag(STOCK_TAG)); + } + } + + @Nullable + @Override + public FluidStack getFluid() { + if (this.stock != null && this.stock instanceof WrappedFluidStack) { + return ((WrappedFluidStack) this.stock).getDelegate(); + } + return null; + } + + @Override + public int getFluidAmount() { + return this.stock != null ? (int) this.stock.getStackSize() : 0; + } + + @Override + public int getCapacity() { + // Its capacity is always 0. + return 0; + } + + @Override + public FluidTankInfo getInfo() { + return new FluidTankInfo(this); + } + + @Override + public IFluidTankProperties[] getTankProperties() { + return new IFluidTankProperties[] { + new FluidTankProperties(this.getFluid(), 0) + }; + } + + @Override + public int fill(FluidStack resource, boolean doFill) { + return 0; + } + + @Nullable + @Override + public FluidStack drain(FluidStack resource, boolean doDrain) { + if (this.getFluid() != null && this.getFluid().isFluidEqual(resource)) { + return this.drain(resource.amount, doDrain); + } + return null; + } + + @Nullable + @Override + public FluidStack drain(int maxDrain, boolean doDrain) { + if (this.stock == null) { + return null; + } + int drained = (int) Math.min(this.stock.getStackSize(), maxDrain); + FluidStack result = new FluidStack(this.stock.getFluid(), drained); + if (doDrain) { + this.stock.decStackSize(drained); + if (this.stock.getStackSize() == 0) { + this.stock = null; + } + trigger(); + } + return result; + } + + @Override + public void addNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { + this.notifiableEntities.add(metaTileEntity); + } + + @Override + public void removeNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { + this.notifiableEntities.remove(metaTileEntity); + } + + protected void trigger() { + for (MetaTileEntity metaTileEntity : this.notifiableEntities) { + if (metaTileEntity != null && metaTileEntity.isValid()) { + this.addToNotifiedList(metaTileEntity, this, false); + } + } + if (holder != null) { + holder.markDirty(); + } + } + + @Override + public ExportOnlyAEFluidSlot copy() { + return new ExportOnlyAEFluidSlot( + this.holder, + this.config == null ? null : this.config.copy(), + this.stock == null ? null : this.stock.copy(), + null); + } + + protected MetaTileEntity getHolder() { + return holder; + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemList.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemList.java new file mode 100644 index 00000000000..995670eff15 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemList.java @@ -0,0 +1,126 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; + +import gregtech.api.capability.impl.NotifiableItemStackHandler; +import gregtech.api.metatileentity.MetaTileEntity; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import appeng.api.storage.data.IAEItemStack; +import org.jetbrains.annotations.NotNull; + +public class ExportOnlyAEItemList extends NotifiableItemStackHandler { + + protected final int size; + protected ExportOnlyAEItemSlot[] inventory; + + public ExportOnlyAEItemList(MetaTileEntity holder, int slots, MetaTileEntity entityToNotify) { + super(holder, slots, entityToNotify, false); + this.size = slots; + createInventory(holder); + } + + protected void createInventory(MetaTileEntity holder) { + this.inventory = new ExportOnlyAEItemSlot[size]; + for (int i = 0; i < size; i++) { + this.inventory[i] = new ExportOnlyAEItemSlot(); + } + for (ExportOnlyAEItemSlot slot : this.inventory) { + slot.setTrigger(this::onContentsChanged); + } + } + + public ExportOnlyAEItemSlot[] getInventory() { + return inventory; + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + for (int index = 0; index < size; index++) { + if (nbt.hasKey("#" + index)) { + NBTTagCompound slotTag = nbt.getCompoundTag("#" + index); + this.inventory[index].deserializeNBT(slotTag); + } + } + } + + @Override + public NBTTagCompound serializeNBT() { + NBTTagCompound nbt = new NBTTagCompound(); + for (int index = 0; index < size; index++) { + NBTTagCompound slot = this.inventory[index].serializeNBT(); + nbt.setTag("#" + index, slot); + } + return nbt; + } + + @Override + public void setStackInSlot(int slot, @NotNull ItemStack stack) { + // NO-OP + } + + @Override + public int getSlots() { + return size; + } + + @NotNull + @Override + public ItemStack getStackInSlot(int slot) { + if (slot >= 0 && slot < size) { + return this.inventory[slot].getStackInSlot(0); + } + return ItemStack.EMPTY; + } + + @NotNull + @Override + public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + return stack; + } + + @NotNull + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (slot >= 0 && slot < size) { + return this.inventory[slot].extractItem(0, amount, simulate); + } + return ItemStack.EMPTY; + } + + @Override + public int getSlotLimit(int slot) { + return Integer.MAX_VALUE; + } + + @Override + protected int getStackLimit(int slot, @NotNull ItemStack stack) { + return Integer.MAX_VALUE; + } + + public void clearConfig() { + for (var slot : inventory) { + slot.setConfig(null); + slot.setStock(null); + } + } + + public boolean hasStackInConfig(ItemStack stack, boolean checkExternal) { + if (stack == null || stack.isEmpty()) return false; + for (ExportOnlyAEItemSlot slot : inventory) { + IAEItemStack config = slot.getConfig(); + if (config != null && config.isSameType(stack)) { + return true; + } + } + return false; + } + + public boolean isAutoPull() { + return false; + } + + public boolean isStocking() { + return false; + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemSlot.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemSlot.java new file mode 100644 index 00000000000..1408d77ad49 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAEItemSlot.java @@ -0,0 +1,138 @@ +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; + +import gregtech.common.metatileentities.multi.multiblockpart.appeng.stack.WrappedItemStack; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.items.IItemHandlerModifiable; + +import appeng.api.storage.data.IAEItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Consumer; + +public class ExportOnlyAEItemSlot extends ExportOnlyAESlot implements IItemHandlerModifiable { + + protected Consumer trigger; + + public ExportOnlyAEItemSlot(IAEItemStack config, IAEItemStack stock) { + super(config, stock); + } + + public ExportOnlyAEItemSlot() { + super(); + } + + public void setTrigger(Consumer trigger) { + this.trigger = trigger; + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + if (nbt.hasKey(CONFIG_TAG)) { + this.config = WrappedItemStack.fromNBT(nbt.getCompoundTag(CONFIG_TAG)); + } + if (nbt.hasKey(STOCK_TAG)) { + this.stock = WrappedItemStack.fromNBT(nbt.getCompoundTag(STOCK_TAG)); + } + } + + @Override + public ExportOnlyAEItemSlot copy() { + return new ExportOnlyAEItemSlot( + this.config == null ? null : this.config.copy(), + this.stock == null ? null : this.stock.copy()); + } + + @Override + public void setStackInSlot(int slot, @NotNull ItemStack stack) {} + + @Override + public int getSlots() { + return 1; + } + + @NotNull + @Override + public ItemStack getStackInSlot(int slot) { + if (slot == 0 && this.stock != null) { + return this.stock.getDefinition(); + } + return ItemStack.EMPTY; + } + + @NotNull + @Override + public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + return stack; + } + + @NotNull + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (slot == 0 && this.stock != null) { + int extracted = (int) Math.min(this.stock.getStackSize(), amount); + ItemStack result = this.stock.createItemStack(); + result.setCount(extracted); + if (!simulate) { + this.stock.decStackSize(extracted); + if (this.stock.getStackSize() == 0) { + this.stock = null; + } + } + if (this.trigger != null) { + this.trigger.accept(0); + } + return result; + } + return ItemStack.EMPTY; + } + + @Override + public IAEItemStack requestStack() { + IAEItemStack result = super.requestStack(); + if (result instanceof WrappedItemStack) { + return ((WrappedItemStack) result).getAEStack(); + } else { + return result; + } + } + + @Override + public IAEItemStack exceedStack() { + IAEItemStack result = super.exceedStack(); + if (result instanceof WrappedItemStack) { + return ((WrappedItemStack) result).getAEStack(); + } else { + return result; + } + } + + @Override + public void addStack(IAEItemStack stack) { + if (this.stock == null) { + this.stock = WrappedItemStack.fromItemStack(stack.createItemStack()); + } else { + this.stock.add(stack); + } + this.trigger.accept(0); + } + + @Override + public void setStack(IAEItemStack stack) { + if (this.stock == null && stack == null) { + return; + } else if (stack == null) { + this.stock = null; + } else { + // todo this could maybe be improved with better comparison check + this.stock = WrappedItemStack.fromItemStack(stack.createItemStack()); + } + this.trigger.accept(0); + } + + @Override + public int getSlotLimit(int slot) { + return Integer.MAX_VALUE; + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/ExportOnlyAESlot.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAESlot.java similarity index 94% rename from src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/ExportOnlyAESlot.java rename to src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAESlot.java index 8d5027add51..316a76e422b 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/ExportOnlyAESlot.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/ExportOnlyAESlot.java @@ -1,4 +1,4 @@ -package gregtech.common.metatileentities.multi.multiblockpart.appeng; +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.util.INBTSerializable; @@ -6,11 +6,6 @@ import appeng.api.storage.data.IAEStack; import org.jetbrains.annotations.Nullable; -/** - * @author GlodBlock - * @Description A export only slot to hold {@link IAEStack} - * @date 2023/4/22-13:42 - */ public abstract class ExportOnlyAESlot> implements IConfigurableSlot, INBTSerializable { @@ -64,7 +59,9 @@ public T exceedStack() { return null; } - abstract void addStack(T stack); + public abstract void addStack(T stack); + + public abstract void setStack(T stack); @Override public NBTTagCompound serializeNBT() { diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/IConfigurableSlot.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/IConfigurableSlot.java similarity index 66% rename from src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/IConfigurableSlot.java rename to src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/IConfigurableSlot.java index 6cc3a48771d..9e4532c8f19 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/IConfigurableSlot.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/slot/IConfigurableSlot.java @@ -1,10 +1,5 @@ -package gregtech.common.metatileentities.multi.multiblockpart.appeng; +package gregtech.common.metatileentities.multi.multiblockpart.appeng.slot; -/** - * @Author GlodBlock - * @Description A slot that can be set to keep requesting. - * @Date 2023/4/21-0:34 - */ public interface IConfigurableSlot { T getConfig(); diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/stack/WrappedItemStack.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/stack/WrappedItemStack.java index 854996b0db4..274d4aac26c 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/stack/WrappedItemStack.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/stack/WrappedItemStack.java @@ -191,12 +191,18 @@ public boolean sameOre(IAEItemStack iaeItemStack) { @Override public boolean isSameType(IAEItemStack iaeItemStack) { - return false; + if (iaeItemStack == null) return false; + IAEItemStack aeStack = AEItemStack.fromItemStack(this.delegate); + if (aeStack == null) return false; + return aeStack.isSameType(iaeItemStack); } @Override public boolean isSameType(ItemStack itemStack) { - return false; + if (this.delegate.isEmpty()) return itemStack.isEmpty(); + IAEItemStack aeStack = AEItemStack.fromItemStack(this.delegate); + if (aeStack == null) return false; + return aeStack.isSameType(itemStack); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/hpca/MetaTileEntityHPCAComponent.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/hpca/MetaTileEntityHPCAComponent.java index 4a8da7d2234..dba69e698e8 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/hpca/MetaTileEntityHPCAComponent.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/hpca/MetaTileEntityHPCAComponent.java @@ -5,7 +5,6 @@ import gregtech.api.capability.IHPCAComponentHatch; import gregtech.api.capability.IHPCAComputationProvider; import gregtech.api.capability.IHPCACoolantProvider; -import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.unification.material.Materials; @@ -25,7 +24,6 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; -import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; @@ -63,11 +61,6 @@ protected boolean openGUIOnRightClick() { return false; } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; - } - @Override public MultiblockAbility getAbility() { return MultiblockAbility.HPCA_COMPONENT; @@ -236,7 +229,7 @@ public boolean shouldDropWhenDestroyed() { } @Override - public void getDrops(NonNullList dropsList, @Nullable EntityPlayer harvester) { + public void getDrops(@NotNull List<@NotNull ItemStack> dropsList, @Nullable EntityPlayer harvester) { if (canBeDamaged() && isDamaged()) { if (isAdvanced()) { dropsList.add(MetaBlocks.COMPUTER_CASING diff --git a/src/main/java/gregtech/common/metatileentities/primitive/MetaTileEntityCharcoalPileIgniter.java b/src/main/java/gregtech/common/metatileentities/primitive/MetaTileEntityCharcoalPileIgniter.java index 56a96fb43ca..ecbd0241f1d 100644 --- a/src/main/java/gregtech/common/metatileentities/primitive/MetaTileEntityCharcoalPileIgniter.java +++ b/src/main/java/gregtech/common/metatileentities/primitive/MetaTileEntityCharcoalPileIgniter.java @@ -5,7 +5,6 @@ import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IMultiblockController; import gregtech.api.capability.IWorkable; -import gregtech.api.gui.ModularUI; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.metaitem.stats.IItemBehaviour; import gregtech.api.metatileentity.MetaTileEntity; @@ -13,6 +12,7 @@ import gregtech.api.metatileentity.multiblock.IMultiblockPart; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.pattern.*; +import gregtech.api.util.Mods; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.TooltipHelper; @@ -22,7 +22,6 @@ import net.minecraft.block.Block; import net.minecraft.client.resources.I18n; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.init.SoundEvents; import net.minecraft.item.ItemFireball; @@ -336,11 +335,6 @@ public ICubeRenderer getBaseTexture(IMultiblockPart sourcePart) { return Textures.BRONZE_PLATED_BRICKS; } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; - } - @Override protected boolean openGUIOnRightClick() { return false; @@ -449,7 +443,7 @@ public static void addWallBlock(@NotNull Block block) { } @ZenMethod("addWallBlock") - @Optional.Method(modid = GTValues.MODID_CT) + @Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) @SuppressWarnings("unused") public static void addWallBlockCT(@NotNull IBlock block) { WALL_BLOCKS.add(CraftTweakerMC.getBlock(block)); diff --git a/src/main/java/gregtech/common/metatileentities/steam/SteamMiner.java b/src/main/java/gregtech/common/metatileentities/steam/SteamMiner.java index e3d3c75cb12..3f70bf75aaf 100644 --- a/src/main/java/gregtech/common/metatileentities/steam/SteamMiner.java +++ b/src/main/java/gregtech/common/metatileentities/steam/SteamMiner.java @@ -254,6 +254,7 @@ public void receiveCustomData(int dataId, PacketBuffer buf) { this.minerLogic.receiveCustomData(dataId, buf); } + @Override @SideOnly(Side.CLIENT) public Pair getParticleTexture() { return Pair.of(Textures.STEAM_CASING_BRONZE.getSpriteOnSide(SimpleSidedCubeRenderer.RenderSide.TOP), diff --git a/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamBoiler.java b/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamBoiler.java index a39ebdfff58..3d63eb651ab 100644 --- a/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamBoiler.java +++ b/src/main/java/gregtech/common/metatileentities/steam/boiler/SteamBoiler.java @@ -216,7 +216,7 @@ private void updateCurrentTemperature() { if (fuelBurnTimeLeft % 2 == 0 && currentTemperature < getMaxTemperate()) currentTemperature++; fuelBurnTimeLeft -= isHighPressure ? 2 : 1; - if (fuelBurnTimeLeft == 0) { + if (fuelBurnTimeLeft <= 0) { this.fuelMaxBurnTime = 0; this.timeBeforeCoolingDown = getCooldownInterval(); // boiler has no fuel now, so queue burning state update @@ -306,6 +306,10 @@ public double getTemperaturePercent() { return currentTemperature / (getMaxTemperate() * 1.0); } + public int getCurrentTemperature() { + return currentTemperature; + } + public double getFuelLeftPercent() { return fuelMaxBurnTime == 0 ? 0.0 : fuelBurnTimeLeft / (fuelMaxBurnTime * 1.0); } @@ -372,7 +376,7 @@ public SoundEvent getSound() { } @Override - public void clearMachineInventory(NonNullList itemBuffer) { + public void clearMachineInventory(@NotNull List<@NotNull ItemStack> itemBuffer) { super.clearMachineInventory(itemBuffer); clearInventory(itemBuffer, containerInventory); } 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/metatileentities/steam/multiblockpart/MetaTileEntitySteamItemBus.java b/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamItemBus.java index 97f855406e2..56b15d8c93f 100644 --- a/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamItemBus.java +++ b/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamItemBus.java @@ -26,7 +26,7 @@ import com.cleanroommc.modularui.api.widget.IWidget; import com.cleanroommc.modularui.factory.PosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; -import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandlers; import com.cleanroommc.modularui.widgets.ItemSlot; import com.cleanroommc.modularui.widgets.layout.Grid; @@ -86,7 +86,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, } @Override - public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { guiSyncManager.registerSlotGroup("item_inv", 2); List> widgets = new ArrayList<>(); diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index f5efc438a37..035b741ef76 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -14,7 +14,6 @@ import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.IRecipe; import net.minecraft.util.EnumFacing; -import net.minecraft.util.NonNullList; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.common.ForgeHooks; @@ -24,6 +23,7 @@ import com.google.common.collect.Lists; import java.util.Collections; +import java.util.List; import java.util.Map; public class CraftingRecipeLogic { @@ -111,9 +111,8 @@ public boolean performRecipe(EntityPlayer player) { return false; } ForgeHooks.setCraftingPlayer(player); - NonNullList remainingItems = cachedRecipe.getRemainingItems(inventoryCrafting); // todo right here is - // where tools get - // damaged (in UI) + // todo right here is where tools get damaged (in UI) + List remainingItems = cachedRecipe.getRemainingItems(inventoryCrafting); ForgeHooks.setCraftingPlayer(null); for (int i = 0; i < remainingItems.size(); i++) { ItemStack itemStack = remainingItems.get(i); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityBuffer.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityBuffer.java index a7fa403e9db..1ecb31c1821 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityBuffer.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityBuffer.java @@ -18,9 +18,10 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; -import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.ItemStackHandler; import codechicken.lib.render.CCRenderState; @@ -29,6 +30,7 @@ import codechicken.lib.vec.Matrix4; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -64,6 +66,7 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { } @Override + @SideOnly(Side.CLIENT) public Pair getParticleTexture() { return Pair.of(Textures.VOLTAGE_CASINGS[tier].getParticleSprite(), this.getPaintingColorForRendering()); } @@ -147,7 +150,7 @@ public void addToolUsages(ItemStack stack, @Nullable World world, List t } @Override - public void clearMachineInventory(NonNullList itemBuffer) { + public void clearMachineInventory(@NotNull List<@NotNull ItemStack> itemBuffer) { clearInventory(itemBuffer, itemStackHandler); } } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java index 44859246953..1f00f06818b 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java @@ -19,7 +19,6 @@ import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; -import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; @@ -35,18 +34,18 @@ import com.cleanroommc.modularui.api.widget.IWidget; import com.cleanroommc.modularui.factory.PosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; -import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandlers; import com.cleanroommc.modularui.widgets.ItemSlot; import com.cleanroommc.modularui.widgets.layout.Grid; import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; import static gregtech.api.capability.GregtechDataCodes.IS_TAPED; -import static gregtech.api.capability.GregtechDataCodes.TAG_KEY_PAINTING_COLOR; public class MetaTileEntityCrate extends MetaTileEntity { @@ -75,11 +74,6 @@ public boolean hasFrontFacing() { return false; } - @Override - public int getLightOpacity() { - return 1; - } - @Override public String getHarvestTool() { return ModHandler.isMaterialWood(material) ? ToolClasses.AXE : ToolClasses.WRENCH; @@ -93,7 +87,7 @@ protected void initializeInventory() { } @Override - public void clearMachineInventory(NonNullList itemBuffer) { + public void clearMachineInventory(@NotNull List<@NotNull ItemStack> itemBuffer) { if (!isTaped) { clearInventory(itemBuffer, inventory); } @@ -146,7 +140,7 @@ public boolean usesMui2() { } @Override - public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { guiSyncManager.registerSlotGroup("item_inv", rowSize); int rows = inventorySize / rowSize; diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java index 50dd8dc5cbe..3829ae30586 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java @@ -33,6 +33,7 @@ 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; import java.util.List; @@ -42,26 +43,13 @@ public class MetaTileEntityCreativeChest extends MetaTileEntityQuantumChest { private int itemsPerCycle = 1; private int ticksPerCycle = 1; - private final GTItemStackHandler handler = new GTItemStackHandler(this, 1) { - - @Override - protected int getStackLimit(int slot, ItemStack stack) { - return 1; - } - - @Override - public void setStackInSlot(int slot, ItemStack stack) { - this.validateSlotIndex(slot); - stack.setCount(1); - this.stacks.set(slot, stack); - this.onContentsChanged(slot); - } - }; + private final GTItemStackHandler handler; private boolean active; public MetaTileEntityCreativeChest(ResourceLocation metaTileEntityId) { super(metaTileEntityId, GTValues.MAX, 0); + this.handler = new CreativeItemStackHandler(1); } @Override @@ -69,10 +57,13 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, Textures.QUANTUM_STORAGE_RENDERER.renderMachine(renderState, translation, ArrayUtils.add(pipeline, new ColourMultiplier(GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))), - this.getFrontFacing(), this.getTier()); + this); Textures.CREATIVE_CONTAINER_OVERLAY.renderSided(EnumFacing.UP, renderState, translation, pipeline); Textures.PIPE_OUT_OVERLAY.renderSided(this.getOutputFacing(), renderState, translation, pipeline); - Textures.ITEM_OUTPUT_OVERLAY.renderSided(this.getOutputFacing(), renderState, translation, pipeline); + if (!isConnected() && active) { + Textures.ITEM_OUTPUT_OVERLAY.renderSided(this.getOutputFacing(), renderState, translation, pipeline); + } + renderIndicatorOverlay(renderState, translation, pipeline); } @Override @@ -110,8 +101,14 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { }).setMaxLength(11).setNumbersOnly(1, Integer.MAX_VALUE)); builder.label(7, 65, "gregtech.creative.chest.tpc"); - builder.widget(new CycleButtonWidget(7, 101, 162, 20, () -> active, value -> active = value, - "gregtech.creative.activity.off", "gregtech.creative.activity.on")); + builder.widget(new CycleButtonWidget(7, 101, 162, 20, () -> active, value -> { + active = value; + scheduleRenderUpdate(); + var c = getQuantumController(); + if (c != null) c.updateHandler(); + }, "gregtech.creative.activity.off", "gregtech.creative.activity.on")); + + builder.widget(createConnectedGui(6)); return builder.build(getHolder(), entityPlayer); } @@ -122,7 +119,7 @@ public void update() { this.virtualItemStack = stack; // For rendering purposes super.update(); if (ticksPerCycle == 0 || getOffsetTimer() % ticksPerCycle != 0) return; - if (getWorld().isRemote || !active || stack.isEmpty()) return; + if (getWorld().isRemote || !active || stack.isEmpty() || isConnected()) return; TileEntity tile = getNeighbor(getOutputFacing()); if (tile != null) { @@ -189,8 +186,44 @@ public void addInformation(ItemStack stack, @Nullable World player, List } @Override - public void receiveInitialSyncData(PacketBuffer buf) { + public void receiveInitialSyncData(@NotNull PacketBuffer buf) { super.receiveInitialSyncData(buf); this.handler.setStackInSlot(0, this.virtualItemStack); } + + @Override + public IItemHandler getTypeValue() { + return this.handler; + } + + protected class CreativeItemStackHandler extends GTItemStackHandler { + + CreativeItemStackHandler(int size) { + super(MetaTileEntityCreativeChest.this, size); + } + + @NotNull + @Override + public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + return stack; + } + + @NotNull + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (!active) return ItemStack.EMPTY; + return GTUtility.copy(Math.min(amount, itemsPerCycle), getStackInSlot(0)); + } + + @Override + protected int getStackLimit(int slot, ItemStack stack) { + return 1; + } + + @Override + public void setStackInSlot(int slot, ItemStack stack) { + super.setStackInSlot(slot, stack); + virtualItemStack = GTUtility.copy(1, stack); + } + } } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeEnergy.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeEnergy.java index ec6afb97341..33e9469453d 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeEnergy.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeEnergy.java @@ -29,6 +29,8 @@ import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.ColourMultiplier; @@ -78,6 +80,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, } @Override + @SideOnly(Side.CLIENT) public Pair getParticleTexture() { return Pair.of(Textures.VOLTAGE_CASINGS[this.setTier].getParticleSprite(), this.getPaintingColorForRendering()); } @@ -143,7 +146,7 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { } else { voltage = V[MAX]; amps = Integer.MAX_VALUE; - setTier = 14; + setTier = MAX; } }, "gregtech.creative.energy.sink", "gregtech.creative.energy.source")); @@ -154,6 +157,7 @@ public void setActive(boolean active) { this.active = active; if (!getWorld().isRemote) { writeCustomData(GregtechDataCodes.UPDATE_ACTIVE, buf -> buf.writeBoolean(active)); + markDirty(); } } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java index 1f35630af35..fd2cb5e24e5 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java @@ -25,7 +25,9 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTank; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.FluidTankPropertiesWrapper; import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.IFluidTankProperties; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.ColourMultiplier; @@ -44,7 +46,7 @@ public class MetaTileEntityCreativeTank extends MetaTileEntityQuantumTank { public MetaTileEntityCreativeTank(ResourceLocation metaTileEntityId) { super(metaTileEntityId, GTValues.MAX, -1); - this.fluidTank = new FluidTank(1); + this.fluidTank = new CreativeFluidTank(1); } @Override @@ -52,16 +54,17 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, Textures.QUANTUM_STORAGE_RENDERER.renderMachine(renderState, translation, ArrayUtils.add(pipeline, new ColourMultiplier(GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))), - this.getFrontFacing(), this.getTier()); + this); Textures.CREATIVE_CONTAINER_OVERLAY.renderSided(EnumFacing.UP, renderState, translation, pipeline); if (this.getOutputFacing() != null) { Textures.PIPE_OUT_OVERLAY.renderSided(this.getOutputFacing(), renderState, translation, pipeline); - if (isAutoOutputFluids()) { + if (!isConnected() && active) { Textures.FLUID_OUTPUT_OVERLAY.renderSided(this.getOutputFacing(), renderState, translation, pipeline); } } QuantumStorageRenderer.renderTankFluid(renderState, translation, pipeline, this.fluidTank, getWorld(), getPos(), getFrontFacing()); + renderIndicatorOverlay(renderState, translation, pipeline); } @Override @@ -100,8 +103,14 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { }).setMaxLength(11).setNumbersOnly(1, Integer.MAX_VALUE)); builder.label(7, 65, "gregtech.creative.tank.tpc"); - builder.widget(new CycleButtonWidget(7, 101, 162, 20, () -> active, value -> active = value, - "gregtech.creative.activity.off", "gregtech.creative.activity.on")); + builder.widget(new CycleButtonWidget(7, 101, 162, 20, () -> active, value -> { + active = value; + scheduleRenderUpdate(); + var c = getQuantumController(); + if (c != null) c.updateHandler(); + }, "gregtech.creative.activity.off", "gregtech.creative.activity.on")); + + builder.widget(createConnectedGui(6)); return builder.build(getHolder(), entityPlayer); } @@ -110,7 +119,7 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { public void update() { super.update(); if (ticksPerCycle == 0 || getOffsetTimer() % ticksPerCycle != 0 || fluidTank.getFluid() == null || - getWorld().isRemote || !active) + getWorld().isRemote || !active || isConnected()) return; TileEntity tile = getNeighbor(getOutputFacing()); @@ -121,7 +130,6 @@ public void update() { return; FluidStack stack = fluidTank.getFluid().copy(); - stack.amount = mBPerCycle; int canInsertAmount = fluidHandler.fill(stack, false); stack.amount = Math.min(mBPerCycle, canInsertAmount); @@ -165,4 +173,63 @@ public void addInformation(ItemStack stack, @Nullable World player, List I18n.format("gregtech.creative_tooltip.2") + I18n.format("gregtech.creative_tooltip.3")); // do not append the normal tooltips } + + private class CreativeFluidTank extends FluidTank { + + public CreativeFluidTank(int capacity) { + super(capacity); + } + + @Override + public IFluidTankProperties[] getTankProperties() { + if (this.tankProperties == null) { + this.tankProperties = new IFluidTankProperties[] { + new FluidTankPropertiesWrapper(fluidTank) { + + @Override + public int getCapacity() { + return mBPerCycle; + } + + @Override + public FluidStack getContents() { + if (!active) return null; + var f = super.getContents(); + if (f != null) f.amount = mBPerCycle; + return f; + } + + @Override + public boolean canDrainFluidType(FluidStack fluidStack) { + if (!active) return false; + return super.canDrainFluidType(fluidStack); + } + } + }; + } + return this.tankProperties; + } + + @Override + public FluidStack drain(FluidStack resource, boolean doDrain) { + return drain(resource == null ? 0 : resource.amount, doDrain); + } + + @Override + public FluidStack drain(int maxDrain, boolean doDrain) { + if (!active) return null; + + var f = super.drain(maxDrain, false); + if (f != null) { + f = f.copy(); + f.amount = Math.min(mBPerCycle, maxDrain); + } + return f; + } + + @Override + public int fill(FluidStack resource, boolean doFill) { + return 0; + } + } } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java index ae83ad54a49..a478d5ac3b6 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityDrum.java @@ -3,13 +3,11 @@ import gregtech.api.capability.IPropertyFluidFilter; import gregtech.api.capability.impl.FilteredFluidHandler; import gregtech.api.capability.impl.GTFluidHandlerItemStack; -import gregtech.api.gui.ModularUI; import gregtech.api.items.toolitem.ToolClasses; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.recipes.ModHandler; import gregtech.api.unification.material.Material; -import gregtech.api.unification.material.properties.FluidPipeProperties; import gregtech.api.unification.material.properties.PropertyKey; import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; @@ -44,6 +42,7 @@ import codechicken.lib.vec.Matrix4; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; @@ -53,36 +52,59 @@ public class MetaTileEntityDrum extends MetaTileEntity { + private final IPropertyFluidFilter fluidFilter; + private final boolean isWood; + private final int color; private final int tankSize; - private final Material material; + private FilteredFluidHandler fluidTank; private boolean isAutoOutput = false; - public MetaTileEntityDrum(ResourceLocation metaTileEntityId, Material material, int tankSize) { + /** + * @param metaTileEntityId the id for the MTE + * @param material the material the drum is made of, must have + * {@link gregtech.api.unification.material.properties.FluidProperty}. + * @param tankSize the size of the storage tank + */ + public MetaTileEntityDrum(ResourceLocation metaTileEntityId, @NotNull Material material, int tankSize) { super(metaTileEntityId); + IPropertyFluidFilter filter = material.getProperty(PropertyKey.FLUID_PIPE); + if (filter == null) { + throw new IllegalArgumentException("Material " + material + " requires FluidPipeProperty for Drums"); + } + this.fluidFilter = filter; + this.isWood = ModHandler.isMaterialWood(material); + this.color = material.getMaterialRGB(); this.tankSize = tankSize; - this.material = material; initializeInventory(); } - @Override - public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { - return new MetaTileEntityDrum(metaTileEntityId, material, tankSize); - } - - @Override - public int getLightOpacity() { - return 1; + /** + * + * @param metaTileEntityId the id for the MTE + * @param fluidFilter the filter for which fluids can be stored + * @param isWood if the drum is made of wood + * @param color the color of the drum in RGB format + * @param tankSize the size of the storage tank + */ + public MetaTileEntityDrum(ResourceLocation metaTileEntityId, @NotNull IPropertyFluidFilter fluidFilter, + boolean isWood, int color, int tankSize) { + super(metaTileEntityId); + this.fluidFilter = fluidFilter; + this.isWood = isWood; + this.color = color; + this.tankSize = tankSize; + initializeInventory(); } @Override - public boolean isOpaqueCube() { - return false; + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { + return new MetaTileEntityDrum(metaTileEntityId, fluidFilter, isWood, color, tankSize); } @Override public String getHarvestTool() { - return ModHandler.isMaterialWood(material) ? ToolClasses.AXE : ToolClasses.WRENCH; + return isWood ? ToolClasses.AXE : ToolClasses.WRENCH; } @Override @@ -92,14 +114,14 @@ public boolean hasFrontFacing() { @Override protected void initializeInventory() { - if (this.material == null) return; // call before field initialization, should be called later with fields set - super.initializeInventory(); - IPropertyFluidFilter filter = this.material.getProperty(PropertyKey.FLUID_PIPE); - if (filter == null) { - throw new IllegalArgumentException( - String.format("Material %s requires FluidPipePropety for Drums", material)); + // call before field initialization, should be called later with fields set + if (this.fluidFilter == null) { + return; } - this.fluidInventory = this.fluidTank = new FilteredFluidHandler(tankSize).setFilter(filter); + + super.initializeInventory(); + this.fluidTank = new FilteredFluidHandler(tankSize).setFilter(this.fluidFilter); + this.fluidInventory = this.fluidTank; } @Override @@ -129,7 +151,7 @@ public ICapabilityProvider initItemStackCapabilities(ItemStack itemStack) { } @Override - public void writeInitialSyncData(PacketBuffer buf) { + public void writeInitialSyncData(@NotNull PacketBuffer buf) { super.writeInitialSyncData(buf); FluidStack fluidStack = fluidTank.getFluid(); buf.writeBoolean(fluidStack != null); @@ -142,7 +164,7 @@ public void writeInitialSyncData(PacketBuffer buf) { } @Override - public void receiveInitialSyncData(PacketBuffer buf) { + public void receiveInitialSyncData(@NotNull PacketBuffer buf) { super.receiveInitialSyncData(buf); FluidStack fluidStack = null; if (buf.readBoolean()) { @@ -156,7 +178,7 @@ public void receiveInitialSyncData(PacketBuffer buf) { } @Override - public void receiveCustomData(int dataId, PacketBuffer buf) { + public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { super.receiveCustomData(dataId, buf); if (dataId == UPDATE_AUTO_OUTPUT) { this.isAutoOutput = buf.readBoolean(); @@ -212,27 +234,26 @@ private void toggleOutput() { @Override @SideOnly(Side.CLIENT) public Pair getParticleTexture() { - if (ModHandler.isMaterialWood(material)) { + if (isWood) { return Pair.of(Textures.WOODEN_DRUM.getParticleTexture(), getPaintingColorForRendering()); } else { - int color = ColourRGBA.multiply( - GTUtility.convertRGBtoOpaqueRGBA_CL(material.getMaterialRGB()), - GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering())); - color = GTUtility.convertOpaqueRGBA_CLtoRGB(color); + int color = GTUtility.convertOpaqueRGBA_CLtoRGB(ColourRGBA.multiply( + GTUtility.convertRGBtoOpaqueRGBA_CL(this.color), + GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))); return Pair.of(Textures.DRUM.getParticleTexture(), color); } } @Override public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { - if (ModHandler.isMaterialWood(material)) { + if (isWood) { ColourMultiplier multiplier = new ColourMultiplier( GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering())); Textures.WOODEN_DRUM.render(renderState, translation, ArrayUtils.add(pipeline, multiplier), getFrontFacing()); } else { ColourMultiplier multiplier = new ColourMultiplier( - ColourRGBA.multiply(GTUtility.convertRGBtoOpaqueRGBA_CL(material.getMaterialRGB()), + ColourRGBA.multiply(GTUtility.convertRGBtoOpaqueRGBA_CL(this.color), GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))); Textures.DRUM.render(renderState, translation, ArrayUtils.add(pipeline, multiplier), getFrontFacing()); Textures.DRUM_OVERLAY.render(renderState, translation, pipeline); @@ -252,8 +273,7 @@ public int getDefaultPaintingColor() { @SideOnly(Side.CLIENT) public void addInformation(ItemStack stack, @Nullable World player, List tooltip, boolean advanced) { tooltip.add(I18n.format("gregtech.universal.tooltip.fluid_storage_capacity", tankSize)); - FluidPipeProperties pipeProperties = material.getProperty(PropertyKey.FLUID_PIPE); - pipeProperties.appendTooltips(tooltip, true, true); + this.fluidFilter.appendTooltips(tooltip, true, true); if (TooltipHelper.isShiftDown()) { tooltip.add(I18n.format("gregtech.tool_action.screwdriver.access_covers")); @@ -266,7 +286,7 @@ public void addInformation(ItemStack stack, @Nullable World player, List FluidStack fluidStack = FluidStack.loadFluidStackFromNBT(tagCompound.getCompoundTag("Fluid")); if (fluidStack == null) return; tooltip.add(I18n.format("gregtech.machine.fluid_tank.fluid", fluidStack.amount, - I18n.format(fluidStack.getUnlocalizedName()))); + fluidStack.getFluid().getLocalizedName(fluidStack))); } } @@ -276,11 +296,6 @@ public boolean showToolUsages() { return false; } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; - } - @Override public NBTTagCompound writeToNBT(NBTTagCompound data) { super.writeToNBT(data); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumChest.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumChest.java index be6c63f5dec..d6646cb40de 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumChest.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumChest.java @@ -31,7 +31,6 @@ import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; -import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.text.ITextComponent; @@ -40,6 +39,8 @@ import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.Constants.NBT; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; @@ -60,7 +61,7 @@ import static gregtech.api.capability.GregtechDataCodes.*; -public class MetaTileEntityQuantumChest extends MetaTileEntity +public class MetaTileEntityQuantumChest extends MetaTileEntityQuantumStorage implements ITieredMetaTileEntity, IActiveOutputSide, IFastRenderMetaTileEntity { private final int tier; @@ -102,7 +103,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, Textures.QUANTUM_STORAGE_RENDERER.renderMachine(renderState, translation, ArrayUtils.add(pipeline, new ColourMultiplier(GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))), - this.getFrontFacing(), this.tier); + this); Textures.QUANTUM_CHEST_OVERLAY.renderSided(EnumFacing.UP, renderState, translation, pipeline); if (outputFacing != null) { Textures.PIPE_OUT_OVERLAY.renderSided(outputFacing, renderState, translation, pipeline); @@ -110,6 +111,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, Textures.ITEM_OUTPUT_OVERLAY.renderSided(outputFacing, renderState, translation, pipeline); } } + renderIndicatorOverlay(renderState, translation, pipeline); } @Override @@ -118,6 +120,7 @@ public void renderMetaTileEntity(double x, double y, double z, float partialTick } @Override + @SideOnly(Side.CLIENT) public Pair getParticleTexture() { return Pair.of(Textures.VOLTAGE_CASINGS[tier].getParticleSprite(), getPaintingColorForRendering()); } @@ -157,7 +160,10 @@ public void update() { } if (previousStack == null || !areItemStackIdentical(previousStack, virtualItemStack)) { - writeCustomData(UPDATE_ITEM, buf -> buf.writeItemStack(virtualItemStack)); + writeCustomData(UPDATE_ITEM, buf -> { + virtualItemStack.setCount(1); + buf.writeItemStack(virtualItemStack); + }); previousStack = virtualItemStack; } if (previousStackSize != itemsStoredInside) { @@ -185,7 +191,6 @@ protected void addDisplayInformation(List textList) { @Override public void addInformation(ItemStack stack, @Nullable World player, List tooltip, boolean advanced) { super.addInformation(stack, player, tooltip, advanced); - tooltip.add(I18n.format("gregtech.machine.quantum_chest.tooltip")); tooltip.add(I18n.format("gregtech.universal.tooltip.item_storage_total", maxStoredItems)); NBTTagCompound compound = stack.getTagCompound(); @@ -348,6 +353,8 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { .shouldUseBaseBackground()) .bindPlayerInventory(entityPlayer.inventory); + builder.widget(createConnectedGui(64)); + return builder.build(getHolder(), entityPlayer); } @@ -380,17 +387,18 @@ public boolean onWrenchClick(EntityPlayer playerIn, EnumHand hand, EnumFacing fa } @Override - public void writeInitialSyncData(PacketBuffer buf) { + public void writeInitialSyncData(@NotNull PacketBuffer buf) { super.writeInitialSyncData(buf); buf.writeByte(getOutputFacing().getIndex()); buf.writeBoolean(autoOutputItems); + this.virtualItemStack.setCount(1); buf.writeItemStack(virtualItemStack); buf.writeLong(itemsStoredInside); buf.writeBoolean(voiding); } @Override - public void receiveInitialSyncData(PacketBuffer buf) { + public void receiveInitialSyncData(@NotNull PacketBuffer buf) { super.receiveInitialSyncData(buf); this.outputFacing = EnumFacing.VALUES[buf.readByte()]; this.autoOutputItems = buf.readBoolean(); @@ -412,7 +420,7 @@ public boolean isValidFrontFacing(EnumFacing facing) { } @Override - public void receiveCustomData(int dataId, PacketBuffer buf) { + public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { super.receiveCustomData(dataId, buf); if (dataId == UPDATE_OUTPUT_FACING) { this.outputFacing = EnumFacing.VALUES[buf.readByte()]; @@ -513,7 +521,7 @@ public boolean isAllowInputFromOutputSideFluids() { } @Override - public void clearMachineInventory(NonNullList itemBuffer) { + public void clearMachineInventory(@NotNull List<@NotNull ItemStack> itemBuffer) { clearInventory(itemBuffer, importItems); } @@ -546,6 +554,16 @@ public void setAllowInputFromOutputSide(boolean allowInputFromOutputSide) { } } + @Override + public Type getType() { + return Type.ITEM; + } + + @Override + public IItemHandler getTypeValue() { + return this.combinedInventory; + } + @Override public AxisAlignedBB getRenderBoundingBox() { return new AxisAlignedBB(getPos()); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumExtender.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumExtender.java new file mode 100644 index 00000000000..cc37c7385ca --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumExtender.java @@ -0,0 +1,81 @@ +package gregtech.common.metatileentities.storage; + +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.capability.IDualHandler; +import gregtech.api.gui.ModularUI; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.util.GTUtility; +import gregtech.client.renderer.texture.Textures; + +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.ResourceLocation; + +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.ColourMultiplier; +import codechicken.lib.render.pipeline.IVertexOperation; +import codechicken.lib.vec.Matrix4; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; + +public class MetaTileEntityQuantumExtender extends MetaTileEntityQuantumStorage { + + public MetaTileEntityQuantumExtender(ResourceLocation metaTileEntityId) { + super(metaTileEntityId); + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { + return new MetaTileEntityQuantumExtender(metaTileEntityId); + } + + @Override + public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { + var newPipeline = ArrayUtils.add(pipeline, + new ColourMultiplier(GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))); + if (isConnected() && getQuantumController().isPowered()) { + Textures.QUANTUM_EXTENDER_ACTIVE.render(renderState, translation, newPipeline); + } else { + Textures.QUANTUM_EXTENDER.render(renderState, translation, newPipeline); + } + } + + @Override + public Pair getParticleTexture() { + return Pair.of(Textures.QUANTUM_EXTENDER.getParticleSprite(), getPaintingColorForRendering()); + } + + @Override + protected ModularUI createUI(EntityPlayer entityPlayer) { + return null; + } + + @Override + protected boolean openGUIOnRightClick() { + return false; + } + + @Override + public boolean hasFrontFacing() { + return false; + } + + @Override + public Type getType() { + return Type.EXTENDER; + } + + @Override + public IDualHandler getTypeValue() { + return null; + } + + @Override + public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == GregtechDataCodes.REMOVE_CONTROLLER) scheduleRenderUpdate(); + } +} diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumProxy.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumProxy.java new file mode 100644 index 00000000000..42deb4d91aa --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumProxy.java @@ -0,0 +1,105 @@ +package gregtech.common.metatileentities.storage; + +import gregtech.api.capability.IDualHandler; +import gregtech.api.capability.IQuantumController; +import gregtech.api.gui.ModularUI; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.util.GTUtility; +import gregtech.client.renderer.texture.Textures; + +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.items.CapabilityItemHandler; + +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.ColourMultiplier; +import codechicken.lib.render.pipeline.IVertexOperation; +import codechicken.lib.vec.Matrix4; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.Nullable; + +public class MetaTileEntityQuantumProxy extends MetaTileEntityQuantumStorage { + + public MetaTileEntityQuantumProxy(ResourceLocation metaTileEntityId) { + super(metaTileEntityId); + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { + return new MetaTileEntityQuantumProxy(metaTileEntityId); + } + + @Override + public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { + var newPipeline = ArrayUtils.add(pipeline, + new ColourMultiplier(GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))); + if (isConnected() && getQuantumController().isPowered()) { + Textures.QUANTUM_PROXY_ACTIVE.render(renderState, translation, newPipeline); + } else { + Textures.QUANTUM_PROXY_INACTIVE.render(renderState, translation, newPipeline); + } + } + + @Override + public Pair getParticleTexture() { + return Pair.of(Textures.QUANTUM_PROXY_INACTIVE.getParticleSprite(), getPaintingColorForRendering()); + } + + @Override + protected ModularUI createUI(EntityPlayer entityPlayer) { + return null; + } + + @Override + protected boolean openGUIOnRightClick() { + return false; + } + + @Override + public boolean hasFrontFacing() { + return false; + } + + @Override + public T getCapability(Capability capability, EnumFacing side) { + if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || + capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) { + var controller = getPoweredController(); + if (controller != null) + return controller.getCapability(capability, side); + } + return super.getCapability(capability, side); + } + + @Override + public void setDisconnected() { + super.setDisconnected(); + notifyBlockUpdate(); + } + + @Override + public Type getType() { + return Type.PROXY; + } + + @Override + public IDualHandler getTypeValue() { + var controller = getPoweredController(); + if (controller == null) return null; + return controller.getHandler(); + } + + @Nullable + private IQuantumController getPoweredController() { + if (!isConnected()) return null; + var controller = getQuantumController(); + if (controller == null || !controller.isPowered()) return null; + return controller; + } +} diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumStorage.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumStorage.java new file mode 100644 index 00000000000..d57f907af8d --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumStorage.java @@ -0,0 +1,216 @@ +package gregtech.common.metatileentities.storage; + +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.capability.IQuantumController; +import gregtech.api.capability.IQuantumStorage; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.widgets.ClickButtonWidget; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.util.GTUtility; +import gregtech.client.renderer.handler.BlockPosHighlightRenderer; +import gregtech.client.renderer.texture.Textures; +import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; +import gregtech.client.utils.RenderUtil; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.IVertexOperation; +import codechicken.lib.vec.Matrix4; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.ref.WeakReference; +import java.util.List; + +public abstract class MetaTileEntityQuantumStorage extends MetaTileEntity implements IQuantumStorage { + + /** not synced, server only. lazily initialized from pos */ + private WeakReference controller = new WeakReference<>(null); + + /** synced, server and client */ + private BlockPos controllerPos; + + private ClickButtonWidget connectedIcon; + + public MetaTileEntityQuantumStorage(ResourceLocation metaTileEntityId) { + super(metaTileEntityId); + } + + @SuppressWarnings("DataFlowIssue") + @SideOnly(Side.CLIENT) + protected void renderIndicatorOverlay(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { + SimpleOverlayRenderer texture; + if (isConnected()) { + texture = getQuantumController().isPowered() ? + Textures.QUANTUM_INDICATOR_POWERED : + Textures.QUANTUM_INDICATOR_CONNECTED; + } else { + texture = Textures.QUANTUM_INDICATOR; + } + texture.renderSided(getFrontFacing(), renderState, RenderUtil.adjustTrans(translation, getFrontFacing(), 1), + pipeline); + } + + @Override + public void setConnected(IQuantumController controller) { + if (getWorld().isRemote) return; + + if (!controller.getPos().equals(controllerPos)) { + this.controller = new WeakReference<>(controller); + this.controllerPos = controller.getPos(); + writeCustomData(GregtechDataCodes.UPDATE_CONTROLLER_POS, buf -> buf.writeBlockPos(controllerPos)); + markDirty(); + } + } + + @Override + public void setDisconnected() { + if (getWorld().isRemote) return; + + controller.clear(); + controllerPos = null; + writeCustomData(GregtechDataCodes.REMOVE_CONTROLLER, buf -> {}); + markDirty(); + } + + // use this to make sure controller is properly initialized + @Override + public final IQuantumController getQuantumController() { + if (isConnected()) { + if (controller.get() != null) return controller.get(); + MetaTileEntity mte = GTUtility.getMetaTileEntity(getWorld(), controllerPos); + if (mte instanceof IQuantumController quantumController) { + controller = new WeakReference<>(quantumController); + return quantumController; + } else { + // controller is no longer there for some reason, need to disconnect + setDisconnected(); + tryFindNetwork(); + } + } + return null; + } + + @Override + public BlockPos getControllerPos() { + return controllerPos; + } + + @Override + public void onRemoval() { + if (!getWorld().isRemote && isConnected()) { + IQuantumController controller = getQuantumController(); + if (controller != null) controller.rebuildNetwork(); + } + } + + @Override + public void onPlacement(@Nullable EntityLivingBase placer) { + super.onPlacement(placer); + if (getWorld() == null || getWorld().isRemote) + return; + + // add to the network if an adjacent block is part of a network + // use whatever we find first, merging networks is not supported + tryFindNetwork(); + } + + @Override + public void writeInitialSyncData(@NotNull PacketBuffer buf) { + super.writeInitialSyncData(buf); + buf.writeBoolean(controllerPos != null); + if (controllerPos != null) { + buf.writeBlockPos(controllerPos); + } + } + + @Override + public void receiveInitialSyncData(@NotNull PacketBuffer buf) { + super.receiveInitialSyncData(buf); + if (buf.readBoolean()) { + controllerPos = buf.readBlockPos(); + scheduleRenderUpdate(); + } + } + + @Override + public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == GregtechDataCodes.UPDATE_CONTROLLER_POS) { + this.controllerPos = buf.readBlockPos(); + this.controller.clear(); + + if (this.connectedIcon != null) { + this.connectedIcon.setButtonTexture(GuiTextures.GREGTECH_LOGO); + this.connectedIcon.setTooltipText("gregtech.machine.quantum_storage.connected", + controllerPos.getX(), controllerPos.getZ(), controllerPos.getY()); + } + scheduleRenderUpdate(); + } else if (dataId == GregtechDataCodes.REMOVE_CONTROLLER) { + this.controllerPos = null; + this.controller.clear(); + if (this.connectedIcon != null) { + this.connectedIcon.setButtonTexture(GuiTextures.GREGTECH_LOGO_DARK); + this.connectedIcon.setTooltipText("gregtech.machine.quantum_storage.disconnected"); + } + scheduleRenderUpdate(); + } else if (dataId == GregtechDataCodes.LOCATE_CONTROLLER) { + // tell controller to highlight + BlockPosHighlightRenderer.renderBlockBoxHighLight(getControllerPos(), 6000, 1500); + Minecraft.getMinecraft().player.closeScreen(); + } + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + NBTTagCompound tagCompound = super.writeToNBT(data); + tagCompound.setBoolean("HasController", controllerPos != null); + if (controllerPos != null) { + tagCompound.setLong("ControllerPos", controllerPos.toLong()); + } + return tagCompound; + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + if (data.getBoolean("HasController")) { + this.controllerPos = BlockPos.fromLong(data.getLong("ControllerPos")); + } + } + + protected ClickButtonWidget createConnectedGui(int y) { + connectedIcon = new ClickButtonWidget(151, y, 18, 18, "", + clickData -> { + if (isConnected()) + writeCustomData(GregtechDataCodes.LOCATE_CONTROLLER, buffer -> {}); + }); + connectedIcon.setButtonTexture(isConnected() ? GuiTextures.GREGTECH_LOGO : GuiTextures.GREGTECH_LOGO_DARK); + + if (isConnected()) { + connectedIcon.setTooltipText("gregtech.machine.quantum_storage.connected", + controllerPos.getX(), controllerPos.getZ(), controllerPos.getY()); + } else { + connectedIcon.setTooltipText("gregtech.machine.quantum_storage.disconnected"); + } + + return connectedIcon; + } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + tooltip.add(I18n.format("gregtech.machine.quantum_chest.tooltip")); + } +} diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumStorageController.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumStorageController.java new file mode 100644 index 00000000000..c4431e902a9 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumStorageController.java @@ -0,0 +1,519 @@ +package gregtech.common.metatileentities.storage; + +import gregtech.api.GTValues; +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.capability.IDualHandler; +import gregtech.api.capability.IEnergyContainer; +import gregtech.api.capability.IQuantumController; +import gregtech.api.capability.IQuantumStorage; +import gregtech.api.capability.impl.EnergyContainerList; +import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.ItemHandlerList; +import gregtech.api.metatileentity.ITieredMetaTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.util.GTUtility; +import gregtech.client.renderer.texture.Textures; + +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.nbt.NBTTagLong; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; + +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.ColourMultiplier; +import codechicken.lib.render.pipeline.IVertexOperation; +import codechicken.lib.vec.Matrix4; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.ref.WeakReference; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.Set; + +import static gregtech.api.capability.IQuantumStorage.Type.*; + +public class MetaTileEntityQuantumStorageController extends MetaTileEntity implements IQuantumController { + + private static final int MAX_DISTANCE_RADIUS = 16; + + private EnergyContainerList energyHandler = new EnergyContainerList(Collections.emptyList()); + private final List energyContainers = new ArrayList<>(); + /** Somewhat lazily initialized, make sure to call {@code getStorage()} before trying to access anything in this */ + private Map>> storageInstances = new HashMap<>(); + + /** The "definitive" set of positions of storage instances */ + private Set storagePositions = new HashSet<>(); + private final Map> typePosMap = new EnumMap<>(IQuantumStorage.Type.class); + private final BlockPos[] bounds = new BlockPos[2]; + private long energyConsumption = 0; + private final QuantumControllerHandler handler = new QuantumControllerHandler(); + + private boolean isDead = false; + private boolean isPowered = false; + + public MetaTileEntityQuantumStorageController(ResourceLocation metaTileEntityId) { + super(metaTileEntityId); + for (var type : VALUES) { + typePosMap.put(type, new HashSet<>()); + } + } + + @Override + public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { + return new MetaTileEntityQuantumStorageController(metaTileEntityId); + } + + @Override + public void update() { + super.update(); + if (getWorld().isRemote) return; + + if (getOffsetTimer() % 10 == 0) { + boolean isPowered = energyHandler.getEnergyStored() > energyConsumption && energyConsumption > 0; + if (isPowered) energyHandler.removeEnergy(energyConsumption); + + if (isPowered != this.isPowered) { + this.isPowered = isPowered; + + writeCustomData(GregtechDataCodes.UPDATE_ENERGY, buf -> { + buf.writeBoolean(this.isPowered); + buf.writeBlockPos(this.bounds[0]); + buf.writeBlockPos(this.bounds[1]); + }); + updateHandler(); + } + } + } + + public boolean isPowered() { + return isPowered; + } + + @Override + public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == GregtechDataCodes.UPDATE_ENERGY) { + this.isPowered = buf.readBoolean(); + getWorld().markBlockRangeForRenderUpdate(buf.readBlockPos(), buf.readBlockPos()); + scheduleRenderUpdate(); + } else if (dataId == GregtechDataCodes.UPDATE_ENERGY_PER) { + this.energyConsumption = buf.readLong(); + } + } + + @Override + public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { + var front = isPowered() ? + Textures.QUANTUM_CONTROLLER_FRONT_ACTIVE : + Textures.QUANTUM_CONTROLLER_FRONT_INACTIVE; + var sides = isPowered() ? + Textures.QUANTUM_CONTROLLER_ACTIVE : + Textures.QUANTUM_CONTROLLER_INACTIVE; + + var newPipeline = ArrayUtils.add(pipeline, + new ColourMultiplier(GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))); + + front.renderSided(getFrontFacing(), renderState, translation, newPipeline); + + for (EnumFacing facing : EnumFacing.VALUES) { + if (facing == getFrontFacing()) continue; + sides.renderSided(facing, renderState, translation, newPipeline); + } + } + + @Override + public Pair getParticleTexture() { + return Pair.of(Textures.QUANTUM_CONTROLLER_ACTIVE.getParticleSprite(), getPaintingColorForRendering()); + } + + @Override + protected boolean openGUIOnRightClick() { + return false; // todo use mui2 for ui? + } + + @Override + public boolean isValidFrontFacing(EnumFacing facing) { + return true; + } + + @Nullable + @SuppressWarnings("SameParameterValue") + private IQuantumStorage getStorage(BlockPos pos, boolean rebuild) { + if (getWorld().isRemote) return null; + if (storageInstances.containsKey(pos)) { + WeakReference> storageRef = storageInstances.get(pos); + IQuantumStorage storage = storageRef.get(); + if (storage != null) { + return storage; + } + } + // need to make sure it still exists + MetaTileEntity mte = GTUtility.getMetaTileEntity(getWorld(), pos); + if (mte instanceof IQuantumStoragestorage) { + storageInstances.put(pos, new WeakReference<>(storage)); + return storage; + } else if (rebuild) { + // need to remove and rebuild + storagePositions.remove(pos); + rebuildNetwork(); + return null; + } + return null; + } + + @Nullable + public final IQuantumStorage getStorage(BlockPos pos) { + return getStorage(pos, false); + } + + @Override + public boolean canConnect(IQuantumStorage storage) { + return !isDead && isInRange(storage.getPos()); + } + + private boolean isInRange(BlockPos pos) { + return Math.abs(getPos().getX() - pos.getX()) <= MAX_DISTANCE_RADIUS && // valid X + Math.abs(getPos().getY() - pos.getY()) <= MAX_DISTANCE_RADIUS && // valid Y + Math.abs(getPos().getZ() - pos.getZ()) <= MAX_DISTANCE_RADIUS; // valid Z + } + + @Override + public void onRemoval() { + if (getWorld().isRemote) return; + isDead = true; + for (BlockPos pos : storagePositions) { + IQuantumStorage storage = getStorage(pos); + if (storage != null) storage.setDisconnected(); + } + handler.invalidate(); + storagePositions.clear(); + storageInstances.clear(); + typePosMap.clear(); + } + + @Override + public void onPlacement(@Nullable EntityLivingBase placer) { + super.onPlacement(placer); + rebuildNetwork(); + } + + @Override + public void onLoad() { + calculateEnergyUsage(); + super.onLoad(); + } + + // Used when this controller is initially placed. Try to find all possible + // storage instances that are connected and within our distance radius + @Override + public void rebuildNetwork() { + if (getWorld().isRemote) return; + var oldInstances = storageInstances; + var oldPositions = storagePositions; + + storageInstances = new HashMap<>(); + storagePositions = new HashSet<>(); + + typePosMap.values().forEach(Set::clear); + + Queue searchQueue = new ArrayDeque<>(); + Set checked = new HashSet<>(); + + // check the posses around the controller + for (EnumFacing facing : EnumFacing.VALUES) { + if (checkStorageNeighbor(this, facing)) { + searchQueue.add(getPos().offset(facing)); + } + } + + int minx = getPos().getX(); + int miny = getPos().getY(); + int minz = getPos().getZ(); + int maxx = minx; + int maxy = miny; + int maxz = minz; + + // while there are blocks to search + while (!searchQueue.isEmpty()) { + BlockPos pos = searchQueue.remove(); + + if (!checked.add(pos)) + continue; + + if (!isInRange(pos) || !getWorld().isBlockLoaded(pos, false)) continue; + + var state = getWorld().getBlockState(pos); + if (state.getBlock().isAir(state, getWorld(), pos)) continue; + + MetaTileEntity mte = GTUtility.getMetaTileEntity(getWorld(), pos); + // the mte at this pos is always an instance of quantum storage + IQuantumStorage storage = (IQuantumStorage) mte; + + // connected to some other network already, ignore + if (storage.isConnected() && !storage.getControllerPos().equals(getPos())) continue; + + // valid chest/tank located, add it + storageInstances.put(pos, new WeakReference<>(storage)); + storagePositions.add(pos); + typePosMap.get(storage.getType()).add(pos); + storage.setConnected(this); + oldInstances.remove(pos); + oldPositions.remove(pos); + + // calculate bounds + minx = Math.min(minx, pos.getX()); + miny = Math.min(miny, pos.getY()); + minz = Math.min(minz, pos.getZ()); + + maxx = Math.max(maxx, pos.getX()); + maxy = Math.max(maxy, pos.getY()); + maxz = Math.max(maxz, pos.getZ()); + + // check against already check posses so we don't recheck a checked pos + for (EnumFacing facing : EnumFacing.VALUES) { + BlockPos offsetPos = pos.offset(facing); + if (checked.contains(offsetPos) || getPos().equals(offsetPos)) continue; + state = getWorld().getBlockState(offsetPos); + if (state.getBlock().isAir(state, getWorld(), offsetPos)) continue; + + // add a new pos to search + if (checkStorageNeighbor(mte, facing)) + searchQueue.add(offsetPos); + } + } + + // update bounds + this.bounds[0] = new BlockPos(minx, miny, minz); + this.bounds[1] = new BlockPos(maxx, maxy, maxz); + + // check old posses to disconnect the storages + for (BlockPos pos : oldPositions) { + + // if we already checked this pos before, don't check it again + if (checked.contains(pos)) continue; + + // if the pos is air, there's nothing to check + var state = getWorld().getBlockState(pos); + if (state.getBlock().isAir(state, getWorld(), pos)) continue; + + IQuantumStorage storage = oldInstances.get(pos).get(); + if (storage == null) { + MetaTileEntity mte = GTUtility.getMetaTileEntity(getWorld(), pos); + if (!(mte instanceof IQuantumStoragequantumStorage)) { + continue; + } + storage = quantumStorage; + } + storage.setDisconnected(); + } + handler.rebuildCache(); + calculateEnergyUsage(); + markDirty(); + } + + private static boolean checkStorageNeighbor(MetaTileEntity mte, EnumFacing facing) { + if (mte.getNeighbor(facing) instanceof IGregTechTileEntity gtte) { + return gtte.getMetaTileEntity() instanceof IQuantumStorage; + } + return false; + } + + @Override + public void updateHandler() { + if (getWorld().isRemote) return; + notifyBlockUpdate(); + for (var pos : typePosMap.get(PROXY)) { + var storage = getStorage(pos); + if (storage == null) continue; + storage.notifyBlockUpdate(); + } + } + + private void calculateEnergyUsage() { + energyContainers.clear(); + energyConsumption = 0; + for (var pos : storagePositions) { + var storage = getStorage(pos); + if (storage != null) { + typePosMap.get(storage.getType()).add(pos); + energyConsumption += getTypeEnergy(storage); + if (storage.getType() == ENERGY) { + energyContainers.add((IEnergyContainer) storage.getTypeValue()); + } + } + } + energyHandler = new EnergyContainerList(energyContainers); + writeCustomData(GregtechDataCodes.UPDATE_ENERGY_PER, buf -> buf.writeLong(energyConsumption)); + } + + public long getTypeEnergy(IQuantumStorage storage) { + return switch (storage.getType()) { + case ITEM, FLUID -> { + int tier = storage instanceof ITieredMetaTileEntity tieredMTE ? tieredMTE.getTier() : 1; + yield tier > 5 ? + GTValues.VH[GTValues.HV] : + GTValues.VH[GTValues.LV]; + } + case PROXY -> 8L; + case EXTENDER -> 2L; + case ENERGY -> 1L; + }; + } + + @Override + public int getCount(IQuantumStorage.Type type) { + return typePosMap.get(type).size(); + } + + public final long getEnergyUsage() { + return energyConsumption; + } + + @Override + public void writeInitialSyncData(@NotNull PacketBuffer buf) { + super.writeInitialSyncData(buf); + buf.writeBoolean(this.isPowered); + buf.writeLong(this.energyConsumption); + } + + @Override + public void receiveInitialSyncData(@NotNull PacketBuffer buf) { + super.receiveInitialSyncData(buf); + this.isPowered = buf.readBoolean(); + this.energyConsumption = buf.readLong(); + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + NBTTagCompound tagCompound = super.writeToNBT(data); + NBTTagList list = new NBTTagList(); + for (BlockPos pos : storagePositions) { + list.appendTag(new NBTTagLong(pos.toLong())); + } + tagCompound.setTag("StorageInstances", list); + tagCompound.setLong("MinBound", bounds[0].toLong()); + tagCompound.setLong("MaxBound", bounds[1].toLong()); + tagCompound.setBoolean("isPowered", this.isPowered); + return tagCompound; + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + NBTTagList list = data.getTagList("StorageInstances", Constants.NBT.TAG_LONG); + for (int i = 0; i < list.tagCount(); i++) { + storagePositions.add(BlockPos.fromLong(((NBTTagLong) list.get(i)).getLong())); + } + this.bounds[0] = BlockPos.fromLong(data.getLong("MinBound")); + this.bounds[1] = BlockPos.fromLong(data.getLong("MaxBound")); + this.isPowered = data.getBoolean("isPowered"); + } + + @SuppressWarnings("unchecked") + @Override + public T getCapability(@NotNull Capability capability, EnumFacing side) { + if (isPowered()) { + if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY && handler.hasItemHandlers()) { + return (T) handler.getItemHandlers(); + } else if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY && handler.hasFluidTanks()) { + return (T) handler.getFluidTanks(); + } + } + + return super.getCapability(capability, side); + } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, + boolean advanced) { + tooltip.add(I18n.format("gregtech.machine.quantum_chest.tooltip")); + } + + @Override + public IDualHandler getHandler() { + return this.handler; + } + + // todo use DualHandler instead once the multis ability pr is merged + private class QuantumControllerHandler implements IDualHandler { + + // IFluidHandler saved values + private FluidTankList fluidTanks; + + // IItemHandler saved values + private ItemHandlerList itemHandlers; + + private void invalidate() { + fluidTanks = new FluidTankList(false); + itemHandlers = new ItemHandlerList(Collections.emptyList()); + } + + private void rebuildCache() { + List itemHandlerList = new ArrayList<>(); + List fluidTankList = new ArrayList<>(); + for (BlockPos pos : storagePositions) { + IQuantumStorage storage = getStorage(pos); + if (storage == null) continue; + switch (storage.getType()) { + case ITEM -> itemHandlerList.add((IItemHandler) storage.getTypeValue()); + case FLUID -> fluidTankList.add((IFluidTank) storage.getTypeValue()); + } + } + + // todo allow this "allowSameFluidFill" to be configured in this controller? + this.fluidTanks = new FluidTankList(false, fluidTankList); + this.itemHandlers = new ItemHandlerList(itemHandlerList); + } + + @Override + public boolean hasFluidTanks() { + return getFluidTanks().getTanks() > 0; + } + + @Override + public boolean hasItemHandlers() { + return !getItemHandlers().getBackingHandlers().isEmpty(); + } + + @Override + public FluidTankList getFluidTanks() { + if (fluidTanks == null) { + rebuildCache(); + } + return fluidTanks; + } + + @Override + public ItemHandlerList getItemHandlers() { + if (itemHandlers == null) { + rebuildCache(); + } + return itemHandlers; + } + } +} diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java index 6e27064a4e3..0d675b9b1c9 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumTank.java @@ -11,7 +11,14 @@ import gregtech.api.cover.CoverRayTracer; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.*; +import gregtech.api.gui.widgets.AdvancedTextWidget; +import gregtech.api.gui.widgets.FluidContainerSlotWidget; +import gregtech.api.gui.widgets.ImageWidget; +import gregtech.api.gui.widgets.LabelWidget; +import gregtech.api.gui.widgets.PhantomTankWidget; +import gregtech.api.gui.widgets.SlotWidget; +import gregtech.api.gui.widgets.TankWidget; +import gregtech.api.gui.widgets.ToggleButtonWidget; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.IFastRenderMetaTileEntity; import gregtech.api.metatileentity.ITieredMetaTileEntity; @@ -33,6 +40,7 @@ import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentTranslation; @@ -42,8 +50,11 @@ import net.minecraftforge.common.util.Constants; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTank; +import net.minecraftforge.fluids.IFluidTank; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.IItemHandlerModifiable; import codechicken.lib.raytracer.CuboidRayTraceResult; @@ -63,7 +74,7 @@ import static gregtech.api.capability.GregtechDataCodes.*; import static net.minecraftforge.fluids.capability.templates.FluidHandlerItemStack.FLUID_NBT_KEY; -public class MetaTileEntityQuantumTank extends MetaTileEntity +public class MetaTileEntityQuantumTank extends MetaTileEntityQuantumStorage implements ITieredMetaTileEntity, IActiveOutputSide, IFastRenderMetaTileEntity { private final int tier; @@ -127,9 +138,17 @@ public void update() { updatePreviousFluid(null); } else if (previousFluid.getFluid().equals(currentFluid.getFluid()) && previousFluid.amount != currentFluid.amount) { + int currentFill = MathHelper + .floor(16 * ((float) currentFluid.amount) / fluidTank.getCapacity()); + int previousFill = MathHelper + .floor(16 * ((float) previousFluid.amount) / fluidTank.getCapacity()); // tank has fluid with changed amount previousFluid.amount = currentFluid.amount; - writeCustomData(UPDATE_FLUID_AMOUNT, buf -> buf.writeInt(currentFluid.amount)); + writeCustomData(UPDATE_FLUID_AMOUNT, buf -> { + buf.writeInt(currentFluid.amount); + buf.writeBoolean(currentFill != previousFill); + }); + } else if (!previousFluid.equals(currentFluid)) { // tank has a different fluid from before @@ -259,7 +278,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, Textures.QUANTUM_STORAGE_RENDERER.renderMachine(renderState, translation, ArrayUtils.add(pipeline, new ColourMultiplier(GTUtility.convertRGBtoOpaqueRGBA_CL(getPaintingColorForRendering()))), - this.getFrontFacing(), this.tier); + this); Textures.QUANTUM_TANK_OVERLAY.renderSided(EnumFacing.UP, renderState, translation, pipeline); if (outputFacing != null) { Textures.PIPE_OUT_OVERLAY.renderSided(outputFacing, renderState, translation, pipeline); @@ -269,23 +288,25 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, } QuantumStorageRenderer.renderTankFluid(renderState, translation, pipeline, fluidTank, getWorld(), getPos(), getFrontFacing()); + renderIndicatorOverlay(renderState, translation, pipeline); } @Override public void renderMetaTileEntity(double x, double y, double z, float partialTicks) { if (this.fluidTank.getFluid() == null || this.fluidTank.getFluid().amount == 0) return; + QuantumStorageRenderer.renderTankAmount(x, y, z, this.getFrontFacing(), this.fluidTank.getFluid().amount); } @Override + @SideOnly(Side.CLIENT) public Pair getParticleTexture() { return Pair.of(Textures.VOLTAGE_CASINGS[tier].getParticleSprite(), getPaintingColorForRendering()); } @Override public void addInformation(ItemStack stack, @Nullable World player, List tooltip, boolean advanced) { - super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.quantum_tank.tooltip")); tooltip.add(I18n.format("gregtech.universal.tooltip.fluid_storage_capacity", maxFluidCapacity)); NBTTagCompound tag = stack.getTagCompound(); @@ -329,8 +350,8 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { }) .setAlwaysShowFull(true).setDrawHoveringText(false); - return ModularUI.defaultBuilder() - .widget(new ImageWidget(7, 16, 81, 46, GuiTextures.DISPLAY)) + ModularUI.Builder builder = ModularUI.defaultBuilder(); + builder.widget(new ImageWidget(7, 16, 81, 46, GuiTextures.DISPLAY)) .widget(new LabelWidget(11, 20, "gregtech.gui.fluid_amount", 0xFFFFFF)) .widget(tankWidget) .widget(new AdvancedTextWidget(11, 30, getFluidAmountText(tankWidget), 0xFFFFFF)) @@ -351,8 +372,11 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { .widget(new ToggleButtonWidget(43, 64, 18, 18, GuiTextures.BUTTON_FLUID_VOID, this::isVoiding, this::setVoiding) .setTooltipText("gregtech.gui.fluid_voiding.tooltip") - .shouldUseBaseBackground()) - .bindPlayerInventory(entityPlayer.inventory) + .shouldUseBaseBackground()); + + builder.widget(createConnectedGui(64)); + + return builder.bindPlayerInventory(entityPlayer.inventory) .build(getHolder(), entityPlayer); } @@ -431,7 +455,7 @@ public boolean isAllowInputFromOutputSideFluids() { } @Override - public void receiveCustomData(int dataId, PacketBuffer buf) { + public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { super.receiveCustomData(dataId, buf); if (dataId == UPDATE_OUTPUT_FACING) { this.outputFacing = EnumFacing.VALUES[buf.readByte()]; @@ -443,15 +467,19 @@ public void receiveCustomData(int dataId, PacketBuffer buf) { try { this.fluidTank.setFluid(FluidStack.loadFluidStackFromNBT(buf.readCompoundTag())); } catch (IOException ignored) { - GTLog.logger.warn("Failed to load fluid from NBT in a quantum tank at " + this.getPos() + - " on a routine fluid update"); + GTLog.logger.warn("Failed to load fluid from NBT in a quantum tank at {} on a routine fluid update", + this.getPos()); } scheduleRenderUpdate(); } else if (dataId == UPDATE_FLUID_AMOUNT) { + // amount must always be read even if it cannot be used to ensure the reader index advances + int amount = buf.readInt(); + boolean updateRendering = buf.readBoolean(); FluidStack stack = fluidTank.getFluid(); if (stack != null) { - stack.amount = Math.min(buf.readInt(), fluidTank.getCapacity()); - scheduleRenderUpdate(); + stack.amount = Math.min(amount, fluidTank.getCapacity()); + if (updateRendering) + scheduleRenderUpdate(); } } else if (dataId == UPDATE_IS_VOIDING) { setVoiding(buf.readBoolean()); @@ -464,7 +492,7 @@ public boolean isValidFrontFacing(EnumFacing facing) { } @Override - public void writeInitialSyncData(PacketBuffer buf) { + public void writeInitialSyncData(@NotNull PacketBuffer buf) { super.writeInitialSyncData(buf); buf.writeByte(getOutputFacing().getIndex()); buf.writeBoolean(autoOutputFluids); @@ -475,7 +503,7 @@ public void writeInitialSyncData(PacketBuffer buf) { } @Override - public void receiveInitialSyncData(PacketBuffer buf) { + public void receiveInitialSyncData(@NotNull PacketBuffer buf) { super.receiveInitialSyncData(buf); this.outputFacing = EnumFacing.VALUES[buf.readByte()]; @@ -690,4 +718,14 @@ public int getPriority() { return !locked || lockedFluid == null ? IFilter.noPriority() : IFilter.whitelistPriority(1); } } + + @Override + public Type getType() { + return Type.FLUID; + } + + @Override + public IFluidTank getTypeValue() { + return fluidTank; + } } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 93dc559bb11..bbfb8c2685e 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -31,9 +31,10 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; -import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.ItemStackHandler; import codechicken.lib.render.CCRenderState; @@ -120,6 +121,7 @@ public int getDefaultPaintingColor() { } @Override + @SideOnly(Side.CLIENT) public Pair getParticleTexture() { return Pair.of(Textures.CRAFTING_TABLE.getParticleSprite(), getDefaultPaintingColor()); } @@ -182,7 +184,7 @@ private CraftingRecipeLogic getCraftingRecipeLogic() { } @Override - public void clearMachineInventory(NonNullList itemBuffer) { + public void clearMachineInventory(@NotNull List<@NotNull ItemStack> itemBuffer) { super.clearMachineInventory(itemBuffer); clearInventory(itemBuffer, internalInventory); clearInventory(itemBuffer, toolInventory); diff --git a/src/main/java/gregtech/common/mui/widget/GTFluidSlot.java b/src/main/java/gregtech/common/mui/widget/GTFluidSlot.java new file mode 100644 index 00000000000..1b0ccff4ebe --- /dev/null +++ b/src/main/java/gregtech/common/mui/widget/GTFluidSlot.java @@ -0,0 +1,142 @@ +package gregtech.common.mui.widget; + +import gregtech.api.GTValues; +import gregtech.api.mui.sync.GTFluidSyncHandler; +import gregtech.api.util.FluidTooltipUtil; +import gregtech.api.util.LocalizationUtils; +import gregtech.client.utils.TooltipHelper; + +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidTank; + +import com.cleanroommc.modularui.api.ITheme; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.drawable.GuiDraw; +import com.cleanroommc.modularui.drawable.TextRenderer; +import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; +import com.cleanroommc.modularui.screen.Tooltip; +import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.theme.WidgetSlotTheme; +import com.cleanroommc.modularui.theme.WidgetTheme; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.utils.NumberFormat; +import com.cleanroommc.modularui.widget.Widget; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class GTFluidSlot extends Widget implements Interactable, JeiIngredientProvider { + + private final TextRenderer textRenderer = new TextRenderer(); + private GTFluidSyncHandler syncHandler; + + public GTFluidSlot() { + tooltip().setAutoUpdate(true).setHasTitleMargin(true); + tooltipBuilder(tooltip -> { + if (!isSynced()) return; + var fluid = this.syncHandler.getFluid(); + if (fluid == null) return; + + tooltip.addLine(fluid.getLocalizedName()); + tooltip.addLine(IKey.lang("gregtech.fluid.amount", fluid.amount, this.syncHandler.getCapacity())); + + // Add various tooltips from the material + List formula = FluidTooltipUtil.getFluidTooltip(fluid); + if (formula != null) { + for (String s : formula) { + if (s.isEmpty()) continue; + tooltip.addLine(s); + } + } + + addIngotMolFluidTooltip(fluid, tooltip); + }); + } + + public static GTFluidSyncHandler sync(IFluidTank tank) { + return new GTFluidSyncHandler(tank); + } + + @Override + public void onInit() { + this.textRenderer.setShadow(true); + this.textRenderer.setScale(0.5f); + this.textRenderer.setColor(Color.WHITE.main); + } + + public GTFluidSlot syncHandler(IFluidTank fluidTank) { + return syncHandler(new GTFluidSyncHandler(fluidTank)); + } + + public GTFluidSlot syncHandler(GTFluidSyncHandler syncHandler) { + setSyncHandler(syncHandler); + this.syncHandler = syncHandler; + return this; + } + + @Override + public void draw(GuiContext context, WidgetTheme widgetTheme) { + FluidStack content = this.syncHandler.getFluid(); + if (content != null) { + GuiDraw.drawFluidTexture(content, 1, 1, getArea().w() - 2, getArea().h() - 2, 0); + + String s = NumberFormat.formatWithMaxDigits(getBaseUnitAmount(content.amount)) + getBaseUnit(); + this.textRenderer.setAlignment(Alignment.CenterRight, getArea().width - 1f); + this.textRenderer.setPos(0, 12); + this.textRenderer.draw(s); + } + if (isHovering()) { + GlStateManager.colorMask(true, true, true, false); + GuiDraw.drawRect(1, 1, getArea().w() - 2, getArea().h() - 2, + getWidgetTheme(context.getTheme()).getSlotHoverColor()); + GlStateManager.colorMask(true, true, true, true); + } + } + + protected double getBaseUnitAmount(double amount) { + return amount / 1000; + } + + protected String getBaseUnit() { + return "L"; + } + + @NotNull + @Override + public Result onMouseTapped(int mouseButton) { + if (this.syncHandler.canFillSlot() || this.syncHandler.canDrainSlot()) { + this.syncHandler.syncToServer(1, buffer -> buffer.writeBoolean(mouseButton == 0)); + Interactable.playButtonClickSound(); + return Result.SUCCESS; + } + return Result.IGNORE; + } + + @Override + public WidgetSlotTheme getWidgetTheme(ITheme theme) { + return theme.getFluidSlotTheme(); + } + + @Override + public @Nullable Object getIngredient() { + return this.syncHandler.getFluid(); + } + + public static void addIngotMolFluidTooltip(FluidStack fluidStack, Tooltip tooltip) { + // Add tooltip showing how many "ingot moles" (increments of 144) this fluid is if shift is held + if (TooltipHelper.isShiftDown() && fluidStack.amount > GTValues.L) { + int numIngots = fluidStack.amount / GTValues.L; + int extra = fluidStack.amount % GTValues.L; + String fluidAmount = String.format(" %,d L = %,d * %d L", fluidStack.amount, numIngots, GTValues.L); + if (extra != 0) { + fluidAmount += String.format(" + %d L", extra); + } + tooltip.addLine(TextFormatting.GRAY + LocalizationUtils.format("gregtech.gui.amount_raw") + fluidAmount); + } + } +} diff --git a/src/main/java/gregtech/common/mui/widget/HighlightedTextField.java b/src/main/java/gregtech/common/mui/widget/HighlightedTextField.java new file mode 100644 index 00000000000..3bb6a3e652b --- /dev/null +++ b/src/main/java/gregtech/common/mui/widget/HighlightedTextField.java @@ -0,0 +1,95 @@ +package gregtech.common.mui.widget; + +import com.cleanroommc.modularui.api.value.IStringValue; +import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.widgets.textfield.TextFieldHandler; +import com.cleanroommc.modularui.widgets.textfield.TextFieldRenderer; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; + +import java.util.Map; +import java.util.function.Function; + +public class HighlightedTextField extends TextFieldWidget { + + private StringSyncValue stringSyncValue; + + private final TextHighlighter highlighter; + private Runnable onUnfocus; + + public HighlightedTextField() { + this.highlighter = new TextHighlighter(this.handler); + this.renderer = this.highlighter; + this.handler.setRenderer(this.renderer); + } + + @Override + public void afterInit() { + this.highlighter.runHighlighter(getText()); + } + + /** + * Text highlighter applied only in rendering text. Only formatting characters can be inserted. + * + * @param highlightRule Consumer for text highlighter + * @return This + */ + public HighlightedTextField setHighlightRule(Function highlightRule) { + this.highlighter.setHighlightRule(highlightRule); + return getThis(); + } + + @Override + public HighlightedTextField value(IStringValue stringValue) { + this.stringSyncValue = (StringSyncValue) stringValue; + super.value(stringValue); + return getThis(); + } + + @Override + public HighlightedTextField getThis() { + return this; + } + + @Override + public void onRemoveFocus(GuiContext context) { + super.onRemoveFocus(context); + highlighter.runHighlighter(getText()); + if (isSynced()) + this.stringSyncValue.setStringValue(getText(), true, true); + onUnfocus.run(); + } + + public HighlightedTextField onUnfocus(Runnable onUnfocus) { + this.onUnfocus = onUnfocus; + return getThis(); + } + + public static final class TextHighlighter extends TextFieldRenderer { + + private Function highlightRule = string -> string; + + private Map cacheMap = new Object2ObjectOpenHashMap<>(); + + public TextHighlighter(TextFieldHandler handler) { + super(handler); + } + + public void setHighlightRule(Function highlightRule) { + this.highlightRule = highlightRule; + } + + @Override + protected float draw(String text, float x, float y) { + return super.draw(this.cacheMap.getOrDefault(text, text), x, y); + } + + public void runHighlighter(String text) { + if (this.highlightRule == null) { + return; + } + this.cacheMap.computeIfAbsent(text, string -> this.highlightRule.apply(string)); + } + } +} diff --git a/src/main/java/gregtech/common/mui/widget/InteractableText.java b/src/main/java/gregtech/common/mui/widget/InteractableText.java new file mode 100644 index 00000000000..eac6936059a --- /dev/null +++ b/src/main/java/gregtech/common/mui/widget/InteractableText.java @@ -0,0 +1,63 @@ +package gregtech.common.mui.widget; + +import gregtech.api.util.virtualregistry.VirtualEntry; + +import net.minecraft.network.PacketBuffer; + +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.network.NetworkUtils; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.SyncHandler; +import com.cleanroommc.modularui.widgets.TextWidget; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Consumer; + +public class InteractableText extends TextWidget implements Interactable { + + private final T entry; + private final EntryColorSH syncHandler; + + public InteractableText(T entry, Consumer setter) { + super(IKey.str(entry.getColorStr()) + .alignment(Alignment.CenterLeft) + .color(Color.WHITE.darker(1))); + this.entry = entry; + this.syncHandler = new EntryColorSH(setter); + setSyncHandler(this.syncHandler); + } + + @NotNull + @Override + public Result onMousePressed(int mouseButton) { + Interactable.playButtonClickSound(); + this.syncHandler.setColor(this.entry.getColorStr()); + this.syncHandler.syncToServer(1, buf -> NetworkUtils.writeStringSafe(buf, this.entry.getColorStr())); + return Result.SUCCESS; + } + + private static class EntryColorSH extends SyncHandler { + + private final Consumer setter; + + private EntryColorSH(Consumer setter) { + this.setter = setter; + } + + public void setColor(String c) { + this.setter.accept(c); + } + + @Override + public void readOnClient(int id, PacketBuffer buf) {} + + @Override + public void readOnServer(int id, PacketBuffer buf) { + if (id == 1) { + setColor(NetworkUtils.readStringSafe(buf)); + } + } + } +} diff --git a/src/main/java/gregtech/common/mui/widget/orefilter/ItemOreFilterTestSlot.java b/src/main/java/gregtech/common/mui/widget/orefilter/ItemOreFilterTestSlot.java new file mode 100644 index 00000000000..9e16df34dfb --- /dev/null +++ b/src/main/java/gregtech/common/mui/widget/orefilter/ItemOreFilterTestSlot.java @@ -0,0 +1,42 @@ +package gregtech.common.mui.widget.orefilter; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.items.ItemStackHandler; + +import com.cleanroommc.modularui.widgets.slot.ModularSlot; +import org.jetbrains.annotations.NotNull; + +public class ItemOreFilterTestSlot extends ModularSlot { + + OreFilterTestSlot parent; + + public ItemOreFilterTestSlot() { + super(new ItemStackHandler(1), 0, true); + } + + void setParent(OreFilterTestSlot parent) { + this.parent = parent; + } + + @Override + public void putStack(ItemStack stack) { + ItemStack testStack = getStack(); + if ((stack.isEmpty() ^ testStack.isEmpty()) || !testStack.isItemEqual(stack) || + !ItemStack.areItemStackTagsEqual(testStack, stack)) { + ItemStack copy = stack.copy(); + copy.setCount(1); + super.putStack(copy); + this.parent.updatePreview(); + } + } + + @Override + public int getSlotStackLimit() { + return 1; + } + + @Override + public int getItemStackLimit(@NotNull ItemStack stack) { + return 1; + } +} diff --git a/src/main/java/gregtech/common/mui/widget/orefilter/OreFilterTestSlot.java b/src/main/java/gregtech/common/mui/widget/orefilter/OreFilterTestSlot.java new file mode 100644 index 00000000000..1948364bbec --- /dev/null +++ b/src/main/java/gregtech/common/mui/widget/orefilter/OreFilterTestSlot.java @@ -0,0 +1,144 @@ +package gregtech.common.mui.widget.orefilter; + +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.unification.OreDictUnifier; +import gregtech.api.util.function.BooleanConsumer; +import gregtech.api.util.oreglob.OreGlob; +import gregtech.common.covers.filter.oreglob.impl.ImpossibleOreGlob; + +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.theme.WidgetTheme; +import com.cleanroommc.modularui.widgets.ItemSlot; +import it.unimi.dsi.fastutil.objects.Object2BooleanAVLTreeMap; +import it.unimi.dsi.fastutil.objects.Object2BooleanMap; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * @author brachy84 + */ +public class OreFilterTestSlot extends ItemSlot { + + private final ItemOreFilterTestSlot slot; + private Supplier globSupplier = ImpossibleOreGlob::getInstance; + @Nullable + private BooleanConsumer onMatchChange; + private final Object2BooleanMap testResult = new Object2BooleanAVLTreeMap<>(); + private MatchType matchType = MatchType.INVALID; + private boolean matchSuccess; + private boolean matchAll; + + public OreFilterTestSlot() { + this.slot = new ItemOreFilterTestSlot(); + this.slot.setParent(this); + slot(this.slot); + tooltipBuilder(tooltip -> { + if (!isEnabled()) return; + tooltip.addDrawableLines(switch (this.matchType) { + case NO_ORE_DICT_MATCH -> Collections.singletonList(IKey.lang(this.matchSuccess ? + "cover.ore_dictionary_filter.test_slot.no_oredict.matches" : + "cover.ore_dictionary_filter.test_slot.no_oredict.matches_not")); + case ORE_DICT_MATCH -> this.testResult.object2BooleanEntrySet() + .stream().map(e -> IKey.lang(e.getBooleanValue() ? + "cover.ore_dictionary_filter.test_slot.matches" : + "cover.ore_dictionary_filter.test_slot.matches_not", e.getKey())) + .collect(Collectors.toList()); + default -> Collections.singletonList(IKey.lang("cover.ore_dictionary_filter.test_slot.info")); + }); + }); + } + + public OreFilterTestSlot setGlobSupplier(Supplier supplier) { + this.globSupplier = supplier; + this.updatePreview(); + return getThis(); + } + + @Override + public OreFilterTestSlot getThis() { + return this; + } + + public boolean isMatchSuccess() { + return matchSuccess; + } + + public OreFilterTestSlot onMatchChange(@Nullable BooleanConsumer onMatchChange) { + this.onMatchChange = onMatchChange; + return getThis(); + } + + public void setMatchAll(boolean matchAll) { + if (this.matchAll == matchAll) return; + this.matchAll = matchAll; + updatePreview(); + } + + public void updatePreview() { + Set oreDicts = getTestCandidates(); + this.testResult.clear(); + if (oreDicts == null) { + this.matchType = MatchType.INVALID; + updateAndNotifyMatchSuccess(false); + return; + } + OreGlob glob = this.globSupplier.get(); + int success = 0; + if (oreDicts.isEmpty()) { + // no oredict entries + this.testResult.put("", glob != null && glob.matches("")); + this.matchType = MatchType.NO_ORE_DICT_MATCH; + } else { + for (String oreDict : oreDicts) { + boolean matches = glob != null && glob.matches(oreDict); + if (matches) success++; + this.testResult.put(oreDict, matches); + } + this.matchType = MatchType.ORE_DICT_MATCH; + } + updateAndNotifyMatchSuccess(this.matchAll ? success == testResult.size() : success > 0); + this.tooltip().markDirty(); + } + + @Override + public void draw(GuiContext context, WidgetTheme widgetTheme) { + super.draw(context, widgetTheme); + if (this.matchSuccess) { + GTGuiTextures.OREDICT_MATCH + .draw(context, 12, -2, 9, 6, widgetTheme); + } else if (testResult.size() > 0) { + GTGuiTextures.OREDICT_NO_MATCH + .draw(context, 12, -3, 7, 7, widgetTheme); + } + } + + private void updateAndNotifyMatchSuccess(boolean newValue) { + if (this.matchSuccess == newValue) return; + this.matchSuccess = newValue; + if (this.onMatchChange != null) { + this.onMatchChange.apply(newValue); + } + } + + /** + * Get each test candidate for current state of test slot. An empty collection indicates that the match is for items + * without any ore dictionary entry. A {@code null} value indicates that the input state is invalid or empty. + * + * @return each test candidate for current state of test slot + */ + @Nullable + protected Set getTestCandidates() { + return this.slot.getStack().isEmpty() ? null : OreDictUnifier.getOreDictionaryNames(this.slot.getStack()); + } + + private enum MatchType { + NO_ORE_DICT_MATCH, + ORE_DICT_MATCH, + INVALID + } +} diff --git a/src/main/java/gregtech/common/pipelike/cable/BlockCable.java b/src/main/java/gregtech/common/pipelike/cable/BlockCable.java index d384e22e608..204010ed522 100644 --- a/src/main/java/gregtech/common/pipelike/cable/BlockCable.java +++ b/src/main/java/gregtech/common/pipelike/cable/BlockCable.java @@ -1,6 +1,5 @@ package gregtech.common.pipelike.cable; -import gregtech.api.GregTechAPI; import gregtech.api.capability.GregtechCapabilities; import gregtech.api.damagesources.DamageSources; import gregtech.api.items.toolitem.ToolClasses; @@ -14,6 +13,7 @@ import gregtech.api.util.GTUtility; import gregtech.client.renderer.pipe.CableRenderer; import gregtech.client.renderer.pipe.PipeRenderer; +import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.pipelike.cable.net.WorldENet; import gregtech.common.pipelike.cable.tile.TileEntityCable; import gregtech.common.pipelike.cable.tile.TileEntityCableTickable; @@ -54,7 +54,7 @@ public class BlockCable extends BlockMaterialPipe T getCapability(Capability capability, EnumFacing side) { if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) { @@ -96,6 +91,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, } @Override + @SideOnly(Side.CLIENT) public Pair getParticleTexture() { return Pair.of(Textures.VOLTAGE_CASINGS[GTValues.LV].getParticleSprite(), 0xFFFFFF); } diff --git a/src/main/java/gregtech/common/pipelike/itempipe/BlockItemPipe.java b/src/main/java/gregtech/common/pipelike/itempipe/BlockItemPipe.java index e06a3d27d59..7f6c79f9caa 100644 --- a/src/main/java/gregtech/common/pipelike/itempipe/BlockItemPipe.java +++ b/src/main/java/gregtech/common/pipelike/itempipe/BlockItemPipe.java @@ -1,6 +1,5 @@ package gregtech.common.pipelike.itempipe; -import gregtech.api.GregTechAPI; import gregtech.api.items.toolitem.ToolClasses; import gregtech.api.pipenet.block.material.BlockMaterialPipe; import gregtech.api.pipenet.tile.IPipeTile; @@ -10,6 +9,7 @@ import gregtech.api.unification.material.registry.MaterialRegistry; import gregtech.client.renderer.pipe.ItemPipeRenderer; import gregtech.client.renderer.pipe.PipeRenderer; +import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.pipelike.itempipe.net.WorldItemPipeNet; import gregtech.common.pipelike.itempipe.tile.TileEntityItemPipe; import gregtech.common.pipelike.itempipe.tile.TileEntityItemPipeTickable; @@ -44,7 +44,7 @@ public class BlockItemPipe extends BlockMaterialPipe getParticleTexture(World world, BlockPos blockPos) { return ItemPipeRenderer.INSTANCE.getParticleTexture((TileEntityItemPipe) world.getTileEntity(blockPos)); } diff --git a/src/main/java/gregtech/common/pipelike/itempipe/longdistance/MetaTileEntityLDItemEndpoint.java b/src/main/java/gregtech/common/pipelike/itempipe/longdistance/MetaTileEntityLDItemEndpoint.java index e062224904b..dd04ac94ab0 100644 --- a/src/main/java/gregtech/common/pipelike/itempipe/longdistance/MetaTileEntityLDItemEndpoint.java +++ b/src/main/java/gregtech/common/pipelike/itempipe/longdistance/MetaTileEntityLDItemEndpoint.java @@ -2,7 +2,6 @@ import gregtech.api.GTValues; import gregtech.api.capability.impl.ItemHandlerDelegate; -import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.pipenet.longdist.ILDEndpoint; @@ -11,12 +10,13 @@ import gregtech.common.metatileentities.storage.MetaTileEntityLongDistanceEndpoint; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemStackHandler; @@ -55,11 +55,6 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { return new MetaTileEntityLDItemEndpoint(this.metaTileEntityId); } - @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return null; - } - @Override public T getCapability(Capability capability, EnumFacing side) { if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { @@ -97,6 +92,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, } @Override + @SideOnly(Side.CLIENT) public Pair getParticleTexture() { return Pair.of(Textures.VOLTAGE_CASINGS[GTValues.LV].getParticleSprite(), 0xFFFFFF); } diff --git a/src/main/java/gregtech/common/pipelike/itempipe/net/ItemNetHandler.java b/src/main/java/gregtech/common/pipelike/itempipe/net/ItemNetHandler.java index a2313f82398..20967af87e4 100644 --- a/src/main/java/gregtech/common/pipelike/itempipe/net/ItemNetHandler.java +++ b/src/main/java/gregtech/common/pipelike/itempipe/net/ItemNetHandler.java @@ -6,7 +6,11 @@ import gregtech.api.util.FacingPos; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.ItemStackHashStrategy; -import gregtech.common.covers.*; +import gregtech.common.covers.CoverConveyor; +import gregtech.common.covers.CoverItemFilter; +import gregtech.common.covers.CoverRoboticArm; +import gregtech.common.covers.DistributionMode; +import gregtech.common.covers.ItemFilterMode; import gregtech.common.pipelike.itempipe.tile.TileEntityItemPipe; import net.minecraft.item.ItemStack; @@ -364,15 +368,18 @@ public Cover getCoverOnNeighbour(TileEntityItemPipe itemPipe, EnumFacing facing) public ItemStack insertOverRobotArm(IItemHandler handler, CoverRoboticArm arm, ItemStack stack, boolean simulate, int allowed, boolean ignoreLimit) { - int rate; + var matched = arm.getItemFilterContainer().match(stack); boolean isStackSpecific = false; - Object index = arm.getItemFilterContainer().matchItemStack(stack); - if (index instanceof Integer) { - rate = arm.getItemFilterContainer().getSlotTransferLimit(index); + int rate, count; + + if (matched.isMatched()) { + int index = matched.getFilterIndex(); + rate = arm.getItemFilterContainer().getTransferLimit(index); isStackSpecific = true; - } else - rate = arm.getItemFilterContainer().getTransferStackSize(); - int count; + } else { + rate = arm.getItemFilterContainer().getTransferSize(); + } + switch (arm.getTransferMode()) { case TRANSFER_ANY: return insert(handler, stack, simulate, allowed, ignoreLimit); @@ -405,7 +412,7 @@ public static int countStack(IItemHandler handler, ItemStack stack, CoverRobotic ItemStack slot = handler.getStackInSlot(i); if (slot.isEmpty()) continue; if (isStackSpecific ? ItemStackHashStrategy.comparingAllButCount().equals(stack, slot) : - arm.getItemFilterContainer().testItemStack(slot)) { + arm.getItemFilterContainer().test(slot)) { count += slot.getCount(); } } diff --git a/src/main/java/gregtech/common/pipelike/laser/BlockLaserPipe.java b/src/main/java/gregtech/common/pipelike/laser/BlockLaserPipe.java index c7adec7b706..1c3ac132b60 100644 --- a/src/main/java/gregtech/common/pipelike/laser/BlockLaserPipe.java +++ b/src/main/java/gregtech/common/pipelike/laser/BlockLaserPipe.java @@ -1,6 +1,5 @@ package gregtech.common.pipelike.laser; -import gregtech.api.GregTechAPI; import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.items.toolitem.ToolClasses; import gregtech.api.items.toolitem.ToolHelper; @@ -9,6 +8,7 @@ import gregtech.api.pipenet.tile.TileEntityPipeBase; import gregtech.client.renderer.pipe.LaserPipeRenderer; import gregtech.client.utils.BloomEffectUtil; +import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.pipelike.laser.net.WorldLaserPipeNet; import gregtech.common.pipelike.laser.tile.TileEntityLaserPipe; @@ -39,11 +39,12 @@ public class BlockLaserPipe extends BlockPipe getParticleTexture(World world, BlockPos blockPos) { return LaserPipeRenderer.INSTANCE.getParticleTexture((TileEntityLaserPipe) world.getTileEntity(blockPos)); } diff --git a/src/main/java/gregtech/common/pipelike/optical/BlockOpticalPipe.java b/src/main/java/gregtech/common/pipelike/optical/BlockOpticalPipe.java index 87426fb81de..597fc322801 100644 --- a/src/main/java/gregtech/common/pipelike/optical/BlockOpticalPipe.java +++ b/src/main/java/gregtech/common/pipelike/optical/BlockOpticalPipe.java @@ -1,6 +1,5 @@ package gregtech.common.pipelike.optical; -import gregtech.api.GregTechAPI; import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.items.toolitem.ToolClasses; import gregtech.api.items.toolitem.ToolHelper; @@ -8,6 +7,7 @@ import gregtech.api.pipenet.tile.IPipeTile; import gregtech.api.pipenet.tile.TileEntityPipeBase; import gregtech.client.renderer.pipe.OpticalPipeRenderer; +import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.pipelike.optical.net.WorldOpticalPipeNet; import gregtech.common.pipelike.optical.tile.TileEntityOpticalPipe; @@ -37,11 +37,12 @@ public class BlockOpticalPipe extends BlockPipe getParticleTexture(@NotNull World world, BlockPos blockPos) { return OpticalPipeRenderer.INSTANCE.getParticleTexture((TileEntityOpticalPipe) world.getTileEntity(blockPos)); } diff --git a/src/main/java/gregtech/common/terminal/app/VirtualTankApp.java b/src/main/java/gregtech/common/terminal/app/VirtualTankApp.java deleted file mode 100644 index b6a24a190b9..00000000000 --- a/src/main/java/gregtech/common/terminal/app/VirtualTankApp.java +++ /dev/null @@ -1,261 +0,0 @@ -package gregtech.common.terminal.app; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.resources.TextTexture; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.TankWidget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.terminal.gui.widgets.RectButtonWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.terminal.os.menu.IMenuComponent; -import gregtech.api.util.GTLog; -import gregtech.api.util.VirtualTankRegistry; -import gregtech.common.terminal.component.SearchComponent; - -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.PacketBuffer; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTank; -import net.minecraftforge.fluids.IFluidTank; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.commons.lang3.tuple.Pair; - -import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -public class VirtualTankApp extends AbstractApplication implements SearchComponent.IWidgetSearch> { - - private WidgetGroup widgetGroup; - private Map, FluidStack> cacheServer; - @SideOnly(Side.CLIENT) - private Map, IFluidTank> cacheClient; - - public VirtualTankApp() { - super("vtank_viewer"); - } - - @Override - public AbstractApplication initApp() { - this.addWidget(new ImageWidget(5, 5, 333 - 10, 232 - 10, TerminalTheme.COLOR_B_2)); - this.addWidget(new LabelWidget(10, 10, "terminal.vtank_viewer.title", -1)); - this.addWidget(new RectButtonWidget(216, 7, 110, 18) - .setClickListener(cd -> { - if (cd.isClient) { - reloadWidgets(cacheClient); - } - }) - .setIcon(new TextTexture("terminal.vtank_viewer.refresh", -1)) - .setFill(TerminalTheme.COLOR_B_2.getColor())); - widgetGroup = new DraggableScrollableWidgetGroup(10, 30, 313, 195) - .setDraggable(true) - .setYScrollBarWidth(3) - .setYBarStyle(null, TerminalTheme.COLOR_F_1); - if (isClient) { - cacheClient = new HashMap<>(); - } else { - cacheServer = new HashMap<>(); - } - this.addWidget(widgetGroup); - if (!isRemote()) { - refresh(); - } - return this; - } - - private List> findVirtualTanks() { - List> result = new LinkedList<>(); - Map> tankMap = VirtualTankRegistry.getTankMap(); - for (UUID uuid : tankMap.keySet().stream().sorted(Comparator.nullsLast(UUID::compareTo)) - .collect(Collectors.toList())) { - if (uuid == null || uuid.equals(gui.entityPlayer.getUniqueID())) { - for (String key : tankMap.get(uuid).keySet().stream().sorted().collect(Collectors.toList())) { - result.add(new ImmutablePair<>(uuid, key)); - } - } - } - return result; - } - - @Override - public void detectAndSendChanges() { - super.detectAndSendChanges(); - if (gui.entityPlayer.ticksExisted % 20 == 0) { - refresh(); - } - } - - private void refresh() { - Map> tankMap = VirtualTankRegistry.getTankMap(); - Map, FluidStack> access = new HashMap<>(); - for (Pair virtualTankEntry : findVirtualTanks()) { - UUID uuid = virtualTankEntry.getKey(); - String key = virtualTankEntry.getValue(); - FluidStack fluidStack = tankMap.get(uuid).get(key).getFluid(); - access.put(new ImmutablePair<>(uuid, key), fluidStack == null ? null : fluidStack.copy()); - } - if (access.keySet().containsAll(cacheServer.keySet()) && access.size() == cacheServer.size()) { - List> toUpdated = new LinkedList<>(); - for (Map.Entry, FluidStack> entry : access.entrySet()) { - Pair pair = entry.getKey(); - FluidStack fluidStackNew = entry.getValue(); - FluidStack fluidStackOld = cacheServer.get(pair); - if (fluidStackNew == null && fluidStackOld == null) { - continue; - } - if (fluidStackNew != null && fluidStackOld == null) { - toUpdated.add(pair); - } else if (fluidStackNew == null) { - toUpdated.add(pair); - } else if (fluidStackOld.amount != fluidStackNew.amount || !fluidStackNew.isFluidEqual(fluidStackOld)) { - toUpdated.add(pair); - } - } - if (!toUpdated.isEmpty()) { - writeUpdateInfo(-2, buffer -> { // update specific info - buffer.writeVarInt(toUpdated.size()); - for (Pair update : toUpdated) { - buffer.writeBoolean(update.getKey() != null); - if (update.getKey() != null) { - buffer.writeString(update.getKey().toString()); - } - buffer.writeString(update.getValue()); - FluidStack value = access.get(update); - buffer.writeBoolean(value != null); - if (value != null) { - buffer.writeCompoundTag(value.writeToNBT(new NBTTagCompound())); - } - } - }); - } - return; - } - cacheServer = access; - writeUpdateInfo(-1, buffer -> { // update all info - buffer.writeVarInt(cacheServer.size()); - cacheServer.forEach((key, value) -> { - buffer.writeBoolean(key.getKey() != null); - if (key.getKey() != null) { - buffer.writeString(key.getKey().toString()); - } - buffer.writeString(key.getValue()); - buffer.writeBoolean(value != null); - if (value != null) { - buffer.writeCompoundTag(value.writeToNBT(new NBTTagCompound())); - } - }); - }); - } - - @Override - public void readUpdateInfo(int id, PacketBuffer buffer) { - if (id == -1) { // update all info - int size = buffer.readVarInt(); - cacheClient.clear(); - try { - for (int i = 0; i < size; i++) { - UUID uuid = null; - if (buffer.readBoolean()) { - uuid = UUID.fromString(buffer.readString(32767)); - } - String key = buffer.readString(32767); - IFluidTank fluidTank = new FluidTank(64000); - if (buffer.readBoolean()) { - fluidTank.fill(FluidStack.loadFluidStackFromNBT(buffer.readCompoundTag()), true); - } - cacheClient.put(new ImmutablePair<>(uuid, key), fluidTank); - } - } catch (Exception e) { - GTLog.logger.error("error sync fluid", e); - } - reloadWidgets(cacheClient); - } else if (id == -2) { - int size = buffer.readVarInt(); - try { - for (int i = 0; i < size; i++) { - UUID uuid = null; - if (buffer.readBoolean()) { - uuid = UUID.fromString(buffer.readString(32767)); - } - String key = buffer.readString(32767); - FluidStack fluidStack = null; - if (buffer.readBoolean()) { - fluidStack = FluidStack.loadFluidStackFromNBT(buffer.readCompoundTag()); - } - - IFluidTank fluidTank = cacheClient.get(new ImmutablePair<>(uuid, key)); - if (fluidTank != null) { - fluidTank.drain(64000, true); - if (fluidStack != null) { - fluidTank.fill(fluidStack, true); - } - } - } - } catch (Exception e) { - GTLog.logger.error("error sync fluid", e); - } - } else { - super.readUpdateInfo(id, buffer); - } - } - - private void reloadWidgets(Map, IFluidTank> map) { - widgetGroup.clearAllWidgets(); - AtomicInteger cy = new AtomicInteger(); - map.forEach((key, fluidTank) -> { - if (key.getKey() != null) { - widgetGroup.addWidget(new ImageWidget(0, cy.get() + 4, 8, 8, GuiTextures.LOCK_WHITE)); - } - widgetGroup.addWidget(new TankWidget(fluidTank, 8, cy.get(), 18, 18) - .setAlwaysShowFull(true) - .setBackgroundTexture(GuiTextures.FLUID_SLOT).setClient()); - widgetGroup.addWidget(new LabelWidget(36, cy.get() + 5, key.getValue(), -1) - .setWidth(180)); - cy.addAndGet(23); - }); - } - - @Override - public List getMenuComponents() { - return Collections.singletonList(new SearchComponent<>(this)); - } - - @Override - public String resultDisplay(Pair result) { - FluidStack fluidStack = VirtualTankRegistry.getTankMap().get(result.getKey()).get(result.getValue()).getFluid(); - return String.format("Lock: %b, ID: %s, Fluid: %s", result.getKey() != null, result.getValue(), - fluidStack == null ? "-" : fluidStack.getLocalizedName()); - } - - @Override - public void selectResult(Pair result) { - Map, IFluidTank> map = new HashMap<>(); - map.put(result, cacheClient.get(result)); - reloadWidgets(map); - } - - @Override - public void search(String word, Consumer> find) { - if (!isClient) - return; - for (Map.Entry, IFluidTank> access : cacheClient.entrySet()) { - Pair accessingCover = access.getKey(); - if (accessingCover.getValue() != null && - accessingCover.getValue().toLowerCase().contains(word.toLowerCase())) { - find.accept(accessingCover); - } else { - FluidStack fluidStack = access.getValue().getFluid(); - if (fluidStack != null && fluidStack.getLocalizedName().toLowerCase().contains(word.toLowerCase())) { - find.accept(accessingCover); - } - } - } - } -} diff --git a/src/main/java/gregtech/common/terminal/app/appstore/AppCardWidget.java b/src/main/java/gregtech/common/terminal/app/appstore/AppCardWidget.java deleted file mode 100644 index f06ec173db3..00000000000 --- a/src/main/java/gregtech/common/terminal/app/appstore/AppCardWidget.java +++ /dev/null @@ -1,201 +0,0 @@ -package gregtech.common.terminal.app.appstore; - -import gregtech.api.GTValues; -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.resources.*; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.gui.widgets.AnimaWidgetGroup; -import gregtech.api.terminal.gui.widgets.CircleButtonWidget; -import gregtech.api.terminal.os.TerminalDialogWidget; -import gregtech.api.terminal.os.TerminalOSWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.util.interpolate.Eases; -import gregtech.api.util.interpolate.Interpolator; -import gregtech.client.shader.Shaders; -import gregtech.client.utils.RenderUtil; -import gregtech.common.items.behaviors.TerminalBehaviour; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; -import net.minecraft.network.PacketBuffer; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import java.awt.*; -import java.util.List; - -public class AppCardWidget extends AnimaWidgetGroup { - - private final AbstractApplication application; - private final AppStoreApp store; - @SideOnly(Side.CLIENT) - private ImageWidget stateWidget; - @SideOnly(Side.CLIENT) - private ImageWidget bgWidget; - @SideOnly(Side.CLIENT) - private IGuiTexture banner; - @SideOnly(Side.CLIENT) - private int offset; - @SideOnly(Side.CLIENT) - private int alpha; - - public AppCardWidget(int x, int y, AbstractApplication application, AppStoreApp store) { - super(x, y, 100, 100); - this.application = application; - this.store = store; - TerminalOSWidget os = store.getOs(); - if (os.isRemote()) { - this.addWidget(new CircleButtonWidget(15, 17) - .setColors(TerminalTheme.COLOR_B_2.getColor(), - application.getThemeColor(), - TerminalTheme.COLOR_B_2.getColor()) - .setHoverText(application.getUnlocalizedName()) - .setIcon(application.getIcon())); - this.addWidget(new ImageWidget(30, 0, 65, 34, - new TextTexture(application.getUnlocalizedName(), -1).setDropShadow(true) - .setWidth(65))); - offset = Math.abs(GTValues.RNG.nextInt()) % 200; - banner = application.getBanner(); - if (os.installedApps.contains(application)) { - if (TerminalBehaviour.isCreative(os.itemStack) || application.getMaxTier() == - Math.min(os.tabletNBT.getCompoundTag(application.getRegistryName()).getInteger("_tier"), - application.getMaxTier())) { - updateState(0); - } else { - updateState(1); - } - } else { - updateState(2); - } - } - } - - @SideOnly(Side.CLIENT) - public void updateState(int state) { - String text = "Latest"; - int bg = 0xff4B4C4C; - if (state == 1) { - text = "Upgrade"; - bg = 0xffF7911F; - } else if (state == 2) { - text = "Install"; - bg = 0xff67F74B; - } - if (stateWidget != null) { - removeWidget(stateWidget); - removeWidget(bgWidget); - } - stateWidget = new ImageWidget(15, 85, 70, 15, - new TextTexture(text, -1).setWidth(70).setDropShadow(true).setType(TextTexture.TextType.HIDE)); - bgWidget = new ImageWidget(15, 85, 70, 13, new ColorRectTexture(bg)); - this.addWidget(bgWidget); - this.addWidget(stateWidget); - } - - private void openDialog() { - new AppPageWidget(application, store, this).open(); - } - - @Override - public void handleClientAction(int id, PacketBuffer buffer) { - if (id == -1) { // open page - if (buffer.readBoolean()) { - openDialog(); - } - } else { - super.handleClientAction(id, buffer); - } - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (isMouseOverElement(mouseX, mouseY)) { - writeClientAction(-1, buffer -> buffer.writeBoolean(true)); - openDialog(); - } - return super.mouseClicked(mouseX, mouseY, button); - } - - @Override - public void hookDrawInForeground(int mouseX, int mouseY) { - // hover - int x = getPosition().x; - int y = getPosition().y; - int width = getSize().width; - int height = getSize().height; - if (isMouseOverElement(mouseX, mouseY) && - store.getOs().desktop.widgets.stream().noneMatch(app -> app instanceof TerminalDialogWidget)) { - int dur = 7; - int maxAlpha = 100; // 0-255!!!!! - float partialTicks = Minecraft.getMinecraft().getRenderPartialTicks(); - if (alpha != maxAlpha && interpolator == null) { - interpolator = new Interpolator(0, maxAlpha, dur, Eases.LINEAR, - value -> alpha = value.intValue(), - value -> interpolator = null); - interpolator.start(); - } - // smooth - int color; - if (alpha == maxAlpha) { - color = TerminalTheme.COLOR_B_2.getColor() & 0x00ffffff | ((alpha) << 24); - } else { - color = TerminalTheme.COLOR_B_2.getColor() & 0x00ffffff | - ((alpha + (int) (maxAlpha * partialTicks / dur)) << 24); - } - int finalColor = color; - RenderUtil.useScissor(store.getPosition().x, store.getPosition().y, store.getSize().width, - store.getSize().height, () -> { - drawSolidRect(0, 0, gui.getScreenWidth(), y, finalColor); - drawSolidRect(0, y + height, gui.getScreenWidth(), gui.getScreenHeight(), finalColor); - drawSolidRect(0, y, x, height, finalColor); - drawSolidRect(x + width, y, gui.getScreenWidth(), height, finalColor); - - drawBorder(x, y, width, height, application.getThemeColor(), -1); - }); - } else { - alpha = 0; - } - super.hookDrawInForeground(mouseX, mouseY); - } - - @Override - public void hookDrawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - int x = getPosition().x; - int y = getPosition().y; - int width = getSize().width; - int height = getSize().height; - Color color = new Color(application.getThemeColor()); - drawSolidRect(x, y, width, height, color.getRGB() & 0x00ffffff | 0x4f000000); - if (banner != null) { - banner.draw(x, y, width, 34); - } else { - if (Shaders.allowedShader()) { - float time = offset + (gui.entityPlayer.ticksExisted + partialTicks) / 20f; - ShaderTexture.createShader("banner.frag").draw(x, y, width, 34, uniformCache -> { - uniformCache.glUniform1F("u_time", time); - uniformCache.glUniform3F("b_color", color.getRed() / 255f, color.getGreen() / 255f, - color.getBlue() / 255f); - }); - } else { - drawSolidRect(x, y, width, 34, color.getRGB()); - } - } - super.hookDrawInBackground(mouseX, mouseY, partialTicks, context); - - // description - FontRenderer fr = Minecraft.getMinecraft().fontRenderer; - List description = fr.listFormattedStringToWidth(application.getDescription(), 90); - int fColor = store.darkMode ? -1 : 0xff333333; - for (int i = 0; i < Math.min(description.size(), 4); i++) { - fr.drawString(description.get(i), x + 5, y + 40 + i * fr.FONT_HEIGHT, fColor, store.darkMode); - } - if (description.size() > 4) { - fr.drawString("...", x + 5, y + 40 + 4 * fr.FONT_HEIGHT, fColor, store.darkMode); - } - - // shadow - drawGradientRect(x, y + 34, width, 3, 0x6f000000, 0, false); - drawRectShadow(x, y, width, height, 5); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/appstore/AppPageWidget.java b/src/main/java/gregtech/common/terminal/app/appstore/AppPageWidget.java deleted file mode 100644 index dc02aac2078..00000000000 --- a/src/main/java/gregtech/common/terminal/app/appstore/AppPageWidget.java +++ /dev/null @@ -1,305 +0,0 @@ -package gregtech.common.terminal.app.appstore; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.SlotWidget; -import gregtech.api.terminal.TerminalRegistry; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.gui.widgets.CircleButtonWidget; -import gregtech.api.terminal.os.TerminalDialogWidget; -import gregtech.api.terminal.os.TerminalOSWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.util.interpolate.Eases; -import gregtech.api.util.interpolate.Interpolator; -import gregtech.common.inventory.handlers.SingleItemStackHandler; -import gregtech.common.items.behaviors.TerminalBehaviour; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.resources.I18n; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.nbt.NBTTagString; -import net.minecraftforge.common.util.Constants; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -public class AppPageWidget extends TerminalDialogWidget { - - private final AbstractApplication application; - private final AppCardWidget appCardWidget; - private final AppStoreApp store; - private final CircleButtonWidget[] buttons; - private int lineWidth; - private boolean back; - - public AppPageWidget(AbstractApplication application, AppStoreApp store, AppCardWidget appCardWidget) { // 323 222 - super(store.getOs(), 5, 5, 333 - 10, 232 - 10); - this.appCardWidget = appCardWidget; - this.application = application; - this.store = store; - String name = this.application.getRegistryName(); - int stage = application.getMaxTier() + 1; - - int dur = 323 / (stage + 1); - buttons = new CircleButtonWidget[stage]; - for (int i = 0; i < stage; i++) { - int tier = i; - // upgrade button - buttons[i] = new CircleButtonWidget(dur + dur * i, 110, 6, 2, 0) - .setClickListener(cd -> buttonClicked(tier)); - this.addWidget(buttons[i]); - } - this.addWidget(new CircleButtonWidget(310, 10, 6, 1, 8) - .setColors(0, - TerminalTheme.COLOR_7.getColor(), - TerminalTheme.COLOR_3.getColor()) - .setIcon(GuiTextures.ICON_REMOVE) - .setHoverText("terminal.store.close") - .setClickListener(cd -> close())); - if (store.getOs().isRemote()) { - // profile - int color = application.getThemeColor(); - int lightColor = color & 0x00ffffff | ((0x6f) << 24); - IGuiTexture profile = application.getProfile(); - this.addWidget(new ImageWidget(10, 15, 80, 80, profile)); - - for (int i = 0; i < stage; i++) { - List demand = TerminalRegistry.getAppHardwareDemand(name, i) - .stream() - .map(hw -> hw.getLocalizedName() + "(" + hw.addInformation() + ")") - .collect(Collectors.toList()); - demand.add(0, application.getTierInformation(i)); - buttons[i].setColors(0, lightColor, color).setHoverText(demand.toArray(new String[0])); - List conditions = TerminalRegistry.getAppHardwareUpgradeConditions(name, i); - // line - if (conditions.size() > 0) { - this.addWidget(new ImageWidget(dur + dur * i, 115, 1, - -18 + (conditions.size() >= 4 ? 4 * 25 : conditions.size() * 25), - new ColorRectTexture(0xafffffff))); - } - // conditions - for (int j = 0; j < conditions.size(); j++) { - this.addWidget(new SlotWidget(new SingleItemStackHandler(conditions.get(j)), 0, - dur + dur * i + 25 * (j / 4) - 9, 120 + 25 * (j % 4), false, false)); - } - } - } - } - - private void buttonClicked(int tier) { - int lastTier; - TerminalOSWidget os = store.getOs(); - if (!os.installedApps.contains(application)) { - lastTier = -1; - } else if (TerminalBehaviour.isCreative(os.itemStack)) { - lastTier = application.getMaxTier(); - } else { - lastTier = Math.min(os.tabletNBT.getCompoundTag(application.getRegistryName()).getInteger("_tier"), - application.getMaxTier()); - } - String name = application.getRegistryName(); - if (tier > lastTier) { - boolean match = true; // inventory match - List requirements = new ArrayList<>(); - ItemStack missStack = null; - if (!gui.entityPlayer.isCreative()) { - for (int i = lastTier + 1; i <= tier; i++) { - for (ItemStack condition : TerminalRegistry.getAppHardwareUpgradeConditions(name, i)) { - boolean miss = true; - for (ItemStack requirement : requirements) { - if (requirement.isItemEqual(condition)) { - requirement.setCount(requirement.getCount() + condition.getCount()); - miss = false; - break; - } - } - if (miss) { - requirements.add(condition.copy()); - } - } - } - for (ItemStack requirement : requirements) { - int left = requirement.getCount(); - for (ItemStack hold : gui.entityPlayer.inventory.mainInventory) { - if (requirement.isItemEqual(hold)) { - if (hold.getCount() < left) { - left -= hold.getCount(); - } else { - left = 0; - } - if (left == 0) { - break; - } - } - } - if (left > 0) { - missStack = requirement.copy(); - missStack.setCount(left); - match = false; - break; - } - } - } - - if (match) { - if (os.isRemote()) { - appCardWidget.updateState(tier == application.getMaxTier() ? 0 : 1); - } - if (!gui.entityPlayer.isCreative()) { // cost - TerminalDialogWidget - .showConfirmDialog(store.getOs(), "terminal.dialog.notice", "terminal.store.match", res -> { - if (res) { - for (ItemStack requirement : requirements) { - int left = requirement.getCount(); - for (ItemStack hold : gui.entityPlayer.inventory.mainInventory) { - if (requirement.isItemEqual(hold)) { - if (hold.getCount() <= left) { - hold.setCount(0); - left -= hold.getCount(); - } else { - hold.setCount(hold.getCount() - left); - left = 0; - } - if (left == 0) { - break; - } - } - } - } - updateTerminalAppTier(tier, lastTier); - } - }).open(); - } else { - updateTerminalAppTier(tier, lastTier); - } - } else { - if (isRemote()) { - TerminalDialogWidget.showInfoDialog(store.getOs(), - "terminal.dialog.notice", - I18n.format("terminal.store.miss", missStack.getDisplayName(), missStack.getCount())) - .setClientSide().open(); - } - } - } - } - - private void updateTerminalAppTier(int tier, int lastTier) { - TerminalOSWidget os = store.getOs(); - os.openedApps.stream() - .filter(app -> app.getRegistryName().equals(this.application.getRegistryName())) - .findFirst() - .ifPresent(app -> os.closeApplication(app, os.isRemote())); - if (lastTier == -1) { // update terminal - NBTTagList installed = os.tabletNBT.getTagList("_installed", Constants.NBT.TAG_STRING); - installed.appendTag(new NBTTagString(application.getRegistryName())); - os.tabletNBT.setTag("_installed", installed); - os.installApplication(application); - } - NBTTagCompound tag = os.tabletNBT.getCompoundTag(application.getRegistryName()); - tag.setInteger("_tier", tier); - os.tabletNBT.setTag(application.getRegistryName(), tag); - lineWidth = 0; - } - - @Override - public void hookDrawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - int x = getPosition().x; - int y = getPosition().y; - int width = getSize().width; - int height = getSize().height; - - GlStateManager.disableDepth(); - - drawSolidRect(x, y, width, height, store.darkMode ? 0xcf000000 : 0xdfdddddd); - super.hookDrawInBackground(mouseX, mouseY, partialTicks, context); - int stage; - TerminalOSWidget os = store.getOs(); - if (!os.installedApps.contains(application)) { - stage = 0; - } else if (TerminalBehaviour.isCreative(os.itemStack)) { - stage = application.getMaxTier() + 1; - } else { - stage = Math.min(os.tabletNBT.getCompoundTag(application.getRegistryName()).getInteger("_tier"), - application.getMaxTier()) + 1; - } - int maxStage = application.getMaxTier() + 1; - int color = application.getThemeColor(); - int lightColor = color & 0x00ffffff | ((0x6f) << 24); - int dur = 323 / (maxStage + 1); - - int hover = -1; - for (int i = 0; i < buttons.length; i++) { - if (buttons[i].isMouseOverElement(mouseX, mouseY)) { - hover = i; - } - } - - // draw current tier - drawSolidRect(x, y + 110 - 2, dur * stage, 4, color); - if (stage == maxStage) { - drawSolidRect(x + stage * dur, y + 110 - 2, dur, 4, color); - } else { - drawSolidRect(x + stage * dur, y + 110 - 2, dur, 4, lightColor); - } - - int end = dur * (hover + 1 - stage); - - if (hover + 1 > stage) { - if (lineWidth != end && (interpolator == null || back)) { - back = false; - interpolator = new Interpolator(lineWidth, end, (end - lineWidth) / 15, Eases.LINEAR, - value -> lineWidth = value.intValue(), - value -> interpolator = null); - interpolator.start(); - } - } else { - if (lineWidth != 0 && (interpolator == null || !back)) { - back = true; - interpolator = new Interpolator(lineWidth, 0, lineWidth / 15, Eases.LINEAR, - value -> lineWidth = value.intValue(), - value -> interpolator = null); - interpolator.start(); - } - } - - if (lineWidth != 0) { - int smoothWidth = lineWidth; - if (hover + 1 > stage) { - if (lineWidth != end) { - smoothWidth += partialTicks * end / 10; - } - } else { - smoothWidth -= partialTicks * end / 10; - } - - drawSolidRect(x + stage * dur, y + 110 - 2, smoothWidth, 4, color); - } - - // description - FontRenderer fr = Minecraft.getMinecraft().fontRenderer; - List description = fr.listFormattedStringToWidth(application.getDescription(), 210); - int fColor = store.darkMode ? -1 : 0xff333333; - String localizedName = I18n.format(application.getUnlocalizedName()); - drawStringSized(localizedName, x + 100, y + 14, fColor, store.darkMode, 2, false); - if (isMouseOver(x + 100, y + 14, fr.getStringWidth(localizedName) * 2, fr.FONT_HEIGHT * 2, mouseX, mouseY)) { - drawHoveringText(ItemStack.EMPTY, Collections.singletonList("(" + application.getRegistryName() + ")"), 200, - mouseX, mouseY); - } - for (int i = 0; i < description.size(); i++) { - fr.drawString(description.get(i), x + 100, y + 35 + i * fr.FONT_HEIGHT, fColor, store.darkMode); - } - - drawBorder(x + 10, y + 15, 80, 80, store.darkMode ? -1 : 0xff333333, 2); - - GlStateManager.enableDepth(); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/appstore/AppStoreApp.java b/src/main/java/gregtech/common/terminal/app/appstore/AppStoreApp.java deleted file mode 100644 index 6e1ffea4e6e..00000000000 --- a/src/main/java/gregtech/common/terminal/app/appstore/AppStoreApp.java +++ /dev/null @@ -1,114 +0,0 @@ -package gregtech.common.terminal.app.appstore; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.resources.ItemStackTexture; -import gregtech.api.gui.resources.TextTexture; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.terminal.TerminalRegistry; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.terminal.os.menu.IMenuComponent; -import gregtech.api.util.Size; -import gregtech.common.items.MetaItems; -import gregtech.common.terminal.component.ClickComponent; - -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import java.util.Collections; -import java.util.List; - -public class AppStoreApp extends AbstractApplication { - - @SideOnly(Side.CLIENT) - protected boolean darkMode; - - public AppStoreApp() { - super("store"); - } - - @Override - public IGuiTexture getIcon() { - return new ItemStackTexture(MetaItems.COIN_GOLD_ANCIENT.getStackForm()); - } - - @Override - public AbstractApplication initApp() { - DraggableScrollableWidgetGroup group = new DraggableScrollableWidgetGroup(0, 0, 333, 232); - this.addWidget(group); - int index = 0; - int yOffset = 50; - group.addWidget(new ImageWidget(0, 0, 333, 30, GuiTextures.UI_FRAME_SIDE_UP)); - group.addWidget(new LabelWidget(333 / 2, 10, getUnlocalizedName(), -1).setShadow(true).setYCentered(true) - .setXCentered(true)); - for (AbstractApplication app : TerminalRegistry.getAllApps()) { - group.addWidget(new AppCardWidget(5 + 110 * (index % 3), yOffset + 110 * (index / 3), app, this)); - index++; - } - int y = yOffset + 110 * ((index + 2) / 3); - group.addWidget(new ImageWidget(0, y, 333, 30, new ColorRectTexture(TerminalTheme.COLOR_B_2.getColor()))); - group.addWidget( - new ImageWidget(0, y, 333, 30, new TextTexture("Copyright @2021-xxxx Gregicality Team XD", -1))); - loadLocalConfig(nbt -> this.darkMode = nbt.getBoolean("dark")); - return this; - } - - @Override - public NBTTagCompound closeApp() { - for (Widget widget : getOs().desktop.widgets) { - if (widget instanceof AppPageWidget) { - ((AppPageWidget) widget).close(); - } - } - saveLocalConfig(nbt -> nbt.setBoolean("dark", this.darkMode)); - return super.closeApp(); - } - - @Override - protected void hookDrawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - int x = getPosition().x; - int y = getPosition().y; - int width = getSize().width; - int height = getSize().height; - drawSolidRect(x, y, width, height, darkMode ? TerminalTheme.COLOR_B_2.getColor() : 0x9fffffff); - super.hookDrawInBackground(mouseX, mouseY, partialTicks, context); - } - - @Override - public List getMenuComponents() { - ClickComponent darkMode = new ClickComponent().setIcon(GuiTextures.ICON_VISIBLE) - .setHoverText("terminal.prospector.vis_mode").setClickConsumer(cd -> { - if (cd.isClient) { - this.darkMode = !this.darkMode; - } - }); - return Collections.singletonList(darkMode); - } - - @Override - public void onOSSizeUpdate(int width, int height) { - this.setSize(new Size(width, height)); - for (Widget dragWidget : this.widgets) { - if (dragWidget instanceof DraggableScrollableWidgetGroup) { - int lastWidth = dragWidget.getSize().width; - for (Widget widget : ((DraggableScrollableWidgetGroup) dragWidget).widgets) { - if (widget instanceof AppCardWidget) { - widget.addSelfPosition((width - lastWidth) / 2, 0); - } else if (widget instanceof ImageWidget) { - widget.setSize(new Size(width, 30)); - } else { - widget.addSelfPosition((width - lastWidth) / 2, 0); - } - } - dragWidget.setSize(new Size(width, height)); - } - } - } -} diff --git a/src/main/java/gregtech/common/terminal/app/batterymanager/BatteryManagerApp.java b/src/main/java/gregtech/common/terminal/app/batterymanager/BatteryManagerApp.java deleted file mode 100644 index 25fae6eee53..00000000000 --- a/src/main/java/gregtech/common/terminal/app/batterymanager/BatteryManagerApp.java +++ /dev/null @@ -1,65 +0,0 @@ -package gregtech.common.terminal.app.batterymanager; - -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.resources.ItemStackTexture; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.terminal.TerminalRegistry; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.gui.widgets.RectButtonWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.common.items.MetaItems; -import gregtech.common.terminal.hardware.BatteryHardware; - -import net.minecraft.client.resources.I18n; - -import java.util.concurrent.atomic.AtomicInteger; - -public class BatteryManagerApp extends AbstractApplication { - - public BatteryManagerApp() { - super("battery"); - } - - @Override - public IGuiTexture getIcon() { - return new ItemStackTexture(MetaItems.BATTERY_HV_SODIUM.getStackForm()); - } - - @Override - public boolean isClientSideApp() { - return true; - } - - @Override - public AbstractApplication initApp() { - if (isClient) { - this.addWidget(new ImageWidget(5, 5, 333 - 10, 232 - 10, TerminalTheme.COLOR_B_2)); - this.addWidget(new ImageWidget(170, 15, 1, 232 - 30, TerminalTheme.COLOR_7)); - this.addWidget(new BatteryWidget(10, 10 + (212 - 150) / 2, 150, 150, getOs())); - addBatteryApps(); - } - return this; - } - - private void addBatteryApps() { - AtomicInteger index = new AtomicInteger(); - for (AbstractApplication installed : getOs().installedApps) { - TerminalRegistry - .getAppHardwareDemand(installed.getRegistryName(), - getOs().tabletNBT.getCompoundTag(installed.getRegistryName()).getInteger("_tier")) - .stream() - .filter(i -> i instanceof BatteryHardware).findFirst() - .ifPresent(battery -> { - long charge = ((BatteryHardware) battery).getCharge(); - this.addWidget(new RectButtonWidget(180 + (index.get() % 5) * 30, 15 + (index.get() / 5) * 30, - 20, 20, 2) - .setIcon(installed.getIcon()) - // warn unsafe call the I18n here. - .setHoverText(I18n.format("terminal.battery.hover", - I18n.format(installed.getUnlocalizedName()), charge)) - .setColors(0, TerminalTheme.COLOR_7.getColor(), 0)); - index.getAndIncrement(); - }); - } - } -} diff --git a/src/main/java/gregtech/common/terminal/app/batterymanager/BatteryWidget.java b/src/main/java/gregtech/common/terminal/app/batterymanager/BatteryWidget.java deleted file mode 100644 index 50dc490e3dd..00000000000 --- a/src/main/java/gregtech/common/terminal/app/batterymanager/BatteryWidget.java +++ /dev/null @@ -1,62 +0,0 @@ -package gregtech.common.terminal.app.batterymanager; - -import gregtech.api.capability.GregtechCapabilities; -import gregtech.api.capability.IElectricItem; -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.ShaderTexture; -import gregtech.api.terminal.os.TerminalOSWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.client.shader.Shaders; - -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -public class BatteryWidget extends Widget { - - @SideOnly(Side.CLIENT) - private ShaderTexture battery; - private final TerminalOSWidget os; - - public BatteryWidget(int x, int y, int width, int height, TerminalOSWidget os) { - super(x, y, width, height); - this.os = os; - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - super.drawInBackground(mouseX, mouseY, partialTicks, context); - int x = getPosition().x; - int y = getPosition().y; - int width = getSize().width; - int height = getSize().height; - float left = 0; - IElectricItem electricItem = os.hardwareProvider.getCapability(GregtechCapabilities.CAPABILITY_ELECTRIC_ITEM, - null); - if (electricItem != null) { - left = electricItem.getCharge() / (float) electricItem.getMaxCharge(); - } - if (Shaders.allowedShader()) { - float progress = left; - float time = (gui.entityPlayer.ticksExisted + partialTicks) / 20f; - int color = TerminalTheme.COLOR_F_1.getColor(); - if (battery == null) { - battery = ShaderTexture.createShader("battery.frag"); - } - battery.draw(x, y, width, height, uniformCache -> { - uniformCache.glUniform1F("u_time", time); - uniformCache.glUniform1F("progress", progress); - uniformCache.glUniform3F("c_ring", .55f, .7f, .7f); - uniformCache.glUniform3F("c_sector", (color >> 16 & 255) / 255.0F, (color >> 8 & 255) / 255.0F, - (color & 255) / 255.0F); - uniformCache.glUniform3F("c_water", (1 - progress), progress, 0f); - }); - } else { - int b_color = (int) (255 * (1 - left)) << 16 | (int) (255 * left) << 8 | 255 << 24; - drawBorder(x, y, width, height, TerminalTheme.COLOR_1.getColor(), 2); - drawSolidRect(x, y + height - (int) (height * left), width, (int) (height * left), b_color); - } - drawStringSized(String.format("%.2f%%", left * 100), x + width / 2f + 3, y + height / 2f - 7, -1, true, 2, - true); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/capeselector/CapeSelectorApp.java b/src/main/java/gregtech/common/terminal/app/capeselector/CapeSelectorApp.java deleted file mode 100644 index 2105e3ed11e..00000000000 --- a/src/main/java/gregtech/common/terminal/app/capeselector/CapeSelectorApp.java +++ /dev/null @@ -1,62 +0,0 @@ -package gregtech.common.terminal.app.capeselector; - -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.resources.TextureArea; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.SimpleTextWidget; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.client.renderer.texture.Textures; -import gregtech.common.terminal.app.capeselector.widget.CapeListWidget; - -public class CapeSelectorApp extends AbstractApplication { - - protected CapeListWidget capeListWidget; - - public CapeSelectorApp() { - super("cape_selector"); - } - - @Override - public IGuiTexture getIcon() { - return new TextureArea(Textures.GREGTECH_CAPE_TEXTURE, 28f / 64, 0, 22f / 64, 22f / 32); - } - - @Override - public AbstractApplication initApp() { - this.addWidget(new ImageWidget(5, 5, 333 - 10, 232 - 10, TerminalTheme.COLOR_B_2)); - - this.setCapeList(new CapeListWidget(27, 43, 4, 3, this.gui.entityPlayer.getPersistentID())); - this.getCapeList().setYScrollBarWidth(3).setYBarStyle(null, TerminalTheme.COLOR_F_1); - - this.addWidget(new SimpleTextWidget(166, 33, "", 0xFFFFFF, () -> { - if (this.getCapeList().getCapes() == null || this.getCapeList().getCapes().isEmpty()) { - return "terminal.cape_selector.empty"; - } - return "terminal.cape_selector.select"; - })); - - this.addWidget(new SimpleTextWidget(166, 45, "", 0xFFFFFF, () -> { - if (this.getCapeList().getCapes() == null || this.getCapeList().getCapes().isEmpty()) { - return "terminal.cape_selector.tip"; - } - return ""; - })); - - return super.initApp(); - } - - protected void setCapeList(CapeListWidget widget) { - this.capeListWidget = widget; - this.addWidget(capeListWidget); - } - - public CapeListWidget getCapeList() { - return this.capeListWidget; - } - - @Override - public boolean isClientSideApp() { - return false; - } -} diff --git a/src/main/java/gregtech/common/terminal/app/capeselector/widget/CapeListWidget.java b/src/main/java/gregtech/common/terminal/app/capeselector/widget/CapeListWidget.java deleted file mode 100644 index 98f7bd57e35..00000000000 --- a/src/main/java/gregtech/common/terminal/app/capeselector/widget/CapeListWidget.java +++ /dev/null @@ -1,126 +0,0 @@ -package gregtech.common.terminal.app.capeselector.widget; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.SizedTextureArea; -import gregtech.api.gui.resources.TextureArea; -import gregtech.api.gui.widgets.ClickButtonWidget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.util.CapesRegistry; -import gregtech.client.utils.RenderUtil; - -import net.minecraft.network.PacketBuffer; -import net.minecraft.util.ResourceLocation; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -public class CapeListWidget extends DraggableScrollableWidgetGroup { - - private final UUID uuid; - private List capes; - private int selectedX, selectedY = -1; - - public CapeListWidget(int xPosition, int yPosition, int width, int height, UUID uuid) { - super(xPosition, yPosition, width * 70, height * 56); // Cape banners are 28x44, expanded to 70x56 - this.uuid = uuid; - } - - @Override - public void detectAndSendChanges() { - super.detectAndSendChanges(); - if (capes == null) { - updateCapeCandidates(CapesRegistry.getUnlockedCapes(uuid)); - writeUpdateInfo(-1, buf -> { - buf.writeVarInt(capes.size()); - capes.stream().map(ResourceLocation::toString).forEach(buf::writeString); - }); - } - } - - @Override - public void readUpdateInfo(int id, PacketBuffer buffer) { - if (id == -1) { - capes = new ArrayList<>(); - int count = buffer.readVarInt(); - for (int i = 0; i < count; i++) { - capes.add(new ResourceLocation(buffer.readString(Short.MAX_VALUE))); - } - updateCapeCandidates(capes); - } else { - super.readUpdateInfo(id, buffer); - } - } - - private void updateCapeCandidates(List capes) { - this.capes = capes; - int width = (getSize().width) / 70; - int rowNumber = 0; - if (capes == null || capes.isEmpty()) return; - int i = 0; - while (true) { - WidgetGroup row = new WidgetGroup(); - for (int rowPosition = 0; rowPosition < width; rowPosition++) { - TextureArea capeImage = new SizedTextureArea(capes.get(i), 0.5, 0, 14f / 64, 22f / 32, 28, 44); - - int finalRowPosition = rowPosition; - int finalRowNumber = rowNumber; - int finalI = i; - ClickButtonWidget capeButton = new ClickButtonWidget(rowPosition * 70 + 21, rowNumber * 56, 28, 44, "", - (data) -> this.setCape(finalRowPosition, finalRowNumber, capes.get(finalI))) - .setButtonTexture(capeImage) - .setShouldClientCallback(true); - row.addWidget(capeButton); - - if (capes.get(i).equals(CapesRegistry.getPlayerCape(uuid))) { // If this is the cape that the player is - // wearing right now, select it. - selectedX = finalRowPosition; - selectedY = finalRowNumber; - } - i++; - if (i == capes.size()) { - this.addWidget(row); - return; - } - } - this.addWidget(row); - rowNumber++; - } - } - - private void setCape(int x, int y, ResourceLocation cape) { - if (selectedX == x && selectedY == y) { - selectedX = -1; // Sets a "not in use" flag. - cape = null; - } else { - selectedX = x; - selectedY = y; - } - if (!isRemote()) { - CapesRegistry.giveCape(uuid, cape); - } - } - - public List getCapes() { - return capes; - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - super.drawInBackground(mouseX, mouseY, partialTicks, context); - - if (selectedX == -1 || selectedY == -1) - return; - - // Get selected cape button - Widget button = ((WidgetGroup) this.widgets.get(this.selectedY)).widgets.get(this.selectedX); - - RenderUtil.useScissor(getPosition().x, getPosition().y, getSize().width - yBarWidth, - getSize().height - xBarHeight, () -> { - drawSelectionOverlay(button.getPosition().x - 6, button.getPosition().y - 6, - button.getSize().width + 12, button.getSize().height + 12); // Add a bit of margin - }); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/console/ConsoleApp.java b/src/main/java/gregtech/common/terminal/app/console/ConsoleApp.java deleted file mode 100644 index 6147c219ad4..00000000000 --- a/src/main/java/gregtech/common/terminal/app/console/ConsoleApp.java +++ /dev/null @@ -1,55 +0,0 @@ -package gregtech.common.terminal.app.console; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.gui.widgets.MachineSceneWidget; -import gregtech.api.terminal.os.TerminalDialogWidget; -import gregtech.common.metatileentities.storage.MetaTileEntityWorkbench; - -import net.minecraft.tileentity.TileEntity; - -public class ConsoleApp extends AbstractApplication { - - public ConsoleApp() { - super("console"); - } - - private IGregTechTileEntity getMTE() { - if (os.clickPos != null) { - TileEntity te = os.getModularUI().entityPlayer.world.getTileEntity(os.clickPos); - if (te instanceof IGregTechTileEntity && ((IGregTechTileEntity) te).isValid()) { - return (IGregTechTileEntity) te; - } - } - return null; - } - - @Override - public AbstractApplication initApp() { - IGregTechTileEntity mteResult = getMTE(); - - if (mteResult == null || - mteResult.getMetaTileEntity() instanceof MetaTileEntityWorkbench) // Remove Crafting Station compat - { // 333 232 - TerminalDialogWidget.showInfoDialog(os, - "terminal.dialog.notice", - "terminal.console.notice", - () -> os.closeApplication(this, isClient)).open(); - return this; - } - MachineConsoleWidget consoleWidget = new MachineConsoleWidget(200, 16, 133, 200); - this.addWidget(consoleWidget); - if (isClient) { - this.addWidget(0, - new MachineSceneWidget(0, 16, 200, 200, os.clickPos).setOnSelected(consoleWidget::setFocus)); - this.addWidget(new ImageWidget(0, 0, 333, 16, GuiTextures.UI_FRAME_SIDE_UP)); - this.addWidget(new ImageWidget(0, 216, 333, 16, GuiTextures.UI_FRAME_SIDE_DOWN)); - } else { - this.addWidget(0, new WidgetGroup()); // placeholder - } - return this; - } -} diff --git a/src/main/java/gregtech/common/terminal/app/console/MachineConsoleWidget.java b/src/main/java/gregtech/common/terminal/app/console/MachineConsoleWidget.java deleted file mode 100644 index a3272fa06c3..00000000000 --- a/src/main/java/gregtech/common/terminal/app/console/MachineConsoleWidget.java +++ /dev/null @@ -1,466 +0,0 @@ -package gregtech.common.terminal.app.console; - -import gregtech.api.capability.GregtechTileCapabilities; -import gregtech.api.capability.IControllable; -import gregtech.api.capability.impl.AbstractRecipeLogic; -import gregtech.api.capability.impl.RecipeLogicSteam; -import gregtech.api.cover.Cover; -import gregtech.api.cover.CoverWithUI; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.resources.ItemStackTexture; -import gregtech.api.gui.resources.TextTexture; -import gregtech.api.gui.widgets.*; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.metatileentity.SimpleMachineMetaTileEntity; -import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.terminal.gui.widgets.RectButtonWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.util.Size; -import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMaintenanceHatch; -import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockPart; -import gregtech.common.metatileentities.storage.MetaTileEntityQuantumChest; -import gregtech.common.metatileentities.storage.MetaTileEntityQuantumTank; - -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.init.Items; -import net.minecraft.network.PacketBuffer; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumHand; -import net.minecraft.util.NonNullList; -import net.minecraft.util.math.BlockPos; -import net.minecraftforge.items.ItemStackHandler; - -import org.lwjgl.opengl.GL11; - -/** - * Created with IntelliJ IDEA. - * - * @Author: KilaBash - * @Date: 2021/08/25 - * @Description: - */ -public class MachineConsoleWidget extends WidgetGroup { - - private BlockPos pos; - private EnumFacing facing; - private MetaTileEntity mte; - private UIWidgetGroup uiWidgetGroup; - - public MachineConsoleWidget(int x, int y, int width, int height) { - super(x, y, width, height); - } - - public void setFocus(BlockPos pos, EnumFacing facing) { - this.pos = new BlockPos(pos); - this.facing = facing; - this.mte = null; - checkMachine(); - } - - @Override - public void updateScreen() { - super.updateScreen(); - checkMachine(); - } - - private void checkMachine() { - if (mte != null && mte.isValid()) { - return; - } - if (pos != null && facing != null) { - TileEntity te = gui.entityPlayer.world.getTileEntity(pos); - clearAllWidgets(); - if (te instanceof IGregTechTileEntity && ((IGregTechTileEntity) te).isValid()) { - mte = ((IGregTechTileEntity) te).getMetaTileEntity(); - initWidgets(); - if (isRemote()) { - writeClientAction(5, buf -> { - buf.writeBlockPos(pos); - buf.writeByte(facing.getIndex()); - }); - } - } - } - } - - private void initWidgets() { - if (mte != null) { - uiWidgetGroup = new UIWidgetGroup(); - uiWidgetGroup.setActive(false); - uiWidgetGroup.setVisible(false); - Size size = getSize(); - addWidget(new ImageWidget(0, 0, size.width, size.height, GuiTextures.BACKGROUND)); - addWidget(new SimpleTextWidget(size.width / 2, 12, "", -1, () -> facing.toString().toUpperCase()) - .setShadow(true)); - int y = 20; - if (mte.hasFrontFacing()) { - addWidget(new RectButtonWidget(10, y, size.width - 20, 20, 1) - .setClickListener(clickData -> { - if (!isRemote() && mte.isValidFrontFacing(facing)) { - mte.setFrontFacing(facing); - } - }) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), - TerminalTheme.COLOR_B_2.getColor()) - .setIcon(new TextTexture("terminal.console.front", -1))); - y += 25; - } - - // IControllable - IControllable controllable = mte.getCapability(GregtechTileCapabilities.CAPABILITY_CONTROLLABLE, facing); - if (controllable != null) { - addWidget(new RectButtonWidget(10, y, 20, 20, 1) - .setToggleButton(GuiTextures.BUTTON_WORKING_ENABLE.getSubArea(0, 0, 1, 0.5), (c, p) -> { - if (!isRemote()) { - controllable.setWorkingEnabled(p); - } - }) - .setValueSupplier(false, controllable::isWorkingEnabled) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), 0) - .setHoverText("terminal.console.controllable") - .setIcon(GuiTextures.BUTTON_WORKING_ENABLE.getSubArea(0, 0.5, 1, 0.5))); - // AbstractRecipeLogic - AbstractRecipeLogic recipeLogic = mte.getCapability(GregtechTileCapabilities.CAPABILITY_RECIPE_LOGIC, - facing); - if (recipeLogic != null) { - addWidget(new CycleButtonWidget(35, y, 20, 20, - recipeLogic.getAvailableOverclockingTiers(), recipeLogic::getOverclockTier, - recipeLogic::setOverclockTier) - .setTooltipHoverString("gregtech.gui.overclock.description") - .setButtonTexture(GuiTextures.BUTTON_OVERCLOCK)); - addWidget(new ProgressWidget(recipeLogic::getProgressPercent, 60, y, 63, 20, - GuiTextures.PROGRESS_BAR_ARC_FURNACE, ProgressWidget.MoveType.HORIZONTAL)); - if (recipeLogic instanceof RecipeLogicSteam) { - y += 25; - addWidget(new RectButtonWidget(10, y, size.width - 20, 20, 1) - .setClickListener(clickData -> { - EnumFacing currentVentingSide = ((RecipeLogicSteam) recipeLogic).getVentingSide(); - if (currentVentingSide == facing || mte.getFrontFacing() == facing) return; - ((RecipeLogicSteam) recipeLogic).setVentingSide(facing); - }) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), - TerminalTheme.COLOR_B_2.getColor()) - .setIcon(new TextTexture("terminal.console.venting", -1))); - } - } - y += 25; - } - - // SimpleMachineMetaTileEntity - if (mte instanceof SimpleMachineMetaTileEntity) { - SimpleMachineMetaTileEntity simpleMTE = (SimpleMachineMetaTileEntity) mte; - // items output - if (simpleMTE.getExportItems().getSlots() > 0) { - addWidget(new ImageWidget(10, y, 20, 20, new ItemStackTexture(Items.GLOWSTONE_DUST))); - addWidget(new RectButtonWidget(33, y, 50, 20, 1) - .setClickListener(clickData -> { - if (!isRemote() && mte.getFrontFacing() != facing) { - simpleMTE.setOutputFacingItems(facing); - } - }) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), - TerminalTheme.COLOR_B_2.getColor()) - .setHoverText("terminal.console.items")); - addWidget(new SimpleTextWidget(58, y + 10, "", -1, - () -> simpleMTE.getOutputFacingItems().toString())); - addWidget(new RectButtonWidget(83, y, 20, 20, 1) - .setToggleButton(GuiTextures.BUTTON_ITEM_OUTPUT.getSubArea(0, 0.5, 1, 0.5), (c, p) -> { - if (!isRemote()) { - simpleMTE.setAutoOutputItems(p); - } - }) - .setInitValue(simpleMTE.isAutoOutputItems()) - .setValueSupplier(false, simpleMTE::isAutoOutputItems) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), 0) - .setHoverText("terminal.console.auto_output") - .setIcon(GuiTextures.BUTTON_ITEM_OUTPUT.getSubArea(0, 0, 1, 0.5))); - addWidget(new RectButtonWidget(103, y, 20, 20, 1) - .setToggleButton(GuiTextures.BUTTON_ALLOW_IMPORT_EXPORT.getSubArea(0, 0.5, 1, 0.5), - (c, p) -> { - if (!isRemote()) { - simpleMTE.setAllowInputFromOutputSideItems(p); - } - }) - .setInitValue(simpleMTE.isAllowInputFromOutputSideItems()) - .setValueSupplier(false, simpleMTE::isAllowInputFromOutputSideItems) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), 0) - .setHoverText("terminal.console.input") - .setIcon(GuiTextures.BUTTON_ALLOW_IMPORT_EXPORT.getSubArea(0, 0, 1, 0.5))); - y += 20; - } - - // fluids output - if (simpleMTE.getExportFluids().getTanks() > 0) { - addWidget(new ImageWidget(10, y, 20, 20, new ItemStackTexture(Items.WATER_BUCKET))); - addWidget(new RectButtonWidget(33, y, 50, 20, 1) - .setClickListener(clickData -> { - if (!isRemote() && simpleMTE.getFrontFacing() != facing) { - simpleMTE.setOutputFacingFluids(facing); - } - }) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), - TerminalTheme.COLOR_B_2.getColor()) - .setHoverText("terminal.console.fluids")); - addWidget(new SimpleTextWidget(58, y + 10, "", -1, - () -> simpleMTE.getOutputFacingFluids().toString())); - addWidget(new RectButtonWidget(83, y, 20, 20, 1) - .setToggleButton(GuiTextures.BUTTON_FLUID_OUTPUT.getSubArea(0, 0.5, 1, 0.5), (c, p) -> { - if (!isRemote()) { - simpleMTE.setAutoOutputFluids(p); - } - }) - .setInitValue(simpleMTE.isAutoOutputFluids()) - .setValueSupplier(false, simpleMTE::isAutoOutputFluids) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), 0) - .setHoverText("terminal.console.auto_output") - .setIcon(GuiTextures.BUTTON_FLUID_OUTPUT.getSubArea(0, 0, 1, 0.5))); - addWidget(new RectButtonWidget(103, y, 20, 20, 1) - .setToggleButton(GuiTextures.BUTTON_ALLOW_IMPORT_EXPORT.getSubArea(0, 0.5, 1, 0.5), - (c, p) -> { - if (!isRemote()) { - simpleMTE.setAllowInputFromOutputSideFluids(p); - } - }) - .setInitValue(simpleMTE.isAllowInputFromOutputSideFluids()) - .setValueSupplier(false, simpleMTE::isAllowInputFromOutputSideFluids) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), 0) - .setHoverText("terminal.console.input") - .setIcon(GuiTextures.BUTTON_ALLOW_IMPORT_EXPORT.getSubArea(0, 0, 1, 0.5))); - y += 20; - } - y += 5; - } - - // MetaTileEntityQuantumTank - if (mte instanceof MetaTileEntityQuantumChest) { - MetaTileEntityQuantumChest chest = (MetaTileEntityQuantumChest) mte; - addWidget(new ImageWidget(10, y, 20, 20, new ItemStackTexture(Items.GLOWSTONE_DUST))); - addWidget(new RectButtonWidget(33, y, 50, 20, 1) - .setClickListener(clickData -> { - if (!isRemote() && mte.getFrontFacing() != facing) { - chest.setOutputFacing(facing); - } - }) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), - TerminalTheme.COLOR_B_2.getColor()) - .setHoverText("terminal.console.items")); - addWidget(new SimpleTextWidget(58, y + 10, "", -1, () -> chest.getOutputFacing().toString())); - addWidget(new RectButtonWidget(83, y, 20, 20, 1) - .setToggleButton(GuiTextures.BUTTON_ITEM_OUTPUT.getSubArea(0, 0.5, 1, 0.5), (c, p) -> { - if (!isRemote()) { - chest.setAutoOutputItems(p); - } - }) - .setInitValue(chest.isAutoOutputItems()) - .setValueSupplier(false, chest::isAutoOutputItems) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), 0) - .setHoverText("terminal.console.auto_output") - .setIcon(GuiTextures.BUTTON_ITEM_OUTPUT.getSubArea(0, 0, 1, 0.5))); - addWidget(new RectButtonWidget(103, y, 20, 20, 1) - .setToggleButton(GuiTextures.BUTTON_ALLOW_IMPORT_EXPORT.getSubArea(0, 0.5, 1, 0.5), (c, p) -> { - if (!isRemote()) { - chest.setAllowInputFromOutputSide(p); - } - }) - .setInitValue(chest.isAllowInputFromOutputSideItems()) - .setValueSupplier(false, chest::isAllowInputFromOutputSideItems) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), 0) - .setHoverText("terminal.console.input") - .setIcon(GuiTextures.BUTTON_ALLOW_IMPORT_EXPORT.getSubArea(0, 0, 1, 0.5))); - y += 25; - } else if (mte instanceof MetaTileEntityQuantumTank) { - MetaTileEntityQuantumTank tank = (MetaTileEntityQuantumTank) mte; - addWidget(new ImageWidget(10, y, 20, 20, new ItemStackTexture(Items.WATER_BUCKET))); - addWidget(new RectButtonWidget(33, y, 50, 20, 1) - .setClickListener(clickData -> { - if (!isRemote() && tank.getFrontFacing() != facing) { - tank.setOutputFacing(facing); - } - }) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), - TerminalTheme.COLOR_B_2.getColor()) - .setHoverText("terminal.console.fluids")); - addWidget(new SimpleTextWidget(58, y + 10, "", -1, () -> tank.getOutputFacing().toString())); - addWidget(new RectButtonWidget(83, y, 20, 20, 1) - .setToggleButton(GuiTextures.BUTTON_FLUID_OUTPUT.getSubArea(0, 0.5, 1, 0.5), (c, p) -> { - if (!isRemote()) { - tank.setAutoOutputFluids(p); - } - }) - .setInitValue(tank.isAutoOutputFluids()) - .setValueSupplier(false, tank::isAutoOutputFluids) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), 0) - .setHoverText("terminal.console.auto_output") - .setIcon(GuiTextures.BUTTON_FLUID_OUTPUT.getSubArea(0, 0, 1, 0.5))); - addWidget(new RectButtonWidget(103, y, 20, 20, 1) - .setToggleButton(GuiTextures.BUTTON_ALLOW_IMPORT_EXPORT.getSubArea(0, 0.5, 1, 0.5), (c, p) -> { - if (!isRemote()) { - tank.setAllowInputFromOutputSide(p); - } - }) - .setInitValue(tank.isAllowInputFromOutputSideFluids()) - .setValueSupplier(false, tank::isAllowInputFromOutputSideFluids) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), 0) - .setHoverText("terminal.console.input") - .setIcon(GuiTextures.BUTTON_ALLOW_IMPORT_EXPORT.getSubArea(0, 0, 1, 0.5))); - y += 25; - } - - // MultiBlockPart - if (mte instanceof MetaTileEntityMultiblockPart) { - // MetaTileEntityMaintenanceHatch - if (mte instanceof MetaTileEntityMaintenanceHatch) { - addWidget(new RectButtonWidget(10, y, size.width - 20, 20, 1) - .setClickListener(clickData -> { - if (!isRemote()) { - ((MetaTileEntityMaintenanceHatch) mte).fixAllMaintenanceProblems(); - } - }) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), - TerminalTheme.COLOR_B_2.getColor()) - .setIcon(new TextTexture("terminal.console.maintenance", -1))); - y += 25; - } - } - - // CoverBehavior - Cover cover = mte.getCoverAtSide(facing); - if (cover != null) { - this.addWidget(new SlotWidget(new ItemStackHandler(NonNullList.withSize(1, cover.getPickItem())), 0, - 10, y, false, false)); - addWidget(new SimpleTextWidget(58, y + 10, "terminal.console.cover_rs", -1, - () -> String.valueOf(cover.getRedstoneSignalOutput())).setShadow(true).setCenter(true)); - if (cover instanceof CoverWithUI) { - addWidget(new RectButtonWidget(83, y, 40, 20, 1) - .setClickListener( - clickData -> uiWidgetGroup.openUI(((CoverWithUI) cover).createUI(gui.entityPlayer))) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), - TerminalTheme.COLOR_B_2.getColor()) - .setIcon(new TextTexture("terminal.console.cover_gui", -1))); - } - y += 25; - } - addWidget(new RectButtonWidget(10, y, size.width - 20, 20, 1) - .setClickListener(clickData -> uiWidgetGroup.openUI(mte.getModularUI(gui.entityPlayer))) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), - TerminalTheme.COLOR_B_2.getColor()) - .setIcon(new TextTexture("terminal.console.gui", -1))); - - addWidget(uiWidgetGroup); - } - } - - @Override - public void handleClientAction(int id, PacketBuffer buffer) { - if (id == 5) { - setFocus(buffer.readBlockPos(), EnumFacing.VALUES[buffer.readByte()]); - } else { - super.handleClientAction(id, buffer); - } - } - - @Override - public void drawInForeground(int mouseX, int mouseY) { - if (uiWidgetGroup != null && uiWidgetGroup.isVisible()) { - return; - } - super.drawInForeground(mouseX, mouseY); - } - - private static class UIWidgetGroup extends WidgetGroup { - - private IGuiTexture background; - - public void clearUI() { - background = null; - clearAllWidgets(); - setActive(false); - setVisible(false); - } - - public void openUI(ModularUI ui) { - clearUI(); - if (ui != null) { - background = ui.backgroundPath; - for (Widget widget : ui.guiWidgets.values()) { - if (widget instanceof SlotWidget) { - SlotWidget slotWidget = (SlotWidget) widget; - if (slotWidget.getHandle().getStack() == gui.entityPlayer.getHeldItem(EnumHand.MAIN_HAND)) { - slotWidget.setActive(false); - } - } - addWidget(widget); - } - setSize(new Size(ui.getWidth(), ui.getHeight())); - addSelfPosition(gui.getScreenWidth() / 2 - getPosition().x - ui.getWidth() / 2, - gui.getScreenHeight() / 2 - getPosition().y - ui.getHeight() / 2); - setActive(true); - setVisible(true); - } - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - drawSolidRect(0, 0, gui.getScreenWidth(), gui.getScreenHeight(), 0xbf000000); - if (background != null) { - background.draw(getPosition().x, getPosition().y, getSize().width, getSize().height); - } - GL11.glDisable(GL11.GL_SCISSOR_TEST); - GlStateManager.disableDepth(); - super.drawInBackground(mouseX, mouseY, partialTicks, context); - GlStateManager.enableDepth(); - GL11.glEnable(GL11.GL_SCISSOR_TEST); - } - - @Override - public boolean keyTyped(char charTyped, int keyCode) { - if (keyCode == 1) { - clearUI(); - writeClientAction(5, buffer -> buffer.writeBoolean(true)); - return true; - } - super.keyTyped(charTyped, keyCode); - return true; - } - - @Override - public void handleClientAction(int id, PacketBuffer buffer) { - if (id == 5) { - if (buffer.readBoolean()) { - clearUI(); - } - } else { - super.handleClientAction(id, buffer); - } - } - - @Override - public boolean mouseWheelMove(int mouseX, int mouseY, int wheelDelta) { - super.mouseWheelMove(mouseX, mouseY, wheelDelta); - return true; - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - super.mouseClicked(mouseX, mouseY, button); - return true; - } - - @Override - public boolean mouseDragged(int mouseX, int mouseY, int button, long timeDragged) { - super.mouseDragged(mouseX, mouseY, button, timeDragged); - return true; - } - - @Override - public boolean mouseReleased(int mouseX, int mouseY, int button) { - super.mouseReleased(mouseX, mouseY, button); - return true; - } - } -} diff --git a/src/main/java/gregtech/common/terminal/app/game/maze/MazeApp.java b/src/main/java/gregtech/common/terminal/app/game/maze/MazeApp.java deleted file mode 100644 index bd944c9d9da..00000000000 --- a/src/main/java/gregtech/common/terminal/app/game/maze/MazeApp.java +++ /dev/null @@ -1,274 +0,0 @@ -package gregtech.common.terminal.app.game.maze; - -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.gui.widgets.ClickButtonWidget; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.SimpleTextWidget; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.common.terminal.app.game.maze.widget.EnemyWidget; -import gregtech.common.terminal.app.game.maze.widget.MazeWidget; -import gregtech.common.terminal.app.game.maze.widget.PlayerWidget; - -import org.lwjgl.input.Keyboard; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; - -public class MazeApp extends AbstractApplication { - - private int gameState = 0; - private PlayerWidget player; - private EnemyWidget enemy; - private MazeWidget maze; - private int timer = 0; - private int mazesSolved = 0; - private float speed = 25; - private int lastPlayerInput = -2; - public static int MAZE_SIZE = 9; - private List movementStore; - private boolean lastPausePress; - - private List[] FSM; - - public MazeApp() { - super("maze"); - } - - public AbstractApplication initApp() { - if (isClient) { - movementStore = new ArrayList<>(); - FSM = new List[4]; - FSM[0] = new LinkedList<>(); - FSM[1] = new LinkedList<>(); - FSM[2] = new LinkedList<>(); - FSM[3] = new LinkedList<>(); - this.setOs(os); - this.addWidget(new ImageWidget(5, 5, 333 - 10, 232 - 10, TerminalTheme.COLOR_B_2)); - // enemy 0: Title - this.addWidget(new LabelWidget(333 / 2, 222 / 2 - 50, "terminal.maze.title", 0xFFFFFFFF).setXCentered(true), - 0); - this.addWidget(new ClickButtonWidget(323 / 2 - 10, 222 / 2 - 10, 30, 30, "terminal.maze.play", - (clickData -> { - this.setGameState(1); - this.resetGame(); - })).setShouldClientCallback(true), 0); - // GameState 1: Play - this.setMaze(new MazeWidget()); - this.setPlayer(new PlayerWidget(0, 0, this)); - this.setEnemy(new EnemyWidget(-100, -100, this)); - // GameState 2: Pause - this.addWidget(new ImageWidget(5, 5, 333 - 10, 232 - 10, new ColorRectTexture(0xFF000000)), 2, 3); - this.addWidget(new ClickButtonWidget(323 / 2 - 10, 222 / 2 - 10, 50, 20, "terminal.maze.continue", - (clickData) -> this.setGameState(1)).setShouldClientCallback(true), 2); - this.addWidget(new LabelWidget(333 / 2, 222 / 2 - 50, "terminal.maze.pause", 0xFFFFFFFF).setXCentered(true), - 2); - // GameState 3: Death - this.addWidget( - new SimpleTextWidget(333 / 2, 232 / 2 - 40, "", 0xFFFFFFFF, () -> "terminal.maze.death.1", true), - 3); - this.addWidget(new SimpleTextWidget(333 / 2, 232 / 2 - 28, "terminal.maze.death.2", 0xFFFFFFFF, - () -> String.valueOf(this.getMazesSolved()), true), 3); - this.addWidget( - new SimpleTextWidget(333 / 2, 232 / 2 - 16, "", 0xFFFFFFFF, () -> "terminal.maze.death.3", true), - 3); - this.addWidget( - new ClickButtonWidget(323 / 2 - 10, 222 / 2 + 10, 40, 20, "terminal.maze.retry", (clickData -> { - this.setGameState(1); - this.setMazesSolved(0); - MAZE_SIZE = 9; - speed = 25; - this.resetGame(); - })).setShouldClientCallback(true), 3); - } - return this; - } - - public void addWidget(Widget widget, int... visibleStates) { - this.addWidget(widget); - for (int state : visibleStates) { - FSM[state].add(widget); - } - widget.setVisible(Arrays.stream(visibleStates).allMatch(state -> state == gameState)); - } - - public void setPlayer(PlayerWidget player) { - this.player = player; - this.addWidget(player, 1, 2, 3); - } - - public void setMaze(MazeWidget maze) { - this.maze = maze; - this.addWidget(maze, 1, 2, 3); - } - - public void setEnemy(EnemyWidget enemy) { - this.enemy = enemy; - this.addWidget(enemy, 1, 2, 3); - } - - @Override - public boolean canOpenMenuOnEdge() { - return gameState != 1; - } - - @Override - public boolean isClientSideApp() { - return true; - } - - @Override - public void updateScreen() { - super.updateScreen(); - int lastState = gameState; - if (gameState == 1) { - if (Keyboard.isKeyDown(Keyboard.KEY_P)) { - gameState = 2; - lastPausePress = true; - } - if (Keyboard.isKeyDown(Keyboard.KEY_LEFT) ^ Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) { - if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) - attemptMovePlayer(0); // Left - else - attemptMovePlayer(1); // Right - } - if (Keyboard.isKeyDown(Keyboard.KEY_UP) ^ Keyboard.isKeyDown(Keyboard.KEY_DOWN)) { - if (Keyboard.isKeyDown(Keyboard.KEY_UP)) - attemptMovePlayer(2); // Up - else - attemptMovePlayer(3); // Down - } - timer++; - if (enemy.posX < 0 && timer % (speed * MAZE_SIZE - 1) < 1) { - enemy.setGridPosition(0, 0); - } else if (timer % speed < 1) { - moveEnemy(); - } - if (enemy.posX == player.posX && enemy.posY == player.posY) { - gameState = 3; - } - } - if (gameState == 2) { - if (!Keyboard.isKeyDown(Keyboard.KEY_P)) - lastPausePress = false; - if (Keyboard.isKeyDown(Keyboard.KEY_P) && !lastPausePress) - gameState = 1; - } - if (gameState != lastState) { - FSM[lastState].forEach(widget -> widget.setVisible(false)); - FSM[gameState].forEach(widget -> widget.setVisible(true)); - } - } - - public int getGameState() { - return gameState; - } - - public void setGameState(int gameState) { - if (gameState != this.gameState) { - FSM[this.gameState].forEach(widget -> widget.setVisible(false)); - FSM[gameState].forEach(widget -> widget.setVisible(true)); - } - this.gameState = gameState; - } - - public int getRenderX(int posX) { - return this.maze.getSelfPosition().x + posX * 10; - } - - public int getRenderY(int posY) { - return this.maze.getSelfPosition().y + posY * 10; - } - - public int getTimer() { - return timer; - } - - private void attemptMovePlayer(int direction) { - if (timer < lastPlayerInput + 2) { - return; - } - lastPlayerInput = timer; - - // Did the player reach the end? - if (player.posX == MAZE_SIZE - 1 && player.posY == MAZE_SIZE - 1 && direction == 3) { - mazesSolved++; - speed *= 0.95; - if (mazesSolved % 4 == 0) { - MAZE_SIZE += 2; - speed *= 1.07; - } - resetGame(); - return; - } - - if (direction == 0 && !maze.isThereWallAt(player.posX, player.posY, false)) { - player.move(-1, 0); - if (movementStore.size() > 0 && movementStore.get(movementStore.size() - 1) == 1) { - movementStore.remove(movementStore.size() - 1); - } else { - movementStore.add(direction); - } - } else if (direction == 1 && !maze.isThereWallAt(player.posX + 1, player.posY, false)) { - player.move(1, 0); - if (movementStore.size() > 0 && movementStore.get(movementStore.size() - 1) == 0) { - movementStore.remove(movementStore.size() - 1); - } else { - movementStore.add(direction); - } - } else if (direction == 2 && !maze.isThereWallAt(player.posX, player.posY, true)) { - player.move(0, -1); - if (movementStore.size() > 0 && movementStore.get(movementStore.size() - 1) == 3) { - movementStore.remove(movementStore.size() - 1); - } else { - movementStore.add(direction); - } - } else if (direction == 3 && !maze.isThereWallAt(player.posX, player.posY + 1, true)) { - player.move(0, 1); - if (movementStore.size() > 0 && movementStore.get(movementStore.size() - 1) == 2) { - movementStore.remove(movementStore.size() - 1); - } else { - movementStore.add(direction); - } - } - } - - private void moveEnemy() { // Move enemy with the latest movements - if (enemy.posX < 0 || movementStore.isEmpty()) - return; - - int direction = movementStore.get(0); - if (direction == 0) { - enemy.move(-1, 0); - } else if (direction == 1) { - enemy.move(1, 0); - } else if (direction == 2) { - enemy.move(0, -1); - } else if (direction == 3) { - enemy.move(0, 1); - } - movementStore.remove(0); - } - - private void resetGame() { - player.setGridPosition(0, 0); - maze.recalculateSize(); - maze.initMaze(); - movementStore.clear(); - timer = 0; - lastPlayerInput = -5; - enemy.setGridPosition(-100, -100); - } - - public int getMazesSolved() { - return mazesSolved; - } - - public void setMazesSolved(int mazesSolved) { - this.mazesSolved = mazesSolved; - } -} diff --git a/src/main/java/gregtech/common/terminal/app/game/maze/widget/EnemyWidget.java b/src/main/java/gregtech/common/terminal/app/game/maze/widget/EnemyWidget.java deleted file mode 100644 index e16117666e2..00000000000 --- a/src/main/java/gregtech/common/terminal/app/game/maze/widget/EnemyWidget.java +++ /dev/null @@ -1,17 +0,0 @@ -package gregtech.common.terminal.app.game.maze.widget; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.util.Position; -import gregtech.common.terminal.app.game.maze.MazeApp; - -public class EnemyWidget extends PlayerWidget { - - public EnemyWidget(int posX, int posY, MazeApp app) { - super(posX, posY, app); - } - - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - this.setSelfPosition(new Position(app.getRenderX(posX), app.getRenderY(posY))); - drawSolidRect(this.getPosition().x, this.getPosition().y, 10, 10, 0xFFFFAAAA); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/game/maze/widget/MazeWidget.java b/src/main/java/gregtech/common/terminal/app/game/maze/widget/MazeWidget.java deleted file mode 100644 index d3f71ebf18e..00000000000 --- a/src/main/java/gregtech/common/terminal/app/game/maze/widget/MazeWidget.java +++ /dev/null @@ -1,191 +0,0 @@ -package gregtech.common.terminal.app.game.maze.widget; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.util.Position; -import gregtech.api.util.Size; - -import net.minecraft.util.math.Vec2f; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import static gregtech.common.terminal.app.game.maze.MazeApp.MAZE_SIZE; - -public class MazeWidget extends Widget { - - boolean[][] topWalls = new boolean[MAZE_SIZE][MAZE_SIZE]; - boolean[][] leftWalls = new boolean[MAZE_SIZE][MAZE_SIZE]; - boolean[][] includedSpots; - private int squaresChecked; - - public MazeWidget() { - super(333 / 2 - (MAZE_SIZE * 5), 232 / 2 - (MAZE_SIZE * 5), MAZE_SIZE * 10, MAZE_SIZE * 10); - initMaze(); - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - // Draw outer lines - createBorder(); - // Draw inner lines - createInternalLines(); - } - - public void recalculateSize() { - this.setSelfPosition(new Position(333 / 2 - (MAZE_SIZE * 5), 232 / 2 - (MAZE_SIZE * 5))); - this.setSize(new Size(MAZE_SIZE * 10, MAZE_SIZE * 10)); - topWalls = new boolean[MAZE_SIZE][MAZE_SIZE]; - leftWalls = new boolean[MAZE_SIZE][MAZE_SIZE]; - } - - public void createBorder() { - List lineBuffer = new ArrayList<>(); - lineBuffer.add(new Vec2f(getPosition().x + 10, getPosition().y)); - lineBuffer.add(new Vec2f(this.getSize().width + getPosition().x, getPosition().y)); - lineBuffer.add(new Vec2f(this.getSize().width + getPosition().x, this.getSize().height + getPosition().y + 2)); // Corrects - // for - // line - // width - // misalignment - drawLines(lineBuffer, 0xFFFFFFFF, 0xFFFFFFFF, 4); - lineBuffer.clear(); - lineBuffer.add(new Vec2f(this.getSize().width + getPosition().x - 10, this.getSize().height + getPosition().y)); - lineBuffer.add(new Vec2f(getPosition().x, this.getSize().height + getPosition().y)); - lineBuffer.add(new Vec2f(getPosition().x, getPosition().y - 2)); - drawLines(lineBuffer, 0xFFFFFFFF, 0xFFFFFFFF, 4); - } - - public boolean isThereWallAt(int x, int y, boolean onTops) { - if (x >= MAZE_SIZE || y >= MAZE_SIZE) - return true; - if (x < 0 || y < 0) - return true; - if ((x == 0 && !onTops) || (y == 0 && onTops)) - return true; - if (onTops) { - return topWalls[x][y]; - } else { - return leftWalls[x][y]; - } - } - - public void createInternalLines() { - for (int i = 0; i < MAZE_SIZE; i++) { - for (int j = 0; j < MAZE_SIZE; j++) { - List list = new ArrayList<>(); - if (j != 0 && isThereWallAt(i, j, true)) { - list.add(new Vec2f(getPosition().x + 10 * i, getPosition().y + 10 * j)); - list.add(new Vec2f(getPosition().x + 10 * (i + 1), getPosition().y + 10 * j)); - drawLines(list, 0xFFFFFFFF, 0xFFFFFFFF, 2); - list.clear(); - } - if (i != 0 && isThereWallAt(i, j, false)) { - list.add(new Vec2f(getPosition().x + 10 * i, getPosition().y + 10 * j)); - list.add(new Vec2f(getPosition().x + 10 * i, getPosition().y + 10 * (j + 1))); - drawLines(list, 0xFFFFFFFF, 0xFFFFFFFF, 2); - } - } - } - } - - public void initMaze() { - includedSpots = new boolean[MAZE_SIZE][MAZE_SIZE]; - for (int i = 0; i < MAZE_SIZE; i++) { // Fill array with walls so that they can be carved out - for (int j = 0; j < MAZE_SIZE; j++) { - leftWalls[i][j] = true; - topWalls[i][j] = true; - } - } - - includedSpots[(int) (Math.random() * MAZE_SIZE)][(int) (Math.random() * MAZE_SIZE)] = true; // Can seed our - // particular maze - // Improves maze randomization. - List positions = new ArrayList<>(); - for (int i = 0; i < MAZE_SIZE * MAZE_SIZE; i++) { - positions.add(i); - } - Collections.shuffle(positions); - - for (int position : positions) { - if (!includedSpots[position / MAZE_SIZE][position % MAZE_SIZE]) { - do { - resetStuckCounter(); - } while (!this.createPath(position / MAZE_SIZE, position % MAZE_SIZE, - new boolean[MAZE_SIZE][MAZE_SIZE])); - } - } - } - - // Wilson random walk maze generation - public boolean createPath(int x, int y, boolean[][] walkedPaths) { - squaresChecked++; - if (squaresChecked > 20000) // Probably stuck. - return false; - if (walkedPaths[x][y]) - return false; - if (this.includedSpots[x][y]) - return true; - this.includedSpots[x][y] = true; - walkedPaths[x][y] = true; - // Find unoccupied directions - // Left 0 - List directions = new ArrayList<>(); - if (x != 0 && !walkedPaths[x - 1][y]) { - directions.add(0); - } - // Right 1 - if (x != MAZE_SIZE - 1 && !walkedPaths[x + 1][y]) { - directions.add(1); - } - // Up 2 - if (y != 0 && !walkedPaths[x][y - 1]) { - directions.add(2); - } - // Down 3 - if (y != MAZE_SIZE - 1 && !walkedPaths[x][y + 1]) { - directions.add(3); - } - Collections.shuffle(directions); - // Select one - while (directions.size() > 0) { - int direction = directions.get(directions.size() - 1); - // Use direction to create new coordinates - int newX = x; - int newY = y; - if (direction == 0) { - newX--; - } else if (direction == 1) { - newX++; - } else if (direction == 2) { - newY--; - } else if (direction == 3) { - newY++; - } - if (createPath(newX, newY, walkedPaths)) { - // Delete walls and return - if (direction == 0) { - leftWalls[x][y] = false; - } else if (direction == 1) { - leftWalls[x + 1][y] = false; - } else if (direction == 2) { - topWalls[x][y] = false; - } else if (direction == 3) { - topWalls[x][y + 1] = false; - } - return true; - } else { - directions.remove(directions.size() - 1); - } - } - // Reset current position - this.includedSpots[x][y] = false; - walkedPaths[x][y] = false; - return false; - } - - public void resetStuckCounter() { - squaresChecked = 0; - } -} diff --git a/src/main/java/gregtech/common/terminal/app/game/maze/widget/PlayerWidget.java b/src/main/java/gregtech/common/terminal/app/game/maze/widget/PlayerWidget.java deleted file mode 100644 index 2198456833c..00000000000 --- a/src/main/java/gregtech/common/terminal/app/game/maze/widget/PlayerWidget.java +++ /dev/null @@ -1,36 +0,0 @@ -package gregtech.common.terminal.app.game.maze.widget; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.util.Position; -import gregtech.common.terminal.app.game.maze.MazeApp; - -public class PlayerWidget extends Widget { - - protected MazeApp app; - public int posX; - public int posY; - - public PlayerWidget(int posX, int posY, MazeApp app) { - super(app.getRenderX(posX), app.getRenderY(posY), 10, 10); - this.app = app; - this.posX = posX; - this.posY = posY; - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - this.setSelfPosition(new Position(app.getRenderX(posX), app.getRenderY(posY))); - drawSolidRect(this.getPosition().x, this.getPosition().y, 10, 10, 0xAAAAAAFF); - } - - public void move(int deltaX, int deltaY) { - this.posX += deltaX; - this.posY += deltaY; - } - - public void setGridPosition(int posX, int posY) { - this.posX = posX; - this.posY = posY; - } -} diff --git a/src/main/java/gregtech/common/terminal/app/game/minesweeper/MinesweeperApp.java b/src/main/java/gregtech/common/terminal/app/game/minesweeper/MinesweeperApp.java deleted file mode 100644 index 7608e54b85d..00000000000 --- a/src/main/java/gregtech/common/terminal/app/game/minesweeper/MinesweeperApp.java +++ /dev/null @@ -1,82 +0,0 @@ -package gregtech.common.terminal.app.game.minesweeper; - -import gregtech.api.gui.widgets.SimpleTextWidget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.common.terminal.app.game.minesweeper.widget.MineMapWidget; - -public class MinesweeperApp extends AbstractApplication { - - private MineMapWidget mineField; - private WidgetGroup textGroup; - private int timer; - private int resetCountdown = 100; - - public MinesweeperApp() { - super("minesweeper"); - } - - @Override - public AbstractApplication initApp() { - mineField = new MineMapWidget(20, 12, 40); - this.addWidget(mineField); - this.addWidget(new SimpleTextWidget(333 / 6, 10, "", 0xFFCCCCCC, this::getFlagsPercentage, true)); - textGroup = new WidgetGroup(0, 0, 200, 50); - this.addWidget(textGroup); - setTextStatus(); - - return this; - } - - @Override - public boolean canOpenMenuOnEdge() { - return false; - } - - @Override - public void updateScreen() { - super.updateScreen(); - if (mineField.hasWon() || mineField.hasLost()) { - if (mineField.hasWon()) { - mineField.notifyWon(); - } - resetCountdown--; - setTextStatus(); - } else - timer++; - if (resetCountdown == 0) { - mineField.resetData(); - resetCountdown = 100; - timer = 0; - setTextStatus(); - } - } - - public String getFlagsPercentage() { - return mineField.flagsPlaced + "/" + mineField.mineCount; - } - - public void setTextStatus() { // swap widget for localization - if (resetCountdown == 100) { - textGroup.clearAllWidgets(); - textGroup.addWidget(new SimpleTextWidget(333 / 8 * 5, 10, "terminal.minesweeper.time", 0xFFCCCCCC, - () -> String.valueOf(timer / 20), true)); // Normal - } else if (resetCountdown == 99) { - textGroup.clearAllWidgets(); - if (mineField.hasLost()) { - textGroup.addWidget(new SimpleTextWidget(333 / 8 * 5, 10, "terminal.minesweeper.lose", 0xFFCCCCCC, - () -> String.valueOf(resetCountdown / 20), true)); // Losing condition - } else { - textGroup.addWidget(new SimpleTextWidget(333 / 8 * 5, 10, "terminal.minesweeper.win.1", 0xFFCCCCCC, - () -> String.valueOf(timer / 20), true)); // Winning condition - textGroup.addWidget(new SimpleTextWidget(333 / 8 * 5, 20, "terminal.minesweeper.win.2", 0xFFCCCCCC, - () -> String.valueOf(resetCountdown / 20), true)); - } - } - } - - @Override - public boolean isClientSideApp() { - return true; - } -} diff --git a/src/main/java/gregtech/common/terminal/app/game/minesweeper/widget/MineMapWidget.java b/src/main/java/gregtech/common/terminal/app/game/minesweeper/widget/MineMapWidget.java deleted file mode 100644 index 5037833c929..00000000000 --- a/src/main/java/gregtech/common/terminal/app/game/minesweeper/widget/MineMapWidget.java +++ /dev/null @@ -1,220 +0,0 @@ -package gregtech.common.terminal.app.game.minesweeper.widget; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.TextureArea; -import gregtech.api.util.interpolate.RGBInterpolator; - -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.util.ResourceLocation; - -public class MineMapWidget extends Widget { - - private static final TextureArea COVERED = new TextureArea( - new ResourceLocation("gregtech:textures/gui/terminal/minesweeper/covered.png"), 0, 0, 1, 1); - private static final TextureArea FLAG = new TextureArea( - new ResourceLocation("gregtech:textures/gui/terminal/minesweeper/flag.png"), 0, 0, 1, 1); - private static final TextureArea BOMB = new TextureArea( - new ResourceLocation("gregtech:textures/gui/terminal/minesweeper/bomb.png"), 0, 0, 1, 1); - - private static final TextureArea[] NUMBERS = { - new TextureArea(new ResourceLocation("gregtech:textures/gui/terminal/minesweeper/blank.png"), 0, 0, 1, 1), - new TextureArea(new ResourceLocation("gregtech:textures/gui/terminal/minesweeper/1.png"), 0, 0, 1, 1), - new TextureArea(new ResourceLocation("gregtech:textures/gui/terminal/minesweeper/2.png"), 0, 0, 1, 1), - new TextureArea(new ResourceLocation("gregtech:textures/gui/terminal/minesweeper/3.png"), 0, 0, 1, 1), - new TextureArea(new ResourceLocation("gregtech:textures/gui/terminal/minesweeper/4.png"), 0, 0, 1, 1), - new TextureArea(new ResourceLocation("gregtech:textures/gui/terminal/minesweeper/5.png"), 0, 0, 1, 1), - new TextureArea(new ResourceLocation("gregtech:textures/gui/terminal/minesweeper/6.png"), 0, 0, 1, 1), - new TextureArea(new ResourceLocation("gregtech:textures/gui/terminal/minesweeper/7.png"), 0, 0, 1, 1), - new TextureArea(new ResourceLocation("gregtech:textures/gui/terminal/minesweeper/8.png"), 0, 0, 1, 1) - }; - - public int mineCount; - public int flagsPlaced; - - private int width; - private int height; - - private boolean isPrepared; - - private boolean[][] mines; - private boolean[][] flags; - private boolean[][] checkedSpaces; - private int[][] generatedNumbers; - - private boolean isLost; - private boolean isWon; - private int timer = 0; - private static final RGBInterpolator interpolator = new RGBInterpolator(5, - (r, g, b) -> GlStateManager.color(r.floatValue(), g.floatValue(), b.floatValue()), - (r, g, b) -> GlStateManager.color(0, 0, 0)); - - public MineMapWidget(int width, int height, int mineCount) { - super(333 / 2 - width * 8, 232 / 2 - height * 8, width * 16, height * 16); - this.width = width; - this.height = height; - this.resetData(); - this.mineCount = mineCount; - } - - public void resetData() { - mines = new boolean[width][height]; - generatedNumbers = new int[width][height]; - checkedSpaces = new boolean[width][height]; - flags = new boolean[width][height]; - isLost = false; - isWon = false; - isPrepared = false; - flagsPlaced = 0; - } - - public void initMines(int startX, int startY) { - int minesPlaced = 0; - while (minesPlaced < mineCount) { - for (; minesPlaced < mineCount; minesPlaced++) { - placeMine(startX, startY); - } - - // Are there any sections that we can't figure out what's inside? - for (int i = 0; i < width; i++) { - for (int j = 0; j < height; j++) { - boolean isTrapped = true; - // The weird ternaries here are making sure to not cause overflows - for (int xMod = i == 0 ? 0 : -1; xMod < (i == width - 1 ? 1 : 2); xMod++) { - for (int yMod = j == 0 ? 0 : -1; yMod < (j == height - 1 ? 1 : 2); yMod++) { - isTrapped &= mines[i + xMod][j + yMod]; - } - } - if (isTrapped) { - // Yes, so just take out the middle - mines[i][j] = false; - minesPlaced--; - } - } - } - } - - // Add to surrounding numbers for the mine - // The weird ternaries here are making sure to not cause overflows - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - if (mines[x][y]) { - for (int xMod = x == 0 ? 0 : -1; xMod < (x == width - 1 ? 1 : 2); xMod++) { - for (int yMod = y == 0 ? 0 : -1; yMod < (y == height - 1 ? 1 : 2); yMod++) { - generatedNumbers[x + xMod][y + yMod]++; - } - } - } - } - } - isPrepared = true; - } - - private void placeMine(int startX, int startY) { - int x = (int) (Math.random() * width); - int y = (int) (Math.random() * height); - - // The weird part to the right is making sure the player doesn't start on a numbered tile - while (mines[x][y] || ((startX < x + 3 && startX > x - 3) && (startY < y + 3 && startY > y - 3))) { - x = (int) (Math.random() * width); - y = (int) (Math.random() * height); - } - mines[x][y] = true; - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - timer++; - if (isWon && !interpolator.isActivated()) { // Fancy colors :) - interpolator.start(); - } - if (!isWon && interpolator.isActivated()) { - interpolator.stop(); - } - interpolator.update(); - for (int i = 0; i < width; i++) { - for (int j = 0; j < height; j++) { - if (isLost && mines[i][j]) // If the player lost, show where the mines are. - BOMB.draw(i * 16 + getPosition().getX(), j * 16 + getPosition().getY(), 16, 16); - else if (!checkedSpaces[i][j]) { - if (flags[i][j]) - FLAG.draw(i * 16 + getPosition().getX(), j * 16 + getPosition().getY(), 16, 16); - else - COVERED.draw(i * 16 + getPosition().getX(), j * 16 + getPosition().getY(), 16, 16); - } else if (!mines[i][j]) - NUMBERS[generatedNumbers[i][j]].draw(i * 16 + getPosition().getX(), j * 16 + getPosition().getY(), - 16, 16); - else - BOMB.draw(i * 16 + getPosition().getX(), j * 16 + getPosition().getY(), 16, 16); - } - } - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (isWon || isLost) { - return false; // Don't let them interact now... - } - - int gridX = (mouseX - getPosition().getX()) / 16; - int gridY = (mouseY - getPosition().getY()) / 16; - if (gridX >= width || gridY >= height || gridX < 0 || gridY < 0) { - return false; - } - - if (button == 0 && !flags[gridX][gridY]) { - if (!isPrepared) - initMines(gridX, gridY); - if (generatedNumbers[gridX][gridY] == 0) - uncoverSafeTiles(gridX, gridY); - else - checkedSpaces[gridX][gridY] = true; - if (mines[gridX][gridY]) - isLost = true; - } else if (button == 1 && !checkedSpaces[gridX][gridY]) { - flags[gridX][gridY] = !flags[gridX][gridY]; - if (flags[gridX][gridY]) - flagsPlaced++; - else - flagsPlaced--; - } - - return true; - } - - private void uncoverSafeTiles(int x, int y) { - checkedSpaces[x][y] = true; - if (generatedNumbers[x][y] != 0) - return; - // Weird ternaries again for preventing ArrayIndexOutOfBounds exceptions - for (int xMod = x == 0 ? 0 : -1; xMod < (x == width - 1 ? 1 : 2); xMod++) { - for (int yMod = y == 0 ? 0 : -1; yMod < (y == height - 1 ? 1 : 2); yMod++) { - if (!checkedSpaces[x + xMod][y + yMod]) - uncoverSafeTiles(x + xMod, y + yMod); - } - } - } - - public boolean hasLost() { - return isLost; - } - - public boolean hasWon() { - if (!isPrepared) - return false; - for (int i = 0; i < width; i++) { - for (int j = 0; j < height; j++) { - if (mines[i][j] != flags[i][j] || checkedSpaces[i][j] == mines[i][j]) { // If there is an unchecked safe - // square, or an uncovered - // bomb... - return false; - } - } - } - return true; - } - - public void notifyWon() { - isWon = true; - } -} diff --git a/src/main/java/gregtech/common/terminal/app/game/pong/PongApp.java b/src/main/java/gregtech/common/terminal/app/game/pong/PongApp.java deleted file mode 100644 index 32d3ad523aa..00000000000 --- a/src/main/java/gregtech/common/terminal/app/game/pong/PongApp.java +++ /dev/null @@ -1,175 +0,0 @@ -package gregtech.common.terminal.app.game.pong; - -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.SimpleTextWidget; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.util.Position; -import gregtech.common.terminal.app.game.pong.widget.BallWidget; -import gregtech.common.terminal.app.game.pong.widget.PaddleWidget; - -import org.lwjgl.input.Keyboard; -import org.lwjgl.util.vector.Vector2f; - -import java.awt.*; -import java.util.ArrayList; -import java.util.List; - -public class PongApp extends AbstractApplication { - - private BallWidget ball; - private int leftScore; - private int rightScore; - private List paddles; - private List solidObjects; - private int userInput = -1; - private int timer = 0; - - public PongApp() { - super("pong"); - } - - @Override - public AbstractApplication initApp() { - if (isClient) { - paddles = new ArrayList<>(); - solidObjects = new ArrayList<>(); - this.addWidget(new ImageWidget(5, 5, 333 - 10, 232 - 10, TerminalTheme.COLOR_B_2)); - this.addWidget(new ImageWidget(333 / 2 - 4, 5, 6, 232 - 10, new ColorRectTexture(0xAAAAAAAA))); - this.setBall(new BallWidget(333 / 2 - 1, 232 / 2 - 1)); - this.addWidget(new SimpleTextWidget(50, 20, "", 0xAAAAAA, () -> String.valueOf(this.getScore(true)), true)); - this.addWidget( - new SimpleTextWidget(283, 20, "", 0xAAAAAA, () -> String.valueOf(this.getScore(false)), true)); - this.initPaddles(); - } - return this; - } - - @Override - public boolean canOpenMenuOnEdge() { - return false; - } - - @Override - public boolean isClientSideApp() { - return true; - } - - public void setBall(BallWidget ball) { - this.ball = ball; - this.addWidget(ball); - } - - public void initPaddles() { - paddles.add(new PaddleWidget(20, 232 / 2 - 1, 4, 20, (PaddleWidget paddle) -> this.getUserInput())); - paddles.add(new PaddleWidget(313, 232 / 2 - 1, 4, 20, this::simplePaddleAI)); - paddles.forEach(this::addWidget); - this.solidObjects.add(new Rectangle(0, 0, 333, 10)); - this.solidObjects.add(new Rectangle(0, 222, 333, 10)); - } - - public void score(boolean side) { - if (side) { - leftScore++; - ball.theta = (float) Math.PI; - } else { - rightScore++; - ball.theta = (float) 0; - } - ball.theta += Math.random() * 0.2; - ball.setSelfPosition(new Position(333 / 2 - 1, 232 / 2 - 1)); - } - - @Override - public void updateScreenOnFrame() { - if (ball.getSelfPosition().getX() < 10) { - this.score(false); // Right side gains a point - } else if (ball.getSelfPosition().getX() > 323) { - this.score(true); // Left side gains a point - } else { - paddles.forEach((paddle) -> solidObjects.add(new Rectangle(paddle.toSelfRectangleBox()))); - int timeLeft = 1; - - TwoDimensionalRayTracer.TwoDimensionalRayTraceResult result = TwoDimensionalRayTracer - .nearestBoxSegmentCollision( - new Vector2f(ball.getSelfPosition().x, ball.getSelfPosition().y), - new Vector2f((float) (Math.cos(ball.theta) * 2), (float) (Math.sin(ball.theta) * 2)), - solidObjects, - new Vector2f(4, 4)); - while (result.time != 1 && timeLeft != 0) { - float angleMod = 0; - if (result.pos.y < result.collidedWith.getCenterY() - 2) { - angleMod -= Math.signum(result.normal.x) * 0.6; - } else if (result.pos.x > result.collidedWith.getCenterY() + 2) { - angleMod += Math.signum(result.normal.x) * 0.6; - } - ball.theta = (float) (Math.acos(result.normal.x) * 2 - ball.theta + Math.PI + angleMod) % (2 * Math.PI); // Reflects - // with - // a - // slight - // angle - // modification. - - if (ball.theta > Math.PI / 2 - 0.5 && ball.theta < Math.PI / 2 + 0.5) { - if (ball.theta <= Math.PI / 2) - ball.theta = Math.PI / 2 - 0.51; - else - ball.theta = Math.PI / 2 + 0.51; - } - if (ball.theta > 3 * Math.PI / 2 - 0.5 && ball.theta < 3 * Math.PI / 2 + 0.5) { - if (ball.theta < 3 * Math.PI / 2) - ball.theta = 3 * Math.PI / 2 - 0.51; - else - ball.theta = 3 * Math.PI / 2 + 0.51; - } - timeLeft -= result.time * timeLeft; - result = TwoDimensionalRayTracer.nearestBoxSegmentCollision( - new Vector2f(ball.getSelfPosition().x, ball.getSelfPosition().y), - new Vector2f((float) (Math.cos(ball.theta) * 3 * timeLeft), - (float) (Math.sin(ball.theta) * 3 * timeLeft)), - solidObjects, - new Vector2f(4, 4)); - // To prevent it getting permanently lodged into something. - ball.addSelfPosition((Math.cos(ball.theta) * 2 * (result.time + 0.1) * (timeLeft + 0.1)), - (Math.sin(ball.theta) * 2 * (result.time + 0.1) * (timeLeft + 0.1))); - } - ball.addSelfPosition((Math.cos(ball.theta) * 2 * timeLeft), (Math.sin(ball.theta) * 2 * timeLeft)); - solidObjects.remove(2); - solidObjects.remove(2); - } - if (ball.getSelfPosition().getY() > 222) { - ball.setSelfPosition(new Position(ball.getSelfPosition().getX(), 211)); - } else if (ball.getSelfPosition().getY() < 10) - ball.setSelfPosition(new Position(ball.getSelfPosition().getX(), 21)); - timer++; - if (Keyboard.isKeyDown(Keyboard.KEY_UP) ^ Keyboard.isKeyDown(Keyboard.KEY_DOWN)) { - if (Keyboard.isKeyDown(Keyboard.KEY_UP)) - userInput = 1; - else - userInput = 0; - } else { - userInput = -1; - } - super.updateScreenOnFrame(); - } - - public int simplePaddleAI(PaddleWidget paddle) { - if (this.timer % 3 == 0) - return -1; - if ((ball.getSelfPosition().getY() + 2 * paddle.getSelfPosition().getY()) / 3 < paddle.getSelfPosition().getY()) - return 1; - else if ((ball.getSelfPosition().getY() + 2 * paddle.getSelfPosition().getY()) / 3 > - paddle.getSelfPosition().getY()) - return 0; - return -1; - } - - public int getScore(boolean side) { - return side ? leftScore : rightScore; - } - - public int getUserInput() { - return userInput; - } -} diff --git a/src/main/java/gregtech/common/terminal/app/game/pong/TwoDimensionalRayTracer.java b/src/main/java/gregtech/common/terminal/app/game/pong/TwoDimensionalRayTracer.java deleted file mode 100644 index a32469e6fcb..00000000000 --- a/src/main/java/gregtech/common/terminal/app/game/pong/TwoDimensionalRayTracer.java +++ /dev/null @@ -1,86 +0,0 @@ -package gregtech.common.terminal.app.game.pong; - -import org.lwjgl.util.vector.Vector2f; - -import java.awt.*; -import java.util.List; - -import static net.minecraft.util.math.MathHelper.clamp; - -// Huge thanks to https://noonat.github.io/intersect! -public class TwoDimensionalRayTracer { - - public static class TwoDimensionalRayTraceResult { - - public Vector2f pos = new Vector2f(); - public Vector2f delta = new Vector2f(); - public Vector2f normal = new Vector2f(); - public float time = -1; - public Rectangle collidedWith = new Rectangle(); - } - - /** - * Detects the intersection between a segment and a box, if there is any. - * - * @param pos The original position of the point. - * @param delta The proposed new position of the point. - * @param boxSize The half-width and half-height of the box - * @return The resulting intersection between a segment and a box, or else null - */ - public static TwoDimensionalRayTraceResult intersectBoxSegment(Vector2f pos, Vector2f delta, Vector2f boxCenter, - Vector2f boxSize) { - float scaleX = (float) (1.0 / delta.x); - float scaleY = (float) (1.0 / delta.y); - float signX = Math.signum(scaleX); - float signY = Math.signum(scaleY); - float nearTimeX = (boxCenter.x - signX * (boxSize.x) - pos.x) * scaleX; - float nearTimeY = (boxCenter.y - signY * (boxSize.y) - pos.y) * scaleY; - float farTimeX = (boxCenter.x + signX * (boxSize.x) - pos.x) * scaleX; - float farTimeY = (boxCenter.y + signY * (boxSize.y) - pos.y) * scaleY; - - if (nearTimeX > farTimeY || nearTimeY > farTimeX) { - return null; - } - - double nearTime = Math.max(nearTimeX, nearTimeY); - double farTime = Math.min(farTimeX, farTimeY); - - if (nearTime >= 1 || farTime <= 0) { - return null; - } - - TwoDimensionalRayTraceResult result = new TwoDimensionalRayTraceResult(); - - result.time = (float) clamp(nearTime, 0, 1); - if (nearTimeX > nearTimeY) { - result.normal.x = -signX; - result.normal.y = 0; - } else { - result.normal.x = 0; - result.normal.y = -signY; - } - result.delta.x = (float) ((1.0 - result.time) * -delta.x); - result.delta.y = (float) ((1.0 - result.time) * -delta.y); - result.pos.x = pos.x + delta.x * result.time; - result.pos.y = pos.y + delta.y * result.time; - return result; - } - - public static TwoDimensionalRayTraceResult nearestBoxSegmentCollision(Vector2f pos, Vector2f delta, - List boxes, Vector2f padding) { - TwoDimensionalRayTraceResult result = new TwoDimensionalRayTraceResult(); - result.time = 1; - result.pos.x = pos.x + delta.x; - result.pos.y = pos.y + delta.y; - for (Rectangle box : boxes) { - TwoDimensionalRayTraceResult sweep = intersectBoxSegment(pos, delta, - new Vector2f((float) box.getCenterX(), (float) box.getCenterY()), - new Vector2f((float) box.getWidth() / 2 + padding.x, (float) box.getHeight() / 2 + padding.y)); - if (sweep != null && sweep.time < result.time) { - result = sweep; - result.collidedWith = box; - } - } - return result; - } -} diff --git a/src/main/java/gregtech/common/terminal/app/game/pong/widget/BallWidget.java b/src/main/java/gregtech/common/terminal/app/game/pong/widget/BallWidget.java deleted file mode 100644 index 49aa63629af..00000000000 --- a/src/main/java/gregtech/common/terminal/app/game/pong/widget/BallWidget.java +++ /dev/null @@ -1,48 +0,0 @@ -package gregtech.common.terminal.app.game.pong.widget; - -import gregtech.api.gui.resources.TextureArea; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.util.Position; - -import net.minecraft.util.ResourceLocation; - -import org.lwjgl.util.vector.Vector2f; - -public class BallWidget extends ImageWidget { - - public double theta; - private double xAccurate; - private double yAccurate; - - public BallWidget(int xPosition, int yPosition) { - super(xPosition, yPosition, 8, 8, - new TextureArea(new ResourceLocation("gregtech:textures/gui/widget/pong_ball.png"), 0, 0, 1, 1)); - theta = (Math.random() > 0.5 ? Math.PI : Math.PI / 2) + Math.random() * 0.2; - xAccurate = xPosition; - yAccurate = yPosition; - } - - @Override - public void setSelfPosition(Position selfPosition) { - super.setSelfPosition(selfPosition); - xAccurate = selfPosition.x; - yAccurate = selfPosition.y; - } - - @Override - public Position addSelfPosition(int addX, int addY) { - xAccurate += addX; - yAccurate += addY; - return super.addSelfPosition(addX, addY); - } - - public void addSelfPosition(double addX, double addY) { - xAccurate += addX; - yAccurate += addY; - super.setSelfPosition(new Position((int) xAccurate, (int) yAccurate)); - } - - public Vector2f getPreciseSelfPosition() { - return new Vector2f((float) xAccurate, (float) yAccurate); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/game/pong/widget/PaddleWidget.java b/src/main/java/gregtech/common/terminal/app/game/pong/widget/PaddleWidget.java deleted file mode 100644 index 758f2c80a20..00000000000 --- a/src/main/java/gregtech/common/terminal/app/game/pong/widget/PaddleWidget.java +++ /dev/null @@ -1,54 +0,0 @@ -package gregtech.common.terminal.app.game.pong.widget; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.util.Position; - -import java.awt.*; -import java.util.function.Function; - -public class PaddleWidget extends Widget { - - Function controlSupplier; - - public PaddleWidget(int x, int y, int width, int height, Function controlSupplier) { - super(x, y, width, height); - this.controlSupplier = controlSupplier; - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - drawSolidRect(this.toRectangleBox().x - this.toRectangleBox().width / 2, - this.toRectangleBox().y - this.toRectangleBox().height / 2, this.toRectangleBox().width, - this.toRectangleBox().height, 0xFFFFFFFF); - } - - @Override - public void updateScreenOnFrame() { - super.updateScreenOnFrame(); - if (this.getSelfPosition().getY() < 30) { - this.setSelfPosition(new Position(this.getSelfPosition().getX(), 30)); - } - if (this.getSelfPosition().getY() > 202) { - this.setSelfPosition(new Position(this.getSelfPosition().getX(), 202)); - } - int speed; - switch (controlSupplier.apply(this)) { - case 0: - speed = 2; - break; - case 1: - speed = -2; - break; - default: - speed = 0; - } - this.addSelfPosition(0, speed); - } - - public Rectangle toSelfRectangleBox() { - return new Rectangle(this.getSelfPosition().x - this.toRectangleBox().width / 2 - 2, - this.getSelfPosition().y - this.toRectangleBox().height / 2, - this.toRectangleBox().width, this.toRectangleBox().height); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guide/GuideApp.java b/src/main/java/gregtech/common/terminal/app/guide/GuideApp.java deleted file mode 100644 index 2d94001217a..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guide/GuideApp.java +++ /dev/null @@ -1,337 +0,0 @@ -package gregtech.common.terminal.app.guide; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.terminal.TerminalRegistry; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.gui.widgets.TreeListWidget; -import gregtech.api.terminal.os.TerminalOSWidget; -import gregtech.api.terminal.os.menu.IMenuComponent; -import gregtech.api.terminal.util.TreeNode; -import gregtech.api.util.FileUtility; -import gregtech.api.util.GTLog; -import gregtech.api.util.Position; -import gregtech.api.util.Size; -import gregtech.common.terminal.app.guide.widget.GuidePageWidget; -import gregtech.common.terminal.component.SearchComponent; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.resources.I18n; -import net.minecraftforge.fml.common.FMLCommonHandler; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.*; -import java.util.function.Consumer; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public abstract class GuideApp extends AbstractApplication implements - SearchComponent.IWidgetSearch>> { - - private GuidePageWidget pageWidget; - private TreeListWidget tree; - private TreeNode ROOT; - private Map jsonObjectMap; - private final IGuiTexture icon; - private float scale = 1; - - public GuideApp(String name, IGuiTexture icon) { - super(name); - this.icon = icon; - } - - @Override - public IGuiTexture getIcon() { - return icon; - } - - @Override - public AbstractApplication initApp() { - if (isClient) { - ROOT = new TreeNode<>(0, "root"); - jsonObjectMap = new HashMap<>(); - loadJsonFiles(); - buildTree(); - } - return this; - } - - protected void loadPage(TreeNode leaf) { - if (leaf == null) { - return; - } - if (this.pageWidget != null) { - this.removeWidget(this.pageWidget); - } - this.pageWidget = new GuidePageWidget(getOs().getSize().width - 200, 0, 200, getOs().getSize().height, 5); - if (leaf.isLeaf() && leaf.getContent() != null) { - JsonObject page = jsonObjectMap.get(leaf.getContent()); - if (page != null) { - this.pageWidget.loadJsonConfig(page); - } - } - this.addWidget(this.pageWidget); - this.onOSSizeUpdate(getOs().getSize().width, getOs().getSize().height); - } - - @Override - public boolean isClientSideApp() { - return true; - } - - protected IGuiTexture itemIcon(T item) { - return null; - } - - /** - * Should return a localised representation of the item - * - * @param item item - * @return localised name - */ - protected abstract String itemName(T item); - - protected abstract String rawItemName(T item); - - protected final TreeNode getTree() { - return ROOT; - } - - public final void loadJsonFiles() { - List jsons = new ArrayList<>(); - String lang = Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage().getLanguageCode(); - try { - Path guidePath = TerminalRegistry.TERMINAL_PATH.toPath().resolve("guide/" + this.getRegistryName()); - Path en_us = guidePath.resolve("en_us"); - List configPaths; - try (Stream stream = Files.walk(en_us)) { - configPaths = stream.filter(Files::isRegularFile) - .filter(f -> f.toString().endsWith(".json")) - .collect(Collectors.toList()); - } - configPaths.forEach(file -> { - File langFile = guidePath.resolve(lang + "/" + en_us.relativize(file)).toFile(); - JsonObject json = GuideApp.getConfig(langFile); - if (json == null) { - json = GuideApp.getConfig(file.toFile()); - } - if (json != null) { - jsons.add(json); - } - }); - } catch (IOException e) { - GTLog.logger.error("Failed to load file on path {}", "terminal", e); - } - ROOT = new TreeNode<>(0, "root"); - jsonObjectMap = new HashMap<>(); - for (JsonObject json : jsons) { - T t = ofJson(json); - if (t != null) { - registerItem(t, json.get("section").getAsString()); - jsonObjectMap.put(t, json); - } - } - } - - public abstract T ofJson(JsonObject json); - - private static JsonObject getConfig(File file) { - JsonElement je = FileUtility.loadJson(file); - return je == null ? null : je.isJsonObject() ? je.getAsJsonObject() : null; - } - - // ISearch - @Override - public boolean isManualInterrupt() { - return true; - } - - @Override - public void search(String word, Consumer>> find) { - Stack> stack = new Stack<>(); - if (getTree() != null) { - stack.push(getTree()); - dfsSearch(Thread.currentThread(), stack, word.toLowerCase(), find); - } - } - - private boolean dfsSearch(Thread thread, Stack> stack, String regex, - Consumer>> find) { - if (thread.isInterrupted()) { - return true; - } else { - TreeNode node = stack.peek(); - if (!node.isLeaf() && I18n.format(node.getKey()).toLowerCase().contains(regex)) { - find.accept((Stack>) stack.clone()); - } else if (node.isLeaf()) { - String name = itemName(node.getContent()); - if (name == null) { - name = node.getKey(); - } - if (I18n.format(name).toLowerCase().contains(regex)) { - find.accept((Stack>) stack.clone()); - } - } - if (node.getChildren() != null) { - for (TreeNode child : node.getChildren()) { - stack.push(child); - if (dfsSearch(thread, stack, regex, find)) return true; - stack.pop(); - } - } - } - return false; - } - - protected void registerItem(T item, String path) { - if (FMLCommonHandler.instance().getSide().isClient()) { - String[] parts = path.split("/"); - TreeNode child = ROOT; - if (!parts[0].isEmpty()) { - for (String sub : parts) { - child = child.getOrCreateChild(sub); - } - } - child.addContent(rawItemName(item), item); - } - } - - @Override - public void selectResult(Stack> result) { - if (result.size() > 0 && tree != null) { - List path = result.stream().map(TreeNode::getKey).collect(Collectors.toList()); - path.remove(0); - loadPage(tree.jumpTo(path)); - } - } - - @Override - public String resultDisplay(Stack> result) { - Iterator> iterator = result.iterator(); - if (!iterator.hasNext()) return ""; - iterator.next(); // skip root - StringBuilder builder = new StringBuilder(); - while (iterator.hasNext()) { - TreeNode node = iterator.next(); - builder.append(node.getContent() == null ? node.getKey() : itemName(node.getContent())); - if (iterator.hasNext()) - builder.append(" / "); - } - return builder.toString(); - } - - @Override - public List getMenuComponents() { - return Collections.singletonList(new SearchComponent<>(this)); - } - - private void buildTree() { - this.tree = new TreeListWidget<>(0, 0, getOs().getSize().width - 200, getOs().getSize().height, getTree(), - this::loadPage).setContentIconSupplier(this::itemIcon) - .setContentNameSupplier(this::itemName) - .setKeyNameSupplier(key -> key) - .setNodeTexture(GuiTextures.BORDERED_BACKGROUND) - .setLeafTexture(GuiTextures.SLOT_DARKENED); - this.addWidget(this.tree); - } - - @Override - protected void hookDrawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - if (this.tree != null) this.tree.drawInBackground(mouseX, mouseY, partialTicks, context); - if (this.pageWidget != null) { - Position position = this.pageWidget.getPosition(); - mouseX = (int) ((mouseX - position.x * (1 - scale)) / scale); - mouseY = (int) (mouseY / scale); - GlStateManager.translate(position.x * (1 - scale), 0, 0); - GlStateManager.scale(scale, scale, 1); - this.pageWidget.drawInBackground(mouseX, mouseY, partialTicks, context); - GlStateManager.scale(1 / scale, 1 / scale, 1); - GlStateManager.translate(position.x * (scale - 1), 0, 0); - } - } - - @Override - protected void hookDrawInForeground(int mouseX, int mouseY) { - if (this.tree != null) this.tree.drawInForeground(mouseX, mouseY); - if (this.pageWidget != null) { - Position position = this.pageWidget.getPosition(); - mouseX = (int) ((mouseX - position.x * (1 - scale)) / scale); - mouseY = (int) (mouseY / scale); - GlStateManager.translate(position.x * (1 - scale), 0, 0); - GlStateManager.scale(scale, scale, 1); - this.pageWidget.drawInForeground(mouseX, mouseY); - GlStateManager.scale(1 / scale, 1 / scale, 1); - GlStateManager.translate(position.x * (scale - 1), 0, 0); - } - } - - @Override - public boolean mouseWheelMove(int mouseX, int mouseY, int wheelDelta) { - if (this.tree != null && this.tree.mouseWheelMove(mouseX, mouseY, wheelDelta)) return true; - if (this.pageWidget != null) { - Position position = this.pageWidget.getPosition(); - mouseX = (int) ((mouseX - position.x * (1 - scale)) / scale); - mouseY = (int) (mouseY / scale); - return this.pageWidget.mouseWheelMove(mouseX, mouseY, wheelDelta); - } - return false; - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (this.tree != null && this.tree.mouseClicked(mouseX, mouseY, button)) return true; - if (this.pageWidget != null) { - Position position = this.pageWidget.getPosition(); - mouseX = (int) ((mouseX - position.x * (1 - scale)) / scale); - mouseY = (int) (mouseY / scale); - return this.pageWidget.mouseClicked(mouseX, mouseY, button); - } - return false; - } - - @Override - public boolean mouseDragged(int mouseX, int mouseY, int button, long timeDragged) { - if (this.tree != null && this.tree.mouseDragged(mouseX, mouseY, button, timeDragged)) return true; - if (this.pageWidget != null) { - Position position = this.pageWidget.getPosition(); - mouseX = (int) ((mouseX - position.x * (1 - scale)) / scale); - mouseY = (int) (mouseY / scale); - return this.pageWidget.mouseDragged(mouseX, mouseY, button, timeDragged); - } - return false; - } - - @Override - public boolean mouseReleased(int mouseX, int mouseY, int button) { - if (this.tree != null && this.tree.mouseReleased(mouseX, mouseY, button)) return true; - if (this.pageWidget != null) { - Position position = this.pageWidget.getPosition(); - mouseX = (int) ((mouseX - position.x * (1 - scale)) / scale); - mouseY = (int) (mouseY / scale); - return this.pageWidget.mouseReleased(mouseX, mouseY, button); - } - return false; - } - - @Override - public void onOSSizeUpdate(int width, int height) { - this.setSize(new Size(width, height)); - int treeWidth = Math.max(TerminalOSWidget.DEFAULT_WIDTH - 200, getOs().getSize().width / 3); - if (this.tree != null) { - this.tree.setSize(new Size(treeWidth, height)); - } - if (this.pageWidget != null) { - this.scale = (width - treeWidth) / 200f; - this.pageWidget.setSize(new Size(200, (int) (height / scale))); - this.pageWidget.setSelfPosition(new Position(treeWidth, 0)); - } - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guide/ItemGuideApp.java b/src/main/java/gregtech/common/terminal/app/guide/ItemGuideApp.java deleted file mode 100644 index d86bfe35d0c..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guide/ItemGuideApp.java +++ /dev/null @@ -1,103 +0,0 @@ -package gregtech.common.terminal.app.guide; - -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.resources.ItemStackTexture; -import gregtech.api.items.metaitem.MetaItem; -import gregtech.common.items.MetaItems; - -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import java.util.Objects; - -public class ItemGuideApp extends GuideApp { - - public ItemGuideApp() { - super("items", new ItemStackTexture(MetaItems.PROSPECTOR_LV.getStackForm())); - } - - @Override - protected String itemName(GuideItem item) { - return item.stack.getDisplayName(); - } - - @Override - protected String rawItemName(GuideItem item) { - if (item.stack.getItem() instanceof MetaItem) { - MetaItem.MetaValueItem metaValueItem = ((MetaItem) item.stack.getItem()) - .getItem((short) item.stack.getMetadata()); - if (metaValueItem != null) return metaValueItem.unlocalizedName; - } - return item.stack.getTranslationKey(); - } - - @Override - protected IGuiTexture itemIcon(GuideItem item) { - return new ItemStackTexture(item.stack); - } - - @Override - public GuideItem ofJson(JsonObject json) { - return GuideItem.ofJson(json); - } - - public static class GuideItem { - - public final ItemStack stack; - public final String name; - - public GuideItem(ItemStack stack, String name) { - this.stack = stack; - this.name = name; - } - - public GuideItem(ItemStack stack) { - this(stack, Objects.requireNonNull(stack.getItem().getRegistryName()) + ":" + stack.getMetadata()); - } - - public GuideItem(MetaItem.MetaValueItem item) { - this(item.getStackForm(), item.unlocalizedName); - } - - public static GuideItem ofJson(JsonObject json) { - if (json.has("item")) { - JsonElement element = json.get("item"); - if (element.isJsonPrimitive()) { - String[] s = element.getAsString().split(":"); - if (s.length < 2) return null; - Item item = Item.getByNameOrId(s[0] + ":" + s[1]); - if (item == null) return null; - int meta = 0; - if (s.length > 2) - meta = Integer.parseInt(s[2]); - return new GuideItem(new ItemStack(item, 1, meta)); - } - } - if (json.has("metaitem")) { - String metaItemId = json.get("metaitem").getAsString(); - for (MetaItem metaItem : MetaItem.getMetaItems()) { - MetaItem.MetaValueItem metaValueItem = metaItem.getAllItems().stream() - .filter(m -> m.unlocalizedName.equals(metaItemId)).findFirst().orElse(null); - if (metaValueItem != null) return new GuideItem(metaValueItem); - } - } - return null; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GuideItem guideItem = (GuideItem) o; - return Objects.equals(stack, guideItem.stack) && Objects.equals(name, guideItem.name); - } - - @Override - public int hashCode() { - return Objects.hash(stack, name); - } - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guide/MultiBlockGuideApp.java b/src/main/java/gregtech/common/terminal/app/guide/MultiBlockGuideApp.java deleted file mode 100644 index 6e261666def..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guide/MultiBlockGuideApp.java +++ /dev/null @@ -1,46 +0,0 @@ -package gregtech.common.terminal.app.guide; - -import gregtech.api.GregTechAPI; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.resources.ItemStackTexture; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.util.GTUtility; -import gregtech.common.metatileentities.MetaTileEntities; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -public class MultiBlockGuideApp extends GuideApp { - - public MultiBlockGuideApp() { - super("multiblocks", new ItemStackTexture(MetaTileEntities.ELECTRIC_BLAST_FURNACE.getStackForm())); - } - - @Override - public MetaTileEntity ofJson(JsonObject json) { - String[] valids = { "multiblock", "metatileentity" }; - 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())); - } - } - return null; - } - - @Override - protected IGuiTexture itemIcon(MetaTileEntity item) { - return new ItemStackTexture(item.getStackForm()); - } - - @Override - protected String itemName(MetaTileEntity item) { - return item.getStackForm().getDisplayName(); - } - - @Override - protected String rawItemName(MetaTileEntity item) { - return item.metaTileEntityId.getPath(); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guide/SimpleMachineGuideApp.java b/src/main/java/gregtech/common/terminal/app/guide/SimpleMachineGuideApp.java deleted file mode 100644 index 171f108dfbb..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guide/SimpleMachineGuideApp.java +++ /dev/null @@ -1,47 +0,0 @@ -package gregtech.common.terminal.app.guide; - -import gregtech.api.GTValues; -import gregtech.api.GregTechAPI; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.resources.ItemStackTexture; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.util.GTUtility; -import gregtech.common.metatileentities.MetaTileEntities; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -public class SimpleMachineGuideApp extends GuideApp { - - public SimpleMachineGuideApp() { - super("machines", new ItemStackTexture(MetaTileEntities.CHEMICAL_REACTOR[GTValues.LV].getStackForm())); - } - - @Override - protected IGuiTexture itemIcon(MetaTileEntity item) { - return new ItemStackTexture(item.getStackForm()); - } - - @Override - protected String itemName(MetaTileEntity item) { - return item.getStackForm().getDisplayName(); - } - - @Override - protected String rawItemName(MetaTileEntity item) { - return item.metaTileEntityId.getPath(); - } - - @Override - public MetaTileEntity ofJson(JsonObject json) { - String[] valids = { "machine", "generator", "metatileentity" }; - 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())); - } - } - return null; - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guide/TutorialGuideApp.java b/src/main/java/gregtech/common/terminal/app/guide/TutorialGuideApp.java deleted file mode 100644 index eeed5585413..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guide/TutorialGuideApp.java +++ /dev/null @@ -1,32 +0,0 @@ -package gregtech.common.terminal.app.guide; - -import gregtech.api.gui.resources.ItemStackTexture; - -import net.minecraft.client.resources.I18n; -import net.minecraft.init.Items; - -import com.google.gson.JsonObject; - -public class TutorialGuideApp extends GuideApp { - - public TutorialGuideApp() { - super("tutorials", new ItemStackTexture(Items.PAPER)); - } - - @Override - protected String itemName(String item) { - return I18n.format(item); - } - - @Override - protected String rawItemName(String item) { - return item; - } - - @Override - public String ofJson(JsonObject json) { - if (json.has("tutorial")) - return json.get("tutorial").getAsString(); - return json.get("title").getAsString(); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guide/widget/CardWidget.java b/src/main/java/gregtech/common/terminal/app/guide/widget/CardWidget.java deleted file mode 100644 index 3d59cc9f862..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guide/widget/CardWidget.java +++ /dev/null @@ -1,80 +0,0 @@ -package gregtech.common.terminal.app.guide.widget; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.util.Position; -import gregtech.api.util.Size; -import gregtech.common.terminal.app.guideeditor.widget.configurator.BooleanConfigurator; -import gregtech.common.terminal.app.guideeditor.widget.configurator.NumberConfigurator; - -import com.google.gson.JsonObject; - -import java.util.function.Consumer; - -public class CardWidget extends GuideWidget { - - public final static String NAME = "card"; - - // config - public int width; - public int height; - public boolean isShadow; - - @Override - public String getRegistryName() { - return NAME; - } - - @Override - public JsonObject getTemplate(boolean isFixed) { - JsonObject template = super.getTemplate(isFixed); - template.addProperty("fill", -3745585); - template.addProperty("width", 120); - template.addProperty("height", 60); - template.addProperty("isShadow", true); - return template; - } - - @Override - public void loadConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, boolean isFixed, - Consumer needUpdate) { - group.addWidget(new BooleanConfigurator(group, config, "isShadow", true).setOnUpdated(needUpdate)); - if (!isFixed) { - group.addWidget(new NumberConfigurator(group, config, "width").setOnUpdated(needUpdate)); - group.addWidget(new NumberConfigurator(group, config, "height").setOnUpdated(needUpdate)); - } - super.loadConfigurator(group, config, isFixed, needUpdate); - } - - @Override - protected Widget initStream() { - int pageWidth = getSize().width; - int x = getSelfPosition().x; - int y = getSelfPosition().y; - if (page != null) { - x = page.getMargin(); - pageWidth = page.getPageWidth() - 2 * x; - } - this.setSelfPosition(new Position(x + (pageWidth - width) / 2, y)); - return initFixed(); - } - - @Override - protected Widget initFixed() { - this.setSize(new Size(width, height)); - return this; - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - if (isShadow) { - int x = getPosition().x; - int y = getPosition().y; - int width = getSize().width; - int height = getSize().height; - drawRectShadow(x, y, width, height, 5); - } - super.drawInBackground(mouseX, mouseY, partialTicks, context); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guide/widget/GuidePageWidget.java b/src/main/java/gregtech/common/terminal/app/guide/widget/GuidePageWidget.java deleted file mode 100644 index bf388e66b09..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guide/widget/GuidePageWidget.java +++ /dev/null @@ -1,190 +0,0 @@ -package gregtech.common.terminal.app.guide.widget; - -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.util.Position; -import gregtech.api.util.Size; -import gregtech.api.util.interpolate.Eases; -import gregtech.api.util.interpolate.Interpolator; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; - -import java.awt.*; -import java.util.*; -import java.util.List; - -public class GuidePageWidget extends DraggableScrollableWidgetGroup { - - public static final Map REGISTER_WIDGETS = new HashMap<>(); - - static { // register guide widgets - REGISTER_WIDGETS.put(TextBoxWidget.NAME, new TextBoxWidget()); - REGISTER_WIDGETS.put(ImageWidget.NAME, new ImageWidget()); - REGISTER_WIDGETS.put(CardWidget.NAME, new CardWidget()); - REGISTER_WIDGETS.put(SlotListWidget.NAME, new SlotListWidget()); - REGISTER_WIDGETS.put(TankListWidget.NAME, new TankListWidget()); - } - - protected TextBoxWidget title; - protected List stream = new ArrayList<>(); - protected List fixed = new ArrayList<>(); - protected Interpolator interpolator; - private final int margin; - - public GuidePageWidget(int xPosition, int yPosition, int width, int height, int margin) { - super(xPosition, yPosition, width, height); - this.margin = margin; - this.setBackground(new ColorRectTexture(-1)) - .setDraggable(true) - .setYScrollBarWidth(4) - .setYBarStyle(new ColorRectTexture(new Color(142, 142, 142)), - new ColorRectTexture(new Color(148, 226, 193))); - this.setUseScissor(false); - } - - public int getPageWidth() { - return this.getSize().width - yBarWidth; - } - - public int getMargin() { - return margin; - } - - public void setTitle(String config) { - int x = 5; - int y = 2; - int width = this.getSize().width - yBarWidth - 10; - int height = 0; - if (title != null) { - height = title.getSize().height; - x = title.getSelfPosition().x; - y = title.getSelfPosition().y; - removeWidget(title); - } - title = new TextBoxWidget(5, 2, width, - Collections.singletonList(config), - 0, 15, 0xffffffff, 0x6fff0000, 0xff000000, - true, true); - this.addWidget(title); - title.setSelfPosition(new Position(x, y)); - int offset = title.getSize().height - height; - if (offset != 0) { - for (Widget widget : stream) { - widget.addSelfPosition(0, offset); - } - } - } - - public String getTitle() { - return title == null ? "" : String.join("\n", title.content); - } - - public String loadJsonConfig(String config) { - try { - loadJsonConfig(new JsonParser().parse(config).getAsJsonObject()); - } catch (Exception e) { - this.clearAllWidgets(); - return e.getMessage(); - } - return null; - } - - public void loadJsonConfig(JsonObject config) { - this.stream.clear(); - this.fixed.clear(); - this.title = null; - this.clearAllWidgets(); - int pageWidth = getPageWidth(); - int margin = getMargin(); - // add title - setTitle(config.get("title").getAsString()); - - // add stream widgets - if (config.has("stream")) { - stream = new ArrayList<>(); - int y = title.getSize().height + 10; - for (JsonElement element : config.getAsJsonArray("stream")) { - JsonObject widgetConfig = element.getAsJsonObject(); - Widget widget = REGISTER_WIDGETS.get(widgetConfig.get("type").getAsString()) - .updateOrCreateStreamWidget(margin, y, pageWidth - 2 * margin, widgetConfig); - y += widget.getSize().height + 5; - stream.add(widget); - this.addWidget(widget); - } - } - // add fixed widgets - if (config.has("fixed")) { - fixed = new ArrayList<>(); - for (JsonElement element : config.getAsJsonArray("fixed")) { - JsonObject widgetConfig = element.getAsJsonObject(); - Widget widget = REGISTER_WIDGETS.get(widgetConfig.get("type").getAsString()).updateOrCreateFixedWidget( - widgetConfig.get("x").getAsInt(), - widgetConfig.get("y").getAsInt(), - widgetConfig.get("width").getAsInt(), - widgetConfig.get("height").getAsInt(), - widgetConfig); - fixed.add(widget); - this.addWidget(widget); - } - } - } - - public void onSizeUpdate(Widget widget, Size oldSize) { - int offset = widget.getSize().height - oldSize.height; - maxHeight = Math.max(maxHeight, widget.getSize().height + widget.getSelfPosition().y); - int index = stream.indexOf(widget); - if (index < 0) return; - for (int i = stream.size() - 1; i > index; i--) { - Widget nextWidget = stream.get(i); - nextWidget.addSelfPosition(0, offset); - } - } - - public void onPositionUpdate(Widget widget, Position oldPosition) { - if (oldPosition.y + widget.getSize().height == maxHeight) { - maxHeight = 0; - for (Widget widget1 : widgets) { - maxHeight = Math.max(maxHeight, widget1.getSize().height + widget1.getSelfPosition().y + scrollYOffset); - } - } - } - - protected int getStreamBottom() { - if (stream != null && stream.size() > 0) { - Widget widget = stream.get(stream.size() - 1); - return widget.getSize().height + widget.getSelfPosition().y + scrollYOffset; - } else { - return title.getSize().height + 10; - } - } - - @Override - public void updateScreen() { - if (interpolator != null) interpolator.update(); - super.updateScreen(); - } - - public void jumpToRef(String ref) { - if (interpolator != null && !interpolator.isFinish()) return; - for (Widget widget : widgets) { - if (widget instanceof IGuideWidget && ref.equals(((IGuideWidget) widget).getRef())) { - interpolator = new Interpolator(scrollYOffset, widget.getSelfPosition().y + scrollYOffset, 20, - Eases.QUAD_OUT, - value -> setScrollYOffset(value.intValue()), - value -> interpolator = null); - interpolator.start(); - } - } - } - - @Override - public void addWidget(Widget widget) { - super.addWidget(widget); - if (widget instanceof IGuideWidget) { - ((IGuideWidget) widget).setPage(this); - } - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guide/widget/GuideWidget.java b/src/main/java/gregtech/common/terminal/app/guide/widget/GuideWidget.java deleted file mode 100644 index 9055e6cf1cb..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guide/widget/GuideWidget.java +++ /dev/null @@ -1,185 +0,0 @@ -package gregtech.common.terminal.app.guide.widget; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.util.Position; -import gregtech.api.util.Size; -import gregtech.common.terminal.app.guideeditor.widget.configurator.ColorConfigurator; -import gregtech.common.terminal.app.guideeditor.widget.configurator.NumberConfigurator; -import gregtech.common.terminal.app.guideeditor.widget.configurator.StringConfigurator; -import gregtech.common.terminal.app.guideeditor.widget.configurator.TextListConfigurator; - -import net.minecraft.item.ItemStack; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -public abstract class GuideWidget extends Widget implements IGuideWidget { - - // config - public String ref; - public int fill; - public int stroke; - public int stroke_width = 1; - public String link; - public List hover_text; - - private transient boolean isFixed; - protected transient GuidePageWidget page; - protected transient JsonObject config; - - public GuideWidget(int x, int y, int width, int height) { - super(x, y, width, height); - } - - public GuideWidget() { - super(Position.ORIGIN, Size.ZERO); - } - - @Override - public JsonObject getConfig() { - return config; - } - - @Override - public boolean isFixed() { - return isFixed; - } - - protected abstract Widget initFixed(); - - protected Widget initStream() { - return initFixed(); - } - - @Override - public void setStroke(int color) { - this.stroke = color; - } - - @Override - public void setSize(Size size) { - Size oldSize = this.getSize(); - super.setSize(size); - if (page != null) { - page.onSizeUpdate(this, oldSize); - } - } - - @Override - protected void recomputePosition() { - Position oldPosition = getPosition(); - super.recomputePosition(); - if (page != null) { - page.onPositionUpdate(this, oldPosition); - } - } - - @Override - public JsonObject getTemplate(boolean isFixed) { - JsonObject template = new JsonObject(); - template.addProperty("type", getRegistryName()); - if (isFixed) { - template.addProperty("x", 0); - template.addProperty("y", 0); - template.addProperty("width", 100); - template.addProperty("height", 100); - } - template.addProperty("ref", (String) null); - template.addProperty("stroke", (String) null); - template.addProperty("stroke_width", (String) null); - template.addProperty("fill", (String) null); - template.addProperty("link", (String) null); - template.add("hover_text", new Gson().toJsonTree(hover_text)); - return template; - } - - @Override - public void loadConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, boolean isFixed, - Consumer needUpdate) { - group.addWidget(new ColorConfigurator(group, config, "fill", 0).setOnUpdated(needUpdate)); - group.addWidget(new ColorConfigurator(group, config, "stroke", 0).setOnUpdated(needUpdate)); - group.addWidget(new NumberConfigurator(group, config, "stroke_width", 1).setOnUpdated(needUpdate)); - group.addWidget(new StringConfigurator(group, config, "ref", "").setOnUpdated(needUpdate)); - group.addWidget(new StringConfigurator(group, config, "link", "").setOnUpdated(needUpdate)); - group.addWidget(new TextListConfigurator(group, 40, config, "hover_text", "").setOnUpdated(needUpdate)); - } - - @Override - public String getRef() { - return ref; - } - - @Override - public Widget updateOrCreateStreamWidget(int x, int y, int pageWidth, JsonObject config) { - if (config == null) { - return initStream(); - } - GuideWidget widget = new Gson().fromJson(config, this.getClass()); - widget.isFixed = false; - widget.setSelfPosition(new Position(x, y)); - widget.setSize(new Size(pageWidth, 0)); - widget.config = config; - return widget.initStream(); - } - - @Override - public Widget updateOrCreateFixedWidget(int x, int y, int width, int height, JsonObject config) { - if (config == null) { - return initFixed(); - } - GuideWidget widget = new Gson().fromJson(config, this.getClass()); - widget.isFixed = true; - widget.setSelfPosition(new Position(x, y)); - widget.setSize(new Size(width, height)); - widget.config = config; - return widget.initFixed(); - } - - @Override - public void setPage(GuidePageWidget page) { - this.page = page; - } - - @Override - public void drawInForeground(int mouseX, int mouseY) { - if (link != null && isMouseOverElement(mouseX, mouseY)) { - Position position = getPosition(); - Size size = getSize(); - drawBorder(position.x, position.y, size.width, size.height, 0xff0000ff, stroke_width); - } - if ((hover_text != null || link != null) && isMouseOverElement(mouseX, mouseY)) { - List tooltip = hover_text == null ? new ArrayList<>() : new ArrayList<>(hover_text); - if (link != null) { - tooltip.add("§9Ctrl+Click§r §e(" + link + ")§r"); - } - drawHoveringText(ItemStack.EMPTY, tooltip, 100, mouseX, mouseY); - } - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - Position position = getPosition(); - Size size = getSize(); - if (stroke != 0) { - drawBorder(position.x, position.y, size.width, size.height, stroke, stroke_width); - } - if (fill != 0) { - drawSolidRect(position.x, position.y, size.width, size.height, fill); - } - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (link != null && isMouseOverElement(mouseX, mouseY) && isCtrlDown()) { - page.jumpToRef(link); - return true; - } - return false; - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guide/widget/GuideWidgetGroup.java b/src/main/java/gregtech/common/terminal/app/guide/widget/GuideWidgetGroup.java deleted file mode 100644 index 51a91cf93dc..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guide/widget/GuideWidgetGroup.java +++ /dev/null @@ -1,196 +0,0 @@ -package gregtech.common.terminal.app.guide.widget; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.util.Position; -import gregtech.api.util.Size; -import gregtech.common.terminal.app.guideeditor.widget.configurator.ColorConfigurator; -import gregtech.common.terminal.app.guideeditor.widget.configurator.NumberConfigurator; -import gregtech.common.terminal.app.guideeditor.widget.configurator.StringConfigurator; -import gregtech.common.terminal.app.guideeditor.widget.configurator.TextListConfigurator; - -import net.minecraft.item.ItemStack; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -public abstract class GuideWidgetGroup extends WidgetGroup implements IGuideWidget { - - // config - public String ref; - public int fill; - public int stroke; - public int stroke_width = 1; - public String link; - public List hover_text; - - private transient boolean isFixed; - protected transient GuidePageWidget page; - protected transient JsonObject config; - - public GuideWidgetGroup(int x, int y, int width, int height) { - super(x, y, width, height); - } - - public GuideWidgetGroup() { - super(Position.ORIGIN, Size.ZERO); - } - - @Override - public JsonObject getConfig() { - return config; - } - - @Override - public boolean isFixed() { - return isFixed; - } - - @Override - public void setStroke(int color) { - this.stroke = color; - } - - @Override - public void setSize(Size size) { - Size oldSize = this.getSize(); - super.setSize(size); - if (page != null) { - page.onSizeUpdate(this, oldSize); - } - } - - @Override - protected void recomputePosition() { - Position oldPosition = getPosition(); - super.recomputePosition(); - if (page != null) { - page.onPositionUpdate(this, oldPosition); - } - } - - @Override - public JsonObject getTemplate(boolean isFixed) { - JsonObject template = new JsonObject(); - template.addProperty("type", getRegistryName()); - if (isFixed) { - template.addProperty("x", 0); - template.addProperty("y", 0); - template.addProperty("width", 100); - template.addProperty("height", 100); - } - template.addProperty("ref", (String) null); - template.addProperty("stroke", (String) null); - template.addProperty("stroke_width", (String) null); - template.addProperty("fill", (String) null); - template.addProperty("link", (String) null); - template.add("hover_text", new Gson().toJsonTree(hover_text)); - return template; - } - - @Override - public void loadConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, boolean isFixed, - Consumer needUpdate) { - group.addWidget(new ColorConfigurator(group, config, "fill", 0).setOnUpdated(needUpdate)); - group.addWidget(new ColorConfigurator(group, config, "stroke", 0).setOnUpdated(needUpdate)); - group.addWidget(new NumberConfigurator(group, config, "stroke_width", 1).setOnUpdated(needUpdate)); - group.addWidget(new StringConfigurator(group, config, "ref", "").setOnUpdated(needUpdate)); - group.addWidget(new StringConfigurator(group, config, "link", "").setOnUpdated(needUpdate)); - group.addWidget(new TextListConfigurator(group, 40, config, "hover_text", "").setOnUpdated(needUpdate)); - } - - @Override - public String getRef() { - return ref; - } - - protected Widget initStream() { - return initFixed(); - } - - protected abstract Widget initFixed(); - - @Override - public Widget updateOrCreateStreamWidget(int x, int y, int pageWidth, JsonObject config) { - if (config == null) { - return initStream(); - } - GuideWidgetGroup widget = new Gson().fromJson(config, this.getClass()); - widget.isFixed = false; - widget.setSelfPosition(new Position(x, y)); - widget.setSize(new Size(pageWidth, 0)); - widget.config = config; - return widget.initStream(); - } - - @Override - public Widget updateOrCreateFixedWidget(int x, int y, int width, int height, JsonObject config) { - if (config == null) { - return initFixed(); - } - GuideWidgetGroup widget = new Gson().fromJson(config, this.getClass()); - widget.isFixed = true; - widget.setSelfPosition(new Position(x, y)); - widget.setSize(new Size(width, height)); - widget.config = config; - return widget.initFixed(); - } - - @Override - public void setPage(GuidePageWidget page) { - this.page = page; - } - - @Override - public void addWidget(Widget widget) { - super.addWidget(widget); - if (widget instanceof IGuideWidget) { - ((IGuideWidget) widget).setPage(page); - } - } - - @Override - public void drawInForeground(int mouseX, int mouseY) { - if (link != null && isMouseOverElement(mouseX, mouseY)) { - Position position = getPosition(); - Size size = getSize(); - drawBorder(position.x, position.y, size.width, size.height, 0xff0000ff, stroke_width); - } - if ((hover_text != null || link != null) && isMouseOverElement(mouseX, mouseY)) { - List tooltip = hover_text == null ? new ArrayList<>() : new ArrayList<>(hover_text); - if (link != null) { - tooltip.add("§9Ctrl+Click§r §e(" + link + ")§r"); - } - drawHoveringText(ItemStack.EMPTY, tooltip, 100, mouseX, mouseY); - } - super.drawInForeground(mouseX, mouseY); - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - Position position = getPosition(); - Size size = getSize(); - if (stroke != 0) { - drawBorder(position.x, position.y, size.width, size.height, stroke, stroke_width); - } - if (fill != 0) { - drawSolidRect(position.x, position.y, size.width, size.height, fill); - } - super.drawInBackground(mouseX, mouseY, partialTicks, context); - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (link != null && isMouseOverElement(mouseX, mouseY) && isCtrlDown()) { - page.jumpToRef(link); - return true; - } - return super.mouseClicked(mouseX, mouseY, button); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guide/widget/IGuideWidget.java b/src/main/java/gregtech/common/terminal/app/guide/widget/IGuideWidget.java deleted file mode 100644 index 7fb947c8c26..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guide/widget/IGuideWidget.java +++ /dev/null @@ -1,61 +0,0 @@ -package gregtech.common.terminal.app.guide.widget; - -import gregtech.api.gui.Widget; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.util.Position; -import gregtech.api.util.Size; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import java.lang.reflect.Field; -import java.util.function.Consumer; - -public interface IGuideWidget { - - String getRegistryName(); - - JsonObject getConfig(); - - boolean isFixed(); - - Widget updateOrCreateStreamWidget(int x, int y, int pageWidth, JsonObject config); - - Widget updateOrCreateFixedWidget(int x, int y, int width, int height, JsonObject config); - - void setPage(GuidePageWidget page); - - default void updateValue(String field) { - JsonObject config = getConfig(); - if (config != null && config.has(field)) { - try { - Field f = this.getClass().getField(field); - JsonElement value = config.get(field); - if (value.isJsonNull()) { // default - f.set(this, f.get(GuidePageWidget.REGISTER_WIDGETS.get(getRegistryName()))); - } else { - f.set(this, new Gson().fromJson(value, f.getGenericType())); - } - if (isFixed()) { - updateOrCreateFixedWidget(0, 0, 0, 0, null); - } else { - updateOrCreateStreamWidget(0, 0, 0, null); - } - } catch (Exception ignored) {} - } - } - - String getRef(); - - JsonObject getTemplate(boolean isFixed); - - void loadConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, boolean isFixed, - Consumer needUpdate); - - void setStroke(int color); - - default void onFixedPositionSizeChanged(Position position, Size size) { - updateOrCreateFixedWidget(0, 0, 0, 0, null); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guide/widget/ImageWidget.java b/src/main/java/gregtech/common/terminal/app/guide/widget/ImageWidget.java deleted file mode 100644 index b5f6fd5d71b..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guide/widget/ImageWidget.java +++ /dev/null @@ -1,112 +0,0 @@ -package gregtech.common.terminal.app.guide.widget; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.resources.ItemStackTexture; -import gregtech.api.gui.resources.TextureArea; -import gregtech.api.gui.resources.URLTexture; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.util.Position; -import gregtech.api.util.Size; -import gregtech.common.terminal.app.guideeditor.widget.configurator.NumberConfigurator; -import gregtech.common.terminal.app.guideeditor.widget.configurator.SelectorConfigurator; -import gregtech.common.terminal.app.guideeditor.widget.configurator.StringConfigurator; - -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.item.Item; -import net.minecraft.util.ResourceLocation; - -import com.google.gson.JsonObject; - -import java.util.Arrays; -import java.util.function.Consumer; - -public class ImageWidget extends GuideWidget { - - public final static String NAME = "image"; - // config - public String form; - public String source; - public int width; - public int height; - - public transient IGuiTexture image; - - @Override - public String getRegistryName() { - return NAME; - } - - @Override - public JsonObject getTemplate(boolean isFixed) { - JsonObject template = super.getTemplate(isFixed); - template.addProperty("form", "resource"); - template.addProperty("source", "gregtech:textures/gui/icon/gregtech_logo.png"); - template.addProperty("width", 50); - template.addProperty("height", 50); - return template; - } - - @Override - public void loadConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, boolean isFixed, - Consumer needUpdate) { - if (!isFixed) { - group.addWidget(new NumberConfigurator(group, config, "width").setOnUpdated(needUpdate)); - group.addWidget(new NumberConfigurator(group, config, "height").setOnUpdated(needUpdate)); - } - group.addWidget(new SelectorConfigurator(group, config, "form", Arrays.asList("url", "item", "resource")) - .setOnUpdated(needUpdate)); - group.addWidget(new StringConfigurator(group, config, "source").setOnUpdated(needUpdate)); - super.loadConfigurator(group, config, isFixed, needUpdate); - } - - @Override - public void updateScreen() { - if (image != null) { - image.updateTick(); - } - } - - @Override - protected Widget initStream() { - int pageWidth = getSize().width; - int x = getSelfPosition().x; - int y = getSelfPosition().y; - if (page != null) { - x = page.getMargin(); - pageWidth = page.getPageWidth() - 2 * x; - } - this.setSelfPosition(new Position(x + (pageWidth - Math.max(0, width)) / 2, y)); - return initFixed(); - } - - @Override - protected Widget initFixed() { - width = Math.max(0, width); - height = Math.max(0, height); - this.setSize(new Size(width, height)); - switch (form) { - case "url": - image = new URLTexture(source); - break; - case "item": - image = new ItemStackTexture(Item.getByNameOrId(source)); - break; - case "resource": - image = new TextureArea(new ResourceLocation(source), 0.0, 0.0, 1.0, 1.0); - break; - } - return this; - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - if (image != null) { - super.drawInBackground(mouseX, mouseY, partialTicks, context); - GlStateManager.color(1, 1, 1, 1); - Position position = getPosition(); - image.draw(position.x, position.y, getSize().width, getSize().height); - } - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guide/widget/SlotListWidget.java b/src/main/java/gregtech/common/terminal/app/guide/widget/SlotListWidget.java deleted file mode 100644 index 4fcb005954c..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guide/widget/SlotListWidget.java +++ /dev/null @@ -1,118 +0,0 @@ -package gregtech.common.terminal.app.guide.widget; - -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.widgets.SlotWidget; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.util.Size; -import gregtech.common.terminal.app.guideeditor.widget.configurator.ItemStackConfigurator; - -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.items.ItemStackHandler; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; - -import java.util.Collections; -import java.util.List; -import java.util.function.Consumer; - -public class SlotListWidget extends GuideWidgetGroup { - - public final static String NAME = "slots"; - - // config - public List item_list; - - @Override - public Widget initFixed() { - this.clearAllWidgets(); - ItemStackHandler itemStackHandler = new ItemStackHandler(item_list.size()); - IGuiTexture background = new ColorRectTexture(0x4f000000); - int size = item_list.size(); - int maxXSize = getSize().width / 18; - int xPos; - if (maxXSize < 1) { - maxXSize = 1; - xPos = 0; - } else { - xPos = (getSize().width - (Math.min(size, maxXSize)) * 18) / 2; - } - int maxYSize = size / maxXSize + ((size % maxXSize) == 0 ? 0 : 1); - for (int y = 0; y <= size / maxXSize; y++) { - for (int x = 0; x < maxXSize; x++) { - int i = x + y * maxXSize; - if (i < size) { - itemStackHandler.setStackInSlot(i, item_list.get(i).getInstance()); - SlotWidget widget = new SlotWidget(itemStackHandler, i, xPos + x * 18, y * 18, false, false); - widget.setBackgroundTexture(background); - this.addWidget(widget); - } - } - } - setSize(new Size(getSize().width / 18 > 0 ? getSize().width : 18, maxYSize * 18)); - return this; - } - - @Override - public String getRegistryName() { - return NAME; - } - - @Override - public JsonObject getTemplate(boolean isFixed) { - JsonObject template = super.getTemplate(isFixed); - template.add("item_list", - new Gson().toJsonTree(Collections.singletonList(new ItemStackInfo("minecraft:ender_pearl", 0, 1)))); - return template; - } - - @Override - public void loadConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, boolean isFixed, - Consumer needUpdate) { - super.loadConfigurator(group, config, isFixed, needUpdate); - group.addWidget(new ItemStackConfigurator(group, config, "item_list").setOnUpdated(needUpdate)); - } - - public static class ItemStackInfo { - - // config - public String id; - public int damage; - public int count = 1; - - private transient ItemStack itemStack; - - public ItemStackInfo() {} - - public void update(ItemStack itemStack) { - ResourceLocation resourceLocation = itemStack.getItem().getRegistryName(); - id = resourceLocation == null ? "minecraft:air" : resourceLocation.toString(); - damage = itemStack.getItemDamage(); - count = itemStack.getCount(); - } - - public ItemStackInfo(String id, int damage, int count) { - this.id = id; - this.damage = damage; - this.count = count; - } - - public ItemStack getInstance() { - if (itemStack == null && id != null) { - Item item = Item.getByNameOrId(id); - if (item == null) { - itemStack = ItemStack.EMPTY; - return itemStack; - } - itemStack = item.getDefaultInstance(); - itemStack.setCount(count); - itemStack.setItemDamage(damage); - } - return itemStack == null ? ItemStack.EMPTY : itemStack; - } - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guide/widget/TankListWidget.java b/src/main/java/gregtech/common/terminal/app/guide/widget/TankListWidget.java deleted file mode 100644 index 8de6641bd72..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guide/widget/TankListWidget.java +++ /dev/null @@ -1,121 +0,0 @@ -package gregtech.common.terminal.app.guide.widget; - -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.widgets.TankWidget; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.util.Size; -import gregtech.common.terminal.app.guideeditor.widget.configurator.FluidStackConfigurator; - -import net.minecraftforge.fluids.Fluid; -import net.minecraftforge.fluids.FluidRegistry; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTank; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; - -import java.awt.*; -import java.util.Collections; -import java.util.List; -import java.util.function.Consumer; - -public class TankListWidget extends GuideWidgetGroup { - - public final static String NAME = "tanks"; - - // config - public List fluid_list; - - protected transient Rectangle scissor; - - @Override - public Widget initFixed() { - this.clearAllWidgets(); - IGuiTexture background = new ColorRectTexture(0x4f000000); - int size = fluid_list.size(); - int maxXSize = getSize().width / 18; - int xPos; - if (maxXSize < 1) { - maxXSize = 1; - xPos = 0; - } else { - xPos = (getSize().width - (Math.min(size, maxXSize)) * 18) / 2; - } - int maxYSize = size / maxXSize + ((size % maxXSize) == 0 ? 0 : 1); - for (int y = 0; y <= size / maxXSize; y++) { - for (int x = 0; x < maxXSize; x++) { - int i = x + y * maxXSize; - if (i < size) { - FluidStack fluidStack = fluid_list.get(i).getInstance(); - TankWidget widget = new TankWidget(new FluidTank(fluidStack, fluid_list.get(i).amount), - xPos + x * 18, y * 18, 18, 18); - widget.setBackgroundTexture(background).setAlwaysShowFull(true).setClient(); - this.addWidget(widget); - } - } - } - setSize(new Size(getSize().width / 18 > 0 ? getSize().width : 18, maxYSize * 18)); - return this; - } - - @Override - public String getRegistryName() { - return NAME; - } - - @Override - public JsonObject getTemplate(boolean isFixed) { - JsonObject template = super.getTemplate(isFixed); - template.add("fluid_list", - new Gson().toJsonTree(Collections.singletonList(new FluidStackInfo("distilled_water", 1)))); - return template; - } - - @Override - public void loadConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, boolean isFixed, - Consumer needUpdate) { - super.loadConfigurator(group, config, isFixed, needUpdate); - group.addWidget(new FluidStackConfigurator(group, config, "fluid_list").setOnUpdated(needUpdate)); - } - - public static class FluidStackInfo { - - // config - public String id; - public int amount = 1; - - private transient FluidStack fluidStack; - - public FluidStackInfo() {} - - public void update(FluidStack itemStack) { - if (itemStack != null) { - id = FluidRegistry.getFluidName(itemStack.getFluid()); - amount = itemStack.amount; - } else { - id = null; - fluidStack = null; - amount = 0; - } - } - - public FluidStackInfo(String id, int amount) { - this.id = id; - this.amount = amount; - } - - public FluidStack getInstance() { - if (fluidStack == null && id != null) { - Fluid fluid = FluidRegistry.getFluid(id); - if (fluid != null) { - fluidStack = new FluidStack(fluid, amount); - } else { - id = null; - } - } - return fluidStack; - } - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guide/widget/TextBoxWidget.java b/src/main/java/gregtech/common/terminal/app/guide/widget/TextBoxWidget.java deleted file mode 100644 index 465a4679b60..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guide/widget/TextBoxWidget.java +++ /dev/null @@ -1,125 +0,0 @@ -package gregtech.common.terminal.app.guide.widget; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.util.Position; -import gregtech.api.util.Size; -import gregtech.common.terminal.app.guideeditor.widget.configurator.BooleanConfigurator; -import gregtech.common.terminal.app.guideeditor.widget.configurator.ColorConfigurator; -import gregtech.common.terminal.app.guideeditor.widget.configurator.NumberConfigurator; -import gregtech.common.terminal.app.guideeditor.widget.configurator.TextListConfigurator; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.resources.I18n; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.function.Consumer; - -public class TextBoxWidget extends GuideWidget { - - public final static String NAME = "textbox"; - - // config - public List content; - public int space = 1; - public int fontSize = 9; - public int fontColor = 0xff000000; - public boolean isShadow = false; - public boolean isCenter = false; - - private transient List textLines; - - public TextBoxWidget(int x, int y, int width, List content, int space, int fontSize, int fontColor, - int fill, int stroke, boolean isCenter, boolean isShadow) { - super(x, y, width, 0); - this.content = content; - this.space = space; - this.fontSize = fontSize; - this.fontColor = fontColor; - this.fill = fill; - this.stroke = stroke; - this.isCenter = isCenter; - this.isShadow = isShadow; - this.initFixed(); - } - - public TextBoxWidget() {} - - @Override - public String getRegistryName() { - return NAME; - } - - @Override - public JsonObject getTemplate(boolean isFixed) { - JsonObject template = super.getTemplate(isFixed); - template.addProperty("space", (String) null); - template.addProperty("fontSize", (String) null); - template.addProperty("fontColor", (String) null); - template.addProperty("isCenter", (String) null); - template.addProperty("isShadow", (String) null); - template.add("content", new Gson().toJsonTree(Arrays.asList("this is a", "textbox!"))); - return template; - } - - @Override - public void loadConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, boolean isFixed, - Consumer needUpdate) { - group.addWidget(new TextListConfigurator(group, 200, config, "content").setOnUpdated(needUpdate)); - group.addWidget(new BooleanConfigurator(group, config, "isCenter", false).setOnUpdated(needUpdate)); - group.addWidget(new NumberConfigurator(group, config, "fontSize", 9).setOnUpdated(needUpdate)); - group.addWidget(new BooleanConfigurator(group, config, "isShadow", false).setOnUpdated(needUpdate)); - group.addWidget(new ColorConfigurator(group, config, "fontColor", 0xff000000).setOnUpdated(needUpdate)); - group.addWidget(new NumberConfigurator(group, config, "space", 1).setOnUpdated(needUpdate)); - super.loadConfigurator(group, config, isFixed, needUpdate); - } - - @Override - protected Widget initFixed() { - this.textLines = new ArrayList<>(); - FontRenderer font = Minecraft.getMinecraft().fontRenderer; - this.space = Math.max(space, 0); - this.fontSize = Math.max(fontSize, 1); - int wrapWidth = getSize().width * font.FONT_HEIGHT / fontSize; - if (content != null) { - for (String textLine : content) { - this.textLines.addAll(font.listFormattedStringToWidth(I18n.format(textLine), wrapWidth)); - } - } - this.setSize(new Size(this.getSize().width, this.textLines.size() * (fontSize + space))); - return this; - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - super.drawInBackground(mouseX, mouseY, partialTicks, context); - if (!textLines.isEmpty()) { - Position position = getPosition(); - Size size = getSize(); - FontRenderer font = Minecraft.getMinecraft().fontRenderer; - float scale = fontSize * 1.0f / font.FONT_HEIGHT; - GlStateManager.pushMatrix(); - GlStateManager.scale(scale, scale, 1); - GlStateManager.translate(position.x / scale, position.y / scale, 0); - float x = 0; - float y = 0; - float ySpace = font.FONT_HEIGHT + space / scale; - for (String textLine : textLines) { - if (isCenter) { - x = (size.width / scale - font.getStringWidth(textLine)) / 2; - } - font.drawString(textLine, x, y, fontColor, isShadow); - y += ySpace; - } - GlStateManager.popMatrix(); - } - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guideeditor/GuideEditorApp.java b/src/main/java/gregtech/common/terminal/app/guideeditor/GuideEditorApp.java deleted file mode 100644 index a8d19adf9e7..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guideeditor/GuideEditorApp.java +++ /dev/null @@ -1,61 +0,0 @@ -package gregtech.common.terminal.app.guideeditor; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.os.menu.IMenuComponent; -import gregtech.common.terminal.app.guideeditor.widget.GuideConfigEditor; -import gregtech.common.terminal.app.guideeditor.widget.GuidePageEditorWidget; -import gregtech.common.terminal.component.ClickComponent; - -import java.util.Arrays; -import java.util.List; - -public class GuideEditorApp extends AbstractApplication { - - private GuideConfigEditor configEditor; - - public GuideEditorApp() { - super("guide_editor"); - } - - @Override - public AbstractApplication initApp() { - if (isClient) { - this.configEditor = new GuideConfigEditor(0, 0, 133, 232, this); - GuidePageEditorWidget pageEditor = new GuidePageEditorWidget(133, 0, 200, 232, 5); - this.configEditor.setGuidePageEditorWidget(pageEditor); - pageEditor.setGuideConfigEditor(this.configEditor); - this.addWidget(pageEditor); - this.addWidget(this.configEditor); - } - return this; - } - - @Override - public List getMenuComponents() { - ClickComponent newPage = new ClickComponent().setIcon(GuiTextures.ICON_NEW_PAGE) - .setHoverText("terminal.component.new_page").setClickConsumer(cd -> { - if (configEditor != null) { - configEditor.newPage(); - } - }); - ClickComponent importPage = new ClickComponent().setIcon(GuiTextures.ICON_LOAD) - .setHoverText("terminal.component.load_file").setClickConsumer(cd -> { - if (configEditor != null) { - configEditor.loadJson(); - } - }); - ClickComponent exportPage = new ClickComponent().setIcon(GuiTextures.ICON_SAVE) - .setHoverText("terminal.component.save_file").setClickConsumer(cd -> { - if (configEditor != null) { - configEditor.saveJson(); - } - }); - return Arrays.asList(newPage, importPage, exportPage); - } - - @Override - public boolean isClientSideApp() { - return true; - } -} 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 deleted file mode 100644 index 83f6ad93091..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/GuideConfigEditor.java +++ /dev/null @@ -1,330 +0,0 @@ -package gregtech.common.terminal.app.guideeditor.widget; - -import gregtech.api.GregTechAPI; -import gregtech.api.block.machines.MachineItemBlock; -import gregtech.api.gui.GuiTextures; -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.tab.IGuiTextureTabInfo; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.terminal.TerminalRegistry; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.gui.CustomTabListRenderer; -import gregtech.api.terminal.gui.widgets.CircleButtonWidget; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.terminal.gui.widgets.SelectorWidget; -import gregtech.api.terminal.gui.widgets.TextEditorWidget; -import gregtech.api.terminal.os.TerminalDialogWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.util.FileUtility; -import gregtech.api.util.Position; -import gregtech.api.util.Size; -import gregtech.common.inventory.handlers.SingleItemStackHandler; -import gregtech.common.terminal.app.guide.GuideApp; -import gregtech.common.terminal.app.guide.ItemGuideApp; -import gregtech.common.terminal.app.guide.MultiBlockGuideApp; -import gregtech.common.terminal.app.guide.SimpleMachineGuideApp; -import gregtech.common.terminal.app.guide.widget.GuidePageWidget; -import gregtech.common.terminal.app.guide.widget.IGuideWidget; -import gregtech.common.terminal.app.guideeditor.GuideEditorApp; - -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraftforge.items.IItemHandlerModifiable; - -import com.google.gson.JsonObject; - -import java.awt.*; -import java.io.File; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - -public class GuideConfigEditor extends TabGroup { - - public String json; - private IGuideWidget selected; - private GuidePageEditorWidget pageEditor; - private TextEditorWidget titleEditor; - private final DraggableScrollableWidgetGroup widgetSelector; - private final DraggableScrollableWidgetGroup widgetConfigurator; - private final CircleButtonWidget[] addButton; - private final GuideEditorApp app; - private final IItemHandlerModifiable handler; - private final List candidates; - private String type; - - public GuideConfigEditor(int x, int y, int width, int height, GuideEditorApp app) { - super(x, y + 10, new CustomTabListRenderer(TerminalTheme.COLOR_F_2, TerminalTheme.COLOR_B_3, 30, 10)); - setSize(new Size(width, height)); - candidates = TerminalRegistry.getAllApps().stream().filter(GuideApp.class::isInstance) - .map(AbstractApplication::getUnlocalizedName).collect(Collectors.toList()); - type = candidates.get(candidates.size() - 1); - handler = new SingleItemStackHandler(1); - addButton = new CircleButtonWidget[2]; - widgetSelector = createWidgetSelector(); - widgetConfigurator = createConfigurator(); - this.addTab(new IGuiTextureTabInfo(new TextTexture("P", -1), "terminal.guide_editor.page_config"), - createPageConfig()); - this.addTab(new IGuiTextureTabInfo(new TextTexture("W", -1), "terminal.guide_editor.widgets_box"), - widgetSelector); - this.addTab(new IGuiTextureTabInfo(new TextTexture("C", -1), "terminal.guide_editor.widget_config"), - widgetConfigurator); - this.setOnTabChanged((oldIndex, newIndex) -> { - if (newIndex == 1) { - addButton[0].setVisible(true); - addButton[1].setVisible(true); - } else { - addButton[0].setVisible(false); - addButton[1].setVisible(false); - } - }); - addButton[0] = new CircleButtonWidget(115, 15, 8, 1, 8) - .setColors(new Color(255, 255, 255, 0).getRGB(), - TerminalTheme.COLOR_7.getColor(), - TerminalTheme.COLOR_4.getColor()) - .setIcon(GuiTextures.ICON_ADD) - .setHoverText("terminal.guide_editor.add_stream") - .setClickListener(this::addStream); - addButton[1] = new CircleButtonWidget(115, 35, 8, 1, 8) - .setColors(new Color(255, 255, 255, 0).getRGB(), - TerminalTheme.COLOR_7.getColor(), - TerminalTheme.COLOR_5.getColor()) - .setIcon(GuiTextures.ICON_ADD) - .setHoverText("terminal.guide_editor.add_fixed") - .setClickListener(this::addFixed); - addButton[0].setVisible(false); - addButton[1].setVisible(false); - this.app = app; - this.addWidget(addButton[0]); - this.addWidget(addButton[1]); - } - - public void setGuidePageEditorWidget(GuidePageEditorWidget pageEditor) { - this.pageEditor = pageEditor; - } - - public GuidePageEditorWidget getPageEditor() { - return pageEditor; - } - - private DraggableScrollableWidgetGroup createPageConfig() { - DraggableScrollableWidgetGroup group = new DraggableScrollableWidgetGroup(0, 0, getSize().width, - getSize().height - 10) - .setBackground(TerminalTheme.COLOR_B_3) - .setYScrollBarWidth(4) - .setYBarStyle(null, TerminalTheme.COLOR_F_1); - group.addWidget(new LabelWidget(5, 5, "section", -1).setShadow(true)); - group.addWidget(new TextFieldWidget(5, 15, 116, 20, new ColorRectTexture(0x9f000000), null, null) - .setTextResponder(s -> { - if (pageEditor != null) { - pageEditor.setSection(s); - } - }, true) - .setTextSupplier(() -> getPageEditor().getSection(), true) - .setMaxStringLength(Integer.MAX_VALUE) - .setValidator(s -> true)); - group.addWidget(new ImageWidget(5, 40, 116, 1, new ColorRectTexture(-1))); - group.addWidget(new LabelWidget(5, 45, "type", -1).setShadow(true)); - - group.addWidget(new SelectorWidget(30, 55, 91, 20, candidates, -1, - () -> type, true).setIsUp(true) - .setOnChanged(type -> this.type = type) - .setColors(TerminalTheme.COLOR_B_2.getColor(), TerminalTheme.COLOR_F_1.getColor(), - TerminalTheme.COLOR_B_2.getColor()) - .setBackground(TerminalTheme.COLOR_6)); - group.addWidget(new PhantomSlotWidget(handler, 0, 6, 56).setBackgroundTexture(TerminalTheme.COLOR_B_2)); - - group.addWidget(new ImageWidget(5, 80, 116, 1, new ColorRectTexture(-1))); - - group.addWidget(new LabelWidget(5, 85, "title", -1).setShadow(true)); - titleEditor = new TextEditorWidget(5, 95, 116, 70, s -> { - if (pageEditor != null) { - pageEditor.setTitle(s); - } - }, true).setContent("Template").setBackground(new ColorRectTexture(0xA3FFFFFF)); - group.addWidget(titleEditor); - return group; - } - - public void updateTitle(String title) { - titleEditor.setContent(title); - } - - private DraggableScrollableWidgetGroup createWidgetSelector() { - DraggableScrollableWidgetGroup group = new DraggableScrollableWidgetGroup(0, 0, getSize().width, - getSize().height - 10) - .setBackground(TerminalTheme.COLOR_B_3) - .setYScrollBarWidth(4) - .setYBarStyle(null, TerminalTheme.COLOR_F_1); - int y = 10; // 133 - for (Map.Entry entry : GuidePageWidget.REGISTER_WIDGETS.entrySet()) { - IGuideWidget widgetTemplate = entry.getValue(); - JsonObject template = widgetTemplate.getTemplate(false); - Widget guideWidget = widgetTemplate.updateOrCreateStreamWidget(5, y + 10, getSize().width - 14, template); - group.addWidget(new LabelWidget(getSize().width / 2 - 1, y - 3, entry.getKey(), -1).setXCentered(true) - .setShadow(true)); - y += guideWidget.getSize().height + 25; - group.addWidget(guideWidget); - } - group.addWidget(new WidgetGroup(new Position(5, group.getWidgetBottomHeight() + 5), Size.ZERO)); - return group; - } - - private DraggableScrollableWidgetGroup createConfigurator() { - return new DraggableScrollableWidgetGroup(0, 0, getSize().width, getSize().height - 10) - .setBackground(TerminalTheme.COLOR_B_3) - .setYScrollBarWidth(4) - .setYBarStyle(null, TerminalTheme.COLOR_F_1); - } - - public void loadConfigurator(IGuideWidget widget) { - widgetConfigurator.clearAllWidgets(); - if (widget != null) { - widget.loadConfigurator(widgetConfigurator, widget.getConfig(), widget.isFixed(), type -> { - widget.updateValue(type); - if (pageEditor != null) { - pageEditor.computeMax(); - } - }); - widgetConfigurator.addWidget( - new WidgetGroup(new Position(5, widgetConfigurator.getWidgetBottomHeight() + 5), Size.ZERO)); - } - } - - public void newPage() { - TerminalDialogWidget - .showConfirmDialog(app.getOs(), "terminal.component.new_page", "terminal.component.confirm", res -> { - if (res) { - pageEditor.loadJsonConfig( - "{\"section\":\"default\",\"title\":\"Template\",\"stream\":[],\"fixed\":[]}"); - getPageEditor().setSection("default"); - updateTitle("Template"); - type = candidates.get(candidates.size() - 1); - handler.setStackInSlot(0, ItemStack.EMPTY); - } - }).setClientSide().open(); - } - - public void loadJson() { - if (pageEditor != null) { - File file = new File(TerminalRegistry.TERMINAL_PATH, "guide"); - TerminalDialogWidget.showFileDialog(app.getOs(), "terminal.component.load_file", file, true, result -> { - if (result != null && result.isFile()) { - try { - JsonObject config = Objects.requireNonNull(FileUtility.loadJson(result)).getAsJsonObject(); - pageEditor.loadJsonConfig(config); - getPageEditor().setSection(config.get("section").getAsString()); - updateTitle(config.get("title").getAsString()); - for (AbstractApplication app : TerminalRegistry.getAllApps()) { - if (app instanceof GuideApp) { - Object object = ((GuideApp) app).ofJson(config); - if (object != null) { - type = app.getUnlocalizedName(); - if (object instanceof ItemGuideApp.GuideItem) { - handler.setStackInSlot(0, ((ItemGuideApp.GuideItem) object).stack.copy()); - } else if (object instanceof MetaTileEntity) { - handler.setStackInSlot(0, ((MetaTileEntity) object).getStackForm()); - } else if (object instanceof ItemStack) { - handler.setStackInSlot(0, ((ItemStack) object).copy()); - } else { - handler.setStackInSlot(0, ItemStack.EMPTY); - } - break; - } - } - } - } catch (Exception e) { - TerminalDialogWidget.showInfoDialog(app.getOs(), "terminal.component.error", - "terminal.component.load_file.error").setClientSide().open(); - } - } - }).setClientSide().open(); - } - } - - public void saveJson() { - if (pageEditor != null) { - File file = new File(TerminalRegistry.TERMINAL_PATH, "guide"); - TerminalDialogWidget.showFileDialog(app.getOs(), "terminal.component.save_file", file, false, result -> { - if (result != null) { - if (!FileUtility.saveJson(result, saveType(pageEditor.getJsonConfig()))) { - TerminalDialogWidget.showInfoDialog(app.getOs(), "terminal.component.error", - "terminal.component.save_file.error").setClientSide().open(); - } - } - }).setClientSide().open(); - } - } - - private JsonObject saveType(JsonObject jsonObject) { - ItemStack stack = handler.getStackInSlot(0); - for (AbstractApplication app : TerminalRegistry.getAllApps()) { - if (app instanceof GuideApp) { - if (type.equals(app.getUnlocalizedName())) { - if (app instanceof ItemGuideApp) { - if (stack.isEmpty()) { - TerminalDialogWidget.showInfoDialog(app.getOs(), "terminal.component.warning", - "terminal.guide_editor.error_type").setClientSide().open(); - } else { - jsonObject.addProperty("item", Item.REGISTRY.getNameForObject(stack.getItem()).toString() + - ":" + stack.getMetadata()); - } - } else if ((app instanceof MultiBlockGuideApp || app instanceof SimpleMachineGuideApp) && - stack.getItem() instanceof MachineItemBlock) { - MetaTileEntity mte = GregTechAPI.MTE_REGISTRY.getObjectById(stack.getItemDamage()); - if (mte != null) { - jsonObject.addProperty("metatileentity", - GregTechAPI.MTE_REGISTRY.getNameForObject(mte).getPath()); - } else { - TerminalDialogWidget.showInfoDialog(app.getOs(), "terminal.component.warning", - "terminal.guide_editor.error_type").setClientSide().open(); - } - } - return jsonObject; - } - } - } - return jsonObject; - } - - private void addFixed(ClickData data) { - if (pageEditor != null && selected != null) { - selected.setStroke(0); - pageEditor.addGuideWidget(selected, true); - selected.setStroke(0xFF7CA1FF); - } - } - - private void addStream(ClickData data) { - if (pageEditor != null && selected != null) { - selected.setStroke(0); - pageEditor.addGuideWidget(selected, false); - selected.setStroke(0xFF7CA1FF); - } - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - boolean flag = super.mouseClicked(mouseX, mouseY, button); - if (selectedTabIndex == 1 && widgetSelector != null) { - for (Widget widget : widgetSelector.widgets) { - if (widget.isMouseOverElement(mouseX, mouseY)) { - if (widget instanceof IGuideWidget) { - if (selected != null) { - selected.setStroke(0); - } - ((IGuideWidget) widget).setStroke(0xFF7CA1FF); - selected = (IGuideWidget) widget; - } - playButtonClickSound(); - return true; - } - } - } - return flag; - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/GuidePageEditorWidget.java b/src/main/java/gregtech/common/terminal/app/guideeditor/widget/GuidePageEditorWidget.java deleted file mode 100644 index 9f15e37b052..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/GuidePageEditorWidget.java +++ /dev/null @@ -1,408 +0,0 @@ -package gregtech.common.terminal.app.guideeditor.widget; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.terminal.gui.widgets.CircleButtonWidget; -import gregtech.api.terminal.gui.widgets.CustomPositionSizeWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.util.Position; -import gregtech.api.util.Size; -import gregtech.api.util.interpolate.Eases; -import gregtech.api.util.interpolate.Interpolator; -import gregtech.common.terminal.app.guide.widget.GuidePageWidget; -import gregtech.common.terminal.app.guide.widget.IGuideWidget; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; - -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; - -public class GuidePageEditorWidget extends GuidePageWidget { - - private Widget selected; - private final WidgetGroup toolButtons; - private final CustomPositionSizeWidget customPositionSizeWidget; - private GuideConfigEditor configEditor; - private String section = "default"; - - public GuidePageEditorWidget(int xPosition, int yPosition, int width, int height, int margin) { - super(xPosition, yPosition, width, height, margin); - this.setDraggable(false); - setTitle("Template"); - customPositionSizeWidget = new CustomPositionSizeWidget(0xff0000ff, 0xffff0000, 2) - .setOnUpdated(this::onPosSizeChanged); - toolButtons = new WidgetGroup(Position.ORIGIN, Size.ZERO); - toolButtons.setVisible(false); - toolButtons.addWidget(new CircleButtonWidget(-20, -4, 8, 1, 12) - .setColors(0, - TerminalTheme.COLOR_B_2.getColor(), - TerminalTheme.COLOR_1.getColor()) - .setIcon(GuiTextures.ICON_UP) - .setHoverText("terminal.guide_editor.up") - .setClickListener(this::moveUp)); - toolButtons.addWidget(new CircleButtonWidget(0, -4, 8, 1, 12) - .setColors(0, - TerminalTheme.COLOR_B_2.getColor(), - TerminalTheme.COLOR_2.getColor()) - .setIcon(GuiTextures.ICON_DOWN) - .setHoverText("terminal.guide_editor.down") - .setClickListener(this::moveDown)); - toolButtons.addWidget(new CircleButtonWidget(20, -4, 8, 1, 12) - .setColors(0, - TerminalTheme.COLOR_B_2.getColor(), - TerminalTheme.COLOR_3.getColor()) - .setIcon(GuiTextures.ICON_REMOVE) - .setHoverText("terminal.guide_editor.remove") - .setClickListener(this::delete)); - addWidget(customPositionSizeWidget); - addWidget(toolButtons); - } - - public void setSection(String section) { - this.section = section; - } - - public String getSection() { - return section; - } - - private void onPosSizeChanged(Position pos, Size size) { - Widget widget = customPositionSizeWidget.getControlled(); - if (widget instanceof IGuideWidget && ((IGuideWidget) widget).isFixed()) { - JsonObject config = ((IGuideWidget) widget).getConfig(); - if (config.has("x")) { - config.addProperty("x", pos.x + scrollXOffset); - ((IGuideWidget) widget).updateValue("x"); - } - if (config.has("y")) { - config.addProperty("y", pos.y + scrollYOffset); - ((IGuideWidget) widget).updateValue("y"); - } - if (config.has("width")) { - config.addProperty("width", size.width); - ((IGuideWidget) widget).updateValue("width"); - } - if (config.has("height")) { - config.addProperty("height", size.height); - ((IGuideWidget) widget).updateValue("height"); - } - ((IGuideWidget) widget).onFixedPositionSizeChanged(pos, size); - } - toolButtons.setSelfPosition(new Position(pos.x + size.width / 2, pos.y)); - } - - public void setGuideConfigEditor(GuideConfigEditor configEditor) { - this.configEditor = configEditor; - } - - private void setToolButton(Widget widget) { - customPositionSizeWidget.setControlled(widget); - customPositionSizeWidget.setVisible(true); - customPositionSizeWidget.setActive(!(widget instanceof IGuideWidget) || ((IGuideWidget) widget).isFixed()); - toolButtons.setVisible(true); - toolButtons.setSelfPosition( - new Position(widget.getSelfPosition().x + widget.getSize().width / 2, widget.getSelfPosition().y)); - } - - private void delete(ClickData clickData) { - removeWidget(selected); - selected = null; - configEditor.loadConfigurator(null); - toolButtons.setSelfPosition(new Position(-scrollYOffset, -scrollYOffset)); - customPositionSizeWidget.setControlled(null); - toolButtons.setVisible(false); - } - - private void moveUp(ClickData clickData) { - moveUp(selected); - } - - private void moveDown(ClickData clickData) { - moveDown(selected); - } - - public JsonObject getJsonConfig() { - JsonObject json = new JsonObject(); - json.addProperty("section", section); - json.addProperty("title", title.content.get(0)); - JsonArray array = new JsonArray(); - json.add("stream", array); - stream.forEach(widget -> { - if (widget instanceof IGuideWidget) { - array.add(((IGuideWidget) widget).getConfig()); - } - }); - - JsonArray array2 = new JsonArray(); - json.add("fixed", array2); - fixed.forEach(widget -> { - if (widget instanceof IGuideWidget) { - array2.add(((IGuideWidget) widget).getConfig()); - } - }); - - return json; - } - - public JsonObject addGuideWidget(IGuideWidget widget, boolean isFixed) { - int pageWidth = getPageWidth(); - int margin = getMargin(); - JsonObject widgetConfig = widget.getTemplate(isFixed); - Widget guideWidget; - if (isFixed) { - int width = widgetConfig.get("width").getAsInt(); - int height = widgetConfig.get("height").getAsInt(); - - guideWidget = widget.updateOrCreateFixedWidget( - (pageWidth - width) / 2 + 5, - this.scrollYOffset + (this.getSize().height - height) / 2, - width, - height, - widgetConfig); - fixed.add(guideWidget); - this.addWidget(guideWidget); - } else { - int index = stream.indexOf(selected); - if (index >= 0) { - guideWidget = widget.updateOrCreateStreamWidget(margin, - selected.getSize().height + selected.getSelfPosition().y + scrollYOffset + 5, - pageWidth - 2 * margin, widgetConfig); - for (int i = index + 1; i < stream.size(); i++) { - stream.get(i).addSelfPosition(0, guideWidget.getSize().height + 5); - } - stream.add(index + 1, guideWidget); - } else { - guideWidget = widget.updateOrCreateStreamWidget(margin, getStreamBottom() + 5, pageWidth - 2 * margin, - widgetConfig); - stream.add(guideWidget); - } - this.addWidget(guideWidget); - computeMax(); - } - return widgetConfig; - } - - public void moveUp(Widget widget) { - int index = stream.indexOf(widget); - if (index > 0) { - Widget target = stream.get(index - 1); - if (interpolator == null) { - int offsetD = 5 + widget.getSize().height; - int offsetU = widget.getPosition().y - target.getPosition().y; - int y1 = widget.getSelfPosition().y; - int y2 = target.getSelfPosition().y; - interpolator = new Interpolator(0, 1, 10, Eases.LINEAR, value -> { - widget.setSelfPosition( - new Position(widget.getSelfPosition().x, (int) (y1 - value.floatValue() * offsetU))); - target.setSelfPosition( - new Position(target.getSelfPosition().x, (int) (y2 + value.floatValue() * offsetD))); - if (widget == selected) { - setToolButton(selected); - } - widget.setVisible(widget.getSelfPosition().y < scrollYOffset + getSize().height && - widget.getSelfPosition().y + widget.getSize().height > 0); - target.setVisible(target.getSelfPosition().y < scrollYOffset + getSize().height && - target.getSelfPosition().y + target.getSize().height > 0); - }, value -> { - interpolator = null; - stream.remove(widget); - stream.add(index - 1, widget); - }).start(); - } - } else { - int index2 = fixed.indexOf(widget); - if (index2 >= 0 && index2 < fixed.size() - 1) { - Widget target = fixed.get(index2 + 1); - fixed.remove(widget); - fixed.add(index2 + 1, widget); - } - } - } - - public void moveDown(Widget widget) { - int index = stream.indexOf(widget); - if (index >= 0 && index < stream.size() - 1) { - Widget target = stream.get(index + 1); - if (interpolator == null) { - int offsetD = 5 + target.getSize().height; - int offsetU = target.getPosition().y - widget.getPosition().y; - int y1 = widget.getSelfPosition().y; - int y2 = target.getSelfPosition().y; - interpolator = new Interpolator(0, 1, 10, Eases.LINEAR, value -> { - widget.setSelfPosition( - new Position(widget.getSelfPosition().x, (int) (y1 + value.floatValue() * offsetD))); - target.setSelfPosition( - new Position(target.getSelfPosition().x, (int) (y2 - value.floatValue() * offsetU))); - if (widget == selected) { - setToolButton(selected); - } - widget.setVisible(widget.getSelfPosition().y < getSize().height - xBarHeight && - widget.getSelfPosition().y + widget.getSize().height > 0); - target.setVisible(target.getSelfPosition().y < getSize().height - xBarHeight && - target.getSelfPosition().y + target.getSize().height > 0); - }, value -> { - interpolator = null; - stream.remove(widget); - stream.add(index + 1, widget); - }).start(); - } - } else { - int index2 = fixed.indexOf(widget); - if (index2 > 0) { - Widget target = fixed.get(index2 - 1); - fixed.remove(widget); - fixed.add(index2 - 1, widget); - } - } - } - - @Override - protected void setScrollYOffset(int scrollYOffset) { - if (scrollYOffset == this.scrollYOffset) return; - int offset = scrollYOffset - this.scrollYOffset; - this.scrollYOffset = scrollYOffset; - for (Widget widget : widgets) { - Position newPos = widget.addSelfPosition(0, -offset); - if (widget != toolButtons) { - widget.setVisible(newPos.y < getSize().height - xBarHeight && newPos.y + widget.getSize().height > 0); - } - } - } - - @Override - public void removeWidget(Widget widget) { - int index = stream.indexOf(widget); - if (index >= 0) { - int offset = widget.getSize().height + 5; - for (int i = stream.size() - 1; i > index; i--) { - Widget bottom = stream.get(i); - Position newPos = bottom.addSelfPosition(0, -offset); - bottom.setVisible(newPos.y < getSize().height - xBarHeight && newPos.y + widget.getSize().height > 0); - } - stream.remove(widget); - } else { - fixed.remove(widget); - } - super.removeWidget(widget); - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (super.mouseClicked(mouseX, mouseY, button)) { - return true; - } - boolean flag = false; - for (int i = fixed.size() - 1; i >= 0; i--) { - Widget widget = fixed.get(i); - if (widget.isMouseOverElement(mouseX, mouseY)) { - if (widget instanceof IGuideWidget && widget != selected) { - configEditor.loadConfigurator((IGuideWidget) widget); - selected = widget; - setToolButton(selected); - } - playButtonClickSound(); - flag = true; - break; - } - } - if (!flag) { - for (Widget widget : stream) { - if (widget.isMouseOverElement(mouseX, mouseY)) { - if (widget instanceof IGuideWidget && widget != selected) { - configEditor.loadConfigurator((IGuideWidget) widget); - selected = widget; - setToolButton(selected); - } - playButtonClickSound(); - flag = true; - break; - } - } - } - return flag; - } - - @Override - protected boolean hookDrawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - int x = getPosition().x; - int width = getSize().width; - if (title.isVisible()) { - title.drawInBackground(mouseX, mouseY, partialTicks, context); - } - for (Widget widget : stream) { - if (widget.isVisible()) { - widget.drawInBackground(mouseX, mouseY, partialTicks, context); - } - } - - boolean flag = false; - for (Widget widget : fixed) { - if (widget.isVisible()) { - widget.drawInBackground(mouseX, mouseY, partialTicks, context); - if (widget.isMouseOverElement(mouseX, mouseY)) { - if (widget != selected) { - drawSelectedBorder(x, width, widget); - } - flag = true; - } - } - } - if (!flag) { - for (Widget widget : stream) { - if (widget.isVisible() && widget != selected && widget.isMouseOverElement(mouseX, mouseY)) { - drawSelectedBorder(x, width, widget); - } - } - } - - if (selected != null) { - FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; - int index = fixed.indexOf(selected); - String layer = "L: " + (index >= 0 ? index : stream.indexOf(selected)); - fontRenderer.drawString(layer, - selected.getPosition().x + (selected.getSize().width - fontRenderer.getStringWidth(layer)) / 2F, - selected.getPosition().y - 20, - 0xffff0000, true); - } - if (toolButtons.isVisible()) { - customPositionSizeWidget.drawInBackground(mouseX, mouseY, partialTicks, context); - toolButtons.drawInBackground(mouseX, mouseY, partialTicks, context); - } - return true; - } - - private void drawSelectedBorder(int x, int width, Widget widget) { - Position pos = widget.getPosition(); - Size s = widget.getSize(); - if (stream.contains(widget)) { - drawSolidRect(x, pos.y, width - yBarWidth, s.height, 0x6f000000); - - } else { - drawSolidRect(pos.x, pos.y, s.width, s.height, 0x6f000000); - } - } - - @Override - public boolean mouseDragged(int mouseX, int mouseY, int button, long timeDragged) { - if (super.mouseDragged(mouseX, mouseY, button, timeDragged) && toolButtons.isVisible()) { - setToolButton(selected); - return true; - } - return false; - } - - @Override - public void clearAllWidgets() { - super.clearAllWidgets(); - selected = null; - configEditor.loadConfigurator(null); - toolButtons.setSelfPosition(new Position(-scrollYOffset, -scrollYOffset)); - customPositionSizeWidget.setControlled(null); - toolButtons.setVisible(false); - addWidget(customPositionSizeWidget); - addWidget(toolButtons); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/BooleanConfigurator.java b/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/BooleanConfigurator.java deleted file mode 100644 index 8814b973136..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/BooleanConfigurator.java +++ /dev/null @@ -1,37 +0,0 @@ -package gregtech.common.terminal.app.guideeditor.widget.configurator; - -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.terminal.gui.widgets.RectButtonWidget; -import gregtech.api.terminal.os.TerminalTheme; - -import com.google.gson.JsonObject; - -import java.awt.*; - -public class BooleanConfigurator extends ConfiguratorWidget { - - public BooleanConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, String name) { - super(group, config, name); - } - - public BooleanConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, String name, - boolean defaultValue) { - super(group, config, name, defaultValue); - } - - protected void init() { - this.addWidget(new RectButtonWidget(0, 15, 10, 10, 2) - .setToggleButton(new ColorRectTexture(new Color(198, 198, 198).getRGB()), (c, p) -> updateValue(p)) - .setValueSupplier(true, () -> { - if (config.get(name).isJsonNull()) { - return defaultValue; - } - return config.get(name).getAsBoolean(); - }) - .setColors(TerminalTheme.COLOR_B_1.getColor(), - TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_1.getColor()) - .setIcon(new ColorRectTexture(new Color(0, 0, 0, 74).getRGB()))); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/ColorConfigurator.java b/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/ColorConfigurator.java deleted file mode 100644 index 5ed6aec5fe6..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/ColorConfigurator.java +++ /dev/null @@ -1,26 +0,0 @@ -package gregtech.common.terminal.app.guideeditor.widget.configurator; - -import gregtech.api.terminal.gui.widgets.ColorWidget; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; - -import com.google.gson.JsonObject; - -public class ColorConfigurator extends ConfiguratorWidget { - - public ColorConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, String name, int defaultValue) { - super(group, config, name, defaultValue); - } - - public ColorConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, String name) { - super(group, config, name); - } - - protected void init() { - this.addWidget(new ColorWidget(0, 15, 85, 10).setColorSupplier(() -> { - if (config.get(name).isJsonNull()) { - return defaultValue; - } - return config.get(name).getAsInt(); - }, true).setOnColorChanged(this::updateValue)); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/ConfiguratorWidget.java b/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/ConfiguratorWidget.java deleted file mode 100644 index 6d05bbac593..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/ConfiguratorWidget.java +++ /dev/null @@ -1,126 +0,0 @@ -package gregtech.common.terminal.app.guideeditor.widget.configurator; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.util.Position; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.I18n; -import net.minecraft.item.ItemStack; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; - -import java.util.Collections; -import java.util.function.Consumer; - -public class ConfiguratorWidget extends WidgetGroup { - - protected T defaultValue; - protected String name; - protected boolean canDefault; - protected boolean isDefault; - protected JsonObject config; - protected DraggableScrollableWidgetGroup group; - private int nameWidth; - private Consumer onUpdated; - - public ConfiguratorWidget(DraggableScrollableWidgetGroup group, JsonObject config, String name) { - this(group, config, name, null); - } - - public ConfiguratorWidget(DraggableScrollableWidgetGroup group, JsonObject config, String name, T defaultValue) { - super(new Position(5, group.getWidgetBottomHeight() + 5)); - this.group = group; - this.defaultValue = defaultValue; - this.name = name; - this.canDefault = defaultValue != null; - this.config = config; - if (config.get(name) == null) { - config.addProperty(name, (String) null); - } - if (canDefault && config.get(name).isJsonNull()) { - isDefault = true; - } - this.addWidget(new LabelWidget(0, 4, name, -1).setShadow(true)); - if (isClientSide()) { - nameWidth = Minecraft.getMinecraft().fontRenderer.getStringWidth(name); - } - init(); - } - - protected void init() {} - - protected void updateValue(T value) { - if (canDefault && isDefault) return; - config.add(name, new Gson().toJsonTree(value)); - update(); - } - - public ConfiguratorWidget setOnUpdated(Consumer onUpdated) { - this.onUpdated = onUpdated; - return this; - } - - protected void update() { - if (onUpdated != null) { - onUpdated.accept(name); - } - } - - @Override - public void drawInForeground(int mouseX, int mouseY) { - int x = getPosition().x; - int y = getPosition().y; - if (canDefault && isMouseOver(x + nameWidth + 4, y + 6, 5, 5, mouseX, mouseY)) { - drawHoveringText(ItemStack.EMPTY, Collections.singletonList(I18n.format("terminal.guide_editor.default")), - 100, mouseX, mouseY); - } - if (!isDefault) { - super.drawInForeground(mouseX, mouseY); - } - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - int x = getPosition().x; - int y = getPosition().y; - drawSolidRect(x, y, this.getSize().width, 1, -1); - if (canDefault) { - drawBorder(x + nameWidth + 4, y + 6, 5, 5, -1, 1); - if (isDefault) { - drawSolidRect(x + nameWidth + 5, y + 7, 3, 3, -1); - } - } - if (canDefault && isDefault) { - super.drawInBackground(-100, -100, partialTicks, context); - drawSolidRect(x, y + 15, this.getSize().width, this.getSize().height - 15, 0x99000000); - } else { - super.drawInBackground(mouseX, mouseY, partialTicks, context); - } - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - int x = getPosition().x; - int y = getPosition().y; - if (!isDefault && super.mouseClicked(mouseX, mouseY, button)) { - return true; - } - if (canDefault && isMouseOver(x + nameWidth + 4, y + 6, 5, 5, mouseX, mouseY)) { - isDefault = !isDefault; - if (isDefault) { - config.addProperty(name, (String) null); - update(); - onDefault(); - } - playButtonClickSound(); - return true; - } - return false; - } - - protected void onDefault() {} -} diff --git a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/FluidStackConfigurator.java b/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/FluidStackConfigurator.java deleted file mode 100644 index 21ab8671f03..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/FluidStackConfigurator.java +++ /dev/null @@ -1,106 +0,0 @@ -package gregtech.common.terminal.app.guideeditor.widget.configurator; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.resources.TextTexture; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.PhantomFluidWidget; -import gregtech.api.gui.widgets.SimpleTextWidget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.terminal.gui.widgets.RectButtonWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.common.terminal.app.guide.widget.TankListWidget; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import java.util.ArrayList; -import java.util.List; - -public class FluidStackConfigurator extends ConfiguratorWidget> { - - DraggableScrollableWidgetGroup container; - List tanks; - - public FluidStackConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, String name) { - super(group, config, name); - } - - protected void init() { - container = new DraggableScrollableWidgetGroup(0, 27, 116, 100); - this.addWidget(container); - this.addWidget(new RectButtonWidget(0, 15, 116, 10, 1) - .setIcon(new TextTexture("terminal.guide_editor.add_slot", -1)) - .setClickListener(cd -> { - addSlot(container, new TankListWidget.FluidStackInfo(null, 0)); - updateValue(); - }) - .setColors(TerminalTheme.COLOR_B_1.getColor(), - TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_1.getColor())); - tanks = new ArrayList<>(); - if (!config.get(name).isJsonNull()) { - Gson gson = new Gson(); - for (JsonElement o : config.get(name).getAsJsonArray()) { - addSlot(container, gson.fromJson(o, TankListWidget.FluidStackInfo.class)); - } - } - } - - private void addSlot(DraggableScrollableWidgetGroup container, TankListWidget.FluidStackInfo fluidStackInfo) { - WidgetGroup group = new WidgetGroup(0, tanks.size() * 20, 116, 20); - tanks.add(fluidStackInfo); - group.addWidget(new PhantomFluidWidget(1, 1, 18, 18, null, null) - .setBackgroundTexture(TerminalTheme.COLOR_B_2) - .setFluidStackSupplier(fluidStackInfo::getInstance, true) - .setFluidStackUpdater(fluidStack -> { - fluidStackInfo.update(fluidStack); - updateValue(); - }, true)); - group.addWidget(new RectButtonWidget(20, 0, 20, 20) - .setColors(TerminalTheme.COLOR_B_1.getColor(), - TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_1.getColor()) - .setClickListener(data -> { - fluidStackInfo.amount = Math.max(0, fluidStackInfo.amount - - (data.isShiftClick ? data.isCtrlClick ? 1000 : 10 : data.isCtrlClick ? 100 : 1)); - updateValue(); - }) - .setHoverText("Shift -10|Ctrl -100|Shift+Ctrl -1000") - .setIcon(new TextTexture("-1", -1))); - group.addWidget(new RectButtonWidget(76, 0, 20, 20) - .setColors(TerminalTheme.COLOR_B_1.getColor(), - TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_1.getColor()) - .setClickListener(data -> { - fluidStackInfo.amount = Math.max(0, fluidStackInfo.amount + - (data.isShiftClick ? data.isCtrlClick ? 1000 : 10 : data.isCtrlClick ? 100 : 1)); - updateValue(); - }) - .setHoverText("Shift +10|Ctrl +100|Shift+Ctrl +1000") - .setIcon(new TextTexture("+1", -1))); - group.addWidget(new ImageWidget(40, 0, 36, 20, TerminalTheme.COLOR_B_2)); - group.addWidget( - new SimpleTextWidget(58, 10, "", 0xFFFFFF, () -> Integer.toString(fluidStackInfo.amount), true)); - group.addWidget(new RectButtonWidget(96, 0, 20, 20) - .setColors(TerminalTheme.COLOR_B_1.getColor(), - TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_1.getColor()) - .setClickListener(data -> { - container.waitToRemoved(group); - tanks.remove(fluidStackInfo); - int index = container.widgets.indexOf(group); - for (int i = container.widgets.size() - 1; i > index; i--) { - container.widgets.get(i).addSelfPosition(0, -20); - } - updateValue(); - }) - .setIcon(GuiTextures.ICON_REMOVE)); - container.addWidget(group); - } - - private void updateValue() { - updateValue(tanks); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/ItemStackConfigurator.java b/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/ItemStackConfigurator.java deleted file mode 100644 index 5171fd0cab7..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/ItemStackConfigurator.java +++ /dev/null @@ -1,104 +0,0 @@ -package gregtech.common.terminal.app.guideeditor.widget.configurator; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.resources.TextTexture; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.PhantomSlotWidget; -import gregtech.api.gui.widgets.SimpleTextWidget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.terminal.gui.widgets.RectButtonWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.common.inventory.handlers.SingleItemStackHandler; -import gregtech.common.terminal.app.guide.widget.SlotListWidget; - -import net.minecraftforge.items.IItemHandlerModifiable; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import java.util.ArrayList; -import java.util.List; - -public class ItemStackConfigurator extends ConfiguratorWidget> { - - DraggableScrollableWidgetGroup container; - List slots; - - public ItemStackConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, String name) { - super(group, config, name); - } - - protected void init() { - container = new DraggableScrollableWidgetGroup(0, 27, 116, 100); - this.addWidget(container); - this.addWidget(new RectButtonWidget(0, 15, 116, 10, 1) - .setIcon(new TextTexture("terminal.guide_editor.add_slot", -1)) - .setClickListener(cd -> { - addSlot(container, new SlotListWidget.ItemStackInfo("minecraft:air", 0, 0)); - updateValue(); - }) - .setColors(TerminalTheme.COLOR_B_1.getColor(), - TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_1.getColor())); - slots = new ArrayList<>(); - if (!config.get(name).isJsonNull()) { - Gson gson = new Gson(); - for (JsonElement o : config.get(name).getAsJsonArray()) { - addSlot(container, gson.fromJson(o, SlotListWidget.ItemStackInfo.class)); - } - } - } - - private void addSlot(DraggableScrollableWidgetGroup container, SlotListWidget.ItemStackInfo itemStackInfo) { - WidgetGroup group = new WidgetGroup(0, slots.size() * 20, 116, 20); - slots.add(itemStackInfo); - IItemHandlerModifiable handler = new SingleItemStackHandler(1); - handler.setStackInSlot(0, itemStackInfo.getInstance()); - group.addWidget(new PhantomSlotWidget(handler, 0, 1, 1).setBackgroundTexture(TerminalTheme.COLOR_B_2) - .setChangeListener(() -> { - itemStackInfo.update(handler.getStackInSlot(0)); - updateValue(); - })); - group.addWidget(new RectButtonWidget(20, 0, 20, 20) - .setColors(TerminalTheme.COLOR_B_1.getColor(), - TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_1.getColor()) - .setClickListener(data -> { - itemStackInfo.count = Math.max(0, itemStackInfo.count - (data.isShiftClick ? 10 : 1)); - updateValue(); - }) - .setIcon(new TextTexture("-1", -1))); - group.addWidget(new RectButtonWidget(76, 0, 20, 20) - .setColors(TerminalTheme.COLOR_B_1.getColor(), - TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_1.getColor()) - .setClickListener(data -> { - itemStackInfo.count = Math.max(0, itemStackInfo.count + (data.isShiftClick ? 10 : 1)); - updateValue(); - }) - .setIcon(new TextTexture("+1", -1))); - group.addWidget(new ImageWidget(40, 0, 36, 20, TerminalTheme.COLOR_B_2)); - group.addWidget(new SimpleTextWidget(58, 10, "", 0xFFFFFF, () -> Integer.toString(itemStackInfo.count), true)); - group.addWidget(new RectButtonWidget(96, 0, 20, 20) - .setColors(TerminalTheme.COLOR_B_1.getColor(), - TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_1.getColor()) - .setClickListener(data -> { - container.waitToRemoved(group); - slots.remove(itemStackInfo); - int index = container.widgets.indexOf(group); - for (int i = container.widgets.size() - 1; i > index; i--) { - container.widgets.get(i).addSelfPosition(0, -20); - } - updateValue(); - }) - .setIcon(GuiTextures.ICON_REMOVE)); - container.addWidget(group); - } - - private void updateValue() { - updateValue(slots); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/NumberConfigurator.java b/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/NumberConfigurator.java deleted file mode 100644 index 7435a9fdfce..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/NumberConfigurator.java +++ /dev/null @@ -1,69 +0,0 @@ -package gregtech.common.terminal.app.guideeditor.widget.configurator; - -import gregtech.api.gui.resources.TextTexture; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.SimpleTextWidget; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.terminal.gui.widgets.RectButtonWidget; -import gregtech.api.terminal.os.TerminalTheme; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -public class NumberConfigurator extends ConfiguratorWidget { - - public NumberConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, String name) { - super(group, config, name); - } - - public NumberConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, String name, int defaultValue) { - super(group, config, name, defaultValue); - } - - protected void init() { - int y = 15; - this.addWidget(new RectButtonWidget(0, y, 20, 20) - .setColors(TerminalTheme.COLOR_B_1.getColor(), - TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_1.getColor()) - .setClickListener(data -> adjustTransferRate(data.isShiftClick ? -100 : -10)) - .setIcon(new TextTexture("-10", -1))); - this.addWidget(new RectButtonWidget(96, y, 20, 20) - .setColors(TerminalTheme.COLOR_B_1.getColor(), - TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_1.getColor()) - .setClickListener(data -> adjustTransferRate(data.isShiftClick ? +100 : +10)) - .setIcon(new TextTexture("+10", -1))); - this.addWidget(new RectButtonWidget(20, y, 20, 20) - .setColors(TerminalTheme.COLOR_B_1.getColor(), - TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_1.getColor()) - .setClickListener(data -> adjustTransferRate(data.isShiftClick ? -5 : -1)) - .setIcon(new TextTexture("-1", -1))); - this.addWidget(new RectButtonWidget(76, y, 20, 20) - .setColors(TerminalTheme.COLOR_B_1.getColor(), - TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_1.getColor()) - .setClickListener(data -> adjustTransferRate(data.isShiftClick ? +5 : +1)) - .setIcon(new TextTexture("+1", -1))); - this.addWidget(new ImageWidget(40, y, 36, 20, TerminalTheme.COLOR_B_2)); - this.addWidget(new SimpleTextWidget(58, 25, "", 0xFFFFFF, () -> { - JsonElement element = config.get(name); - if (element.isJsonNull()) { - return Integer.toString(defaultValue); - } - return element.getAsString(); - }, true)); - } - - private void adjustTransferRate(int added) { - JsonElement element = config.get(name); - int num = 0; - if (!element.isJsonNull()) { - num = element.getAsInt(); - } else { - num = defaultValue; - } - updateValue(num + added); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/SelectorConfigurator.java b/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/SelectorConfigurator.java deleted file mode 100644 index e529beb7f32..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/SelectorConfigurator.java +++ /dev/null @@ -1,38 +0,0 @@ -package gregtech.common.terminal.app.guideeditor.widget.configurator; - -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.terminal.gui.widgets.SelectorWidget; -import gregtech.api.terminal.os.TerminalTheme; - -import com.google.gson.JsonObject; - -import java.util.List; - -public class SelectorConfigurator extends ConfiguratorWidget { - - public SelectorConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, String name, - List candidates, String defaultValue) { - super(group, config, name, defaultValue); - init(candidates); - } - - public SelectorConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, String name, - List candidates) { - super(group, config, name); - init(candidates); - } - - protected void init(List candidates) { - this.addWidget(new SelectorWidget(0, 15, 80, 20, candidates, -1, () -> { - if (config.get(name).isJsonNull()) { - return defaultValue; - } - return config.get(name).getAsString(); - }, true) - .setColors(TerminalTheme.COLOR_B_1.getColor(), - TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_1.getColor()) - .setIsUp(true) - .setOnChanged(this::updateValue)); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/StringConfigurator.java b/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/StringConfigurator.java deleted file mode 100644 index a838e3952aa..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/StringConfigurator.java +++ /dev/null @@ -1,48 +0,0 @@ -package gregtech.common.terminal.app.guideeditor.widget.configurator; - -import gregtech.api.gui.resources.TextTexture; -import gregtech.api.gui.widgets.TextFieldWidget; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.terminal.gui.widgets.RectButtonWidget; -import gregtech.api.terminal.os.TerminalTheme; - -import com.google.gson.JsonObject; - -public class StringConfigurator extends ConfiguratorWidget { - - private TextFieldWidget textFieldWidget; - - public StringConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, String name) { - super(group, config, name); - } - - public StringConfigurator(DraggableScrollableWidgetGroup group, JsonObject config, String name, - String defaultValue) { - super(group, config, name, defaultValue); - } - - protected void init() { - this.addWidget(new RectButtonWidget(76, 15, 40, 20) - .setColors(TerminalTheme.COLOR_B_1.getColor(), - TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_1.getColor()) - .setClickListener(data -> updateString()) - .setIcon(new TextTexture("terminal.guide_editor.update", -1))); - textFieldWidget = new TextFieldWidget(0, 15, 76, 20, TerminalTheme.COLOR_B_2, null, null) - .setMaxStringLength(Integer.MAX_VALUE) - .setValidator(s -> true); - if (config.has(name) && config.get(name).isJsonPrimitive()) { - textFieldWidget.setCurrentString(config.get(name).getAsString()); - } - this.addWidget(textFieldWidget); - } - - private void updateString() { - updateValue(textFieldWidget.getCurrentString()); - } - - @Override - protected void onDefault() { - textFieldWidget.setCurrentString(defaultValue); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/TextListConfigurator.java b/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/TextListConfigurator.java deleted file mode 100644 index f40ed1f8255..00000000000 --- a/src/main/java/gregtech/common/terminal/app/guideeditor/widget/configurator/TextListConfigurator.java +++ /dev/null @@ -1,48 +0,0 @@ -package gregtech.common.terminal.app.guideeditor.widget.configurator; - -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.terminal.gui.widgets.TextEditorWidget; - -import com.google.gson.*; - -import java.util.Collections; -import java.util.List; - -public class TextListConfigurator extends ConfiguratorWidget> { - - private TextEditorWidget editor; - - public TextListConfigurator(DraggableScrollableWidgetGroup group, int height, JsonObject config, String name) { - super(group, config, name); - init(height); - } - - public TextListConfigurator(DraggableScrollableWidgetGroup group, int height, JsonObject config, String name, - String defaultValue) { - super(group, config, name, Collections.singletonList(defaultValue)); - init(height); - } - - protected void init(int height) { - JsonElement element = config.get(name); - String initValue = ""; - if (!element.isJsonNull()) { - List init = new Gson().fromJson(element, List.class); - initValue = String.join("\n", init); - - } - editor = new TextEditorWidget(0, 15, 116, height, this::updateTextList, true).setContent(initValue) - .setBackground(new ColorRectTexture(0xA3FFFFFF)); - this.addWidget(editor); - } - - private void updateTextList(String saved) { - updateValue(Collections.singletonList(saved)); - } - - @Override - protected void onDefault() { - editor.setContent(defaultValue.get(0)); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/hardwaremanager/HardwareManagerApp.java b/src/main/java/gregtech/common/terminal/app/hardwaremanager/HardwareManagerApp.java deleted file mode 100644 index 21554ada83b..00000000000 --- a/src/main/java/gregtech/common/terminal/app/hardwaremanager/HardwareManagerApp.java +++ /dev/null @@ -1,110 +0,0 @@ -package gregtech.common.terminal.app.hardwaremanager; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.resources.*; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.terminal.TerminalRegistry; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.gui.widgets.RectButtonWidget; -import gregtech.api.terminal.hardware.Hardware; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.client.shader.Shaders; -import gregtech.common.items.MetaItems; - -import net.minecraft.client.renderer.GlStateManager; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import java.util.concurrent.atomic.AtomicInteger; - -public class HardwareManagerApp extends AbstractApplication { - - private static final TextureArea CIRCUIT_LINE = TextureArea - .fullImage("textures/gui/terminal/hardware_manager/circuit.png"); - @SideOnly(Side.CLIENT) - private ShaderTexture circuit; - private HardwareSlotWidget selected; - private WidgetGroup apps; - - public HardwareManagerApp() { - super("hardware"); - } - - @Override - public IGuiTexture getIcon() { - return new ItemStackTexture(MetaItems.INTEGRATED_CIRCUIT.getStackForm()); - } - - @Override - public AbstractApplication initApp() { - apps = new WidgetGroup(); - this.addWidget(apps); - int x = 10; - int y = 65; - for (Hardware hardware : os.hardwareProvider.getProviders().values()) { - HardwareSlotWidget hardwareSlotWidget = new HardwareSlotWidget(x, y, os, hardware); - this.addWidget(hardwareSlotWidget); - hardwareSlotWidget.setOnSelected(() -> { - selected = hardwareSlotWidget; - apps.clearAllWidgets(); - AtomicInteger index = new AtomicInteger(0); - for (AbstractApplication installed : getOs().installedApps) { - TerminalRegistry - .getAppHardwareDemand(installed.getRegistryName(), - getOs().tabletNBT.getCompoundTag(installed.getRegistryName()).getInteger("_tier")) - .stream() - .filter(hardware::isHardwareAdequate).findFirst() - .ifPresent(X -> { - apps.addWidget(new RectButtonWidget(162 + (index.get() % 4) * 25, - 122 + (index.get() / 4) * 30, 20, 20, 2) - .setIcon(installed.getIcon()) - .setHoverText(installed.getUnlocalizedName()) - .setColors(0, TerminalTheme.COLOR_7.getColor(), 0)); - index.getAndIncrement(); - }); - } - }); - x += 25; - } - return this; - } - - @Override - protected void hookDrawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - int x = getPosition().x; - int y = getPosition().y; - int width = getSize().width; - int height = getSize().height; - float time = (gui.entityPlayer.ticksExisted + partialTicks) / 20f; - if (Shaders.allowedShader()) { - if (circuit == null) { - circuit = ShaderTexture.createShader("circuit.frag"); - } - ResourceHelper.bindTexture("textures/gui/terminal/terminal_background.png"); - circuit.draw(x, y, width, height, uniformCache -> { - uniformCache.glUniform1F("u_time", time); - uniformCache.glUniform2F("u_mouse", - (float) (mouseX - x) * circuit.getResolution(), - (float) (mouseY - y) * circuit.getResolution()); - }); - } else { - drawSolidRect(x, y, width, height, TerminalTheme.COLOR_B_2.getColor()); - } - GlStateManager.color(1, 1, 1, 0.8f); - CIRCUIT_LINE.draw(x, y, width, height); - GlStateManager.color(1, 1, 1, 1); - - super.hookDrawInBackground(mouseX, mouseY, partialTicks, context); - if (selected != null) { - int sX = x + selected.getSelfPosition().x; - int sY = y + selected.getSelfPosition().y; - int sW = selected.getSize().width; - int sH = selected.getSize().height; - drawBorder(sX, sY, sW, sH, 0xff00af00, 1); - drawSolidRect(sX + sW / 2, sY + sH, 1, 10, 0xff00af00); - drawSolidRect(sX + sW / 2, sY + sH + 10, x + 210 - sX - sW / 2, 1, 0xff00af00); - drawSolidRect(x + 210, sY + sH + 10, 1, y + 110 - sY - sH, 0xff00af00); - } - drawBorder(x + 160, y + 120, 25 * 4, 25 * 4, selected == null ? -1 : 0xff00af00, 1); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/hardwaremanager/HardwareSlotWidget.java b/src/main/java/gregtech/common/terminal/app/hardwaremanager/HardwareSlotWidget.java deleted file mode 100644 index 25c0e795dd3..00000000000 --- a/src/main/java/gregtech/common/terminal/app/hardwaremanager/HardwareSlotWidget.java +++ /dev/null @@ -1,132 +0,0 @@ -package gregtech.common.terminal.app.hardwaremanager; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.terminal.hardware.Hardware; -import gregtech.api.terminal.os.TerminalDialogWidget; -import gregtech.api.terminal.os.TerminalOSWidget; - -import net.minecraft.client.resources.I18n; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.PacketBuffer; - -import java.util.Arrays; -import java.util.Collections; - -public class HardwareSlotWidget extends WidgetGroup { - - private final Hardware hardware; - private final TerminalOSWidget os; - private Runnable onSelected; - - public HardwareSlotWidget(int x, int y, TerminalOSWidget os, Hardware hardware) { - super(x, y, 20, 20); - this.os = os; - this.hardware = hardware; - } - - public void setOnSelected(Runnable onSelected) { - this.onSelected = onSelected; - } - - private void showDialog(int button) { - if (button == 0) { - if (hardware.hasHW()) { - onSelected.run(); - } else { - TerminalDialogWidget.showItemSelector(os, "terminal.hardware.select", true, - itemStack -> hardware.acceptItemStack(itemStack) != null, - itemStack -> { - NBTTagCompound tag = hardware.acceptItemStack(itemStack); - if (tag != null) { - tag.setTag("item", itemStack.serializeNBT()); - os.hardwareProvider.getOrCreateHardwareCompound().setTag(hardware.getRegistryName(), - tag); - os.hardwareProvider.cleanCache(hardware.getRegistryName()); - } - }).open(); - } - } else { - if (hardware.hasHW()) { - boolean emptySlot = false; - for (ItemStack itemStack : gui.entityPlayer.inventory.mainInventory) { - if (itemStack.isEmpty()) { - emptySlot = true; - break; - } - } - if (emptySlot) { - TerminalDialogWidget - .showConfirmDialog(os, "terminal.hardware.remove", "terminal.component.confirm", result -> { - if (result) { - NBTTagCompound tag = os.hardwareProvider.getOrCreateHardwareCompound() - .getCompoundTag(hardware.getRegistryName()); - if (!tag.isEmpty() && tag.hasKey("item")) { - gui.entityPlayer.inventory.addItemStackToInventory( - hardware.onHardwareRemoved(new ItemStack(tag.getCompoundTag("item")))); - } - os.hardwareProvider.getOrCreateHardwareCompound() - .removeTag(hardware.getRegistryName()); - os.hardwareProvider.cleanCache(hardware.getRegistryName()); - } - }).open(); - } else { - TerminalDialogWidget - .showInfoDialog(os, "terminal.component.warning", "terminal.hardware.remove.full").open(); - } - } - } - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (isMouseOverElement(mouseX, mouseY)) { - writeClientAction(1, buffer -> buffer.writeVarInt(button)); - showDialog(button); - return true; - } - return false; - } - - @Override - public void handleClientAction(int id, PacketBuffer buffer) { - if (id == 1) { - showDialog(buffer.readVarInt()); - } - } - - @Override - public void drawInForeground(int mouseX, int mouseY) { - if (hardware != null && isMouseOverElement(mouseX, mouseY)) { - if (!hardware.hasHW()) { - drawHoveringText(ItemStack.EMPTY, Collections.singletonList(hardware.getLocalizedName()), 300, mouseX, - mouseY); - } else { - String info = hardware.addInformation(); - if (info == null) { - drawHoveringText(ItemStack.EMPTY, - Arrays.asList(hardware.getLocalizedName(), I18n.format("terminal.hardware.tip.remove")), - 300, mouseX, mouseY); - } else { - drawHoveringText(ItemStack.EMPTY, - Arrays.asList(String.format("%s (%s)", hardware.getLocalizedName(), info), - I18n.format("terminal.hardware.tip.remove")), - 300, mouseX, mouseY); - } - } - } - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - int x = getPosition().x; - int y = getPosition().y; - int width = getSize().width; - int height = getSize().height; - boolean missing = !hardware.hasHW(); - drawBorder(x - 1, y - 1, width + 2, height + 1, missing ? 0x6fffffff : -1, 1); - hardware.getIcon().draw(x, y, width, height); - super.drawInBackground(mouseX, mouseY, partialTicks, context); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/multiblockhelper/MachineBuilderWidget.java b/src/main/java/gregtech/common/terminal/app/multiblockhelper/MachineBuilderWidget.java deleted file mode 100644 index 899e1dc9d37..00000000000 --- a/src/main/java/gregtech/common/terminal/app/multiblockhelper/MachineBuilderWidget.java +++ /dev/null @@ -1,279 +0,0 @@ -package gregtech.common.terminal.app.multiblockhelper; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.resources.TextTexture; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.SlotWidget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; -import gregtech.api.pattern.MultiblockShapeInfo; -import gregtech.api.pattern.PatternError; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.terminal.gui.widgets.MachineSceneWidget; -import gregtech.api.terminal.gui.widgets.RectButtonWidget; -import gregtech.api.terminal.os.TerminalDialogWidget; -import gregtech.api.terminal.os.TerminalOSWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.util.BlockInfo; -import gregtech.client.utils.RenderBufferHelper; -import gregtech.common.inventory.handlers.CycleItemStackHandler; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockBush; -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraft.entity.player.InventoryPlayer; -import net.minecraft.init.Blocks; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; -import net.minecraft.network.PacketBuffer; -import net.minecraft.util.BlockRenderLayer; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.NonNullList; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import org.lwjgl.opengl.GL11; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * Created with IntelliJ IDEA. - * - * @Author: KilaBash - * @Date: 2021/09/15 - * @Description: - */ -public class MachineBuilderWidget extends WidgetGroup { - - private BlockPos pos; - private EnumFacing facing; - private SlotWidget[] slotWidgets; - TerminalOSWidget os; - @SideOnly(Side.CLIENT) - private MachineSceneWidget sceneWidget; - @SideOnly(Side.CLIENT) - private Set highLightBlocks; - private final MultiblockControllerBase controllerBase; - private int selected = -1; - @SideOnly(Side.CLIENT) - private DraggableScrollableWidgetGroup candidates; - @SideOnly(Side.CLIENT) - private List handlers; - - public MachineBuilderWidget(int x, int y, int width, int height, MultiblockControllerBase controllerBase, - TerminalOSWidget os) { - super(x, y, width, height); - this.os = os; - this.controllerBase = controllerBase; - addWidget(new ImageWidget(0, 0, width, height, GuiTextures.BACKGROUND)); - addWidget(new RectButtonWidget(12, 125, width - 24, 20, 1) - .setClickListener(this::autoBuildButton) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), - TerminalTheme.COLOR_B_2.getColor()) - .setIcon(new TextTexture("terminal.multiblock_ar.builder.auto", -1))); - addWidget(new RectButtonWidget(12, 125 + 25, width - 24, 20, 1) - .setClickListener(this::placeButton) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), - TerminalTheme.COLOR_B_2.getColor()) - .setIcon(new TextTexture("terminal.multiblock_ar.builder.place", -1))); - addWidget(new RectButtonWidget(12, 125 + 50, width - 24, 20, 1) - .setClickListener(this::debugButton) - .setColors(TerminalTheme.COLOR_B_1.getColor(), TerminalTheme.COLOR_7.getColor(), - TerminalTheme.COLOR_B_2.getColor()) - .setIcon(new TextTexture("terminal.multiblock_ar.builder.debug", -1))); - if (os.isRemote()) { - candidates = new DraggableScrollableWidgetGroup(-20, 0, 20, 180); - addWidget(candidates); - } - } - - @Override - public void handleClientAction(int id, PacketBuffer buffer) { - if (id == -2) { // select - this.selected = buffer.readVarInt(); - } else if (id == -3) { // update pos facing - this.pos = buffer.readBlockPos(); - this.facing = EnumFacing.VALUES[buffer.readByte()]; - } else { - super.handleClientAction(id, buffer); - } - } - - /** - * I had to add slotWidget after parent widget be added, because of gtce's {@link gregtech.api.gui.INativeWidget} - * interface. - * Hopefully one day I can remove this worse interface. - */ - public void addPlayerInventory() { - InventoryPlayer inventoryPlayer = gui.entityPlayer.inventory; - slotWidgets = new SlotWidget[36]; - for (int row = 0; row < 6; row++) { - for (int col = 0; col < 6; col++) { - int index = col + row * 6; - boolean isActive = inventoryPlayer.getStackInSlot(index).getItem() instanceof ItemBlock; - slotWidgets[index] = new SlotWidget(inventoryPlayer, index, 12 + col * 18, 12 + row * 18, false, - false) { - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (isMouseOverElement(mouseX, mouseY) && isActive()) { - if (selected != index) { - selected = index; - MachineBuilderWidget.this.writeClientAction(-2, buf -> buf.writeVarInt(index)); - } - } - return super.mouseClicked(mouseX, mouseY, button); - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - super.drawInBackground(mouseX, mouseY, partialTicks, context); - if (selected == index) { - drawSolidRect(getPosition().x, getPosition().y, getSize().width, getSize().height, - 0x4f00ff00); - } - } - }.setBackgroundTexture(GuiTextures.SLOT); - slotWidgets[index].setActive(isActive); - this.addWidget(slotWidgets[index]); - } - } - } - - @SideOnly(Side.CLIENT) - public void setSceneWidget(MachineSceneWidget sceneWidget) { - this.sceneWidget = sceneWidget; - this.highLightBlocks = new HashSet<>(); - MachineSceneWidget.getWorldSceneRenderer().addRenderedBlocks(highLightBlocks, this::highLightRender); - sceneWidget.setOnSelected(this::setFocus); - sceneWidget.getAround().clear(); - Set cores = sceneWidget.getCores(); - int rX = 5; - int rY = 5; - int rZ = 5; - for (MultiblockShapeInfo shapeInfo : controllerBase.getMatchingShapes()) { - BlockInfo[][][] blockInfos = shapeInfo.getBlocks(); - rX = Math.max(blockInfos.length, rX); - rY = Math.max(blockInfos[0].length, rY); - rZ = Math.max(blockInfos[0][0].length, rZ); - } - for (int x = -rX; x <= rX; x++) { - for (int y = -rY; y <= rY; y++) { - for (int z = -rZ; z <= rZ; z++) { - cores.add(controllerBase.getPos().add(x, y, z)); - } - } - } - } - - @SideOnly(Side.CLIENT) - private void setFocus(BlockPos pos, EnumFacing facing) { - this.pos = new BlockPos(pos); - this.facing = facing; - writeClientAction(-3, buf -> { - buf.writeBlockPos(pos); - buf.writeByte(facing.getIndex()); - }); - } - - private void placeButton(ClickData clickData) { - if (pos != null && facing != null && selected != -1) { - World world = controllerBase.getWorld(); - BlockPos offset = pos.offset(facing); - if (world.getBlockState(offset).getBlock() == Blocks.AIR) { - ItemStack itemStack = slotWidgets[selected].getHandle().getStack(); - if (!itemStack.isEmpty() && itemStack.getItem() instanceof ItemBlock) { - ItemBlock itemBlock = (ItemBlock) itemStack.getItem(); - float hitX = pos.getX() + 0.5f; - float hitY = pos.getY() + 0.5f; - float hitZ = pos.getZ() + 0.5f; - Block block = itemBlock.getBlock(); - IBlockState state = block.getStateFromMeta(itemBlock.getMetadata(itemStack.getMetadata())); - if (block instanceof BlockBush) { - // Prevent placing lilypads, grass, etc where they should not be - if (!((BlockBush) block).canBlockStay(world, offset, state)) { - if (clickData.isClient) { - TerminalDialogWidget.showInfoDialog(os, "terminal.component.error", - "This Block cannot be placed here").setClientSide().open(); - } - return; - } - } - - itemBlock.placeBlockAt(itemStack, gui.entityPlayer, world, offset, facing, hitX, hitY, hitZ, state); - itemStack.shrink(1); - } - } - } - } - - @SideOnly(Side.CLIENT) - private void highLightRender(boolean isTESR, int pass, BlockRenderLayer layer) { - if (isTESR && pass == 0) return; - - GlStateManager.disableDepth(); - GlStateManager.disableTexture2D(); - GlStateManager.glLineWidth(5); - - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder buffer = tessellator.getBuffer(); - - buffer.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR); - - for (BlockPos pos : highLightBlocks) { - RenderBufferHelper.renderCubeFrame(buffer, - pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1, - 1, 0, 0, 1); - } - - tessellator.draw(); - - GlStateManager.enableTexture2D(); - GlStateManager.enableDepth(); - GlStateManager.color(1, 1, 1, 1); - } - - private void debugButton(ClickData clickData) { - if (clickData.isClient && controllerBase != null) { - highLightBlocks.clear(); - if (controllerBase.structurePattern.checkPatternFastAt( - controllerBase.getWorld(), controllerBase.getPos(), controllerBase.getFrontFacing().getOpposite(), - controllerBase.getUpwardsFacing(), controllerBase.allowsFlip()) == null) { - PatternError error = controllerBase.structurePattern.getError(); - highLightBlocks.add(new BlockPos(error.getPos())); - List> candidatesItemStack = error.getCandidates(); - candidates.clearAllWidgets(); - int y = 1; - handlers = new ArrayList<>(); - for (List candidate : candidatesItemStack) { - CycleItemStackHandler handler = new CycleItemStackHandler( - NonNullList.from(ItemStack.EMPTY, candidate.toArray(new ItemStack[0]))); - handlers.add(handler); - candidates.addWidget(new SlotWidget(handler, 0, 1, y, false, false) - .setBackgroundTexture(TerminalTheme.COLOR_B_2)); - y += 20; - } - TerminalDialogWidget.showInfoDialog(os, "terminal.component.error", error.getErrorInfo()) - .setClientSide().open(); - } - } - } - - private void autoBuildButton(ClickData clickData) { - if (controllerBase != null) { - if (!clickData.isClient && controllerBase.structurePattern != null) { - controllerBase.structurePattern.autoBuild(gui.entityPlayer, controllerBase); - } - } - } -} diff --git a/src/main/java/gregtech/common/terminal/app/multiblockhelper/MultiBlockPreviewARApp.java b/src/main/java/gregtech/common/terminal/app/multiblockhelper/MultiBlockPreviewARApp.java deleted file mode 100644 index 6e9d04b4705..00000000000 --- a/src/main/java/gregtech/common/terminal/app/multiblockhelper/MultiBlockPreviewARApp.java +++ /dev/null @@ -1,273 +0,0 @@ -package gregtech.common.terminal.app.multiblockhelper; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.gui.resources.ShaderTexture; -import gregtech.api.gui.resources.TextureArea; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; -import gregtech.api.pattern.MultiblockShapeInfo; -import gregtech.api.terminal.app.ARApplication; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.gui.widgets.MachineSceneWidget; -import gregtech.api.terminal.gui.widgets.RectButtonWidget; -import gregtech.api.terminal.os.TerminalDialogWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.client.renderer.handler.MultiblockPreviewRenderer; -import gregtech.client.shader.Shaders; -import gregtech.client.utils.RenderUtil; -import gregtech.common.ConfigHolder; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GLAllocation; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.texture.TextureMap; -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -import net.minecraftforge.client.event.RenderWorldLastEvent; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL13; - -import java.util.*; - -public class MultiBlockPreviewARApp extends ARApplication { - - @SideOnly(Side.CLIENT) - int lastMouseX; - @SideOnly(Side.CLIENT) - int lastMouseY; - @SideOnly(Side.CLIENT) - float partialTicks; - - public MultiBlockPreviewARApp() { - super("multiblock_ar"); - } - - @Override - public AbstractApplication initApp() { // 232 333 - int bW = 120; - int bH = 120; - - addWidget(new ImageWidget(10, 10, 313, 212, new ColorRectTexture(TerminalTheme.COLOR_B_2.getColor()))); - addWidget(new ImageWidget(333 / 2, 20, 1, 222 - 40, new ColorRectTexture(-1))); - - addWidget(new LabelWidget(10 + 313 / 4, 35, "terminal.multiblock_ar.tier.0", -1).setXCentered(true) - .setYCentered(true)); - addWidget(new RectButtonWidget(10 + (313 / 2 - bW) / 2, 50, bW, bH) - .setIcon(TextureArea.fullImage("textures/gui/terminal/multiblock_ar/profile.png")) - .setColors(-1, 0xff00ff00, 0) - .setHoverText("terminal.ar.open") - .setClickListener(clickData -> openAR())); - - addWidget(new LabelWidget(333 / 2 + 313 / 4, 35, "terminal.multiblock_ar.tier.1", - getAppTier() == 0 ? 0xffff0000 : -1).setXCentered(true).setYCentered(true)); - addWidget(new RectButtonWidget(333 / 2 + (313 / 2 - bW) / 2, 50, bW, bH) - .setIcon(this::drawBuilderButton) - .setColors(getAppTier() == 0 ? 0xffff0000 : -1, getAppTier() == 0 ? 0xffff0000 : 0xff00ff00, 0) - .setHoverText( - getAppTier() > 0 ? "terminal.multiblock_ar.builder.hover" : "terminal.multiblock_ar.unlock") - .setClickListener(clickData -> buildMode())); - return this; - } - - private void drawBuilderButton(double x, double y, int width, int height) { - if (Shaders.allowedShader()) { - float time = (gui.entityPlayer.ticksExisted + partialTicks) / 20f; - - MultiblockControllerBase controllerBase = getController(); - int color = controllerBase == null ? -1 : controllerBase.getPaintingColorForRendering(); - - if (controllerBase != null) { - GlStateManager.setActiveTexture(GL13.GL_TEXTURE0); - GlStateManager.enableTexture2D(); - RenderUtil.bindTextureAtlasSprite(controllerBase.getFrontDefaultTexture()); - GlStateManager.setActiveTexture(GL13.GL_TEXTURE1); - GlStateManager.enableTexture2D(); - RenderUtil.bindTextureAtlasSprite(controllerBase.getBaseTexture(null).getParticleSprite()); - } - ShaderTexture.createShader("showcube.frag").draw(x, y, width, height, uniformCache -> { - uniformCache.glUniform1I("faceTexture", 0); - uniformCache.glUniform1I("baseTexture", 1); - uniformCache.glUniform1F("u_time", time); - uniformCache.glUniform3F("f_color", (color >> 16 & 255) / 255.0F, (color >> 8 & 255) / 255.0F, - (color & 255) / 255.0F); - uniformCache.glUniformBoolean("block", controllerBase != null); - if (isMouseOver((int) x, (int) y, width, height, lastMouseX, lastMouseY)) { - uniformCache.glUniform2F("u_mouse", - (float) (((lastMouseX - x) / 2 + width / 3) * ConfigHolder.client.resolution), - (float) (height / 2 * ConfigHolder.client.resolution)); - } - }); - - GlStateManager.setActiveTexture(GL13.GL_TEXTURE1); - GlStateManager.bindTexture(0); - - GlStateManager.setActiveTexture(GL13.GL_TEXTURE0); - GlStateManager.bindTexture(0); - - } else { - GuiTextures.MULTIBLOCK_CATEGORY.draw(x, y, width, height); - } - } - - @Override - public int getMaxTier() { - return 1; - } - - private MultiblockControllerBase getController() { - if (os.clickPos != null) { - TileEntity te = gui.entityPlayer.world.getTileEntity(os.clickPos); - if (te instanceof IGregTechTileEntity && - ((IGregTechTileEntity) te).getMetaTileEntity() instanceof MultiblockControllerBase) { - return (MultiblockControllerBase) ((IGregTechTileEntity) te).getMetaTileEntity(); - } - } - return null; - } - - private void buildMode() { - if (getAppTier() == 0) { - TerminalDialogWidget.showInfoDialog(getOs(), "terminal.dialog.notice", "terminal.multiblock_ar.unlock") - .open(); - } else if (getController() != null) { - widgets.forEach(this::waitToRemoved); - MultiblockControllerBase controllerBase = getController(); - MachineBuilderWidget builderWidget = new MachineBuilderWidget(200, 16, 133, 200, controllerBase, getOs()); - this.addWidget(builderWidget); - builderWidget.addPlayerInventory(); - if (isClient) { - MachineSceneWidget sceneWidget = new MachineSceneWidget(0, 16, 200, 200, controllerBase); - builderWidget.setSceneWidget(sceneWidget); - this.addWidget(0, sceneWidget); - this.addWidget(new ImageWidget(0, 0, 333, 16, GuiTextures.UI_FRAME_SIDE_UP)); - this.addWidget(new ImageWidget(0, 216, 333, 16, GuiTextures.UI_FRAME_SIDE_DOWN)); - } else { - this.addWidget(0, new WidgetGroup()); // placeholder - } - } else { - TerminalDialogWidget.showInfoDialog(getOs(), "terminal.dialog.notice", "terminal.console.notice").open(); - } - } - - @Override - protected void hookDrawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - lastMouseX = mouseX; - lastMouseY = mouseY; - this.partialTicks = partialTicks; - super.hookDrawInBackground(mouseX, mouseY, partialTicks, context); - } - - ////////////////////////////////////// AR///////////////////////////////////////// - - @SideOnly(Side.CLIENT) - private static Map controllerList; - @SideOnly(Side.CLIENT) - private static Set found; - @SideOnly(Side.CLIENT) - private static BlockPos lastPos; - private static int opList = -1; - - @Override - public void onAROpened() { - controllerList = new HashMap<>(); - found = new HashSet<>(); - } - - @SideOnly(Side.CLIENT) - private static boolean inRange(BlockPos playerPos, BlockPos controllerPos) { - return Math.abs(playerPos.getX() - controllerPos.getX()) < 30 && - Math.abs(playerPos.getY() - controllerPos.getY()) < 30 && - Math.abs(playerPos.getZ() - controllerPos.getZ()) < 30; - } - - @SideOnly(Side.CLIENT) - @Override - public void tickAR(EntityPlayer player) { - World world = player.world; - int tick = Math.abs(player.ticksExisted % 27); // 0 - 26 - if (tick == 0) { - boolean reRender = false; - Iterator iterator = controllerList.keySet().iterator(); - if (iterator.hasNext()) { - MultiblockControllerBase controller = iterator.next(); - if (!controller.isValid() || controller.isStructureFormed() || - !inRange(player.getPosition(), controller.getPos())) { - iterator.remove(); - reRender = true; - } - } - for (MultiblockControllerBase controllerBase : found) { - if (!controllerList.containsKey(controllerBase)) { - List shapeInfos = controllerBase.getMatchingShapes(); - if (!shapeInfos.isEmpty()) { - controllerList.put(controllerBase, shapeInfos.get(0)); - reRender = true; - } - } - } - found.clear(); - lastPos = player.getPosition(); - if (reRender) { - opList = GLAllocation.generateDisplayLists(1); // allocate op list - GlStateManager.glNewList(opList, GL11.GL_COMPILE); - controllerList.forEach((controller, shapes) -> MultiblockPreviewRenderer - .renderControllerInList(controller, shapes, 0)); - GlStateManager.glEndList(); - } - } - if (lastPos == null) { - lastPos = player.getPosition(); - } - for (int i = tick * 1000; i < (tick + 1) * 1000; i++) { - int x = i % 30 - 15; - int y = (i / 30) % 30 - 15; - int z = (i / 900) - 15; - TileEntity tileEntity = world.getTileEntity(lastPos.add(x, y, z)); - if (tileEntity instanceof IGregTechTileEntity) { - if (((IGregTechTileEntity) tileEntity).getMetaTileEntity() instanceof MultiblockControllerBase) { - found.add((MultiblockControllerBase) ((IGregTechTileEntity) tileEntity).getMetaTileEntity()); - } - } - } - } - - @SideOnly(Side.CLIENT) - @Override - public void drawARScreen(RenderWorldLastEvent event) { - if (opList != -1) { - MultiblockPreviewRenderer.resetMultiblockRender(); - Minecraft mc = Minecraft.getMinecraft(); - Entity entity = mc.getRenderViewEntity(); - if (entity == null) entity = mc.player; - - float partialTicks = event.getPartialTicks(); - - double tx = entity.lastTickPosX + ((entity.posX - entity.lastTickPosX) * partialTicks); - double ty = entity.lastTickPosY + ((entity.posY - entity.lastTickPosY) * partialTicks); - double tz = entity.lastTickPosZ + ((entity.posZ - entity.lastTickPosZ) * partialTicks); - - Minecraft.getMinecraft().getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); - GlStateManager.color(1F, 1F, 1F, 1F); - GlStateManager.pushMatrix(); - GlStateManager.translate(-tx, -ty, -tz); - GlStateManager.enableBlend(); - - GlStateManager.callList(opList); - - GlStateManager.enableLighting(); - GlStateManager.popMatrix(); - GlStateManager.color(1F, 1F, 1F, 0F); - } - } -} diff --git a/src/main/java/gregtech/common/terminal/app/prospector/ProspectorApp.java b/src/main/java/gregtech/common/terminal/app/prospector/ProspectorApp.java deleted file mode 100644 index fb2144909ce..00000000000 --- a/src/main/java/gregtech/common/terminal/app/prospector/ProspectorApp.java +++ /dev/null @@ -1,221 +0,0 @@ -package gregtech.common.terminal.app.prospector; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.terminal.TerminalRegistry; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.os.TerminalOSWidget; -import gregtech.api.terminal.os.menu.IMenuComponent; -import gregtech.api.util.GTLog; -import gregtech.common.terminal.app.prospector.widget.WidgetOreList; -import gregtech.common.terminal.app.prospector.widget.WidgetProspectingMap; -import gregtech.common.terminal.component.ClickComponent; -import gregtech.common.terminal.component.SearchComponent; -import gregtech.core.network.packets.PacketProspecting; - -import net.minecraft.nbt.CompressedStreamTools; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import com.google.common.collect.Maps; -import com.google.common.collect.Table; -import com.google.common.collect.Tables; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; - -public class ProspectorApp extends AbstractApplication implements SearchComponent.IWidgetSearch { - - private WidgetOreList widgetOreList; - private WidgetProspectingMap widgetProspectingMap; - private ColorRectTexture background; - @SideOnly(Side.CLIENT) - private Table persist; - private final ProspectorMode mode; - - public ProspectorApp(@NotNull ProspectorMode mode) { - super(mode.terminalName); - this.mode = mode; - } - - @Override - public AbstractApplication createAppInstance(TerminalOSWidget os, boolean isClient, NBTTagCompound nbt) { - ProspectorApp app = new ProspectorApp(mode); - app.isClient = isClient; - app.nbt = nbt; - return app; - } - - @Override - public AbstractApplication initApp() { - int chunkRadius = getAppTier() + 3; - int offset = (232 - 32 * 7 + 16) / 2; - background = new ColorRectTexture(0xA0000000); - this.addWidget(new ImageWidget(0, 0, 333, 232, background)); - if (isClient) { - this.addWidget(new ImageWidget(0, 0, 333, offset, GuiTextures.UI_FRAME_SIDE_UP)); - this.addWidget(new ImageWidget(0, 232 - offset, 333, offset, GuiTextures.UI_FRAME_SIDE_DOWN)); - this.widgetOreList = new WidgetOreList(32 * chunkRadius - 16, offset, 333 - 32 * chunkRadius + 16, - 232 - 2 * offset); - this.addWidget(this.widgetOreList); - } - this.widgetProspectingMap = new WidgetProspectingMap(0, offset + (7 - chunkRadius) * 16, chunkRadius, - this.widgetOreList, mode, 1); - if (isClient) { - persist = Tables.newCustomTable(Maps.newHashMap(), Maps::newHashMap); - widgetProspectingMap.setOnPacketReceived(packet -> persist.put(packet.chunkX, packet.chunkZ, packet)); - } - - this.addWidget(1, this.widgetProspectingMap); - loadLocalConfig(nbt -> { - this.widgetProspectingMap.setDarkMode(nbt.getBoolean("dark")); - background.setColor(this.widgetProspectingMap.getDarkMode() ? 0xA0000000 : 0xA0ffffff); - }); - if (isClient) { - loadPacketLocalConfig(); - // Cardinal directions - this.addWidget(new LabelWidget(-2 + (16 * (chunkRadius * 2 - 1)) / 2, offset, "N", this::labelColor) - .setShadow(true)); - this.addWidget(new LabelWidget(-2 + (16 * (chunkRadius * 2 - 1)) / 2, - offset - 6 + 16 * (chunkRadius * 2 - 1), "S", this::labelColor).setShadow(true)); - this.addWidget(new LabelWidget(0, offset - 3 + (16 * (chunkRadius * 2 - 1)) / 2, "W", this::labelColor) - .setShadow(true)); - this.addWidget(new LabelWidget(-6 + 16 * (chunkRadius * 2 - 1), - offset - 3 + (16 * (chunkRadius * 2 - 1)) / 2, "E", this::labelColor).setShadow(true)); - } - return this; - } - - int labelColor() { - return this.widgetProspectingMap.getDarkMode() ? 0xF0F0F0 : 0x404040; - } - - @SideOnly(Side.CLIENT) - protected void loadPacketLocalConfig() { - new Thread(() -> { // thread for better QoL - int posX = gui.entityPlayer.getPosition().getX(); - int posZ = gui.entityPlayer.getPosition().getZ(); - - if (posX % 16 > 7 || posX % 16 == 0) { - posX -= 1; - } else { - posX += 1; - } - // draw red horizontal line - if (posZ % 16 > 7 || posZ % 16 == 0) { - posZ -= 1; - } else { - posZ += 1; - } - - int playerChunkX = gui.entityPlayer.chunkCoordX; - int playerChunkZ = gui.entityPlayer.chunkCoordZ; - int chunkRadius = getAppTier() + 3 - 1; - for (int i = playerChunkX - chunkRadius; i <= playerChunkX + chunkRadius; i++) { - for (int j = playerChunkZ - chunkRadius; j <= playerChunkZ + chunkRadius; j++) { - NBTTagCompound nbt = null; - try { - nbt = CompressedStreamTools.read(new File(TerminalRegistry.TERMINAL_PATH, - String.format("%s/%d/%d_%d.nbt", getRegistryName(), mode.ordinal(), i, j))); - } catch (IOException e) { - GTLog.logger.error("error while loading local nbt for {}", getRegistryName(), e); - } - if (nbt != null) { - PacketProspecting packet = PacketProspecting.readPacketData(nbt); - if (packet != null) { - packet.posX = posX; - packet.posZ = posZ; - persist.put(i, j, packet); - widgetProspectingMap.addPacketToQueue(packet); - } - } - } - } - }).start(); - } - - @SideOnly(Side.CLIENT) - protected void savePacketLocalConfig() { - new Thread(() -> { // thread for better QoL - File folder = new File(TerminalRegistry.TERMINAL_PATH, - String.format("%s/%d", getRegistryName(), mode.ordinal())); - if (!folder.exists()) { - if (!folder.mkdirs()) return; - } - for (Table.Cell cell : persist.cellSet()) { - if (cell.getValue() != null) { - NBTTagCompound nbt = cell.getValue().writePacketData(); - try { - if (!nbt.isEmpty()) { - CompressedStreamTools.safeWrite(nbt, new File(folder, - String.format("%d_%d.nbt", cell.getRowKey(), cell.getColumnKey()))); - } - } catch (IOException e) { - GTLog.logger.error("error while saving local nbt for {}", getRegistryName(), e); - } - } - } - }).start(); - } - - @Override - public NBTTagCompound closeApp() { - saveLocalConfig(nbt -> { - nbt.setBoolean("dark", this.widgetProspectingMap.getDarkMode()); - }); - if (isClient) savePacketLocalConfig(); - return super.closeApp(); - } - - @Override - public int getMaxTier() { - return 4; - } - - @Override - public List getMenuComponents() { - ClickComponent darkMode = new ClickComponent().setIcon(GuiTextures.ICON_VISIBLE) - .setHoverText("terminal.prospector.vis_mode").setClickConsumer(cd -> { - if (cd.isClient) { - widgetProspectingMap.setDarkMode(!widgetProspectingMap.getDarkMode()); - background.setColor(this.widgetProspectingMap.getDarkMode() ? 0xA0000000 : 0xA0ffffff); - } - }); - return Arrays.asList(darkMode, new SearchComponent<>(this)); - } - - @Override - public String resultDisplay(String result) { - if (widgetOreList != null) { - return widgetOreList.ores.get(result); - } - return ""; - } - - @Override - public void selectResult(String result) { - if (widgetOreList != null) { - widgetOreList.setSelected(result); - } - } - - @Override - public void search(String word, Consumer find) { - if (widgetOreList != null) { - word = word.toLowerCase(); - for (Map.Entry entry : widgetOreList.ores.entrySet()) { - if (entry.getKey().toLowerCase().contains(word) || entry.getValue().toLowerCase().contains(word)) { - find.accept(entry.getKey()); - } - } - } - } -} diff --git a/src/main/java/gregtech/common/terminal/app/recipechart/FluidStackHelper.java b/src/main/java/gregtech/common/terminal/app/recipechart/FluidStackHelper.java deleted file mode 100644 index e55f040f585..00000000000 --- a/src/main/java/gregtech/common/terminal/app/recipechart/FluidStackHelper.java +++ /dev/null @@ -1,61 +0,0 @@ -package gregtech.common.terminal.app.recipechart; - -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.TankWidget; -import gregtech.api.terminal.os.TerminalTheme; - -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTank; - -public class FluidStackHelper implements IngredientHelper { - - public static final FluidStackHelper INSTANCE = new FluidStackHelper(); - - @Override - public byte getTypeId() { - return 2; - } - - @Override - public int getAmount(FluidStack fluidStack) { - return fluidStack.amount; - } - - @Override - public void setAmount(FluidStack fluidStack, int amount) { - fluidStack.amount = amount; - } - - @Override - public boolean areEqual(FluidStack t1, FluidStack t2) { - return t1 != null && t1.isFluidEqual(t2); - } - - @Override - public boolean isEmpty(FluidStack fluidStack) { - return fluidStack.getFluid() == null || fluidStack.amount <= 0; - } - - @Override - public String getDisplayName(FluidStack fluidStack) { - return fluidStack.getLocalizedName(); - } - - @Override - public Widget createWidget(FluidStack fluidStack) { - FluidTank tank = new FluidTank(fluidStack, Integer.MAX_VALUE); - return new TankWidget(tank, 0, 0, 18, 18).setAlwaysShowFull(true).setBackgroundTexture(TerminalTheme.COLOR_B_2) - .setClient(); - } - - @Override - public FluidStack deserialize(NBTTagCompound nbt) { - return FluidStack.loadFluidStackFromNBT(nbt); - } - - @Override - public NBTTagCompound serialize(FluidStack fluidStack) { - return fluidStack.writeToNBT(new NBTTagCompound()); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/recipechart/IngredientHelper.java b/src/main/java/gregtech/common/terminal/app/recipechart/IngredientHelper.java deleted file mode 100644 index 74d5fcbf5a1..00000000000 --- a/src/main/java/gregtech/common/terminal/app/recipechart/IngredientHelper.java +++ /dev/null @@ -1,49 +0,0 @@ -package gregtech.common.terminal.app.recipechart; - -import gregtech.api.gui.Widget; - -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.fluids.FluidStack; - -import java.util.Objects; - -public interface IngredientHelper { - - static IngredientHelper getFor(Object o) { - Objects.requireNonNull(o); - if (o.getClass() == ItemStack.class) { - return (IngredientHelper) ItemStackHelper.INSTANCE; - } - if (o.getClass() == FluidStack.class) { - return (IngredientHelper) FluidStackHelper.INSTANCE; - } - throw new IllegalArgumentException(); - } - - static IngredientHelper getForTypeId(int type) { - return switch (type) { - case 1 -> ItemStackHelper.INSTANCE; - case 2 -> FluidStackHelper.INSTANCE; - default -> throw new IllegalArgumentException(); - }; - } - - byte getTypeId(); - - int getAmount(T t); - - void setAmount(T t, int amount); - - boolean areEqual(T t1, T t2); - - boolean isEmpty(T t); - - String getDisplayName(T t); - - Widget createWidget(T t); - - T deserialize(NBTTagCompound nbt); - - NBTTagCompound serialize(T t); -} diff --git a/src/main/java/gregtech/common/terminal/app/recipechart/ItemStackHelper.java b/src/main/java/gregtech/common/terminal/app/recipechart/ItemStackHelper.java deleted file mode 100644 index 268f6799226..00000000000 --- a/src/main/java/gregtech/common/terminal/app/recipechart/ItemStackHelper.java +++ /dev/null @@ -1,62 +0,0 @@ -package gregtech.common.terminal.app.recipechart; - -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.SlotWidget; -import gregtech.api.terminal.os.TerminalTheme; - -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.items.ItemHandlerHelper; -import net.minecraftforge.items.ItemStackHandler; - -public class ItemStackHelper implements IngredientHelper { - - public static final ItemStackHelper INSTANCE = new ItemStackHelper(); - - @Override - public byte getTypeId() { - return 1; - } - - @Override - public int getAmount(ItemStack t) { - return t.getCount(); - } - - @Override - public void setAmount(ItemStack t, int amount) { - t.setCount(amount); - } - - @Override - public boolean areEqual(ItemStack t1, ItemStack t2) { - return ItemHandlerHelper.canItemStacksStack(t1, t2); - } - - @Override - public boolean isEmpty(ItemStack stack) { - return stack.isEmpty(); - } - - @Override - public String getDisplayName(ItemStack stack) { - return stack.getDisplayName(); - } - - @Override - public Widget createWidget(ItemStack stack) { - ItemStackHandler handler = new ItemStackHandler(1); - handler.setStackInSlot(0, stack); - return new SlotWidget(handler, 0, 0, 0, false, false).setBackgroundTexture(TerminalTheme.COLOR_B_2); - } - - @Override - public ItemStack deserialize(NBTTagCompound nbt) { - return new ItemStack(nbt); - } - - @Override - public NBTTagCompound serialize(ItemStack stack) { - return stack.serializeNBT(); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/recipechart/RecipeChartApp.java b/src/main/java/gregtech/common/terminal/app/recipechart/RecipeChartApp.java deleted file mode 100644 index e4abbcd2497..00000000000 --- a/src/main/java/gregtech/common/terminal/app/recipechart/RecipeChartApp.java +++ /dev/null @@ -1,238 +0,0 @@ -package gregtech.common.terminal.app.recipechart; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.Widget; -import gregtech.api.gui.impl.ModularUIContainer; -import gregtech.api.gui.ingredient.IRecipeTransferHandlerWidget; -import gregtech.api.gui.resources.TextTexture; -import gregtech.api.gui.widgets.TabGroup; -import gregtech.api.gui.widgets.tab.IGuiTextureTabInfo; -import gregtech.api.gui.widgets.tab.ITabInfo; -import gregtech.api.terminal.TerminalRegistry; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.gui.CustomTabListRenderer; -import gregtech.api.terminal.os.TerminalDialogWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.terminal.os.menu.IMenuComponent; -import gregtech.api.util.Size; -import gregtech.common.terminal.app.recipechart.widget.RGContainer; -import gregtech.common.terminal.app.recipechart.widget.RGNode; -import gregtech.common.terminal.component.ClickComponent; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.nbt.CompressedStreamTools; -import net.minecraft.nbt.NBTBase; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraftforge.common.util.Constants; - -import mezz.jei.api.gui.IRecipeLayout; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -public class RecipeChartApp extends AbstractApplication implements IRecipeTransferHandlerWidget { - - private TabGroup tabGroup; - - public RecipeChartApp() { - super("recipe_chart"); - } - - @Override - public int getThemeColor() { - return 0xff008001; - } - - @Override - public AbstractApplication initApp() { - if (isClient) { - this.tabGroup = new TabGroup<>(0, 10, new CustomTabListRenderer(TerminalTheme.COLOR_F_2, - TerminalTheme.COLOR_B_3, 333 / getMaxPages(), 10)); - this.tabGroup.setOnTabChanged(this::onPagesChanged); - this.addWidget(this.tabGroup); - loadLocalConfig(nbt -> { - if (nbt == null || nbt.isEmpty()) { - this.addTab("default"); - } else { - for (NBTBase l : nbt.getTagList("list", Constants.NBT.TAG_COMPOUND)) { - NBTTagCompound container = (NBTTagCompound) l; - this.addTab(container.getString("name")).loadFromNBT((NBTTagCompound) container.getTag("data")); - } - tabGroup.setSelectedTab(nbt.getInteger("focus")); - } - }); - } - return this; - } - - private void onPagesChanged(int oldPage, int newPage) { - ITabInfo tabInfo = tabGroup.getTabInfo(newPage); - if (tabInfo instanceof IGuiTextureTabInfo && ((IGuiTextureTabInfo) tabInfo).texture instanceof TextTexture) { - ((TextTexture) ((IGuiTextureTabInfo) tabInfo).texture).setType(TextTexture.TextType.ROLL); - } - tabInfo = tabGroup.getTabInfo(oldPage); - if (tabInfo instanceof IGuiTextureTabInfo && ((IGuiTextureTabInfo) tabInfo).texture instanceof TextTexture) { - ((TextTexture) ((IGuiTextureTabInfo) tabInfo).texture).setType(TextTexture.TextType.HIDE); - } - } - - private RGContainer addTab(String name) { - name = name.isEmpty() ? "default" : name; - RGContainer container = new RGContainer(0, 0, 333, 222, getOs()); - container.setBackground(TerminalTheme.COLOR_B_3); - tabGroup.addTab(new IGuiTextureTabInfo(new TextTexture(name, -1).setWidth(333 / getMaxPages() - 5) - .setType(tabGroup.getAllTag().isEmpty() ? TextTexture.TextType.ROLL : TextTexture.TextType.HIDE), name), - container); - return container; - } - - public int getMaxPages() { - return getAppTier() + 5; - } - - @Override - public List getMenuComponents() { - ClickComponent newPage = new ClickComponent().setIcon(GuiTextures.ICON_NEW_PAGE) - .setHoverText("terminal.component.new_page").setClickConsumer(cd -> { - if (tabGroup == null) return; - if (tabGroup.getAllTag().size() < getMaxPages()) { - TerminalDialogWidget - .showTextFieldDialog(getOs(), "terminal.component.page_name", s -> true, s -> { - if (s != null) { - addTab(s); - } - }).setClientSide().open(); - } else { - TerminalDialogWidget - .showInfoDialog(getOs(), "terminal.component.warning", "terminal.recipe_chart.limit") - .setClientSide().open(); - } - }); - ClickComponent deletePage = new ClickComponent().setIcon(GuiTextures.ICON_REMOVE) - .setHoverText("terminal.recipe_chart.delete").setClickConsumer(cd -> { - if (tabGroup == null) return; - if (tabGroup.getAllTag().size() > 1) { - TerminalDialogWidget.showConfirmDialog(getOs(), "terminal.recipe_chart.delete", - "terminal.component.confirm", r -> { - if (r) { - tabGroup.removeTab(tabGroup.getAllTag().indexOf(tabGroup.getCurrentTag())); - } - }).setClientSide().open(); - } else { - TerminalDialogWidget - .showInfoDialog(getOs(), "terminal.component.warning", "terminal.recipe_chart.limit") - .setClientSide().open(); - } - }); - ClickComponent addSlot = new ClickComponent().setIcon(GuiTextures.ICON_ADD) - .setHoverText("terminal.recipe_chart.add_slot").setClickConsumer(cd -> { - if (tabGroup == null) return; - if (tabGroup.getCurrentTag() != null) { - tabGroup.getCurrentTag().addNode(50, 100); - } - }); - ClickComponent importPage = new ClickComponent().setIcon(GuiTextures.ICON_LOAD) - .setHoverText("terminal.component.load_file").setClickConsumer(cd -> { - if (tabGroup == null) return; - if (tabGroup.getAllTag().size() < getMaxPages()) { - File file = new File(TerminalRegistry.TERMINAL_PATH, "recipe_chart"); - TerminalDialogWidget - .showFileDialog(getOs(), "terminal.component.load_file", file, true, result -> { - if (result != null && result.isFile()) { - try { - NBTTagCompound nbt = CompressedStreamTools.read(result); - addTab(result.getName()).loadFromNBT(nbt); - } catch (IOException e) { - TerminalDialogWidget - .showInfoDialog(getOs(), "terminal.component.error", - "terminal.component.load_file.error") - .setClientSide().open(); - } - } - }).setClientSide().open(); - } else { - TerminalDialogWidget - .showInfoDialog(getOs(), "terminal.component.warning", "terminal.recipe_chart.limit") - .setClientSide().open(); - } - }); - ClickComponent exportPage = new ClickComponent().setIcon(GuiTextures.ICON_SAVE) - .setHoverText("terminal.component.save_file").setClickConsumer(cd -> { - if (tabGroup == null) return; - if (tabGroup.getCurrentTag() != null) { - File file = new File(TerminalRegistry.TERMINAL_PATH, "recipe_chart"); - TerminalDialogWidget - .showFileDialog(getOs(), "terminal.component.save_file", file, false, result -> { - if (result != null) { - try { - CompressedStreamTools.safeWrite(tabGroup.getCurrentTag().saveAsNBT(), - result); - } catch (IOException e) { - TerminalDialogWidget - .showInfoDialog(getOs(), "terminal.component.error", - "terminal.component.save_file.error") - .setClientSide().open(); - } - } - }).setClientSide().open(); - } - }); - return Arrays.asList(newPage, deletePage, addSlot, importPage, exportPage); - } - - @Override - public NBTTagCompound closeApp() { // synced data to server side. - saveLocalConfig(nbt -> { - NBTTagList list = new NBTTagList(); - for (int i = 0; i < tabGroup.getAllTag().size(); i++) { - IGuiTextureTabInfo tabInfo = (IGuiTextureTabInfo) tabGroup.getTabInfo(i); - NBTTagCompound container = new NBTTagCompound(); - container.setString("name", tabInfo.nameLocale); - container.setTag("data", tabGroup.getTabWidget(i).saveAsNBT()); - list.appendTag(container); - } - nbt.setTag("list", list); - nbt.setInteger("focus", tabGroup.getAllTag().indexOf(tabGroup.getCurrentTag())); - }); - return super.closeApp(); - } - - @Override - public boolean isClientSideApp() { - return true; - } - - @Override - public String transferRecipe(ModularUIContainer container, IRecipeLayout recipeLayout, EntityPlayer player, - boolean maxTransfer, boolean doTransfer) { - for (Widget widget : getContainedWidgets(false)) { - if (widget instanceof RGNode && - ((RGNode) widget).transferRecipe(container, recipeLayout, player, maxTransfer, doTransfer)) { - return null; - } - } - return "please select a node."; - } - - @Override - public int getMaxTier() { - return 3; - } - - @Override - public void onOSSizeUpdate(int width, int height) { - this.setSize(new Size(width, height)); - if (tabGroup != null) { - Size size = new Size(width, height - 10); - for (Widget widget : tabGroup.widgets) { - if (widget instanceof RGContainer) { - widget.setSize(size); - } - } - tabGroup.setSize(size); - } - } -} diff --git a/src/main/java/gregtech/common/terminal/app/recipechart/widget/PhantomWidget.java b/src/main/java/gregtech/common/terminal/app/recipechart/widget/PhantomWidget.java deleted file mode 100644 index 280722e7dbc..00000000000 --- a/src/main/java/gregtech/common/terminal/app/recipechart/widget/PhantomWidget.java +++ /dev/null @@ -1,148 +0,0 @@ -package gregtech.common.terminal.app.recipechart.widget; - -import gregtech.api.gui.Widget; -import gregtech.api.gui.ingredient.IGhostIngredientTarget; -import gregtech.api.gui.widgets.PhantomFluidWidget; -import gregtech.api.gui.widgets.PhantomSlotWidget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.common.inventory.handlers.SingleItemStackHandler; - -import net.minecraft.item.ItemStack; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.capability.CapabilityFluidHandler; -import net.minecraftforge.fluids.capability.IFluidHandler; -import net.minecraftforge.items.IItemHandlerModifiable; - -import mezz.jei.api.gui.IGhostIngredientHandler; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.function.Consumer; - -public class PhantomWidget extends WidgetGroup implements IGhostIngredientTarget { - - private final IItemHandlerModifiable itemHandler; - private FluidStack fluidStack; - private PhantomFluidWidget fluidWidget; - private PhantomSlotWidget slotWidget; - private Consumer onChanged; - - public PhantomWidget(int x, int y, Object defaultObj) { - super(x, y, 18, 18); - itemHandler = new SingleItemStackHandler(1); - fluidStack = null; - fluidWidget = new PhantomFluidWidget(0, 0, 18, 18, null, null) - .setFluidStackUpdater(fluid -> { - fluidStack = fluid.copy(); - if (fluidStack != null && fluidStack.amount > 0) { - itemHandler.setStackInSlot(0, ItemStack.EMPTY); - slotWidget.setVisible(false); - fluidWidget.setVisible(true); - if (onChanged != null) { - onChanged.accept(fluidStack); - } - } - }, true).setBackgroundTexture(TerminalTheme.COLOR_B_2).showTip(true) - .setFluidStackSupplier(() -> fluidStack, true); - slotWidget = new PhantomSlotWidget(itemHandler, 0, 0, 0) { - - @Override - public boolean isEnabled() { - return isActive(); - } - }; - slotWidget.setChangeListener(() -> { - if (!itemHandler.getStackInSlot(0).isEmpty()) { - fluidStack = null; - fluidWidget.setVisible(false); - slotWidget.setVisible(true); - if (onChanged != null) { - onChanged.accept(itemHandler.getStackInSlot(0)); - } - } - }).setBackgroundTexture(TerminalTheme.COLOR_B_2); - this.addWidget(fluidWidget); - this.addWidget(slotWidget); - - if (defaultObj instanceof ItemStack) { - itemHandler.setStackInSlot(0, (ItemStack) defaultObj); - fluidWidget.setVisible(false); - slotWidget.setVisible(true); - } else if (defaultObj instanceof FluidStack) { - fluidStack = (FluidStack) defaultObj; - slotWidget.setVisible(false); - fluidWidget.setVisible(true); - } - } - - public PhantomWidget setChangeListener(Consumer onChanged) { - this.onChanged = onChanged; - return this; - } - - public void setObject(FluidStack fluid) { - if (fluid != null) { - fluidStack = fluid.copy(); - if (fluidStack != null && fluidStack.amount > 0) { - itemHandler.setStackInSlot(0, ItemStack.EMPTY); - slotWidget.setVisible(false); - fluidWidget.setVisible(true); - if (onChanged != null) { - onChanged.accept(fluidStack); - } - } - } - } - - public void setObject(ItemStack item) { - if (item != null && !item.isEmpty()) { - ItemStack copy = item.copy(); - copy.setCount(1); - itemHandler.setStackInSlot(0, copy); - fluidStack = null; - fluidWidget.setVisible(false); - slotWidget.setVisible(true); - if (onChanged != null) { - onChanged.accept(copy); - } - } - } - - @Override - public List> getPhantomTargets(Object ingredient) { - if (!isVisible()) { - return Collections.emptyList(); - } - ArrayList> targets = new ArrayList<>(); - for (Widget widget : widgets) { - if (widget instanceof IGhostIngredientTarget) { - targets.addAll(((IGhostIngredientTarget) widget).getPhantomTargets(ingredient)); - } - } - return targets; - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (isMouseOverElement(mouseX, mouseY)) { - ItemStack itemStack = gui.entityPlayer.inventory.getItemStack(); - if (!itemStack.isEmpty()) { - IFluidHandler handlerItem = itemStack - .getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null); - if (handlerItem != null && handlerItem.getTankProperties().length > 0) { - FluidStack fluidStack = handlerItem.getTankProperties()[0].getContents(); - if (fluidStack != null) { - this.setObject(fluidStack); - return true; - } - } - this.setObject(itemStack); - return true; - } - return true; - } - return super.mouseClicked(mouseX, mouseY, button); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/recipechart/widget/RGContainer.java b/src/main/java/gregtech/common/terminal/app/recipechart/widget/RGContainer.java deleted file mode 100644 index b6988b8e0a6..00000000000 --- a/src/main/java/gregtech/common/terminal/app/recipechart/widget/RGContainer.java +++ /dev/null @@ -1,207 +0,0 @@ -package gregtech.common.terminal.app.recipechart.widget; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.terminal.gui.widgets.DraggableScrollableWidgetGroup; -import gregtech.api.terminal.os.TerminalDialogWidget; -import gregtech.api.terminal.os.TerminalOSWidget; -import gregtech.api.terminal.os.TerminalTheme; - -import net.minecraft.nbt.NBTBase; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraftforge.common.util.Constants; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; - -public class RGContainer extends DraggableScrollableWidgetGroup { - - protected TerminalOSWidget os; - private RGNode selectedNode; - private RGLine selectedLine; - protected final List nodes; - protected final List lines; - - public RGContainer(int x, int y, int width, int height, TerminalOSWidget os) { - super(x, y, width, height); - this.os = os; - this.setDraggable(true); - this.setXScrollBarHeight(4); - this.setYScrollBarWidth(4); - this.setXBarStyle(null, TerminalTheme.COLOR_F_1); - this.setYBarStyle(null, TerminalTheme.COLOR_F_1); - nodes = new ArrayList<>(); - lines = new ArrayList<>(); - } - - public RGNode getSelectedNode() { - return selectedNode; - } - - public void setSelectedNode(RGNode selectedNode) { - if (this.selectedNode != null) { - this.selectedNode.updateSelected(false); - } - this.selectedNode = selectedNode; - if (this.selectedNode != null) { - this.selectedNode.updateSelected(true); - } - } - - public RGLine getSelectedLine() { - return selectedLine; - } - - public void setSelectedLine(RGLine selectedLine) { - if (this.selectedLine != null) { - this.selectedLine.updateSelected(false); - } - this.selectedLine = selectedLine; - if (this.selectedLine != null) { - this.selectedLine.updateSelected(true); - } - } - - public RGNode addNode(int x, int y) { - RGNode node = new RGNode(x + getScrollXOffset(), y + getScrollYOffset(), this, null, true); - nodes.add(node); - this.addWidget(node); - return node; - } - - public RGNode addNode(int x, int y, Object object) { - RGNode node = new RGNode(x + getScrollXOffset(), y + getScrollYOffset(), this, object, false); - nodes.add(node); - this.addWidget(node); - return node; - } - - public void removeNode(RGNode node) { - nodes.remove(node); - this.waitToRemoved(node); - } - - public void addOrUpdateLine(RGNode parent, RGNode child) { - Optional optional = lines.stream() - .filter(line -> line.getParent() == parent && line.getChild() == child).findFirst(); - if (!optional.isPresent()) { - RGLine line = new RGLine(parent, child, this); - lines.add(line); - this.addWidget(0, line); - } else { - optional.get().updateLine(); - } - } - - public RGLine getLine(RGNode parent, RGNode child) { - Optional optional = lines.stream() - .filter(line -> line.getParent() == parent && line.getChild() == child).findFirst(); - return optional.orElse(null); - } - - public void removeLine(RGNode parent, RGNode child) { - lines.removeIf(line -> { - if (line.getParent() == parent && line.getChild() == child) { - RGContainer.this.waitToRemoved(line); - return true; - } - return false; - }); - } - - public void loadFromNBT(NBTTagCompound nbt) { - try { - this.clearAllWidgets(); - this.nodes.clear(); - this.lines.clear(); - NBTTagList nodesList = nbt.getTagList("nodes", Constants.NBT.TAG_COMPOUND); - for (NBTBase node : nodesList) { // build nodes - nodes.add(RGNode.deserializeNodeNBT((NBTTagCompound) node, this)); - } - Iterator iterator = nodesList.iterator(); // build relations - for (RGNode node : nodes) { - NBTTagCompound nodeTag = (NBTTagCompound) iterator.next(); - node.deserializeRelationNBT(nodeTag.getTagList("parents", Constants.NBT.TAG_INT_ARRAY), - nodeTag.getTagList("children", Constants.NBT.TAG_INT_ARRAY)); - this.addWidget(node); - } - for (RGLine line : lines) { - removeWidget(line); - } - lines.clear(); - NBTTagList linesList = nbt.getTagList("lines", Constants.NBT.TAG_COMPOUND); - for (NBTBase node : linesList) { // build nodes - RGLine line = RGLine.deserializeLineNBT((NBTTagCompound) node, this); - lines.add(line); - this.addWidget(0, line); - } - } catch (Exception e) { - TerminalDialogWidget.showInfoDialog(os, "ERROR", e.getMessage()).setClientSide().open(); - } - } - - public NBTTagCompound saveAsNBT() { - NBTTagCompound nbt = new NBTTagCompound(); - NBTTagList nodesTag = new NBTTagList(); - for (RGNode node : nodes) { - nodesTag.appendTag(node.serializeNodeNBT()); - } - nbt.setTag("nodes", nodesTag); - NBTTagList linesTag = new NBTTagList(); - for (RGLine line : lines) { - linesTag.appendTag(line.serializeLineNBT()); - } - nbt.setTag("lines", linesTag); - return nbt; - } - - @Override - protected int getMaxHeight() { - return super.getMaxHeight() + 20; - } - - @Override - protected int getMaxWidth() { - return super.getMaxWidth() + 20; - } - - @Override - protected boolean hookDrawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - if (draggedWidget != null && draggedWidget == selectedNode) { - for (RGNode node : nodes) { - if (node != selectedNode && node.canMerge(selectedNode)) { - drawBorder(node.getPosition().x, node.getPosition().y, 18, 18, 0XFF0000FF, 2); - break; - } - } - } - return super.hookDrawInBackground(mouseX, mouseY, partialTicks, context); - } - - @Override - public boolean mouseReleased(int mouseX, int mouseY, int button) { - if (draggedWidget != null && draggedWidget == selectedNode) { - for (RGNode node : nodes) { - if (node != selectedNode && node.canMerge(selectedNode)) { - node.mergeNode(selectedNode); - break; - } - } - } - return super.mouseReleased(mouseX, mouseY, button); - } - - @Override - public boolean mouseWheelMove(int mouseX, int mouseY, int wheelDelta) { - for (int i = widgets.size() - 1; i >= 0; i--) { - Widget widget = widgets.get(i); - if (widget.isVisible() && widget.isActive() && widget.mouseWheelMove(mouseX, mouseY, wheelDelta)) { - return true; - } - } - return false; - } -} diff --git a/src/main/java/gregtech/common/terminal/app/recipechart/widget/RGLine.java b/src/main/java/gregtech/common/terminal/app/recipechart/widget/RGLine.java deleted file mode 100644 index 4fca6a6ea70..00000000000 --- a/src/main/java/gregtech/common/terminal/app/recipechart/widget/RGLine.java +++ /dev/null @@ -1,225 +0,0 @@ -package gregtech.common.terminal.app.recipechart.widget; - -import gregtech.api.GTValues; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.SimpleTextWidget; -import gregtech.api.gui.widgets.SlotWidget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.metatileentity.SimpleMachineMetaTileEntity; -import gregtech.api.terminal.gui.widgets.CircleButtonWidget; -import gregtech.api.terminal.os.TerminalDialogWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.util.GTUtility; -import gregtech.api.util.Position; -import gregtech.api.util.Size; - -import net.minecraft.client.resources.I18n; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.math.Vec2f; -import net.minecraftforge.items.ItemStackHandler; - -import java.util.ArrayList; -import java.util.List; - -public class RGLine extends WidgetGroup { - - protected final RGNode parent; - protected final RGNode child; - protected final ItemStack catalyst; - protected int ratio; - private boolean isSelected; - private final List points; - private final RGContainer container; - private final WidgetGroup infoGroup; - private final WidgetGroup toolGroup; - - public RGLine(RGNode parent, RGNode child, RGContainer container) { - super(0, 0, 0, 0); - this.parent = parent; - this.child = child; - this.container = container; - this.points = new ArrayList<>(); - this.catalyst = parent.catalyst; - - infoGroup = new WidgetGroup(0, 0, 0, 0); - if (catalyst != null) { - ItemStackHandler handler = new ItemStackHandler(); - handler.setStackInSlot(0, catalyst); - infoGroup.addWidget( - new SlotWidget(handler, 0, 0, 0, false, false).setBackgroundTexture(new ColorRectTexture(0))); - MetaTileEntity mte = GTUtility.getMetaTileEntity(catalyst); - if (mte instanceof SimpleMachineMetaTileEntity) { - infoGroup.addWidget(new LabelWidget(9, -10, - I18n.format("terminal.recipe_chart.tier") + - GTValues.VN[((SimpleMachineMetaTileEntity) mte).getTier()], - -1).setXCentered(true).setShadow(true)); - } - } - - infoGroup.setVisible(false); - infoGroup.setActive(false); - this.addWidget(infoGroup); - - toolGroup = new WidgetGroup(0, 0, 0, 0); - toolGroup.addWidget(new CircleButtonWidget(-8, 0, 8, 1, 12) - .setColors(0, TerminalTheme.COLOR_7.getColor(), 0) - .setIcon(GuiTextures.ICON_VISIBLE) - .setHoverText("terminal.recipe_chart.visible") - .setClickListener(cd -> { - infoGroup.setActive(!infoGroup.isActive()); - infoGroup.setVisible(!infoGroup.isVisible()); - })); - toolGroup.addWidget(new CircleButtonWidget(8, 0, 8, 1, 12) - .setColors(0, TerminalTheme.COLOR_7.getColor(), 0) - .setIcon(GuiTextures.ICON_CALCULATOR) - .setHoverText("terminal.recipe_chart.ratio") - .setClickListener(cd -> TerminalDialogWidget - .showTextFieldDialog(container.os, "terminal.recipe_chart.ratio", s -> { - try { - return Integer.parseInt(s) > 0; - } catch (Exception ignored) { - return false; - } - }, s -> { - if (s != null) { - ratio = Integer.parseInt(s); - parent.updateDemand(parent.getHeadDemand()); - } - }).setClientSide().open())); - toolGroup.addWidget(new SimpleTextWidget(0, -18, "", -1, () -> Integer.toString(ratio), true).setShadow(true)); - toolGroup.setVisible(false); - this.addWidget(toolGroup); - this.ratio = 1; - updateLine(); - } - - public static RGLine deserializeLineNBT(NBTTagCompound nbt, RGContainer container) { - RGLine line = new RGLine(container.nodes.get(nbt.getInteger("parent")), - container.nodes.get(nbt.getInteger("child")), container); - line.ratio = nbt.getInteger("ratio"); - boolean visible = nbt.getBoolean("visible"); - line.infoGroup.setVisible(visible); - line.infoGroup.setActive(visible); - return line; - } - - public NBTTagCompound serializeLineNBT() { - NBTTagCompound nbt = new NBTTagCompound(); - nbt.setInteger("parent", container.nodes.indexOf(parent)); - nbt.setInteger("child", container.nodes.indexOf(child)); - nbt.setInteger("ratio", ratio); - nbt.setBoolean("visible", infoGroup.isVisible()); - return nbt; - } - - public RGNode getParent() { - return parent; - } - - public RGNode getChild() { - return child; - } - - public List getPoints() { - return points; - } - - public ItemStack getCatalyst() { - return catalyst; - } - - public void updateSelected(boolean isSelected) { - this.isSelected = isSelected; - toolGroup.setVisible(this.isSelected); - } - - public void updateLine() { - this.points.clear(); - Position pos1 = parent.getNodePosition(child); - Position pos2 = child.getNodePosition(null); - int x1, x2, y1, y2; - if (Math.abs(pos1.x - pos2.x) > Math.abs(pos1.y - pos2.y)) { - if (pos1.x > pos2.x) { - x1 = pos1.x; - y1 = pos1.y + 9; - x2 = pos2.x + 18; - } else { - x1 = pos1.x + 18; - y1 = pos1.y + 9; - x2 = pos2.x; - } - y2 = pos2.y + 9; - points.addAll(genBezierPoints(new Vec2f(x1, y1), new Vec2f(x2, y2), true, 0.01f)); - } else { - if (pos1.y > pos2.y) { - x1 = pos1.x + 9; - y1 = pos1.y; - y2 = pos2.y + 18; - } else { - x1 = pos1.x + 9; - y1 = pos1.y + 18; - y2 = pos2.y; - } - x2 = pos2.x + 9; - points.addAll(genBezierPoints(new Vec2f(x1, y1), new Vec2f(x2, y2), false, 0.01f)); - } - Position position = pos2.subtract(child.getSelfPosition()); - this.setSelfPosition(new Position(Math.min(x1, x2), Math.min(y1, y2)).subtract(position)); - int width = Math.abs(x1 - x2); - int height = Math.abs(y1 - y2); - this.setSize(new Size(width, height)); - this.setVisible(true); - this.setActive(true); - toolGroup.setSelfPosition(new Position((width) / 2, 0)); - infoGroup.setSelfPosition(new Position((width - 18) / 2, (height - 18) / 2)); - } - - public boolean isMouseOver(int mouseX, int mouseY) { - if (points == null || points.size() == 0) return false; - float x = points.get(0).x; - float y = points.get(0).y; - float x2 = points.get(points.size() - 1).x; - float y2 = points.get(points.size() - 1).y; - if (mouseX >= Math.min(x, x2) && mouseY >= Math.min(y, y2) && Math.max(x, x2) > mouseX && - Math.max(y, y2) > mouseY) { - for (Vec2f point : points) { - if ((mouseX - point.x) * (mouseX - point.x) + (mouseY - point.y) * (mouseY - point.y) < 4) { - return true; - } - } - } - return false; - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - if (isSelected) { - drawSolidRect(getPosition().x, getPosition().y, getSize().width, getSize().height, 0x2fffffff); - drawLines(points, 0x2fff0000, 0xffff0000, 2); - } else { - drawLines(points, 0x2fffff00, 0xff00ff00, 2); - } - Vec2f point = points.get(points.size() - 1); - drawSolidRect((int) (point.x - 1.5), (int) (point.y - 1.5), 3, 3, 0XFF00FF00); - super.drawInBackground(mouseX, mouseY, partialTicks, context); - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (super.mouseClicked(mouseX, mouseY, button)) { - return true; - } else if (isMouseOver(mouseX, mouseY)) { - if (!isSelected) { - container.setSelectedLine(this); - } - } else if (isSelected) { - container.setSelectedLine(null); - } - return false; - } -} diff --git a/src/main/java/gregtech/common/terminal/app/recipechart/widget/RGNode.java b/src/main/java/gregtech/common/terminal/app/recipechart/widget/RGNode.java deleted file mode 100644 index b8b466fb311..00000000000 --- a/src/main/java/gregtech/common/terminal/app/recipechart/widget/RGNode.java +++ /dev/null @@ -1,626 +0,0 @@ -package gregtech.common.terminal.app.recipechart.widget; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.gui.impl.ModularUIContainer; -import gregtech.api.gui.widgets.SimpleTextWidget; -import gregtech.api.gui.widgets.SlotWidget; -import gregtech.api.gui.widgets.TankWidget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.metatileentity.SimpleMachineMetaTileEntity; -import gregtech.api.recipes.Recipe; -import gregtech.api.terminal.gui.IDraggable; -import gregtech.api.terminal.gui.widgets.CircleButtonWidget; -import gregtech.api.terminal.os.TerminalDialogWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.util.GTUtility; -import gregtech.api.util.Position; -import gregtech.common.terminal.app.recipechart.IngredientHelper; -import gregtech.integration.jei.JustEnoughItemsModule; -import gregtech.integration.jei.recipe.GTRecipeWrapper; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTBase; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagIntArray; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.util.math.MathHelper; -import net.minecraftforge.common.util.Constants; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidTank; -import net.minecraftforge.fluids.capability.CapabilityFluidHandler; -import net.minecraftforge.fluids.capability.IFluidHandler; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; -import net.minecraftforge.items.ItemStackHandler; - -import mezz.jei.api.gui.IRecipeLayout; -import mezz.jei.api.recipe.IFocus; -import mezz.jei.api.recipe.IRecipeCategory; -import mezz.jei.api.recipe.IRecipeWrapper; -import mezz.jei.gui.Focus; -import mezz.jei.gui.recipes.RecipeLayout; - -import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; - -public class RGNode extends WidgetGroup implements IDraggable { - - private IngredientHelper headHelper; - protected Object head; - protected int recipePer = 1; - protected ItemStack catalyst; - private boolean isSelected; - private WidgetGroup toolGroup; - private WidgetGroup inputsGroup; - private RGContainer container; - private SimpleTextWidget textWidget; - protected Map parentNodes; - protected Map> children; - - public RGNode(int x, int y, RGContainer container, Object head, boolean isPhantom) { - super(x, y, 18, 18); - init(container); - this.head = head; - if (head != null) { - this.headHelper = IngredientHelper.getFor(head); - } - if (isPhantom) { - PhantomWidget phantom = new PhantomWidget(0, 0, head).setChangeListener(object -> { - RGNode.this.head = object; - RGNode.this.headHelper = object != null ? IngredientHelper.getFor(object) : null; - // Reset any children nodes, now that the parent has changed - for (Set childs : children.values()) { - for (RGNode child : childs) { - child.removeParent(this); - } - } - children.clear(); - - // Clear the Inputs for the replaced parent - this.inputsGroup.widgets.clear(); - - }); - this.addWidget(phantom); - toolGroup.addWidget(new CircleButtonWidget(-11, 49, 8, 1, 12) - .setColors(0, TerminalTheme.COLOR_7.getColor(), 0) - .setIcon(GuiTextures.ICON_CALCULATOR) - .setHoverText("terminal.recipe_chart.calculator") - .setClickListener(cd -> TerminalDialogWidget - .showTextFieldDialog(container.os, "terminal.recipe_chart.demand", s -> { - try { - return Integer.parseInt(s) > 0; - } catch (Exception ignored) { - return false; - } - }, s -> { - if (s != null && !s.isEmpty()) { - updateDemand(Integer.parseInt(s)); - } - }).setClientSide().open())); - toolGroup.addWidget(new CircleButtonWidget(9, 49, 8, 1, 12) - .setColors(0, TerminalTheme.COLOR_7.getColor(), 0) - .setIcon(GuiTextures.ICON_ADD) - .setHoverText("terminal.recipe_chart.add") - .setClickListener(cd -> TerminalDialogWidget - .showItemSelector(container.os, "terminal.recipe_chart.demand", false, itemStack -> true, - itemStack -> { - if (itemStack != null && !itemStack.isEmpty()) { - IFluidHandler handlerItem = itemStack.getCapability( - CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null); - if (handlerItem != null && handlerItem.getTankProperties().length > 0) { - FluidStack fluidStack = handlerItem.getTankProperties()[0] - .getContents(); - if (fluidStack != null) { - phantom.setObject(fluidStack); - return; - } - } - phantom.setObject(itemStack); - - // Reset any children nodes, now that the parent has changed - for (Set childs : children.values()) { - for (RGNode child : childs) { - child.removeParent(this); - } - } - children.clear(); - - // Clear the Inputs for the replaced parent - this.inputsGroup.widgets.clear(); - } - }) - .setClientSide().open())); - } else { - addWidget(this.headHelper.createWidget(head)); - } - } - - private void init(RGContainer container) { - this.container = container; - textWidget = new SimpleTextWidget(9, -5, "", -1, - () -> this.head != null ? this.headHelper.getDisplayName(this.head) : "terminal.recipe_chart.drag", - true).setShadow(true); - textWidget.setVisible(false); - textWidget.setActive(false); - this.addWidget(textWidget); - inputsGroup = new WidgetGroup(0, 0, 0, 0); - this.addWidget(inputsGroup); - toolGroup = new WidgetGroup(0, 0, 0, 0); - this.addWidget(toolGroup); - toolGroup.addWidget(new CircleButtonWidget(-11, 9, 8, 1, 12) - .setColors(0, TerminalTheme.COLOR_7.getColor(), TerminalTheme.COLOR_3.getColor()) - .setIcon(GuiTextures.ICON_REMOVE) - .setHoverText("terminal.guide_editor.remove") - .setClickListener(cd -> remove())); - toolGroup.addWidget(new CircleButtonWidget(-11, 29, 8, 1, 12) - .setColors(0, TerminalTheme.COLOR_7.getColor(), 0) - .setIcon(GuiTextures.ICON_VISIBLE) - .setHoverText("terminal.recipe_chart.visible") - .setClickListener(cd -> { - textWidget.setActive(!textWidget.isActive()); - textWidget.setVisible(!textWidget.isVisible()); - })); - toolGroup.addWidget(new CircleButtonWidget(9, 29, 8, 1, 12) - .setColors(0, TerminalTheme.COLOR_7.getColor(), 0) - .setIcon(GuiTextures.ICON_LOCATION) - .setHoverText("terminal.recipe_chart.jei") - .setClickListener(cd -> { - if (JustEnoughItemsModule.jeiRuntime != null && head != null && !this.headHelper.isEmpty(head)) { - JustEnoughItemsModule.jeiRuntime.getRecipesGui().show(new Focus<>(IFocus.Mode.OUTPUT, head)); - } - })); - inputsGroup.setVisible(false); - inputsGroup.setActive(false); - toolGroup.setVisible(false); - toolGroup.setActive(false); - parentNodes = new HashMap<>(); - children = new LinkedHashMap<>(); // important - } - - public int getHeadDemand() { - return this.headHelper.getAmount(this.head); - } - - public int getChildDemand(RGNode child) { - for (Map.Entry> entry : children.entrySet()) { - if (entry.getValue().contains(child)) { - int perC = 0; - if (entry.getKey() instanceof SlotWidget) { - perC = ((SlotWidget) entry.getKey()).getHandle().getStack().getCount(); - } else if (entry.getKey() instanceof TankWidget) { - perC = ((TankWidget) entry.getKey()).fluidTank.getFluidAmount(); - } - int ratioSum = entry.getValue().stream().mapToInt(it -> container.getLine(RGNode.this, it).ratio).sum(); - return MathHelper.ceil(perC * MathHelper.ceil(getHeadDemand() / (float) recipePer) * - container.getLine(RGNode.this, child).ratio / (float) ratioSum); - } - } - return 0; - } - - public boolean canMerge(RGNode node) { - if (this.headHelper == node.headHelper && this.headHelper.areEqual(this.head, node.head)) { - return checkMergeAvailable(node); - } - return false; - } - - private boolean checkMergeAvailable(RGNode node) { - Position pos1 = this.getPosition(); - Position pos2 = node.getPosition(); - return Math.abs(pos1.x - pos2.x) < 18 && Math.abs(pos1.y - pos2.y) < 18 && - !this.findAllChildren().contains(node) && - !node.findAllChildren().contains(this); - } - - public Set findAllChildren() { - Set result = new HashSet<>(); - for (Set nodes : children.values()) { - for (RGNode node : nodes) { - result.add(node); - result.addAll(node.findAllChildren()); - } - } - return result; - } - - public void mergeNode(RGNode node) { - for (RGNode parentNode : node.parentNodes.keySet()) { - for (Set value : parentNode.children.values()) { - if (value.remove(node)) { - value.add(this); - addParent(parentNode); - parentNode.updateDemand(parentNode.getHeadDemand()); - break; - } - } - } - node.remove(); - } - - public void remove() { - if (isSelected) { - container.setSelectedNode(null); - } - container.removeNode(this); - for (RGNode parentNode : parentNodes.keySet()) { - container.removeLine(parentNode, this); - parentNode.onChildRemoved(this); - } - parentNodes.clear(); - for (Set childs : children.values()) { - for (RGNode child : childs) { - child.removeParent(this); - } - } - children.clear(); - } - - public Position getNodePosition(RGNode child) { - if (child != null && isSelected) { - for (Map.Entry> nodeEntry : children.entrySet()) { - if (nodeEntry.getValue().contains(child)) { - return nodeEntry.getKey().getPosition(); - } - } - } - return this.getPosition(); - } - - public void addParent(RGNode parent) { - container.addOrUpdateLine(parent, this); - this.parentNodes.put(parent, parent.getChildDemand(this)); - updateDemand(parentNodes.values().stream().mapToInt(it -> it).sum()); - } - - public void updateDemand(int demand) { - dfsUpdateDemand(demand, new Stack<>()); - } - - private void dfsUpdateDemand(int demand, Stack updated) { - if (updated.contains(this)) return; - updated.push(this); - this.headHelper.setAmount(this.head, demand); - for (Set children : children.values()) { - for (RGNode child : children) { - child.parentNodes.put(this, this.getChildDemand(child)); - child.dfsUpdateDemand(child.parentNodes.values().stream().mapToInt(it -> it).sum(), updated); - } - } - updated.pop(); - } - - public void removeParent(RGNode parent) { - this.parentNodes.remove(parent); - if (parentNodes.size() == 0) { - for (Set childs : children.values()) { - for (RGNode child : childs) { - child.removeParent(RGNode.this); - } - } - children.clear(); - container.removeNode(this); - } else { - updateDemand(parentNodes.values().stream().mapToInt(it -> it).sum()); - } - container.removeLine(parent, this); - } - - public void onChildRemoved(RGNode child) { - for (Set childs : children.values()) { - if (childs.remove(child)) { - updateDemand(getHeadDemand()); - break; - } - } - } - - @Override - protected void onPositionUpdate() { - super.onPositionUpdate(); - for (RGNode parentNode : parentNodes.keySet()) { - container.addOrUpdateLine(parentNode, this); - } - for (Set childs : children.values()) { - for (RGNode child : childs) { - container.addOrUpdateLine(this, child); - } - } - } - - public boolean transferRecipe(ModularUIContainer x, IRecipeLayout recipeLayout, EntityPlayer player, - boolean maxTransfer, boolean doTransfer) { - if (isSelected) { - Object obj = recipeLayout.getFocus() == null ? null : recipeLayout.getFocus().getValue(); - IngredientHelper otherHelper = IngredientHelper.getFor(obj); - if (this.headHelper != otherHelper || !this.headHelper.areEqual(this.head, obj)) { - return false; - } - if (!doTransfer) return true; - RGNode.this.recipePer = 0; - - // items - List itemInputs = new ArrayList<>(); - recipeLayout.getItemStacks().getGuiIngredients().values().forEach(it -> { - if (it.isInput() && it.getDisplayedIngredient() != null) { - ItemStack input = it.getDisplayedIngredient(); - for (ItemStack itemInput : itemInputs) { - if (itemInput.isItemEqual(input)) { - itemInput.setCount(itemInput.getCount() + input.getCount()); - return; - } - } - itemInputs.add(input.copy()); - } else if (head instanceof ItemStack && !it.isInput()) { - for (ItemStack ingredient : it.getAllIngredients()) { - if (((ItemStack) head).isItemEqual(ingredient)) { - RGNode.this.recipePer += ingredient.getCount(); - break; - } - } - } - }); - - // fluids - List fluidInputs = new ArrayList<>(); - recipeLayout.getFluidStacks().getGuiIngredients().values().forEach(it -> { - if (it.isInput() && it.getDisplayedIngredient() != null) { - FluidStack input = it.getDisplayedIngredient(); - for (FluidStack fluidInput : fluidInputs) { - if (fluidInput.isFluidEqual(input)) { - fluidInput.amount += input.amount; - return; - } - } - fluidInputs.add(input.copy()); - } else if (head instanceof FluidStack && !it.isInput()) { - for (FluidStack ingredient : it.getAllIngredients()) { - if (((FluidStack) head).isFluidEqual(ingredient)) { - RGNode.this.recipePer += ingredient.amount; - break; - } - } - } - }); - // CHECK GTCE RECIPES - Recipe recipe = null; - if (recipeLayout instanceof RecipeLayout) { - IRecipeWrapper recipeWrapper = ObfuscationReflectionHelper.getPrivateValue(RecipeLayout.class, - (RecipeLayout) recipeLayout, "recipeWrapper"); - if (recipeWrapper instanceof GTRecipeWrapper) { - recipe = ((GTRecipeWrapper) recipeWrapper).getRecipe(); - } - } - IRecipeCategory category = recipeLayout.getRecipeCategory(); - List catalysts = JustEnoughItemsModule.jeiRuntime.getRecipeRegistry().getRecipeCatalysts(category); - ItemStack catalyst = null; - - if (recipe != null) { // GT - int tierRequire = GTUtility.getTierByVoltage(recipe.getEUt()); - for (Object o : catalysts) { - if (o instanceof ItemStack) { - MetaTileEntity mte = GTUtility.getMetaTileEntity((ItemStack) o); - if (mte instanceof SimpleMachineMetaTileEntity) { - if (tierRequire < ((SimpleMachineMetaTileEntity) mte).getTier()) { - catalyst = (ItemStack) o; - break; - } - } - } - } - } - - if (catalyst == null) { - for (Object o : catalysts) { - if (o instanceof ItemStack) { - catalyst = (ItemStack) o; - break; - } - } - } - setRecipe(itemInputs, fluidInputs, catalyst, Math.max(1, this.recipePer)); - return true; - } - return false; - } - - public void deserializeRelationNBT(NBTTagList parentsTag, NBTTagList childrenTag) { - for (NBTBase nbtBase : parentsTag) { - int[] nbt = ((NBTTagIntArray) nbtBase).getIntArray(); - parentNodes.put(container.nodes.get(nbt[0]), nbt[1]); - } - Iterator iterator = children.keySet().iterator(); - for (NBTBase nbtBase : childrenTag) { - int[] nbt = ((NBTTagIntArray) nbtBase).getIntArray(); - children.get(iterator.next()) - .addAll(Arrays.stream(nbt).mapToObj(it -> container.nodes.get(it)).collect(Collectors.toList())); - } - } - - public static RGNode deserializeNodeNBT(NBTTagCompound nodeTag, RGContainer container) { - byte type = nodeTag.getByte("type"); // 0-null 1-itemstack 2-fluidstack - Object head = null; - if (type != 0) { - IngredientHelper headHelper = (IngredientHelper) IngredientHelper.getForTypeId(type); - head = headHelper.deserialize(nodeTag.getCompoundTag("nbt")); - headHelper.setAmount(head, nodeTag.getInteger("count")); - } - RGNode node = new RGNode(nodeTag.getInteger("x"), nodeTag.getInteger("y"), container, head, - nodeTag.getBoolean("phantom")); - NBTTagList itemsList = nodeTag.getTagList("items", Constants.NBT.TAG_COMPOUND); - NBTTagList fluidsList = nodeTag.getTagList("fluids", Constants.NBT.TAG_COMPOUND); - List itemInputs = new LinkedList<>(); - itemsList.forEach(base -> { - if (base instanceof NBTTagCompound) { - itemInputs.add(new ItemStack((NBTTagCompound) base)); - } - }); - List fluidsInputs = new LinkedList<>(); - fluidsList.forEach(base -> { - if (base instanceof NBTTagCompound) { - fluidsInputs.add(FluidStack.loadFluidStackFromNBT((NBTTagCompound) base)); - } - }); - node.setRecipe(itemInputs, fluidsInputs, - nodeTag.hasKey("catalyst") ? new ItemStack(nodeTag.getCompoundTag("catalyst")) : null, - nodeTag.getInteger("per")); - boolean visible = nodeTag.getBoolean("visible"); - node.textWidget.setVisible(visible); - node.textWidget.setActive(visible); - return node; - } - - public NBTTagCompound serializeNodeNBT() { - // head - NBTTagCompound nbt = new NBTTagCompound(); - nbt.setInteger("x", getSelfPosition().x + container.getScrollXOffset()); - nbt.setInteger("y", getSelfPosition().y + container.getScrollYOffset()); - nbt.setByte("type", this.head == null ? 0 : this.headHelper.getTypeId()); - if (this.head != null) { - nbt.setTag("nbt", this.headHelper.serialize(this.head)); - nbt.setInteger("count", this.headHelper.getAmount(this.head)); - } - nbt.setBoolean("phantom", widgets.stream().anyMatch(it -> it instanceof PhantomWidget)); - // recipe + children - NBTTagList itemsList = new NBTTagList(); - NBTTagList fluidsList = new NBTTagList(); - NBTTagList childrenList = new NBTTagList(); - for (Map.Entry> entry : children.entrySet()) { - Widget widget = entry.getKey(); - if (widget instanceof SlotWidget) { - itemsList.appendTag(((SlotWidget) widget).getHandle().getStack().serializeNBT()); - } else if (widget instanceof TankWidget) { - fluidsList.appendTag(((TankWidget) widget).fluidTank.getFluid().writeToNBT(new NBTTagCompound())); - } else { - continue; - } - NBTTagIntArray childList = new NBTTagIntArray( - entry.getValue().stream().mapToInt(it -> container.nodes.indexOf(it)).toArray()); - childrenList.appendTag(childList); - } - nbt.setTag("items", itemsList); - nbt.setTag("fluids", fluidsList); - nbt.setTag("children", childrenList); - if (catalyst != null) { - nbt.setTag("catalyst", catalyst.serializeNBT()); - } - nbt.setInteger("per", recipePer); - // parent - NBTTagList parentsList = new NBTTagList(); - for (Map.Entry entry : parentNodes.entrySet()) { - parentsList.appendTag( - new NBTTagIntArray(new int[] { container.nodes.indexOf(entry.getKey()), entry.getValue() })); - } - nbt.setTag("parents", parentsList); - nbt.setBoolean("visible", textWidget.isVisible()); - return nbt; - } - - private void setRecipe(List itemInputs, List fluidInputs, ItemStack catalyst, - int recipePer) { - this.recipePer = recipePer; - this.catalyst = catalyst; - inputsGroup.clearAllWidgets(); - for (Set childs : children.values()) { - for (RGNode child : childs) { - child.removeParent(this); - } - } - children.clear(); - AtomicInteger y = new AtomicInteger(-20); - for (ItemStack itemInput : itemInputs) { - ItemStackHandler handler = new ItemStackHandler(1); - handler.setStackInSlot(0, itemInput); - Widget widget = new SlotWidget(handler, 0, 0, y.addAndGet(20), false, false) { - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - return RGNode.this.handleTipsSlotClick(mouseX, mouseY, this, handler.getStackInSlot(0).copy()); - } - }.setBackgroundTexture(TerminalTheme.COLOR_B_2); - inputsGroup.addWidget(widget); - children.put(widget, new HashSet<>()); - } - for (FluidStack fluidInput : fluidInputs) { - FluidTank tank = new FluidTank(fluidInput, Integer.MAX_VALUE); - Widget widget = new TankWidget(tank, 0, y.addAndGet(20), 18, 18) { - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - return RGNode.this.handleTipsSlotClick(mouseX, mouseY, this, tank.getFluid().copy()); - } - }.setAlwaysShowFull(true).setBackgroundTexture(TerminalTheme.COLOR_B_2).setClient(); - inputsGroup.addWidget(widget); - children.put(widget, new HashSet<>()); - } - inputsGroup.setSelfPosition(new Position(25, -(inputsGroup.widgets.size() * 20) / 2 + 8)); - } - - private boolean handleTipsSlotClick(int mouseX, int mouseY, Widget slot, Object object) { - if (slot.isMouseOverElement(mouseX, mouseY)) { - Position position = inputsGroup.getSelfPosition(); - RGNode child = container.addNode(RGNode.this.getSelfPosition().x + 50, - RGNode.this.getSelfPosition().y + position.y + slot.getSelfPosition().y, object); - Set childs = RGNode.this.children.get(slot); - childs.add(child); - - child.addParent(RGNode.this); - RGNode.this.updateDemand(RGNode.this.getHeadDemand()); - return true; - } - return false; - } - - public void updateSelected(boolean selected) { - isSelected = selected; - if (selected) { - toolGroup.setActive(true); - toolGroup.setVisible(true); - inputsGroup.setActive(true); - inputsGroup.setVisible(true); - } else { - toolGroup.setActive(false); - toolGroup.setVisible(false); - inputsGroup.setActive(false); - inputsGroup.setVisible(false); - } - children.forEach((widget, rgNode) -> rgNode.forEach(child -> container.addOrUpdateLine(RGNode.this, child))); - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - int x = getPosition().x; - int y = getPosition().y; - int width = getSize().width; - int height = getSize().height; - if (isSelected) { - drawBorder(x, y, width, height, 0xff00ff00, 2); - } - super.drawInBackground(mouseX, mouseY, partialTicks, context); - } - - @Override - public boolean allowDrag(int mouseX, int mouseY, int button) { - return isMouseOverElement(mouseX, mouseY); - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (isMouseOverElement(mouseX, mouseY)) { - if (!isSelected) { - container.setSelectedNode(this); - } - super.mouseClicked(mouseX, mouseY, button); - return false; - } else if (super.mouseClicked(mouseX, mouseY, button)) { - return true; - } else if (isSelected) { - container.setSelectedNode(null); - } - return false; - } -} diff --git a/src/main/java/gregtech/common/terminal/app/settings/SettingsApp.java b/src/main/java/gregtech/common/terminal/app/settings/SettingsApp.java deleted file mode 100644 index a04035afc07..00000000000 --- a/src/main/java/gregtech/common/terminal/app/settings/SettingsApp.java +++ /dev/null @@ -1,64 +0,0 @@ -package gregtech.common.terminal.app.settings; - -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.gui.resources.TextTexture; -import gregtech.api.gui.widgets.AbstractWidgetGroup; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.TabGroup; -import gregtech.api.gui.widgets.tab.IGuiTextureTabInfo; -import gregtech.api.gui.widgets.tab.ITabInfo; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.gui.CustomTabListRenderer; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.common.terminal.app.settings.widgets.HomeButtonSettings; -import gregtech.common.terminal.app.settings.widgets.OsSettings; -import gregtech.common.terminal.app.settings.widgets.ThemeSettings; - -public class SettingsApp extends AbstractApplication { - - private TabGroup tabGroup; - - public SettingsApp() { - super("settings"); - } - - @Override - public AbstractApplication initApp() { - if (isClient) { - this.addWidget(new ImageWidget(5, 15, 323, 212, new ColorRectTexture(TerminalTheme.COLOR_B_2.getColor()))); - this.tabGroup = new TabGroup<>(5, 15, - new CustomTabListRenderer(TerminalTheme.COLOR_B_2, TerminalTheme.COLOR_F_2, 323 / 3, 10)); - this.addWidget(this.tabGroup); - this.tabGroup.setOnTabChanged(this::onPagesChanged); - addTab("terminal.settings.theme", new ThemeSettings(getOs())); - addTab("terminal.settings.home", new HomeButtonSettings(getOs())); - addTab("terminal.settings.os", new OsSettings(getOs())); - } - return this; - } - - private void onPagesChanged(int oldPage, int newPage) { - ITabInfo tabInfo = tabGroup.getTabInfo(newPage); - if (tabInfo instanceof IGuiTextureTabInfo && ((IGuiTextureTabInfo) tabInfo).texture instanceof TextTexture) { - ((TextTexture) ((IGuiTextureTabInfo) tabInfo).texture).setType(TextTexture.TextType.ROLL); - } - tabInfo = tabGroup.getTabInfo(oldPage); - if (tabInfo instanceof IGuiTextureTabInfo && ((IGuiTextureTabInfo) tabInfo).texture instanceof TextTexture) { - ((TextTexture) ((IGuiTextureTabInfo) tabInfo).texture).setType(TextTexture.TextType.HIDE); - } - } - - private void addTab(String name, AbstractWidgetGroup widget) { - tabGroup.addTab( - new IGuiTextureTabInfo( - new TextTexture(name, -1).setWidth(323 / 3 - 5).setType( - tabGroup.getAllTag().isEmpty() ? TextTexture.TextType.ROLL : TextTexture.TextType.HIDE), - name), - widget); - } - - @Override - public boolean isClientSideApp() { - return true; - } -} diff --git a/src/main/java/gregtech/common/terminal/app/settings/widgets/HomeButtonSettings.java b/src/main/java/gregtech/common/terminal/app/settings/widgets/HomeButtonSettings.java deleted file mode 100644 index 48ab589601f..00000000000 --- a/src/main/java/gregtech/common/terminal/app/settings/widgets/HomeButtonSettings.java +++ /dev/null @@ -1,133 +0,0 @@ -package gregtech.common.terminal.app.settings.widgets; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.AbstractWidgetGroup; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.TextFieldWidget; -import gregtech.api.terminal.gui.widgets.SelectorWidget; -import gregtech.api.terminal.os.SystemCall; -import gregtech.api.terminal.os.TerminalHomeButtonWidget; -import gregtech.api.terminal.os.TerminalOSWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.util.Position; -import gregtech.api.util.Size; - -import net.minecraft.client.resources.I18n; - -import org.apache.commons.lang3.tuple.MutablePair; -import org.apache.commons.lang3.tuple.Pair; - -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -public class HomeButtonSettings extends AbstractWidgetGroup { - - final TerminalOSWidget os; - - public HomeButtonSettings(TerminalOSWidget os) { - super(Position.ORIGIN, new Size(323, 212)); - this.os = os; - List candidates = Arrays.stream(SystemCall.values()).map(SystemCall::getTranslateKey) - .collect(Collectors.toList()); - candidates.add(0, "terminal.system_call.null"); - TerminalHomeButtonWidget home = this.os.home; - this.addWidget(new LabelWidget(10, 15, "terminal.settings.home.double", -1).setYCentered(true)); - this.addWidget(new LabelWidget(50, 15, "+Ctrl", -1).setYCentered(true)); - this.addWidget(new LabelWidget(85, 15, "+Shift", -1).setYCentered(true)); - this.addWidget( - new LabelWidget(170, 15, "terminal.settings.home.action", -1).setXCentered(true).setYCentered(true)); - this.addWidget( - new LabelWidget(270, 15, "terminal.settings.home.args", -1).setXCentered(true).setYCentered(true)); - - for (int shift = 0; shift < 2; shift++) { - for (int ctrl = 0; ctrl < 2; ctrl++) { - for (int doubleClick = 0; doubleClick < 2; doubleClick++) { - int i = TerminalHomeButtonWidget.actionMap(doubleClick == 1, ctrl == 1, shift == 1); - Pair pair = home.getActions()[i]; - int y = i * 22 + 30; - if (doubleClick == 1) { - this.addWidget(new ImageWidget(15, y + 5, 10, 10, GuiTextures.ICON_VISIBLE)); - } - if (ctrl == 1) { - this.addWidget(new ImageWidget(55, y + 5, 10, 10, GuiTextures.ICON_VISIBLE)); - } - if (shift == 1) { - this.addWidget(new ImageWidget(90, y + 5, 10, 10, GuiTextures.ICON_VISIBLE)); - } - TextFieldWidget textFieldWidget = new TextFieldWidget(230, y, 80, 20, TerminalTheme.COLOR_B_3, null, - null) - .setMaxStringLength(Integer.MAX_VALUE) - .setTextResponder(arg -> { - if (arg != null && home.getActions()[i] != null) { - home.getActions()[i].setValue(arg); - } - home.saveConfig(); - }, true) - .setValidator(s -> true); - if (pair != null && pair.getValue() != null) { - textFieldWidget.setCurrentString(pair.getValue()); - } else { - textFieldWidget.setCurrentString(""); - } - - this.addWidget(new SelectorWidget(120, y, 100, 20, candidates, -1, - () -> { - Pair _pair = home.getActions()[i]; - if (_pair != null) { - return _pair.getKey().getTranslateKey(); - } - return "terminal.system_call.null"; - }, true) - .setIsUp(i > 3) - .setHoverText(I18n - .format(doubleClick == 1 ? "terminal.settings.home.double_click" : - "terminal.settings.home.click") + - (ctrl == 1 ? "+Ctrl" : "") + (shift == 1 ? "+Shift" : "")) - .setOnChanged(selected -> { - SystemCall action = SystemCall.getFromName(selected); - if (action != null) { - if (home.getActions()[i] == null) { - home.getActions()[i] = new MutablePair<>(action, null); - } else { - home.getActions()[i] = new MutablePair<>(action, - home.getActions()[i].getValue()); - } - } else { - home.getActions()[i] = null; - } - home.saveConfig(); - }) - .setOnShowChange(isShow -> { - if (isShow) { - for (Widget widget : widgets) { - if (widget instanceof SelectorWidget) { - ((SelectorWidget) widget).hide(); - } - } - } - }) - .setColors(TerminalTheme.COLOR_B_2.getColor(), TerminalTheme.COLOR_F_1.getColor(), - TerminalTheme.COLOR_B_2.getColor()) - .setBackground(TerminalTheme.COLOR_6)); - - this.addWidget(textFieldWidget); - } - } - } - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - for (int i = widgets.size() - 1; i >= 0; i--) { - Widget widget = widgets.get(i); - if (widget.isVisible() && widget.isActive() && widget.mouseClicked(mouseX, mouseY, button)) { - mouseX = -10000; - mouseY = -10000; - } - } - return mouseX == -10000; - } -} diff --git a/src/main/java/gregtech/common/terminal/app/settings/widgets/OsSettings.java b/src/main/java/gregtech/common/terminal/app/settings/widgets/OsSettings.java deleted file mode 100644 index 1ed390a5352..00000000000 --- a/src/main/java/gregtech/common/terminal/app/settings/widgets/OsSettings.java +++ /dev/null @@ -1,72 +0,0 @@ -package gregtech.common.terminal.app.settings.widgets; - -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.gui.widgets.AbstractWidgetGroup; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.terminal.TerminalRegistry; -import gregtech.api.terminal.gui.widgets.RectButtonWidget; -import gregtech.api.terminal.os.TerminalOSWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.util.GTLog; -import gregtech.api.util.Position; -import gregtech.api.util.Size; - -import net.minecraft.nbt.CompressedStreamTools; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.fml.common.FMLCommonHandler; - -import java.io.File; -import java.io.IOException; - -public class OsSettings extends AbstractWidgetGroup { - - public static boolean DOUBLE_CHECK; - static { - if (FMLCommonHandler.instance().getSide().isClient()) { - NBTTagCompound nbt = null; - try { - nbt = CompressedStreamTools.read(new File(TerminalRegistry.TERMINAL_PATH, "config/os_settings.nbt")); - } catch (IOException e) { - GTLog.logger.error("error while loading local nbt for the os settings", e); - } - if (nbt == null) { - DOUBLE_CHECK = true; - } else { - DOUBLE_CHECK = nbt.getBoolean("double_check"); - } - } - } - final TerminalOSWidget os; - - public static void saveConfig() { - if (FMLCommonHandler.instance().getSide().isClient()) { - NBTTagCompound nbt = new NBTTagCompound(); - nbt.setBoolean("double_check", DOUBLE_CHECK); - try { - if (!nbt.isEmpty()) { - CompressedStreamTools.safeWrite(nbt, - new File(TerminalRegistry.TERMINAL_PATH, "config/os_settings.nbt")); - } - } catch (IOException e) { - GTLog.logger.error("error while saving local nbt for the os settings", e); - } - } - } - - public OsSettings(TerminalOSWidget os) { - super(Position.ORIGIN, new Size(323, 212)); - this.os = os; - this.addWidget(new LabelWidget(25, 15, "terminal.settings.os.double_check", -1).setYCentered(true)); - this.addWidget(new RectButtonWidget(10, 10, 10, 10, 2) - .setToggleButton(new ColorRectTexture(TerminalTheme.COLOR_B_2.getColor()), (c, p) -> { - DOUBLE_CHECK = !p; - saveConfig(); - }) - .setValueSupplier(true, () -> !DOUBLE_CHECK) - .setColors(TerminalTheme.COLOR_B_3.getColor(), - TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_3.getColor()) - .setIcon(new ColorRectTexture(TerminalTheme.COLOR_7.getColor())) - .setHoverText("terminal.settings.os.double_check.desc")); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/settings/widgets/ThemeSettings.java b/src/main/java/gregtech/common/terminal/app/settings/widgets/ThemeSettings.java deleted file mode 100644 index d0894a487c1..00000000000 --- a/src/main/java/gregtech/common/terminal/app/settings/widgets/ThemeSettings.java +++ /dev/null @@ -1,167 +0,0 @@ -package gregtech.common.terminal.app.settings.widgets; - -import gregtech.api.gui.resources.*; -import gregtech.api.gui.widgets.*; -import gregtech.api.terminal.TerminalRegistry; -import gregtech.api.terminal.gui.widgets.CircleButtonWidget; -import gregtech.api.terminal.gui.widgets.ColorWidget; -import gregtech.api.terminal.gui.widgets.RectButtonWidget; -import gregtech.api.terminal.gui.widgets.SelectorWidget; -import gregtech.api.terminal.os.TerminalDialogWidget; -import gregtech.api.terminal.os.TerminalOSWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.util.Position; -import gregtech.api.util.Size; - -import net.minecraft.util.ResourceLocation; - -import java.util.Arrays; -import java.util.function.Consumer; - -public class ThemeSettings extends AbstractWidgetGroup { - - private final WidgetGroup textureGroup; - final TerminalOSWidget os; - - public ThemeSettings(TerminalOSWidget os) { - super(Position.ORIGIN, new Size(323, 212)); - this.os = os; - float x = 323 * 1.0f / 13; - int y = 40; - this.addWidget(new LabelWidget(323 / 2, 10, "terminal.settings.theme.color", -1).setXCentered(true)); - this.addColorButton(TerminalTheme.COLOR_1, "COLOR_1", (int) x, y); - this.addColorButton(TerminalTheme.COLOR_2, "COLOR_2", (int) (x * 2), y); - this.addColorButton(TerminalTheme.COLOR_3, "COLOR_3", (int) (x * 3), y); - this.addColorButton(TerminalTheme.COLOR_4, "COLOR_4", (int) (x * 4), y); - this.addColorButton(TerminalTheme.COLOR_5, "COLOR_5", (int) (x * 5), y); - this.addColorButton(TerminalTheme.COLOR_6, "COLOR_6", (int) (x * 6), y); - this.addColorButton(TerminalTheme.COLOR_7, "COLOR_7", (int) (x * 7), y); - this.addColorButton(TerminalTheme.COLOR_F_1, "COLOR_F_1", (int) (x * 8), y); - this.addColorButton(TerminalTheme.COLOR_F_2, "COLOR_F_2", (int) (x * 9), y); - this.addColorButton(TerminalTheme.COLOR_B_1, "COLOR_B_1", (int) (x * 10), y); - this.addColorButton(TerminalTheme.COLOR_B_2, "COLOR_B_2", (int) (x * 11), y); - this.addColorButton(TerminalTheme.COLOR_B_3, "COLOR_B_3", (int) (x * 12), y); - this.addWidget(new LabelWidget(323 / 2, 75, "terminal.settings.theme.wallpaper", -1).setXCentered(true)); - this.addWidget(new ImageWidget((int) x, 95, 150, 105, TerminalTheme.WALL_PAPER).setBorder(2, -1)); - this.addWidget(new SelectorWidget((int) (x + 170), 95, 116, 20, - Arrays.asList( - "terminal.settings.theme.wallpaper.resource", - "terminal.settings.theme.wallpaper.url", - "terminal.settings.theme.wallpaper.color", - "terminal.settings.theme.wallpaper.file"), - -1, this::getLocalizedWallpaperTypeName, true) - .setIsUp(true) - .setOnChanged(this::onModifyTextureChanged) - .setColors(TerminalTheme.COLOR_B_2.getColor(), TerminalTheme.COLOR_F_1.getColor(), - TerminalTheme.COLOR_B_2.getColor()) - .setBackground(TerminalTheme.COLOR_6)); - textureGroup = new WidgetGroup((int) (x + 170), 122, (int) (x * 11 - 170), 65); - this.addWidget(textureGroup); - } - - private String getLocalizedWallpaperTypeName() { - switch (TerminalTheme.WALL_PAPER.getTypeName()) { - case "resource": - return "terminal.settings.theme.wallpaper.resource"; - case "url": - return "terminal.settings.theme.wallpaper.url"; - case "color": - return "terminal.settings.theme.wallpaper.color"; - case "file": - return "terminal.settings.theme.wallpaper.file"; - } - return null; - } - - private void addColorButton(ColorRectTexture texture, String name, int x, int y) { - CircleButtonWidget buttonWidget = new CircleButtonWidget(x, y, 8, 1, 0).setFill(texture.getColor()) - .setStrokeAnima(-1).setHoverText(name); - buttonWidget.setClickListener(cd -> TerminalDialogWidget.showColorDialog(os, name, color -> { - if (color != null) { - buttonWidget.setFill(color); - texture.setColor(color); - if (!TerminalTheme.saveConfig()) { - TerminalDialogWidget - .showInfoDialog(os, "terminal.component.error", "terminal.component.save_file.error") - .setClientSide().open(); - } - } - }, texture.color).setClientSide().open()); - addWidget(buttonWidget); - } - - private void onModifyTextureChanged(String type) { - textureGroup.clearAllWidgets(); - switch (type) { - case "terminal.settings.theme.wallpaper.resource": - if (!(TerminalTheme.WALL_PAPER.getTexture() instanceof TextureArea)) { - TerminalTheme.WALL_PAPER.setTexture(new TextureArea( - new ResourceLocation("gregtech:textures/gui/terminal/terminal_background.png"), 0.0, 0.0, - 1.0, 1.0)); - TerminalTheme.saveConfig(); - } - addStringSetting(((TextureArea) TerminalTheme.WALL_PAPER.getTexture()).imageLocation.toString(), - s -> { - TerminalTheme.WALL_PAPER - .setTexture(new TextureArea(new ResourceLocation(s), 0.0, 0.0, 1.0, 1.0)); - TerminalTheme.saveConfig(); - }); - break; - case "terminal.settings.theme.wallpaper.url": - if (!(TerminalTheme.WALL_PAPER.getTexture() instanceof URLTexture)) { - TerminalTheme.WALL_PAPER.setTexture(new URLTexture(null)); - TerminalTheme.saveConfig(); - } - addStringSetting(((URLTexture) TerminalTheme.WALL_PAPER.getTexture()).url, s -> { - TerminalTheme.WALL_PAPER.setTexture(new URLTexture(s)); - TerminalTheme.saveConfig(); - }); - break; - case "terminal.settings.theme.wallpaper.color": - ColorRectTexture texture; - if (!(TerminalTheme.WALL_PAPER.getTexture() instanceof ColorRectTexture)) { - texture = new ColorRectTexture(-1); - TerminalTheme.WALL_PAPER.setTexture(texture); - TerminalTheme.saveConfig(); - } else { - texture = (ColorRectTexture) TerminalTheme.WALL_PAPER.getTexture(); - } - textureGroup.addWidget(new ColorWidget(0, 0, 80, 10) - .setColorSupplier(texture::getColor, true) - .setOnColorChanged(texture::setColor)); - break; - case "terminal.settings.theme.wallpaper.file": - if (!(TerminalTheme.WALL_PAPER.getTexture() instanceof FileTexture)) { - TerminalTheme.WALL_PAPER.setTexture(new FileTexture(null)); - TerminalTheme.saveConfig(); - } - textureGroup.addWidget(new RectButtonWidget(0, 0, 116, 20) - .setColors(TerminalTheme.COLOR_B_1.getColor(), - TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_1.getColor()) - .setClickListener(cd -> TerminalDialogWidget.showFileDialog(os, "terminal.settings.theme.image", - TerminalRegistry.TERMINAL_PATH, true, file -> { - if (file != null && file.isFile()) { - TerminalTheme.WALL_PAPER.setTexture(new FileTexture(file)); - TerminalTheme.saveConfig(); - } - }).setClientSide().open()) - .setIcon(new TextTexture("terminal.settings.theme.select", -1))); - break; - } - } - - private void addStringSetting(String init, Consumer callback) { - TextFieldWidget textFieldWidget = new TextFieldWidget(0, 0, 76, 20, TerminalTheme.COLOR_B_2, null, null) - .setMaxStringLength(Integer.MAX_VALUE) - .setValidator(s -> true) - .setCurrentString(init == null ? "" : init); - textureGroup.addWidget(textFieldWidget); - textureGroup.addWidget(new RectButtonWidget(76, 0, 40, 20) - .setColors(TerminalTheme.COLOR_B_1.getColor(), - TerminalTheme.COLOR_1.getColor(), - TerminalTheme.COLOR_B_1.getColor()) - .setClickListener(cd -> callback.accept(textFieldWidget.getCurrentString())) - .setIcon(new TextTexture("terminal.guide_editor.update", -1))); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/teleport/TeleportApp.java b/src/main/java/gregtech/common/terminal/app/teleport/TeleportApp.java deleted file mode 100644 index 288f5f39bd2..00000000000 --- a/src/main/java/gregtech/common/terminal/app/teleport/TeleportApp.java +++ /dev/null @@ -1,118 +0,0 @@ -package gregtech.common.terminal.app.teleport; - -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.gui.widgets.*; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.os.SystemCall; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.util.TeleportHandler; -import gregtech.common.entities.PortalEntity; - -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.chunk.Chunk; - -public class TeleportApp extends AbstractApplication { - - private int coordinateX = 0; - private int coordinateY = 1; - private int coordinateZ = 0; - - private int dimension = 0; - - public TeleportApp() { - super("teleport"); - } - - @Override - public AbstractApplication initApp() { - if (nbt != null && nbt.hasKey("LastTeleport")) { - BlockPos pos = BlockPos.fromLong(nbt.getLong("LastTeleport")); - this.coordinateX = pos.getX(); - this.coordinateY = pos.getY(); - this.coordinateZ = pos.getZ(); - this.dimension = nbt.getShort("LastDim"); - } - - // background - this.addWidget(new ImageWidget(5, 5, 323, 212, new ColorRectTexture(TerminalTheme.COLOR_B_2.getColor()))); - int textFieldColor = TerminalTheme.COLOR_B_2.getColor(); - textFieldColor &= 0xFFFFFF; // remove alpha - textFieldColor |= (200 << 24); // alpha 175 - // text field backgrounds - this.addWidget(new ImageWidget(9, 104, 77, 10, new ColorRectTexture(textFieldColor))); - this.addWidget(new ImageWidget(9, 64, 77, 10, new ColorRectTexture(textFieldColor))); - this.addWidget(new ImageWidget(9, 44, 77, 10, new ColorRectTexture(textFieldColor))); - this.addWidget(new ImageWidget(9, 24, 77, 10, new ColorRectTexture(textFieldColor))); - // text field labels - this.addWidget(new LabelWidget(10, 15, "X: ", 0xFFFFFF)); - this.addWidget(new LabelWidget(10, 35, "Y: ", 0xFFFFFF)); - this.addWidget(new LabelWidget(10, 55, "Z: ", 0xFFFFFF)); - this.addWidget( - new SimpleTextWidget(10, 95, "terminal.teleporter.dimension", 0xFFFFFF, () -> "").setCenter(false)); - - this.addWidget(new TextFieldWidget2(10, 105, 75, 16, () -> String.valueOf(dimension), value -> { - if (!value.isEmpty()) { - dimension = Integer.parseInt(value); - } - }).setMaxLength(9).setNumbersOnly(Short.MIN_VALUE, Short.MAX_VALUE)); - this.addWidget(new TextFieldWidget2(10, 65, 75, 16, () -> String.valueOf(coordinateZ), value -> { - if (!value.isEmpty()) { - coordinateZ = Integer.parseInt(value); - } - }).setMaxLength(9).setNumbersOnly(-30000000, 30000000)); - this.addWidget(new TextFieldWidget2(10, 45, 75, 16, () -> String.valueOf(coordinateY), value -> { - if (!value.isEmpty()) { - coordinateY = Integer.parseInt(value); - } - }).setMaxLength(9).setNumbersOnly(1, 255)); - this.addWidget(new TextFieldWidget2(10, 25, 75, 16, () -> String.valueOf(coordinateX), value -> { - if (!value.isEmpty()) { - coordinateX = Integer.parseInt(value); - } - }).setMaxLength(9).setNumbersOnly(-30000000, 30000000)); - - this.addWidget(new ClickButtonWidget(15, 140, 65, 20, "terminal.teleporter.spawn_portal", - data -> this.spawnPortals())); - - return this; - } - - @Override - public NBTTagCompound closeApp() { - NBTTagCompound nbt = new NBTTagCompound(); - nbt.setLong("LastTeleport", new BlockPos(coordinateX, coordinateY, coordinateZ).toLong()); - nbt.setShort("LastDim", (short) dimension); - return nbt; - } - - /** - * Creates two portals, one 5 blocks in front of the player targeting the other portal, the other at the destination - * targeting the first portal - */ - public void spawnPortals() { - Vec3d position = new Vec3d( - gui.entityPlayer.getPosition().getX() + gui.entityPlayer.getLookVec().x * 5, - gui.entityPlayer.getPosition().getY(), - gui.entityPlayer.getPosition().getZ() + gui.entityPlayer.getLookVec().z * 5); - - PortalEntity portal1 = new PortalEntity(gui.entityPlayer.getEntityWorld(), position.x, position.y, position.z); - portal1.setRotation(gui.entityPlayer.rotationYaw, 0.F); - - PortalEntity portal2 = new PortalEntity(gui.entityPlayer.getEntityWorld(), coordinateX, coordinateY, - coordinateZ); - portal2.setRotation(gui.entityPlayer.rotationYaw, 0.F); - - portal1.setTargetCoordinates(dimension, coordinateX, coordinateY, coordinateZ); - portal2.setTargetCoordinates(gui.entityPlayer.dimension, position.x, position.y, position.z); - - gui.entityPlayer.getEntityWorld().spawnEntity(portal1); - Chunk destination = TeleportHandler.getWorldByDimensionID(dimension).getChunkProvider() - .provideChunk(coordinateX >> 4, coordinateZ >> 4); - TeleportHandler.getWorldByDimensionID(dimension).spawnEntity(portal2); - TeleportHandler.getWorldByDimensionID(dimension).getChunkProvider().queueUnload(destination); - - SystemCall.SHUT_DOWN.call(getOs(), isClient); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/worldprospector/WorldProspectorARApp.java b/src/main/java/gregtech/common/terminal/app/worldprospector/WorldProspectorARApp.java deleted file mode 100644 index f4b7fe6f2e1..00000000000 --- a/src/main/java/gregtech/common/terminal/app/worldprospector/WorldProspectorARApp.java +++ /dev/null @@ -1,520 +0,0 @@ -package gregtech.common.terminal.app.worldprospector; - -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.resources.ColorRectTexture; -import gregtech.api.gui.resources.ItemStackTexture; -import gregtech.api.gui.resources.ShaderTexture; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.PhantomSlotUtil; -import gregtech.api.gui.widgets.PhantomSlotWidget; -import gregtech.api.terminal.app.ARApplication; -import gregtech.api.terminal.app.AbstractApplication; -import gregtech.api.terminal.gui.widgets.CircleButtonWidget; -import gregtech.api.terminal.gui.widgets.RectButtonWidget; -import gregtech.api.terminal.os.TerminalDialogWidget; -import gregtech.api.terminal.os.TerminalTheme; -import gregtech.api.unification.OreDictUnifier; -import gregtech.api.unification.stack.MaterialStack; -import gregtech.api.util.GTLog; -import gregtech.client.shader.Shaders; -import gregtech.client.utils.DepthTextureUtil; -import gregtech.client.utils.RenderBufferHelper; -import gregtech.client.utils.TooltipHelper; -import gregtech.common.inventory.handlers.SingleItemStackHandler; -import gregtech.common.items.MetaItems; -import gregtech.common.terminal.app.worldprospector.matcher.BlockStateMatcher; -import gregtech.common.terminal.app.worldprospector.matcher.IMatcher; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockFalling; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraft.client.shader.Framebuffer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; -import net.minecraft.inventory.ClickType; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.PacketBuffer; -import net.minecraft.util.Tuple; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.World; -import net.minecraftforge.client.event.RenderWorldLastEvent; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import mezz.jei.api.gui.IGhostIngredientHandler; -import org.jetbrains.annotations.NotNull; -import org.lwjgl.input.Mouse; -import org.lwjgl.opengl.GL11; - -import java.awt.*; -import java.io.IOException; -import java.util.*; -import java.util.List; - -public class WorldProspectorARApp extends ARApplication { - - private SingleItemStackHandler[] handlers; - private int[] colors; - - public WorldProspectorARApp() { - super("world_prospector"); - } - - @Override - public AbstractApplication initApp() { - addWidget(new ImageWidget(10, 10, 313, 212, new ColorRectTexture(TerminalTheme.COLOR_B_2.getColor()))); - addWidget(new LabelWidget(15 + 150 / 2, 232 / 2, "terminal.world_prospector.radius", -1, - new Object[] { getMaxRadius() }) - .setShadow(true) - .setYCentered(true) - .setXCentered(true)); - int slotSize = (int) Math.pow(2, getAppTier()); - int x = 250 - slotSize * 12; - int y = 232 / 2 - 18; - handlers = new SingleItemStackHandler[slotSize]; - colors = new int[slotSize]; - for (int i = 0; i < slotSize; i++) { - int index = i; - Tuple stack = getSlotStack(i); - if (stack == null) { - handlers[i] = new SingleItemStackHandler(ItemStack.EMPTY); - colors[i] = 0; - } else { - handlers[i] = new SingleItemStackHandler(stack.getFirst()); - colors[i] = stack.getSecond(); - } - RectButtonWidget buttonWidget = new RectButtonWidget(x + i * 24, y + 18, 18, 18, 1); - addWidget(new PhantomSlotWidget(handlers[i], 0, x + i * 24, y) { - - @Override - public List> getPhantomTargets(Object ingredient) { - if (!(ingredient instanceof ItemStack)) { - return Collections.emptyList(); - } - Rectangle rectangle = toRectangleBox(); - return Collections.singletonList(new IGhostIngredientHandler.Target() { - - @NotNull - @Override - public Rectangle getArea() { - return rectangle; - } - - @Override - public void accept(@NotNull Object ingredient) { - if (ingredient instanceof ItemStack) { - int mouseButton = Mouse.getEventButton(); - boolean shiftDown = TooltipHelper.isShiftDown(); - ClickType clickType = shiftDown ? ClickType.QUICK_MOVE : ClickType.PICKUP; - PhantomSlotUtil.slotClickPhantom(slotReference, mouseButton, clickType, - (ItemStack) ingredient); - updateBlockSelectionAndColor((ItemStack) ingredient, index, buttonWidget); - writeClientAction(1, buffer -> { - buffer.writeItemStack((ItemStack) ingredient); - buffer.writeVarInt(mouseButton); - buffer.writeBoolean(shiftDown); - }); - } - } - }); - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (handlers[index].getStackInSlot(0).isEmpty() && isMouseOverElement(mouseX, mouseY)) { - writeClientAction(-1, buffer -> {}); - selectReference(index, buttonWidget); - return true; - } else if (isMouseOverElement(mouseX, mouseY)) { - writeClientAction(0, buffer -> {}); - updateBlockSelectionAndColor(ItemStack.EMPTY, index, buttonWidget); - } - return super.mouseClicked(mouseX, mouseY, button); - } - - @Override - public void handleClientAction(int id, PacketBuffer buffer) { - if (id == -1) { - selectReference(index, buttonWidget); - } else if (id == 0) { - updateBlockSelectionAndColor(ItemStack.EMPTY, index, buttonWidget); - } else if (id == 1) { - try { - buffer.markReaderIndex(); // just want to reset reader index, not both with .clear - ItemStack stack = buffer.readItemStack(); - updateBlockSelectionAndColor(stack, index, buttonWidget); - buffer.resetReaderIndex(); - } catch (IOException e) { - GTLog.logger.error("Could not update block selection from world prospector buffer", e); - } - super.handleClientAction(id, buffer); - } else { - super.handleClientAction(id, buffer); - } - } - }.setBackgroundTexture(new ColorRectTexture(0x4fffffff))); - addWidget(buttonWidget - .setHoverText("terminal.world_prospector.color") - .setColors(0x4fffffff, -1, colors[i]) - .setClickListener(cd -> TerminalDialogWidget - .showColorDialog(getOs(), "terminal.world_prospector.color", res -> { - if (res != null) { - buttonWidget.setFill(res | 0xff000000); - colors[index] = res | 0xff000000; - } - }, colors[index]).open())); - } - addWidget(new CircleButtonWidget(333 / 2, 200) - .setClickListener(cd -> openAR()) - .setHoverText("terminal.ar.open") - .setColors(0, -1, TerminalTheme.COLOR_B_3.getColor()) - .setIcon(new ItemStackTexture(MetaItems.CAMERA.getStackForm()))); - return this; - } - - private void updateBlockSelectionAndColor(ItemStack stack, int index, RectButtonWidget buttonWidget) { - if (stack.getItem() instanceof ItemBlock) { - ItemStack copy = stack.copy(); - copy.setCount(1); - handlers[index].setStackInSlot(0, copy); - - MaterialStack ms = OreDictUnifier.getMaterial(copy); - Block block = ((ItemBlock) copy.getItem()).getBlock(); - if (block instanceof BlockFalling) { - colors[index] = ((BlockFalling) block).getDustColor(block.getStateFromMeta(copy.getMetadata())); - } else if (ms != null) { - colors[index] = ms.material.getMaterialRGB(); - } else { - colors[index] = block.getStateFromMeta(copy.getMetadata()).getMaterial() - .getMaterialMapColor().colorValue; - } - if (colors[index] == 0) { - colors[index] = block.hashCode(); - } - colors[index] = colors[index] | 0xff000000; - buttonWidget.setFill(colors[index]); - } else if (stack.isEmpty()) { - handlers[index].setStackInSlot(0, stack); - colors[index] = 0x00000000; - buttonWidget.setFill(colors[index]); - } - } - - @Override - public NBTTagCompound closeApp() { - NBTTagCompound slots = new NBTTagCompound(); - nbt.removeTag("slots"); - for (int i = 0; i < handlers.length; i++) { - if (!handlers[i].getStackInSlot(0).isEmpty()) { - NBTTagCompound itemTag = new NBTTagCompound(); - itemTag.setTag("item", handlers[i].getStackInSlot(0).serializeNBT()); - itemTag.setInteger("color", colors[i]); - slots.setTag("s" + i, itemTag); - } - } - nbt.setTag("slots", slots); - return nbt; - } - - @Override - public int getMaxTier() { - return 2; - } - - @Override - protected void hookDrawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - super.hookDrawInBackground(mouseX, mouseY, partialTicks, context); - float time = (gui.entityPlayer.ticksExisted + partialTicks) / 20f; - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); - if (Shaders.allowedShader()) { - ShaderTexture.createShader("lightring.frag").draw(getPosition().x + 15, getPosition().y + (232 - 150) / 2f, - 150, 150, uniformCache -> uniformCache.glUniform1F("u_time", time)); - } - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - } - - private void selectReference(int index, RectButtonWidget buttonWidget) { - TerminalDialogWidget.showItemSelector(getOs(), "terminal.world_prospector.reference", false, - stack -> stack.getItem() instanceof ItemBlock, - stack -> updateBlockSelectionAndColor(stack, index, buttonWidget)).open(); - } - - private int getMaxRadius() { - return (int) (15 * Math.pow(2, getAppTier())); - } - - private Tuple getSlotStack(int i) { - if (nbt != null) { - NBTTagCompound slots = nbt.getCompoundTag("slots"); - if (slots.hasKey("s" + i)) { - NBTTagCompound itemTag = slots.getCompoundTag("s" + i); - return new Tuple<>(new ItemStack(itemTag.getCompoundTag("item")), itemTag.getInteger("color")); - } - } - return null; - } - - private List> getAllSlotStack() { - List> stacks = new ArrayList<>(); - if (nbt != null) { - NBTTagCompound slots = nbt.getCompoundTag("slots"); - for (String key : slots.getKeySet()) { - NBTTagCompound itemTag = slots.getCompoundTag(key); - stacks.add(new Tuple<>(new ItemStack(itemTag.getCompoundTag("item")), itemTag.getInteger("color"))); - } - } - return stacks; - } - - ////////////////////////////////////// AR///////////////////////////////////////// - - @SideOnly(Side.CLIENT) - private static Set matchers; - @SideOnly(Side.CLIENT) - private static Map>> founds; - @SideOnly(Side.CLIENT) - private static BlockPos lastPos; - @SideOnly(Side.CLIENT) - private static int radius; - @SideOnly(Side.CLIENT) - private static int maxRadius; - - @SideOnly(Side.CLIENT) - @Override - public void onAROpened() { - founds = new HashMap<>(); - radius = 0; - maxRadius = getMaxRadius(); - lastPos = null; - matchers = new HashSet<>(); - for (Tuple stack : getAllSlotStack()) { - if (stack.getFirst().getItem() instanceof ItemBlock) { - Block block = ((ItemBlock) stack.getFirst().getItem()).getBlock(); - - if (block != Blocks.AIR) { - matchers.add(new BlockStateMatcher(block.getStateFromMeta(stack.getFirst().getMetadata()), - stack.getSecond())); - } - } - } - matchers.forEach(matcher -> founds.put(matcher, new HashMap<>())); - } - - @SideOnly(Side.CLIENT) - private static List bresenhamCircle(int xc, int zc, int r) { - List blockPos = new ArrayList<>(); - int x, z, d; - x = 0; - z = r; - d = 3 - 2 * r; - circlePlot(blockPos, xc, zc, x, z); - while (x < z) { - if (d < 0) { - d = d + 4 * x + 6; - } else { - d = d + 4 * (x - z) + 10; - z--; - } - x++; - circlePlot(blockPos, xc, zc, x, z); - } - return blockPos; - } - - @SideOnly(Side.CLIENT) - private static void circlePlot(List blockPos, int xc, int zc, int x, int z) { - blockPos.add(new BlockPos(xc + x, 0, zc + z)); - blockPos.add(new BlockPos(xc - x, 0, zc + z)); - blockPos.add(new BlockPos(xc + x, 0, zc - z)); - blockPos.add(new BlockPos(xc - x, 0, zc - z)); - blockPos.add(new BlockPos(xc + z, 0, zc + x)); - blockPos.add(new BlockPos(xc - z, 0, zc + x)); - blockPos.add(new BlockPos(xc + z, 0, zc - x)); - blockPos.add(new BlockPos(xc - z, 0, zc - x)); - } - - @SideOnly(Side.CLIENT) - private static void addCluster(BlockPos pos, Map> found) { - final BlockPos min = pos.add(-1, -1, -1); - final BlockPos max = pos.add(1, 1, 1); - - AxisAlignedBB root = null; - for (int y = min.getY(); y <= max.getY(); y++) { - for (int x = min.getX(); x <= max.getX(); x++) { - for (int z = min.getZ(); z <= max.getZ(); z++) { - Vec3d clusterPos = new Vec3d(x + 0.5, y + 0.5, z + 0.5); - AxisAlignedBB find = null; - for (AxisAlignedBB bb : found.keySet()) { - if (bb != root && bb.contains(clusterPos)) { - find = bb; - break; - } - } - if (find != null) { - AxisAlignedBB union; - Set blocks; - if (root == null) { - union = new AxisAlignedBB(pos).union(find); - blocks = found.get(find); - found.remove(find); - } else { - union = root.union(find); - blocks = new HashSet<>(); - blocks.addAll(found.get(find)); - blocks.addAll(found.get(root)); - found.remove(find); - found.remove(root); - } - found.put(union, blocks); - root = union; - found.get(root).add(pos); - } - } - } - } - if (root == null) { - Set blocks = new HashSet<>(); - blocks.add(pos); - found.put(new AxisAlignedBB(pos), blocks); - } - } - - @SideOnly(Side.CLIENT) - @Override - public void tickAR(EntityPlayer player) { - World world = player.world; - if (Minecraft.getMinecraft().isGamePaused()) return; - - if (radius == 0 || lastPos == null) { - lastPos = player.getPosition(); - } - - int maxY = Math.min(256, maxRadius + player.getPosition().getY()); - int minY = Math.max(0, -maxRadius + player.getPosition().getY()); - for (BlockPos pos : bresenhamCircle(lastPos.getX(), lastPos.getZ(), radius)) { - for (int y = minY; y <= maxY; y++) { - for (IMatcher matcher : matchers) { - BlockPos blockPos = new BlockPos(pos.getX(), y, pos.getZ()); - if (matcher.match(world.getBlockState(blockPos))) { - addCluster(blockPos, founds.get(matcher)); - } - } - - } - } - - if (radius == maxRadius) { - radius = 0; - for (IMatcher matcher : matchers) { - Iterator>> it = founds.get(matcher).entrySet().iterator(); - while (it.hasNext()) { - Map.Entry> entry = it.next(); - entry.getValue().removeIf(pos -> !matcher.match(world.getBlockState(pos))); - if (entry.getValue().isEmpty()) { - it.remove(); - } - } - } - } else { - radius++; - } - } - - @SideOnly(Side.CLIENT) - @Override - public void drawARScreen(RenderWorldLastEvent event) { - renderScan(event.getPartialTicks()); - renderAxisAlignedBB(event.getPartialTicks()); - } - - @SideOnly(Side.CLIENT) - private static void renderAxisAlignedBB(float partialTicks) { - Minecraft mc = Minecraft.getMinecraft(); - Entity entity = mc.getRenderViewEntity(); - if (entity == null) return; - final double posX = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * partialTicks; - final double posY = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * partialTicks; - final double posZ = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * partialTicks; - - GlStateManager.disableLighting(); - GlStateManager.disableDepth(); - GlStateManager.enableBlend(); - GlStateManager.disableTexture2D(); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); - - GlStateManager.pushMatrix(); - GlStateManager.translate(-posX, -posY, -posZ); - - final Tessellator tessellator = Tessellator.getInstance(); - final BufferBuilder buffer = tessellator.getBuffer(); - - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR); - - for (IMatcher matcher : matchers) { - int color = matcher.getColor(); - final float r = ((color >> 16) & 0xFF) / 255f; - final float g = ((color >> 8) & 0xFF) / 255f; - final float b = (color & 0xFF) / 255f; - final float a = 1; - for (AxisAlignedBB bound : founds.get(matcher).keySet()) { - RenderBufferHelper.renderCubeFace(buffer, bound.minX, bound.minY, bound.minZ, bound.maxX, bound.maxY, - bound.maxZ, r, g, b, a); - } - } - - tessellator.draw(); - - GlStateManager.popMatrix(); - - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - GlStateManager.enableTexture2D(); - GlStateManager.disableBlend(); - GlStateManager.enableDepth(); - GlStateManager.enableLighting(); - } - - @SideOnly(Side.CLIENT) - private static void renderScan(float getPartialTicks) { - Minecraft mc = Minecraft.getMinecraft(); - World world = mc.world; - Entity viewer = mc.getRenderViewEntity(); - if (world != null && viewer != null && !Shaders.isOptiFineShaderPackLoaded()) { - - Framebuffer fbo = mc.getFramebuffer(); - - GlStateManager.depthMask(false); - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); - - DepthTextureUtil.bindDepthTexture(); - - float time = (viewer.ticksExisted + getPartialTicks) / 20; - - Shaders.renderFullImageInFBO(fbo, Shaders.SCANNING, uniformCache -> { - uniformCache.glUniform1F("u_time", time); - uniformCache.glUniform1F("radius", radius + getPartialTicks); - uniformCache.glUniform1F("u_zFar", mc.gameSettings.renderDistanceChunks * 16 * MathHelper.SQRT_2); - uniformCache.glUniform1F("u_FOV", mc.gameSettings.fovSetting); - }); - - DepthTextureUtil.unBindDepthTexture(); - - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - GlStateManager.disableBlend(); - GlStateManager.depthMask(true); - - } - } -} diff --git a/src/main/java/gregtech/common/terminal/app/worldprospector/matcher/BlockStateMatcher.java b/src/main/java/gregtech/common/terminal/app/worldprospector/matcher/BlockStateMatcher.java deleted file mode 100644 index 1848972b122..00000000000 --- a/src/main/java/gregtech/common/terminal/app/worldprospector/matcher/BlockStateMatcher.java +++ /dev/null @@ -1,71 +0,0 @@ -package gregtech.common.terminal.app.worldprospector.matcher; - -import net.minecraft.block.properties.IProperty; -import net.minecraft.block.state.IBlockState; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -public class BlockStateMatcher implements IMatcher { - - private final IBlockState reference; - private final List> properties = new ArrayList<>(); - private final int meta; - private final int color; - - public BlockStateMatcher(IBlockState state, int color) { - this.reference = state; - for (final IProperty property : state.getPropertyKeys()) { - if (Objects.equals(property.getName(), "variant") || // Vanilla Minecraft. - Objects.equals(property.getName(), "type") || // E.g. ThermalFoundation, TiCon, IC2, Immersive - // Engineering. - Objects.equals(property.getName(), "ore") || // E.g. BigReactors. - Objects.equals(property.getName(), "oretype") || // E.g. DeepResonance. - Objects.equals(property.getName(), "stone_type") || // E.g. gtce. - Objects.equals(property.getName(), "basictype")) { // Galacticraft. - properties.add(property); - } - } - this.meta = reference.getBlock().getMetaFromState(reference); - this.color = color; - } - - public boolean match(final IBlockState state) { - if (reference.getBlock() != state.getBlock()) { - return false; - } - - if (state.getBlock().getMetaFromState(state) != meta) { - return false; - } - - if (properties.isEmpty()) { - return true; - } - - for (final IProperty property : properties) { - if (!state.getPropertyKeys().contains(property)) { - continue; - } - if (!Objects.equals(state.getValue(property), reference.getValue(property))) { - return false; - } - } - - return true; - } - - @Override - public int getColor() { - return color; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof BlockStateMatcher) { - return match(((BlockStateMatcher) obj).reference); - } - return super.equals(obj); - } -} diff --git a/src/main/java/gregtech/common/terminal/app/worldprospector/matcher/IMatcher.java b/src/main/java/gregtech/common/terminal/app/worldprospector/matcher/IMatcher.java deleted file mode 100644 index c96a6c22c36..00000000000 --- a/src/main/java/gregtech/common/terminal/app/worldprospector/matcher/IMatcher.java +++ /dev/null @@ -1,17 +0,0 @@ -package gregtech.common.terminal.app.worldprospector.matcher; - -import net.minecraft.block.state.IBlockState; - -/** - * Created with IntelliJ IDEA. - * - * @Author: KilaBash - * @Date: 2021/09/16 - * @Description: - */ -public interface IMatcher { - - boolean match(final IBlockState state); - - int getColor(); -} diff --git a/src/main/java/gregtech/common/terminal/component/ClickComponent.java b/src/main/java/gregtech/common/terminal/component/ClickComponent.java deleted file mode 100644 index 24031ee4c73..00000000000 --- a/src/main/java/gregtech/common/terminal/component/ClickComponent.java +++ /dev/null @@ -1,46 +0,0 @@ -package gregtech.common.terminal.component; - -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.terminal.os.menu.IMenuComponent; - -import java.util.function.Consumer; - -public class ClickComponent implements IMenuComponent { - - private IGuiTexture icon; - private String hoverText; - private Consumer consumer; - - public ClickComponent setIcon(IGuiTexture icon) { - this.icon = icon; - return this; - } - - public ClickComponent setHoverText(String hoverText) { - this.hoverText = hoverText; - return this; - } - - public ClickComponent setClickConsumer(Consumer consumer) { - this.consumer = consumer; - return this; - } - - @Override - public IGuiTexture buttonIcon() { - return icon; - } - - @Override - public String hoverText() { - return hoverText; - } - - @Override - public void click(Widget.ClickData clickData) { - if (consumer != null) { - consumer.accept(clickData); - } - } -} diff --git a/src/main/java/gregtech/common/terminal/component/setting/GuiTextureSetter.java b/src/main/java/gregtech/common/terminal/component/setting/GuiTextureSetter.java deleted file mode 100644 index add78dfa301..00000000000 --- a/src/main/java/gregtech/common/terminal/component/setting/GuiTextureSetter.java +++ /dev/null @@ -1,33 +0,0 @@ -package gregtech.common.terminal.component.setting; - -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.widgets.WidgetGroup; - -import java.util.function.Consumer; - -public class GuiTextureSetter extends WidgetGroup implements ISetting { - - private final String name; - private Consumer updated; - - public GuiTextureSetter(String name, Consumer updated) { - this.name = name; - this.updated = updated; - } - - @Override - public String getName() { - return name; - } - - @Override - public IGuiTexture getIcon() { - return null; - } - - @Override - public Widget getWidget() { - return null; - } -} diff --git a/src/main/java/gregtech/common/terminal/component/setting/ISetting.java b/src/main/java/gregtech/common/terminal/component/setting/ISetting.java deleted file mode 100644 index 2b3f2fa05d2..00000000000 --- a/src/main/java/gregtech/common/terminal/component/setting/ISetting.java +++ /dev/null @@ -1,13 +0,0 @@ -package gregtech.common.terminal.component.setting; - -import gregtech.api.gui.Widget; -import gregtech.api.gui.resources.IGuiTexture; - -public interface ISetting { - - String getName(); - - IGuiTexture getIcon(); - - Widget getWidget(); -} diff --git a/src/main/java/gregtech/common/terminal/component/setting/IWidgetSettings.java b/src/main/java/gregtech/common/terminal/component/setting/IWidgetSettings.java deleted file mode 100644 index e3affc80eb1..00000000000 --- a/src/main/java/gregtech/common/terminal/component/setting/IWidgetSettings.java +++ /dev/null @@ -1,8 +0,0 @@ -package gregtech.common.terminal.component.setting; - -import gregtech.api.terminal.util.TreeNode; - -public interface IWidgetSettings { - - TreeNode getSettings(); -} diff --git a/src/main/java/gregtech/common/terminal/component/setting/SettingComponent.java b/src/main/java/gregtech/common/terminal/component/setting/SettingComponent.java deleted file mode 100644 index 1f011df5a03..00000000000 --- a/src/main/java/gregtech/common/terminal/component/setting/SettingComponent.java +++ /dev/null @@ -1,29 +0,0 @@ -package gregtech.common.terminal.component.setting; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.terminal.gui.widgets.TreeListWidget; -import gregtech.api.terminal.os.menu.IMenuComponent; - -public class SettingComponent extends WidgetGroup implements IMenuComponent { - - private Widget settingWidget; - - public SettingComponent(IWidgetSettings settings) { - this.addWidget(new TreeListWidget<>(0, 0, 130, 232, settings.getSettings(), (selected) -> { - if (selected.getContent() != null) { - if (settingWidget != null) { - removeWidget(settingWidget); - } - settingWidget = selected.getContent().getWidget(); - if (settingWidget != null) { - addWidget(settingWidget); - } - } - }).setContentIconSupplier(ISetting::getIcon) - .setContentNameSupplier(ISetting::getName) - .setNodeTexture(GuiTextures.BORDERED_BACKGROUND) - .setLeafTexture(GuiTextures.SLOT_DARKENED)); - } -} diff --git a/src/main/java/gregtech/common/terminal/hardware/BatteryHardware.java b/src/main/java/gregtech/common/terminal/hardware/BatteryHardware.java deleted file mode 100644 index b9343e2df94..00000000000 --- a/src/main/java/gregtech/common/terminal/hardware/BatteryHardware.java +++ /dev/null @@ -1,202 +0,0 @@ -package gregtech.common.terminal.hardware; - -import gregtech.api.GTValues; -import gregtech.api.capability.GregtechCapabilities; -import gregtech.api.capability.IElectricItem; -import gregtech.api.capability.impl.ElectricItem; -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.resources.ItemStackTexture; -import gregtech.api.terminal.hardware.Hardware; -import gregtech.api.terminal.hardware.IHardwareCapability; -import gregtech.common.items.MetaItems; - -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.common.capabilities.Capability; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiConsumer; - -/** - * Created with IntelliJ IDEA. - * - * @Author: KilaBash - * @Date: 2021/08/28 - * @Description: - */ -public class BatteryHardware extends Hardware implements IElectricItem, IHardwareCapability { - - protected final List> listeners = new ArrayList<>(); - - public BatteryHardware() {} - - @Override - public boolean isHardwareAdequate(Hardware demand) { - return demand instanceof BatteryHardware && ((BatteryHardware) demand).getTier() <= this.getTier() && - this.getCharge() > 0; - } - - @Override - public String addInformation() { - return GTValues.VN[getTier()]; - } - - @Override - public Hardware createHardware(ItemStack itemStack) { - return new BatteryHardware(); - } - - @Override - public NBTTagCompound acceptItemStack(ItemStack itemStack) { - IElectricItem electricItem = itemStack.getCapability(GregtechCapabilities.CAPABILITY_ELECTRIC_ITEM, null); - if (electricItem == null || !electricItem.canProvideChargeExternally() || !electricItem.chargeable()) { - return null; - } - NBTTagCompound nbt = new NBTTagCompound(); - nbt.setLong("maxCharge", electricItem.getMaxCharge()); - nbt.setLong("charge", electricItem.getCharge()); - nbt.setInteger("tier", electricItem.getTier()); - return nbt; - } - - @Override - public String getRegistryName() { - return "battery"; - } - - @Override - public IGuiTexture getIcon() { - if (!hasHW()) { - return super.getIcon(); - } - return new ItemStackTexture(isCreative() ? MetaItems.ULTIMATE_BATTERY.getInfiniteChargedStack() : getItem()); - } - - @Override - public void addChargeListener(BiConsumer chargeListener) { - listeners.add(chargeListener); - } - - public void setCharge(long change) { - getNBT().setLong("charge", change); - listeners.forEach(l -> l.accept(provider.getItemStack(), change)); - } - - @Override - public long getTransferLimit() { - return GTValues.V[getTier()]; - } - - @Override - public long getMaxCharge() { - return isCreative() ? Long.MAX_VALUE : getNBT().getLong("maxCharge"); - } - - public long getCharge() { - return isCreative() ? Long.MAX_VALUE : getNBT().getLong("charge"); - } - - @Override - public boolean canProvideChargeExternally() { - return false; - } - - @Override - public boolean chargeable() { - return true; - } - - @Override - public long charge(long amount, int chargerTier, boolean ignoreTransferLimit, boolean simulate) { - if (provider.getItemStack().getCount() != 1) { - return 0L; - } - if ((chargerTier >= getTier()) && amount > 0L) { - long canReceive = getMaxCharge() - getCharge(); - if (!ignoreTransferLimit) { - amount = Math.min(amount, getTransferLimit()); - } - long charged = Math.min(amount, canReceive); - if (!simulate) { - setCharge(getCharge() + charged); - } - return charged; - } - return 0; - } - - @Override - public long discharge(long amount, int chargerTier, boolean ignoreTransferLimit, boolean externally, - boolean simulate) { - if (provider.getItemStack().getCount() != 1) { - return 0L; - } - if ((!externally || amount == Long.MAX_VALUE) && (chargerTier >= getTier()) && amount > 0L) { - if (!ignoreTransferLimit) { - amount = Math.min(amount, getTransferLimit()); - } - long charge = getCharge(); - long discharged = Math.min(amount, charge); - if (!simulate) { - setCharge(charge - discharged); - } - return discharged; - } - return 0; - } - - @Override - public int getTier() { - return isCreative() ? GTValues.V.length - 1 : getNBT().getInteger("tier"); - } - - @Override - public boolean hasCapability(@NotNull Capability capability) { - return capability == GregtechCapabilities.CAPABILITY_ELECTRIC_ITEM; - } - - @Nullable - @Override - public T getCapability(@NotNull Capability capability) { - return capability == GregtechCapabilities.CAPABILITY_ELECTRIC_ITEM ? - GregtechCapabilities.CAPABILITY_ELECTRIC_ITEM.cast(this) : null; - } - - @Override - public ItemStack onHardwareRemoved(ItemStack itemStack) { - IElectricItem item = itemStack.getCapability(GregtechCapabilities.CAPABILITY_ELECTRIC_ITEM, null); - if (item instanceof ElectricItem) { - ((ElectricItem) item).setCharge(getCharge()); - } - return itemStack; - } - - public static class BatteryDemand extends BatteryHardware { - - public final int tier; - public final long cost; - - public BatteryDemand(int tier, long cost) { - this.tier = tier; - this.cost = cost; - } - - @Override - public int getTier() { - return tier; - } - - @Override - public long getCharge() { - return this.getCost(); - } - - public long getCost() { - return cost; - } - } -} diff --git a/src/main/java/gregtech/common/terminal/hardware/DeviceHardware.java b/src/main/java/gregtech/common/terminal/hardware/DeviceHardware.java deleted file mode 100644 index ccfa77d077d..00000000000 --- a/src/main/java/gregtech/common/terminal/hardware/DeviceHardware.java +++ /dev/null @@ -1,142 +0,0 @@ -package gregtech.common.terminal.hardware; - -import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.resources.ItemStackTexture; -import gregtech.api.items.metaitem.MetaItem; -import gregtech.api.terminal.hardware.Hardware; -import gregtech.common.items.MetaItems; - -import net.minecraft.client.resources.I18n; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -public class DeviceHardware extends Hardware { - - private final int slot; - - public DeviceHardware(int slot) { - this.slot = slot; - } - - @Override - public String getRegistryName() { - return "device" + slot; - } - - @SideOnly(Side.CLIENT) - @Override - public String getLocalizedName() { - return I18n.format("terminal.hw.device") + " " + slot; - } - - @Override - protected Hardware createHardware(ItemStack itemStack) { - return new DeviceHardware(slot); - } - - @Override - public NBTTagCompound acceptItemStack(ItemStack itemStack) { - for (DEVICE device : DEVICE.values()) { - if (device.itemStack.isItemEqual(itemStack)) { - NBTTagCompound nbt = new NBTTagCompound(); - nbt.setInteger("d", device.ordinal()); - return nbt; - } - } - return null; - } - - @Override - public IGuiTexture getIcon() { - if (!hasHW()) { - return super.getIcon(); - } - if (isCreative()) { - return new ItemStackTexture(DEVICE.values()[slot % DEVICE.values().length].itemStack); - } - return new ItemStackTexture(getDevice().itemStack); - } - - @Override - public boolean isHardwareAdequate(Hardware demand) { - if (demand instanceof DeviceHardware && isCreative()) { - return DEVICE.values()[slot % DEVICE.values().length] == ((DeviceHardware) demand).getDevice(); - } - return demand instanceof DeviceHardware && ((DeviceHardware) demand).getDevice() == this.getDevice(); - } - - @Override - public String addInformation() { - if (isCreative()) { - return DEVICE.values()[slot % DEVICE.values().length].itemStack.getDisplayName(); - } - return getDevice().itemStack.getDisplayName(); - } - - public DEVICE getDevice() { - return DEVICE.values()[getNBT().getInteger("d") % DEVICE.values().length]; - } - - public enum DEVICE { - - PROSPECTOR_LV(MetaItems.PROSPECTOR_LV, "prospector"), - PROSPECTOR_HV(MetaItems.PROSPECTOR_HV, "advanced_prospector"), - WIRELESS(MetaItems.WIRELESS, "wireless"), - CAMERA(MetaItems.CAMERA, "camera"), - - // FIELD GEN - FIELD_GENERATOR_UV(MetaItems.FIELD_GENERATOR_UV, "field_generator"), - - // SOLAR - SOLAR_LV(MetaItems.COVER_SOLAR_PANEL_LV, "solar_lv"); - - ItemStack itemStack; - String name; - - DEVICE(ItemStack itemStack, String name) { - this.itemStack = itemStack; - this.name = name; - } - - DEVICE(MetaItem.MetaValueItem metaItem, String name) { - this.itemStack = metaItem.getStackForm(); - this.name = name; - } - - public static DEVICE fromString(String name) { - for (DEVICE device : values()) { - if (device.name.equals(name.toLowerCase())) { - return device; - } - } - return null; - } - } - - public static class DeviceDemand extends DeviceHardware { - - private final DEVICE device; - - public DeviceDemand(DEVICE device) { - super(0); - this.device = device; - } - - public DeviceDemand(String device) { - super(0); - this.device = DEVICE.fromString(device); - } - - @Override - public String getLocalizedName() { - return I18n.format("terminal.hw.device"); - } - - @Override - public DEVICE getDevice() { - return device; - } - } -} diff --git a/src/main/java/gregtech/core/CoreModule.java b/src/main/java/gregtech/core/CoreModule.java index 46eeb3e8335..aecbe907d48 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; @@ -18,7 +20,7 @@ import gregtech.api.mui.GTGuis; import gregtech.api.recipes.ModHandler; import gregtech.api.recipes.RecipeMap; -import gregtech.api.recipes.recipeproperties.TemperatureProperty; +import gregtech.api.recipes.properties.impl.TemperatureProperty; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Materials; import gregtech.api.unification.material.event.MaterialEvent; @@ -26,9 +28,10 @@ import gregtech.api.unification.material.event.PostMaterialEvent; import gregtech.api.unification.material.registry.MarkerMaterialRegistry; import gregtech.api.util.CapesRegistry; -import gregtech.api.util.VirtualTankRegistry; +import gregtech.api.util.Mods; import gregtech.api.util.input.KeyBind; import gregtech.api.util.oreglob.OreGlob; +import gregtech.api.util.virtualregistry.VirtualEnderRegistry; import gregtech.api.worldgen.bedrockFluids.BedrockFluidVeinHandler; import gregtech.api.worldgen.bedrockFluids.BedrockFluidVeinSaveData; import gregtech.api.worldgen.config.WorldGenRegistry; @@ -36,6 +39,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; @@ -43,7 +47,6 @@ import gregtech.common.command.CommandShaders; import gregtech.common.command.worldgen.CommandWorldgen; import gregtech.common.covers.CoverBehaviors; -import gregtech.common.covers.filter.FilterTypeRegistry; import gregtech.common.covers.filter.oreglob.impl.OreGlobParser; import gregtech.common.items.MetaItems; import gregtech.common.items.ToolItems; @@ -69,6 +72,8 @@ import gregtech.core.sound.GTSoundEvents; import gregtech.core.sound.internal.SoundManager; import gregtech.core.unification.material.internal.MaterialRegistryManager; +import gregtech.datafix.command.CommandDataFix; +import gregtech.integration.bq.BQuDataFixer; import gregtech.loaders.dungeon.DungeonLootLoader; import gregtech.modules.GregTechModules; @@ -185,6 +190,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(); @@ -192,8 +203,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 */ @@ -208,6 +221,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(); @@ -233,7 +249,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."); @@ -255,7 +274,6 @@ public void init(FMLInitializationEvent event) { WorldGenRegistry.INSTANCE.initializeRegistry(); LootTableHelper.initialize(); - FilterTypeRegistry.init(); /* Start Cover Definition Registration */ COVER_REGISTRY.unfreeze(); @@ -301,7 +319,12 @@ public void serverStarting(FMLServerStartingEvent event) { GregTechAPI.commandManager.addCommand(new CommandHand()); GregTechAPI.commandManager.addCommand(new CommandRecipeCheck()); GregTechAPI.commandManager.addCommand(new CommandShaders()); + GregTechAPI.commandManager.addCommand(new CommandDataFix()); CapesRegistry.load(); + + if (Mods.BetterQuestingUnofficial.isModLoaded()) { + BQuDataFixer.onServerStarting(event.getServer()); + } } @Override @@ -324,7 +347,7 @@ public void serverStarted(FMLServerStartedEvent event) { @Override public void serverStopped(FMLServerStoppedEvent event) { - VirtualTankRegistry.clearMaps(); + VirtualEnderRegistry.clearMaps(); CapesRegistry.clearMaps(); } } diff --git a/src/main/java/gregtech/core/network/packets/PacketProspecting.java b/src/main/java/gregtech/core/network/packets/PacketProspecting.java index 47a1780f930..babd70b0db6 100644 --- a/src/main/java/gregtech/core/network/packets/PacketProspecting.java +++ b/src/main/java/gregtech/core/network/packets/PacketProspecting.java @@ -1,6 +1,6 @@ package gregtech.core.network.packets; -import gregtech.common.terminal.app.prospector.ProspectorMode; +import gregtech.common.gui.widget.prospector.ProspectorMode; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; 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..ea8efe93388 --- /dev/null +++ b/src/main/java/gregtech/datafix/GTDataFixers.java @@ -0,0 +1,72 @@ +package gregtech.datafix; + +import gregtech.api.GTValues; +import gregtech.api.GregTechAPI; +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.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; + +import java.util.stream.IntStream; + +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 GT's own MTEs to the new blocks automatically + */ + private static void migrateMTERegistries() { + MTERegistriesMigrator migrator = GregTechAPI.MIGRATIONS.registriesMigrator(); + migrator.migrate(GTValues.MODID, IntStream.range(0, 2000)); + } +} 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/command/CommandDataFix.java b/src/main/java/gregtech/datafix/command/CommandDataFix.java new file mode 100644 index 00000000000..6a7f0cbad40 --- /dev/null +++ b/src/main/java/gregtech/datafix/command/CommandDataFix.java @@ -0,0 +1,33 @@ +package gregtech.datafix.command; + +import gregtech.api.util.Mods; +import gregtech.integration.bq.CommandBQuDataFix; + +import net.minecraft.command.ICommandSender; +import net.minecraftforge.server.command.CommandTreeBase; + +import org.jetbrains.annotations.NotNull; + +public final class CommandDataFix extends CommandTreeBase { + + public CommandDataFix() { + if (Mods.BetterQuestingUnofficial.isModLoaded()) { + addSubcommand(new CommandBQuDataFix()); + } + } + + @Override + public @NotNull String getName() { + return "datafix"; + } + + @Override + public int getRequiredPermissionLevel() { + return 3; + } + + @Override + public @NotNull String getUsage(@NotNull ICommandSender sender) { + return "gregtech.command.datafix.usage"; + } +} 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..73460ac52b8 --- /dev/null +++ b/src/main/java/gregtech/datafix/migration/lib/MTERegistriesMigrator.java @@ -0,0 +1,102 @@ +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; + +import java.util.stream.IntStream; + +/** + * 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 single data fix entry for the multiple MTE registry transition. + *

            + * Callers will probably prefer {@link #migrate(String, IntStream)}. + * + * @param modid the registry's modid + * @param meta the metadata value to migrate + */ + public void migrate(@NotNull String modid, short meta) { + metaModidMap.put(meta, modid); + } + + /** + * Register data fix entries for the multiple MTE registry transition. + *

            + * Register the range of values allocated to the modid using {@link IntStream#range(int, int)} or + * {@link IntStream#builder()}. + * + * @param modid the registry's modid + * @param metaValues the metadata values to migrate + */ + public void migrate(@NotNull String modid, @NotNull IntStream metaValues) { + metaValues.forEach(i -> metaModidMap.put((short) i, 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/IntegrationModule.java b/src/main/java/gregtech/integration/IntegrationModule.java index 15d760b4a63..65f02e3c938 100644 --- a/src/main/java/gregtech/integration/IntegrationModule.java +++ b/src/main/java/gregtech/integration/IntegrationModule.java @@ -2,12 +2,12 @@ import gregtech.api.GTValues; import gregtech.api.modules.GregTechModule; +import gregtech.api.util.Mods; import gregtech.common.items.MetaItems; import gregtech.modules.BaseGregTechModule; import gregtech.modules.GregTechModules; import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -47,13 +47,13 @@ public List> getEventBusSubscribers() { public void init(FMLInitializationEvent event) { super.init(event); - if (Loader.isModLoaded(GTValues.MODID_IE)) { + if (Mods.ImmersiveEngineering.isModLoaded()) { BelljarHandler.registerBasicItemFertilizer(MetaItems.FERTILIZER.getStackForm(), 1.25f); logger.info("Registered Immersive Engineering Compat"); } } - @Optional.Method(modid = GTValues.MODID_EIO) + @Optional.Method(modid = Mods.Names.ENDER_IO) @SubscribeEvent public static void registerFertilizer(@NotNull RegistryEvent.Register event) { event.getRegistry().register(new Bonemeal(MetaItems.FERTILIZER.getStackForm())); diff --git a/src/main/java/gregtech/integration/IntegrationUtil.java b/src/main/java/gregtech/integration/IntegrationUtil.java index bc6334de347..67a9dd8d642 100644 --- a/src/main/java/gregtech/integration/IntegrationUtil.java +++ b/src/main/java/gregtech/integration/IntegrationUtil.java @@ -11,6 +11,7 @@ import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -18,9 +19,16 @@ import java.util.Arrays; import java.util.List; +@Deprecated public class IntegrationUtil { - /** Should only be called after {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent} */ + /** + * Should only be called after {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent} + * + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public static void throwIncompatibilityIfLoaded(String modID, String... customMessages) { if (Loader.isModLoaded(modID)) { String modName = TextFormatting.BOLD + modID + TextFormatting.RESET; @@ -31,7 +39,13 @@ public static void throwIncompatibilityIfLoaded(String modID, String... customMe } } - /** Should only be called after {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent} */ + /** + * Should only be called after {@link net.minecraftforge.fml.common.event.FMLPreInitializationEvent} + * + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") public static void throwIncompatibility(List messages) { if (FMLLaunchHandler.side() == Side.SERVER) { throw new RuntimeException(String.join(",", messages)); @@ -40,16 +54,31 @@ public static void throwIncompatibility(List messages) { } } + /** + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @NotNull public static ItemStack getModItem(@NotNull String modid, @NotNull String name, int meta) { return getModItem(modid, name, meta, 1, null); } + /** + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @NotNull public static ItemStack getModItem(@NotNull String modid, @NotNull String name, int meta, int amount) { return getModItem(modid, name, meta, amount, null); } + /** + * @deprecated Use {@link gregtech.api.util.Mods} instead for these features. + */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2.9") @NotNull public static ItemStack getModItem(@NotNull String modid, @NotNull String name, int meta, int amount, @Nullable String nbt) { diff --git a/src/main/java/gregtech/integration/baubles/BaublesModule.java b/src/main/java/gregtech/integration/baubles/BaublesModule.java index 4371d5a032d..6f725211e8f 100644 --- a/src/main/java/gregtech/integration/baubles/BaublesModule.java +++ b/src/main/java/gregtech/integration/baubles/BaublesModule.java @@ -2,6 +2,7 @@ import gregtech.api.GTValues; import gregtech.api.modules.GregTechModule; +import gregtech.api.util.Mods; import gregtech.common.items.MetaItems; import gregtech.integration.IntegrationSubmodule; import gregtech.modules.GregTechModules; @@ -24,7 +25,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_BAUBLES, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_BAUBLES, + modDependencies = Mods.Names.BAUBLES, name = "GregTech Baubles Integration", description = "Baubles Integration Module") public class BaublesModule extends IntegrationSubmodule { diff --git a/src/main/java/gregtech/integration/bq/BQuDataFixer.java b/src/main/java/gregtech/integration/bq/BQuDataFixer.java new file mode 100644 index 00000000000..f0d5bdb48b8 --- /dev/null +++ b/src/main/java/gregtech/integration/bq/BQuDataFixer.java @@ -0,0 +1,245 @@ +package gregtech.integration.bq; + +import gregtech.api.GregTechAPI; +import gregtech.api.util.Mods; +import gregtech.datafix.migration.lib.MTERegistriesMigrator; + +import net.minecraft.command.ICommandSender; +import net.minecraft.util.ResourceLocation; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public final class BQuDataFixer { + + private static final Logger LOG = LogManager.getLogger(BQuDataFixer.class); + + /** + * {@code saves//betterquesting/QuestDatabase.json} + */ + private static final String QUEST_DB_JSON_FILE = "QuestDatabase.json"; + /** + * {@code config/betterquesting/resources/} + */ + private static final String BQ_RESOURCES_DIR = "resources"; + private static final String MC_CONFIG_DIR = "config"; + + private static final String ID_8 = "id:8"; + private static final String DAMAGE_2 = "Damage:2"; + private static final String TAG_10 = "tag:10"; + private static final String ORIG_ID_8 = "orig_id:8"; + private static final String ORIG_META_3 = "orig_meta:3"; + + private static final String PLACEHOLDER = "betterquesting:placeholder"; + + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + + private BQuDataFixer() {} + + public static void onServerStarting(@NotNull ICommandSender server) { + LOG.info("Attempting to apply BQu DataFixers"); + Path worldDir = server.getEntityWorld().getSaveHandler().getWorldDirectory().toPath(); + if (processWorldDir(worldDir)) { + LOG.info("Successfully applied BQu data fixers"); + } else { + LOG.error("Failed to apply BQu data fixers"); + } + } + + /** + * Processes the current world directory and applies data fixers + * + * @param worldDir the current world's directory + * @return if processing was successful + */ + public static boolean processWorldDir(@NotNull Path worldDir) { + LOG.info("Processing world directory"); + Path bqDir = worldDir.resolve(Mods.Names.BETTER_QUESTING); + Path questDbPath = bqDir.resolve(QUEST_DB_JSON_FILE); + if (!Files.isRegularFile(questDbPath)) { + LOG.info("Unable to find BQ Quest Database, assuming this is a new world"); + return true; + } + + JsonObject json; + try { + json = readJson(questDbPath); + } catch (FileNotFoundException e) { + LOG.info("Unable to find BQ Quest Database, assuming this is a new world"); + return true; + } catch (IOException e) { + LOG.error("Failed to read BQ Quest Database in World Folder", e); + return false; + } + + for (var entry : json.entrySet()) { + recurseJsonApplyFix(entry.getValue()); + } + + try { + writeJson(questDbPath, json); + } catch (IOException e) { + LOG.error("Failed to write BQ Quest DataBase in World Folder", e); + } + + return true; + } + + /** + * Processes the BQu config directory and applies data fixers + * + * @param worldDir the current world's directory + * @return if processing was successful + */ + public static boolean processConfigDir(@NotNull Path worldDir) { + LOG.info("Processing config directory"); + Path mcDir = worldDir.getParent().getParent(); + Path configDir = mcDir.resolve(MC_CONFIG_DIR); + Path bqConfigDir = configDir.resolve(Mods.Names.BETTER_QUESTING); + + List paths; + try (var stream = Files.walk(bqConfigDir, 4)) { + paths = stream.filter(p -> !p.endsWith(BQ_RESOURCES_DIR)) // do not walk down the resources dir + .filter(Files::isRegularFile) + .filter(path -> path.toFile().getName().endsWith(".json")) + .collect(Collectors.toList()); + } catch (IOException e) { + LOG.error("Failed to read BQ Quest Database in Config Folder", e); + return false; + } + + Map map = new Object2ObjectOpenHashMap<>(paths.size()); + for (Path path : paths) { + try { + map.put(path, readJson(path)); + } catch (IOException e) { + LOG.error("Failed to read BQ Quest File from Config Folder", e); + } + } + + map.values().stream() + .flatMap(jsonObject -> jsonObject.entrySet().stream()) + .map(Map.Entry::getValue) + .forEach(BQuDataFixer::recurseJsonApplyFix); + + for (var entry : map.entrySet()) { + try { + writeJson(entry.getKey(), entry.getValue()); + } catch (IOException e) { + LOG.error("Failed to write BQ Quest File in Config Folder", e); + } + } + + return true; + } + + /** + * @param path the path to read + * @return the json object stored at the path + * @throws IOException if failure + */ + private static @NotNull JsonObject readJson(@NotNull Path path) throws IOException { + LOG.info("Reading file at path {}", path); + try (Reader reader = Files.newBufferedReader(path)) { + return GSON.fromJson(reader, JsonObject.class); + } + } + + /** + * Recursively walks a JSON file and applies datafixers to matching sub-objects + * + * @param element the json element to recurse + */ + private static void recurseJsonApplyFix(@NotNull JsonElement element) { + if (element.isJsonObject()) { + JsonObject object = element.getAsJsonObject(); + if (object.has(ID_8)) { + applyDataFix(object); + } else { + for (var entry : object.entrySet()) { + recurseJsonApplyFix(entry.getValue()); + } + } + } else if (element.isJsonArray()) { + for (JsonElement value : element.getAsJsonArray()) { + recurseJsonApplyFix(value); + } + } + } + + /** + * @param path the path to write the file + * @param jsonObject the object to write + * @throws IOException if failure + */ + private static void writeJson(@NotNull Path path, @NotNull JsonObject jsonObject) throws IOException { + LOG.info("Writing file to path {}", path); + try (Writer writer = Files.newBufferedWriter(path)) { + GSON.toJson(jsonObject, writer); + } + } + + /** + * Applies {@link MTERegistriesMigrator} fixes to a BQu json file + * + * @param jsonObject the json to fix + */ + private static void applyDataFix(@NotNull JsonObject jsonObject) { + MTERegistriesMigrator migrator = GregTechAPI.MIGRATIONS.registriesMigrator(); + + ResourceLocation itemBlockId; + short meta; + String id = jsonObject.get(ID_8).getAsString(); + + boolean isPlaceHolder = PLACEHOLDER.equals(id); + + if (isPlaceHolder) { + // fix cases where BQu marks items as missing with placeholders + JsonObject orig = jsonObject.getAsJsonObject(TAG_10); + if (orig == null) { + return; + } + + if (!orig.has(ORIG_ID_8) || !orig.has(ORIG_META_3)) { + return; + } + + itemBlockId = new ResourceLocation(orig.get(ORIG_ID_8).getAsString()); + meta = orig.get(ORIG_META_3).getAsShort(); + } else { + itemBlockId = new ResourceLocation(id); + meta = jsonObject.get(DAMAGE_2).getAsShort(); + } + + ResourceLocation fixedName = migrator.fixItemName(itemBlockId, meta); + if (fixedName != null) { + jsonObject.add(ID_8, new JsonPrimitive(fixedName.toString())); + } + + short fixedMeta = migrator.fixItemMeta(itemBlockId, meta); + if (fixedMeta != meta) { + jsonObject.add(DAMAGE_2, new JsonPrimitive(fixedMeta)); + } + + if (isPlaceHolder) { + jsonObject.remove(TAG_10); + } + } +} diff --git a/src/main/java/gregtech/integration/bq/CommandBQuDataFix.java b/src/main/java/gregtech/integration/bq/CommandBQuDataFix.java new file mode 100644 index 00000000000..85a296091a9 --- /dev/null +++ b/src/main/java/gregtech/integration/bq/CommandBQuDataFix.java @@ -0,0 +1,54 @@ +package gregtech.integration.bq; + +import net.minecraft.command.CommandBase; +import net.minecraft.command.ICommandSender; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.text.Style; +import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.text.TextFormatting; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +import java.nio.file.Path; + +@ApiStatus.Internal +public final class CommandBQuDataFix extends CommandBase { + + @Override + public @NotNull String getName() { + return "bqu"; + } + + @Override + public @NotNull String getUsage(@NotNull ICommandSender sender) { + return "gregtech.command.datafix.bqu.usage"; + } + + @Override + public int getRequiredPermissionLevel() { + return 3; + } + + @Override + public void execute(@NotNull MinecraftServer server, @NotNull ICommandSender sender, String @NotNull [] args) { + if (args.length < 1 || !"confirm".equalsIgnoreCase(args[0])) { + sender.sendMessage(new TextComponentTranslation("gregtech.command.datafix.bqu.backup") + .setStyle(new Style().setColor(TextFormatting.YELLOW))); + return; + } + + sender.sendMessage(new TextComponentTranslation("gregtech.command.datafix.bqu.start") + .setStyle(new Style().setColor(TextFormatting.YELLOW))); + + Path worldDir = server.getEntityWorld().getSaveHandler().getWorldDirectory().toPath(); + + if (BQuDataFixer.processConfigDir(worldDir) && BQuDataFixer.processWorldDir(worldDir)) { + sender.sendMessage(new TextComponentTranslation("gregtech.command.datafix.bqu.complete") + .setStyle(new Style().setColor(TextFormatting.GREEN))); + } else { + sender.sendMessage(new TextComponentTranslation("gregtech.command.datafix.bqu.failed") + .setStyle(new Style().setColor(TextFormatting.RED))); + } + } +} diff --git a/src/main/java/gregtech/integration/chisel/ChiselModule.java b/src/main/java/gregtech/integration/chisel/ChiselModule.java index c6dc3cafe05..c8a5f8d3416 100644 --- a/src/main/java/gregtech/integration/chisel/ChiselModule.java +++ b/src/main/java/gregtech/integration/chisel/ChiselModule.java @@ -5,6 +5,7 @@ import gregtech.api.modules.GregTechModule; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.Materials; +import gregtech.api.util.Mods; import gregtech.common.blocks.BlockColored; import gregtech.common.blocks.BlockCompressed; import gregtech.common.blocks.BlockWarningSign; @@ -31,7 +32,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_CHISEL, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_CHISEL, + modDependencies = Mods.Names.CHISEL, name = "GregTech Chisel Integration", description = "Chisel Integration Module") public class ChiselModule extends IntegrationSubmodule { @@ -110,7 +111,7 @@ private void addVariation(String group, Block block, int meta) { tag.setString("group", group); tag.setString("block", Objects.requireNonNull(block.getRegistryName()).toString()); tag.setInteger("meta", meta); - FMLInterModComms.sendMessage(GTValues.MODID_CHISEL, "add_variation", tag); + FMLInterModComms.sendMessage(Mods.Names.CHISEL, "add_variation", tag); } private boolean doesGroupExist(String group) { diff --git a/src/main/java/gregtech/integration/crafttweaker/CraftTweakerModule.java b/src/main/java/gregtech/integration/crafttweaker/CraftTweakerModule.java index 400c41a1110..f66293465e9 100644 --- a/src/main/java/gregtech/integration/crafttweaker/CraftTweakerModule.java +++ b/src/main/java/gregtech/integration/crafttweaker/CraftTweakerModule.java @@ -4,16 +4,15 @@ import gregtech.api.items.metaitem.MetaOreDictItem; import gregtech.api.modules.GregTechModule; import gregtech.api.unification.material.event.MaterialEvent; +import gregtech.api.util.Mods; import gregtech.integration.IntegrationModule; import gregtech.integration.IntegrationSubmodule; import gregtech.integration.crafttweaker.recipe.MetaItemBracketHandler; -import gregtech.integration.crafttweaker.terminal.CTTerminalRegistry; import gregtech.modules.GregTechModules; import net.minecraft.item.crafting.IRecipe; import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.common.event.FMLLoadCompleteEvent; -import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -27,7 +26,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_CT, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_CT, + modDependencies = Mods.Names.CRAFT_TWEAKER, name = "GregTech CraftTweaker Integration", description = "CraftTweaker Integration Module") public class CraftTweakerModule extends IntegrationSubmodule { @@ -46,11 +45,6 @@ public void preInit(FMLPreInitializationEvent event) { CT_OREDICT_ITEM.setRegistryName("meta_oredict_item_ct"); } - @Override - public void postInit(FMLPostInitializationEvent event) { - CTTerminalRegistry.register(); - } - @Override public void loadComplete(FMLLoadCompleteEvent event) { MetaItemBracketHandler.clearComponentRegistry(); diff --git a/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialBuilder.java b/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialBuilder.java index b8dc8e77a9b..d12a134adc5 100644 --- a/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialBuilder.java +++ b/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialBuilder.java @@ -1,6 +1,5 @@ package gregtech.integration.crafttweaker.material; -import gregtech.api.GTValues; import gregtech.api.fluids.FluidBuilder; import gregtech.api.fluids.FluidState; import gregtech.api.fluids.store.FluidStorageKey; @@ -14,6 +13,7 @@ import gregtech.api.unification.material.properties.ToolProperty; import gregtech.api.unification.stack.MaterialStack; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import net.minecraft.enchantment.Enchantment; @@ -264,7 +264,7 @@ public CTMaterialBuilder itemPipeProperties(int priority, float stacksPerSec) { } @ZenMethod - @net.minecraftforge.fml.common.Optional.Method(modid = GTValues.MODID_CT) + @net.minecraftforge.fml.common.Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) public CTMaterialBuilder addDefaultEnchant(IEnchantment enchantment) { Enchantment enchantmentType = (Enchantment) enchantment.getDefinition().getInternal(); backingBuilder.addDefaultEnchant(enchantmentType, enchantment.getLevel()); diff --git a/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java b/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java index ca5d08a1efa..ed66c077a40 100644 --- a/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java +++ b/src/main/java/gregtech/integration/crafttweaker/material/CTMaterialHelpers.java @@ -4,6 +4,7 @@ import gregtech.api.fluids.FluidState; import gregtech.api.unification.material.Material; import gregtech.api.unification.stack.MaterialStack; +import gregtech.integration.groovy.GroovyScriptModule; import com.google.common.collect.ImmutableList; import crafttweaker.CraftTweakerAPI; @@ -17,7 +18,9 @@ protected static ImmutableList validateComponentList(MaterialStac protected static FluidState validateFluidState(String fluidTypeName) { if (fluidTypeName == null || fluidTypeName.equals("fluid")) return FluidState.LIQUID; - + if (GroovyScriptModule.isCurrentlyRunning()) { + return GroovyScriptModule.parseAndValidateEnumValue(FluidState.class, fluidTypeName, "fluid type"); + } if (fluidTypeName.equals("liquid")) return FluidState.LIQUID; if (fluidTypeName.equals("gas")) return FluidState.GAS; if (fluidTypeName.equals("plasma")) return FluidState.PLASMA; diff --git a/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java b/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java index 3f8e854cb29..c0ae3b20efa 100644 --- a/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java +++ b/src/main/java/gregtech/integration/crafttweaker/material/MaterialExpansion.java @@ -1,11 +1,11 @@ package gregtech.integration.crafttweaker.material; -import gregtech.api.GTValues; import gregtech.api.fluids.store.FluidStorageKeys; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.info.MaterialFlag; import gregtech.api.unification.material.info.MaterialIconSet; import gregtech.api.unification.material.properties.*; +import gregtech.api.util.Mods; import net.minecraft.enchantment.Enchantment; @@ -60,12 +60,12 @@ 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 @ZenGetter("fluid") - @net.minecraftforge.fml.common.Optional.Method(modid = GTValues.MODID_CT) + @net.minecraftforge.fml.common.Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) public static ILiquidDefinition getFluid(Material m) { FluidProperty prop = m.getProperty(PropertyKey.FLUID); if (prop != null) { @@ -164,13 +164,13 @@ public static int toolEnchant(Material m) { } @ZenMethod - @net.minecraftforge.fml.common.Optional.Method(modid = GTValues.MODID_CT) + @net.minecraftforge.fml.common.Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) public static void addToolEnchantment(Material m, IEnchantment enchantment) { addScaledToolEnchantment(m, enchantment, 0); } @ZenMethod - @net.minecraftforge.fml.common.Optional.Method(modid = GTValues.MODID_CT) + @net.minecraftforge.fml.common.Optional.Method(modid = Mods.Names.CRAFT_TWEAKER) public static void addScaledToolEnchantment(Material m, IEnchantment enchantment, double levelGrowth) { if (checkFrozen("add tool enchantment")) return; ToolProperty prop = m.getProperty(PropertyKey.TOOL); diff --git a/src/main/java/gregtech/integration/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/CTRecipe.java b/src/main/java/gregtech/integration/crafttweaker/recipe/CTRecipe.java index 40db5cdb817..ac71e2f0fbb 100644 --- a/src/main/java/gregtech/integration/crafttweaker/recipe/CTRecipe.java +++ b/src/main/java/gregtech/integration/crafttweaker/recipe/CTRecipe.java @@ -15,7 +15,6 @@ import stanhebben.zenscript.annotations.ZenGetter; import stanhebben.zenscript.annotations.ZenMethod; -import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -81,7 +80,7 @@ public int getDuration() { } @ZenGetter("EUt") - public int getEUt() { + public long getEUt() { return this.backingRecipe.getEUt(); } @@ -90,16 +89,6 @@ public boolean isHidden() { return this.backingRecipe.isHidden(); } - @ZenGetter("propertyKeys") - public List getPropertyKeys() { - return new ArrayList<>(this.backingRecipe.getPropertyKeys()); - } - - @ZenMethod - public Object getProperty(String key) { - return this.backingRecipe.getPropertyRaw(key); - } - @ZenMethod public boolean remove() { return this.recipeMap.removeRecipe(this.backingRecipe); diff --git a/src/main/java/gregtech/integration/crafttweaker/recipe/CTRecipeBuilder.java b/src/main/java/gregtech/integration/crafttweaker/recipe/CTRecipeBuilder.java index be74a57456c..b419cc4960b 100644 --- a/src/main/java/gregtech/integration/crafttweaker/recipe/CTRecipeBuilder.java +++ b/src/main/java/gregtech/integration/crafttweaker/recipe/CTRecipeBuilder.java @@ -220,7 +220,7 @@ public CTRecipeBuilder fluidOutputs(ILiquidStack... ingredients) { @ZenMethod public CTRecipeBuilder property(String key, int value) { - boolean applied = this.backingBuilder.applyProperty(key, value); + boolean applied = this.backingBuilder.applyPropertyCT(key, value); if (!applied) { throw new IllegalArgumentException("Property " + key + " cannot be applied to recipe type " + @@ -231,7 +231,7 @@ public CTRecipeBuilder property(String key, int value) { @ZenMethod public CTRecipeBuilder property(String key, String value) { - boolean applied = this.backingBuilder.applyProperty(key, value); + boolean applied = this.backingBuilder.applyPropertyCT(key, value); if (!applied) { throw new IllegalArgumentException("Property " + key + " cannot be applied to recipe type " + @@ -242,7 +242,7 @@ public CTRecipeBuilder property(String key, String value) { @ZenMethod public CTRecipeBuilder property(String key, boolean value) { - boolean applied = this.backingBuilder.applyProperty(key, value); + boolean applied = this.backingBuilder.applyPropertyCT(key, value); if (!applied) { throw new IllegalArgumentException("Property " + key + " cannot be applied to recipe type " + @@ -253,7 +253,7 @@ public CTRecipeBuilder property(String key, boolean value) { @ZenMethod public CTRecipeBuilder property(String key, long value) { - boolean applied = this.backingBuilder.applyProperty(key, value); + boolean applied = this.backingBuilder.applyPropertyCT(key, value); if (!applied) { throw new IllegalArgumentException("Property " + key + " cannot be applied to recipe type " + @@ -264,7 +264,7 @@ public CTRecipeBuilder property(String key, long value) { @ZenMethod public CTRecipeBuilder property(String key, float value) { - boolean applied = this.backingBuilder.applyProperty(key, value); + boolean applied = this.backingBuilder.applyPropertyCT(key, value); if (!applied) { throw new IllegalArgumentException("Property " + key + " cannot be applied to recipe type " + @@ -275,7 +275,7 @@ public CTRecipeBuilder property(String key, float value) { @ZenMethod public CTRecipeBuilder property(String key, IItemStack item) { - boolean applied = this.backingBuilder.applyProperty(key, CraftTweakerMC.getItemStack(item)); + boolean applied = this.backingBuilder.applyPropertyCT(key, CraftTweakerMC.getItemStack(item)); if (!applied) { throw new IllegalArgumentException("Property " + key + " cannot be applied to recipe type " + 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/crafttweaker/terminal/CTTerminalRegistry.java b/src/main/java/gregtech/integration/crafttweaker/terminal/CTTerminalRegistry.java deleted file mode 100644 index 6b3989d8447..00000000000 --- a/src/main/java/gregtech/integration/crafttweaker/terminal/CTTerminalRegistry.java +++ /dev/null @@ -1,184 +0,0 @@ -package gregtech.integration.crafttweaker.terminal; - -import gregtech.api.terminal.TerminalRegistry; -import gregtech.api.terminal.hardware.Hardware; -import gregtech.api.util.GTLog; -import gregtech.common.terminal.hardware.BatteryHardware; -import gregtech.common.terminal.hardware.DeviceHardware; - -import net.minecraft.item.ItemStack; -import net.minecraftforge.common.util.EnumHelper; - -import crafttweaker.annotations.ZenRegister; -import crafttweaker.api.item.IItemStack; -import crafttweaker.api.minecraft.CraftTweakerMC; -import stanhebben.zenscript.annotations.ZenClass; -import stanhebben.zenscript.annotations.ZenMethod; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -@ZenClass("mods.gregtech.TerminalRegistry") -@ZenRegister -@SuppressWarnings("unused") -public class CTTerminalRegistry { - - private static List ctAppRegistryBuilders = new LinkedList<>(); - - @ZenMethod - public static CTAppRegistryBuilder createAppRegistryBuilder(String appName) { - return new CTAppRegistryBuilder(appName); - } - - @ZenMethod - public static void registerDevice(IItemStack device, String name) { - ItemStack itemStack = CraftTweakerMC.getItemStack(device).copy(); - if (!itemStack.isEmpty()) { - itemStack.setCount(1); - EnumHelper.addEnum(DeviceHardware.DEVICE.class, name.toUpperCase(), - new Class[] { ItemStack.class, String.class }, itemStack, name.toLowerCase()); - } - } - - public static void registerAPP(CTAppRegistryBuilder builder) { - if (TerminalRegistry.APP_REGISTER.containsKey(builder.appName)) { - if (builder.isDefaultApp != null) { - TerminalRegistry.DEFAULT_APPS.remove(builder.appName); - if (builder.isDefaultApp) { - TerminalRegistry.DEFAULT_APPS.add(builder.appName); - } - } - if (!builder.hardware.isEmpty()) { - int maxTier = TerminalRegistry.APP_HW_DEMAND.get(builder.appName).length; - List[] hardware = new List[maxTier]; - for (int i = 0; i < maxTier; i++) { - List list = new LinkedList<>(); - if (builder.battery.containsKey(i)) { - list.add(builder.battery.get(i)); - } else if (builder.battery.containsKey(-1)) { - list.add(builder.battery.get(-1)); - } - if (builder.hardware.containsKey(i)) { - list.addAll(builder.hardware.get(i)); - } else if (builder.hardware.containsKey(-1)) { - list.addAll(builder.hardware.get(-1)); - } - if (list.size() > 0) { - hardware[i] = list; - } - } - TerminalRegistry.APP_HW_DEMAND.put(builder.appName, hardware); - } - if (!builder.upgrade.isEmpty()) { - int maxTier = TerminalRegistry.APP_UPGRADE_CONDITIONS.get(builder.appName).length; - List[] upgrade = new List[maxTier]; - if (builder.upgrade.containsKey(-1)) { // register for all tier - Arrays.fill(upgrade, builder.upgrade.get(-1)); - } - builder.upgrade.forEach((tier, listBuilder) -> { // register for specific tier - if (tier != -1 && tier < maxTier) { - upgrade[tier] = listBuilder; - } - }); - TerminalRegistry.APP_UPGRADE_CONDITIONS.put(builder.appName, upgrade); - } - } else { - GTLog.logger.error("Not found the app {}, while load the CT script", builder.appName); - } - } - - public static void register() { - ctAppRegistryBuilders.forEach(CTTerminalRegistry::registerAPP); - ctAppRegistryBuilders = null; - } - - @ZenClass("mods.gregtech.AppRegistryBuilder") - @ZenRegister - public static class CTAppRegistryBuilder { - - final String appName; - Boolean isDefaultApp; - Map battery; - Map> hardware; - Map> upgrade; - - public CTAppRegistryBuilder(String appName) { - this.appName = appName; - this.battery = new HashMap<>(); - this.hardware = new HashMap<>(); - this.upgrade = new HashMap<>(); - } - - @ZenMethod - public CTAppRegistryBuilder isDefaultApp(boolean isDefaultApp) { - this.isDefaultApp = isDefaultApp; - return this; - } - - @ZenMethod - public CTAppRegistryBuilder battery(int batteryTier, long cost) { - battery.put(-1, new BatteryHardware.BatteryDemand(batteryTier, cost)); - return this; - } - - @ZenMethod - public CTAppRegistryBuilder battery(int tier, int batteryTier, long cost) { - battery.put(tier, new BatteryHardware.BatteryDemand(batteryTier, cost)); - return this; - } - - @ZenMethod - public CTAppRegistryBuilder device(String... device) { - Hardware[] hw = Arrays.stream(device).map(DeviceHardware.DeviceDemand::new) - .filter(deviceDemand -> deviceDemand.getDevice() != null).toArray(Hardware[]::new); - hardware(hw); - return this; - } - - @ZenMethod - public CTAppRegistryBuilder device(int tier, String... device) { - this.hardware(tier, Arrays.stream(device).map(DeviceHardware.DeviceDemand::new) - .filter(deviceDemand -> deviceDemand.getDevice() != null).toArray(Hardware[]::new)); - return this; - } - - private void hardware(Hardware... hardware) { - hardware(-1, hardware); - } - - private void hardware(int tier, Hardware... hardware) { - this.hardware.put(tier, new LinkedList<>()); - for (Hardware hw : hardware) { - this.hardware.get(tier).add(hw); - } - } - - @ZenMethod - public CTAppRegistryBuilder upgrade(IItemStack... upgrades) { - upgrade(-1, upgrades); - return this; - } - - @ZenMethod - public CTAppRegistryBuilder upgrade(int tier, IItemStack... upgrades) { - this.upgrade.put(tier, new LinkedList<>()); - for (ItemStack up : Arrays.stream(upgrades).map(CraftTweakerMC::getItemStack) - .filter(itemStack -> !itemStack.isEmpty()).toArray(ItemStack[]::new)) { - this.upgrade.get(tier).add(up); - } - return this; - } - - @ZenMethod - public void build() { - if (ctAppRegistryBuilders == null) { - registerAPP(this); - } else { - ctAppRegistryBuilders.add(this); - } - } - } -} diff --git a/src/main/java/gregtech/integration/ctm/IFacadeWrapper.java b/src/main/java/gregtech/integration/ctm/IFacadeWrapper.java index 76d76eb64c9..287b9a9e647 100644 --- a/src/main/java/gregtech/integration/ctm/IFacadeWrapper.java +++ b/src/main/java/gregtech/integration/ctm/IFacadeWrapper.java @@ -1,6 +1,6 @@ package gregtech.integration.ctm; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import net.minecraft.block.state.IBlockState; import net.minecraft.util.EnumFacing; @@ -11,7 +11,7 @@ import org.jetbrains.annotations.NotNull; import team.chisel.ctm.api.IFacade; -@Optional.Interface(modid = GTValues.MODID_CTM, iface = "team.chisel.ctm.api.IFacade") +@Optional.Interface(modid = Mods.Names.CONNECTED_TEXTURES_MOD, iface = "team.chisel.ctm.api.IFacade") public interface IFacadeWrapper extends IFacade { @NotNull diff --git a/src/main/java/gregtech/integration/forestry/ForestryModule.java b/src/main/java/gregtech/integration/forestry/ForestryModule.java index edd4080c33b..8ac455b702f 100644 --- a/src/main/java/gregtech/integration/forestry/ForestryModule.java +++ b/src/main/java/gregtech/integration/forestry/ForestryModule.java @@ -7,12 +7,15 @@ import gregtech.api.items.toolitem.ItemGTTool; import gregtech.api.modules.GregTechModule; import gregtech.api.recipes.machines.RecipeMapScanner; +import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.Materials; import gregtech.api.unification.material.event.MaterialEvent; import gregtech.api.unification.material.info.MaterialFlags; import gregtech.api.unification.material.properties.OreProperty; import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.api.unification.ore.OrePrefix; +import gregtech.api.util.Mods; import gregtech.common.items.ToolItems; import gregtech.integration.IntegrationModule; import gregtech.integration.IntegrationSubmodule; @@ -25,10 +28,10 @@ import net.minecraft.client.Minecraft; import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; @@ -41,13 +44,15 @@ import forestry.core.items.IColoredItem; import org.jetbrains.annotations.NotNull; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Collections; import java.util.List; @GregTechModule( moduleID = GregTechModules.MODULE_FR, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_FR, + modDependencies = Mods.Names.FORESTRY, name = "GregTech Forestry Integration", description = "Forestry Integration Module") public class ForestryModule extends IntegrationSubmodule { @@ -95,7 +100,7 @@ public void preInit(FMLPreInitializationEvent event) { // GT Frames if (ForestryConfig.enableGTFrames) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { FRAME_ACCELERATED = new GTItemFrame(GTFrameType.ACCELERATED); FRAME_MUTAGENIC = new GTItemFrame(GTFrameType.MUTAGENIC); FRAME_WORKING = new GTItemFrame(GTFrameType.WORKING); @@ -121,7 +126,7 @@ public void preInit(FMLPreInitializationEvent event) { // GT Bees if (ForestryConfig.enableGTBees) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { DROPS = new GTDropItem(); COMBS = new GTCombItem(); } else { @@ -132,7 +137,7 @@ public void preInit(FMLPreInitializationEvent event) { // Remove duplicate/conflicting bees from other Forestry addons. // Done in init to have our changes applied before their registration, // since we load after other Forestry addons purposefully. - if (ForestryConfig.disableConflictingBees && ForestryUtil.apicultureEnabled()) { + if (ForestryConfig.disableConflictingBees && Mods.ForestryApiculture.isModLoaded()) { BeeRemovals.init(); } @@ -149,7 +154,7 @@ public void init(FMLInitializationEvent event) { ForestryElectrodeRecipes.onInit(); } - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.harderForestryRecipes) { ForestryMiscRecipes.initRemoval(); } @@ -160,8 +165,12 @@ public void init(FMLInitializationEvent event) { } } + if (Mods.ExtraBees.isModLoaded()) { + registerAlvearyMutators(); + } + if (event.getSide() == Side.CLIENT) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTBees) { Minecraft.getMinecraft().getItemColors().registerItemColorHandler((stack, tintIndex) -> { if (stack.getItem() instanceof IColoredItem coloredItem) { @@ -176,7 +185,7 @@ public void init(FMLInitializationEvent event) { @Override public void postInit(FMLPostInitializationEvent event) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { getLogger().info("Copying Forestry Centrifuge recipes to GT Centrifuge"); CombRecipes.initForestryCombs(); } @@ -187,7 +196,7 @@ public static void registerItems(RegistryEvent.Register event) { IForgeRegistry registry = event.getRegistry(); // GT Frames - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTFrames) { registry.register(FRAME_ACCELERATED); registry.register(FRAME_MUTAGENIC); @@ -213,20 +222,19 @@ public static void registerItems(RegistryEvent.Register event) { ELECTRODE_OBSIDIAN = forestryMetaItem.addItem(10, "electrode.obsidian"); ELECTRODE_TIN = forestryMetaItem.addItem(11, "electrode.tin"); - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.BinnieCore.isModLoaded()) { ELECTRODE_IRON = forestryMetaItem.addItem(12, "electrode.iron"); } - if (Loader.isModLoaded(GTValues.MODID_XU2)) { + if (Mods.ExtraUtilities2.isModLoaded()) { ELECTRODE_ORCHID = forestryMetaItem.addItem(13, "electrode.orchid"); } - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_TR) || - Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.TechReborn.isModLoaded() || Mods.BinnieCore.isModLoaded()) { ELECTRODE_RUBBER = forestryMetaItem.addItem(14, "electrode.rubber"); } } // GT Drops - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTBees) { registry.register(DROPS); registry.register(COMBS); @@ -237,7 +245,7 @@ public static void registerItems(RegistryEvent.Register event) { @SideOnly(Side.CLIENT) @SubscribeEvent public static void registerModels(ModelRegistryEvent event) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTFrames) { FRAME_ACCELERATED.registerModel(FRAME_ACCELERATED, ForestryAPI.modelManager); FRAME_MUTAGENIC.registerModel(FRAME_MUTAGENIC, ForestryAPI.modelManager); @@ -256,7 +264,7 @@ public static void registerModels(ModelRegistryEvent event) { @SubscribeEvent public static void registerRecipes(RegistryEvent.Register event) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { // GT Frames if (ForestryConfig.enableGTFrames) { ForestryFrameRecipes.init(); @@ -285,7 +293,7 @@ public static void registerRecipes(RegistryEvent.Register event) { @SubscribeEvent public static void registerMaterials(MaterialEvent event) { - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { if (ForestryConfig.enableGTFrames) { Materials.TreatedWood.addFlags(MaterialFlags.GENERATE_LONG_ROD); Materials.Uranium235.addFlags(MaterialFlags.GENERATE_LONG_ROD); @@ -315,7 +323,8 @@ public static void registerMaterials(MaterialEvent event) { createOreProperty(Materials.Osmium, Materials.Iridium); createOreProperty(Materials.Iridium, Materials.Platinum, Materials.Osmium); createOreProperty(Materials.Electrum, Materials.Gold, Materials.Silver); - createOreProperty(Materials.Uranium238, Materials.Lead, Materials.Uranium235, Materials.Thorium); + createOreProperty(Materials.Uranium, Materials.Lead, Materials.Uranium235, Materials.Thorium); + createOreProperty(Materials.Plutonium, Materials.Uraninite, Materials.Lead, Materials.Uraninite); createOreProperty(Materials.NaquadahEnriched, Materials.Naquadah, Materials.Naquadria); createOreProperty(Materials.Uranium235); createOreProperty(Materials.Neutronium); @@ -344,4 +353,31 @@ private static void createOreProperty(Material material, Material... byproducts) material.setProperty(PropertyKey.ORE, property); material.addFlags(MaterialFlags.DISABLE_ORE_BLOCK); } + + private static void registerAlvearyMutators() { + try { + Class mutationHandler = Class.forName("binnie.extrabees.utils.AlvearyMutationHandler"); + Method method = mutationHandler.getDeclaredMethod("addMutationItem", ItemStack.class, float.class); + + registerAlvearyMutator(method, Materials.Uranium, 2.0f); + registerAlvearyMutator(method, Materials.Uranium235, 4.0f); + registerAlvearyMutator(method, Materials.Plutonium241, 6.0f); + registerAlvearyMutator(method, Materials.Plutonium239, 8.0f); + registerAlvearyMutator(method, Materials.NaquadahEnriched, 10.0f); + registerAlvearyMutator(method, Materials.Naquadria, 15.0f); + } catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) { + IntegrationModule.logger.error("Could not register GT Alveary mutators!"); + } + } + + private static void registerAlvearyMutator(Method method, Material material, float chance) { + try { + ItemStack stack = OreDictUnifier.get(OrePrefix.dust, material); + if (stack != ItemStack.EMPTY) { + method.invoke(null, stack, chance); + } + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + IntegrationModule.logger.error("Could not register GT Alveary mutators!"); + } + } } diff --git a/src/main/java/gregtech/integration/forestry/ForestryUtil.java b/src/main/java/gregtech/integration/forestry/ForestryUtil.java index 32fff8e1e19..1bc2a8df6c0 100644 --- a/src/main/java/gregtech/integration/forestry/ForestryUtil.java +++ b/src/main/java/gregtech/integration/forestry/ForestryUtil.java @@ -1,6 +1,6 @@ package gregtech.integration.forestry; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.integration.IntegrationModule; import gregtech.integration.forestry.bees.GTCombType; import gregtech.integration.forestry.bees.GTDropType; @@ -11,52 +11,39 @@ import forestry.api.apiculture.IAlleleBeeSpecies; import forestry.api.genetics.AlleleManager; import forestry.api.genetics.IAlleleFlowers; -import forestry.modules.ModuleHelper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class ForestryUtil { - public static boolean apicultureEnabled() { - return ModuleHelper.isEnabled("apiculture"); - } - - public static boolean arboricultureEnabled() { - return ModuleHelper.isEnabled("arboriculture"); - } - - public static boolean lepidopterologyEnabled() { - return ModuleHelper.isEnabled("lepidopterology"); - } - @Nullable - public static IAlleleBeeEffect getEffect(@NotNull String modid, @NotNull String name) { - String s = switch (modid) { - case GTValues.MODID_EB -> "extrabees.effect." + name; - case GTValues.MODID_MB -> "magicbees.effect" + name; - case GTValues.MODID -> "gregtech.effect." + name; + public static IAlleleBeeEffect getEffect(@NotNull Mods mod, @NotNull String name) { + String s = switch (mod) { + case ExtraBees -> "extrabees.effect." + name; + case MagicBees -> "magicbees.effect" + name; + case GregTech -> "gregtech.effect." + name; default -> "forestry.effect" + name; }; return (IAlleleBeeEffect) AlleleManager.alleleRegistry.getAllele(s); } @Nullable - public static IAlleleFlowers getFlowers(@NotNull String modid, @NotNull String name) { - String s = switch (modid) { - case GTValues.MODID_EB -> "extrabees.flower." + name; - case GTValues.MODID_MB -> "magicbees.flower" + name; - case GTValues.MODID -> "gregtech.flower." + name; + public static IAlleleFlowers getFlowers(@NotNull Mods mod, @NotNull String name) { + String s = switch (mod) { + case ExtraBees -> "extrabees.flower." + name; + case MagicBees -> "magicbees.flower" + name; + case GregTech -> "gregtech.flower." + name; default -> "forestry.flowers" + name; }; return (IAlleleFlowers) AlleleManager.alleleRegistry.getAllele(s); } @Nullable - public static IAlleleBeeSpecies getSpecies(@NotNull String modid, @NotNull String name) { - String s = switch (modid) { - case GTValues.MODID_EB -> "extrabees.species." + name; - case GTValues.MODID_MB -> "magicbees.species" + name; - case GTValues.MODID -> "gregtech.species." + name; + public static IAlleleBeeSpecies getSpecies(@NotNull Mods mod, @NotNull String name) { + String s = switch (mod) { + case ExtraBees -> "extrabees.species." + name; + case MagicBees -> "magicbees.species" + name; + case GregTech -> "gregtech.species." + name; default -> "forestry.species" + name; }; return (IAlleleBeeSpecies) AlleleManager.alleleRegistry.getAllele(s); @@ -74,7 +61,7 @@ public static ItemStack getCombStack(@NotNull GTCombType type, int amount) { .error("Tried to get GregTech Comb stack, but GregTech Bees config is not enabled!"); return ItemStack.EMPTY; } - if (!apicultureEnabled()) { + if (!Mods.ForestryApiculture.isModLoaded()) { IntegrationModule.logger.error("Tried to get GregTech Comb stack, but Apiculture module is not enabled!"); return ItemStack.EMPTY; } @@ -93,7 +80,7 @@ public static ItemStack getDropStack(@NotNull GTDropType type, int amount) { .error("Tried to get GregTech Drop stack, but GregTech Bees config is not enabled!"); return ItemStack.EMPTY; } - if (!apicultureEnabled()) { + if (!Mods.ForestryApiculture.isModLoaded()) { IntegrationModule.logger.error("Tried to get GregTech Drop stack, but Apiculture module is not enabled!"); return ItemStack.EMPTY; } diff --git a/src/main/java/gregtech/integration/forestry/bees/BeeRemovals.java b/src/main/java/gregtech/integration/forestry/bees/BeeRemovals.java index 65546dfe020..39dcb08e103 100644 --- a/src/main/java/gregtech/integration/forestry/bees/BeeRemovals.java +++ b/src/main/java/gregtech/integration/forestry/bees/BeeRemovals.java @@ -1,10 +1,8 @@ package gregtech.integration.forestry.bees; -import gregtech.api.GTValues; +import gregtech.api.util.Mods; import gregtech.integration.IntegrationModule; -import net.minecraftforge.fml.common.Loader; - import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; @@ -16,10 +14,10 @@ public class BeeRemovals { private static final List EB_REMOVALS = new ArrayList<>(); public static void init() { - if (Loader.isModLoaded(GTValues.MODID_MB)) { + if (Mods.MagicBees.isModLoaded()) { removeMagicBees(); } - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { removeExtraBees(); } } diff --git a/src/main/java/gregtech/integration/forestry/bees/ForestryScannerLogic.java b/src/main/java/gregtech/integration/forestry/bees/ForestryScannerLogic.java index 891a8277bc9..0bd8d25bf53 100644 --- a/src/main/java/gregtech/integration/forestry/bees/ForestryScannerLogic.java +++ b/src/main/java/gregtech/integration/forestry/bees/ForestryScannerLogic.java @@ -3,7 +3,7 @@ import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMaps; import gregtech.api.recipes.machines.IScannerRecipeMap; -import gregtech.integration.forestry.ForestryUtil; +import gregtech.api.util.Mods; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -60,7 +60,7 @@ public List getRepresentativeRecipes() { List recipes = new ArrayList<>(); ItemStack outputStack; - if (ForestryUtil.apicultureEnabled()) { + if (Mods.ForestryApiculture.isModLoaded()) { outputStack = ModuleApiculture.getItems().beeDroneGE.getItemStack(); outputStack.setTagCompound(BeeDefinition.COMMON.getIndividual().writeToNBT(new NBTTagCompound())); outputStack.setTranslatableName("gregtech.scanner.forestry.drone"); @@ -98,7 +98,7 @@ public List getRepresentativeRecipes() { .duration(DURATION).EUt(EUT).build().getResult()); } - if (ForestryUtil.arboricultureEnabled()) { + if (Mods.ForestryArboriculture.isModLoaded()) { outputStack = ModuleArboriculture.getItems().sapling.getItemStack(); outputStack.setTagCompound(TreeDefinition.Oak.getIndividual().writeToNBT(new NBTTagCompound())); outputStack.setTranslatableName("gregtech.scanner.forestry.sapling"); @@ -118,7 +118,7 @@ public List getRepresentativeRecipes() { .duration(DURATION).EUt(EUT).build().getResult()); } - if (ForestryUtil.lepidopterologyEnabled()) { + if (Mods.ForestryLepidopterology.isModLoaded()) { outputStack = ModuleLepidopterology.getItems().butterflyGE.getItemStack(); outputStack .setTagCompound(ButterflyDefinition.CabbageWhite.getIndividual().writeToNBT(new NBTTagCompound())); diff --git a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java index 97fed7a25c3..149ba5d57cb 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTBeeDefinition.java @@ -4,21 +4,26 @@ 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.IntegrationUtil; 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; import net.minecraft.item.ItemStack; import net.minecraftforge.common.BiomeDictionary; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Optional; import appeng.core.Api; -import forestry.api.apiculture.*; +import forestry.api.apiculture.BeeManager; +import forestry.api.apiculture.EnumBeeType; +import forestry.api.apiculture.IAlleleBeeSpecies; +import forestry.api.apiculture.IBee; +import forestry.api.apiculture.IBeeGenome; +import forestry.api.apiculture.IBeeMutationBuilder; import forestry.api.core.EnumHumidity; import forestry.api.core.EnumTemperature; import forestry.api.genetics.IAllele; @@ -41,13 +46,14 @@ import java.util.function.Supplier; import static forestry.api.apiculture.EnumBeeChromosome.*; +import static gregtech.api.unification.material.Materials.*; public enum GTBeeDefinition implements IBeeDefinition { // Organic CLAY(GTBranchDefinition.GT_ORGANIC, "Lutum", true, 0xC8C8DA, 0x0000FF, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(22), 0.30f); // CLAY } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.HONEY), 0.30f); @@ -55,8 +61,8 @@ public enum GTBeeDefinition implements IBeeDefinition { beeSpecies.addProduct(new ItemStack(Items.CLAY_BALL), 0.15f); beeSpecies.setHumidity(EnumHumidity.DAMP); beeSpecies.setTemperature(EnumTemperature.NORMAL); - if (Loader.isModLoaded(GTValues.MODID_BOP)) { - beeSpecies.addSpecialty(IntegrationUtil.getModItem(GTValues.MODID_BOP, "mudball", 0), 0.05f); + if (Mods.BiomesOPlenty.isModLoaded()) { + beeSpecies.addSpecialty(Mods.BiomesOPlenty.getItem("mudball", 0), 0.05f); } }, template -> { @@ -76,10 +82,9 @@ public enum GTBeeDefinition implements IBeeDefinition { beeSpecies.addSpecialty(getGTComb(GTCombType.STICKY), 0.05f); beeSpecies.setHumidity(EnumHumidity.DAMP); beeSpecies.setTemperature(EnumTemperature.NORMAL); - if (Loader.isModLoaded(GTValues.MODID_TCON)) { - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_TCON, "edible", 1), 0.10f); - beeSpecies.addSpecialty(IntegrationUtil.getModItem(GTValues.MODID_TCON, "slime_congealed", 2), - 0.01f); + if (Mods.TinkersConstruct.isModLoaded()) { + beeSpecies.addProduct(Mods.TinkersConstruct.getItem("edible", 1), 0.10f); + beeSpecies.addSpecialty(Mods.TinkersConstruct.getItem("slime_congealed", 2), 0.01f); } else { beeSpecies.addSpecialty(new ItemStack(Blocks.SLIME_BLOCK), 0.01f); } @@ -89,9 +94,9 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, FLOWERING, EnumAllele.Flowering.SLOWER); AlleleHelper.getInstance().set(template, TEMPERATURE_TOLERANCE, EnumAllele.Tolerance.BOTH_1); AlleleHelper.getInstance().set(template, HUMIDITY_TOLERANCE, EnumAllele.Tolerance.BOTH_1); - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { AlleleHelper.getInstance().set(template, FLOWER_PROVIDER, - ForestryUtil.getFlowers(GTValues.MODID_EB, "water")); + ForestryUtil.getFlowers(Mods.ExtraBees, "water")); } }, dis -> { @@ -149,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 -> { @@ -166,15 +171,15 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, SPEED, EnumAllele.Speed.SLOWER); AlleleHelper.getInstance().set(template, TEMPERATURE_TOLERANCE, EnumAllele.Tolerance.NONE); AlleleHelper.getInstance().set(template, HUMIDITY_TOLERANCE, EnumAllele.Tolerance.NONE); - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { AlleleHelper.getInstance().set(template, FLOWER_PROVIDER, - ForestryUtil.getFlowers(GTValues.MODID_EB, "water")); + ForestryUtil.getFlowers(Mods.ExtraBees, "water")); } }, dis -> dis.registerMutation(COAL, STICKYRESIN, 4)), ASH(GTBranchDefinition.GT_ORGANIC, "Cinis", true, 0x1E1A18, 0xC6C6C6, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(9), 0.30f); // SEED } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.HONEY), 0.30f); @@ -196,7 +201,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }), APATITE(GTBranchDefinition.GT_ORGANIC, "Stercorat", true, 0x7FCEF5, 0x654525, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(9), 0.15f); // SEED } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.HONEY), 0.15f); @@ -210,14 +215,14 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.LONGER); AlleleHelper.getInstance().set(template, FLOWER_PROVIDER, EnumAllele.Flowers.WHEAT); AlleleHelper.getInstance().set(template, FLOWERING, EnumAllele.Flowering.FASTER); - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { AlleleHelper.getInstance().set(template, FLOWER_PROVIDER, - ForestryUtil.getFlowers(GTValues.MODID_EB, "rock")); + ForestryUtil.getFlowers(Mods.ExtraBees, "rock")); } }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(ASH, COAL, 10); - mutation.requireResource("blockApatite"); + mutation.addMutationCondition(new MaterialMutationCondition(Apatite)); }), BIOMASS(GTBranchDefinition.GT_ORGANIC, "Taeda", true, 0x21E118, 0x17AF0E, beeSpecies -> { @@ -238,7 +243,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }), FERTILIZER(GTBranchDefinition.GT_ORGANIC, "Stercorat", true, 0x7FCEF5, 0x654525, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(9), 0.15f); // SEED } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.MOSSY), 0.15f); @@ -246,7 +251,7 @@ public enum GTBeeDefinition implements IBeeDefinition { beeSpecies.addSpecialty(OreDictUnifier.get(OrePrefix.dustTiny, Materials.Ash), 0.2f); beeSpecies.addSpecialty(OreDictUnifier.get(OrePrefix.dustTiny, Materials.DarkAsh), 0.2f); beeSpecies.addSpecialty(MetaItems.FERTILIZER.getStackForm(), 0.3f); - beeSpecies.addSpecialty(IntegrationUtil.getModItem(GTValues.MODID_FR, "fertilizer_compound", 0), 0.3f); + beeSpecies.addSpecialty(Mods.Forestry.getItem("fertilizer_compound", 0), 0.3f); beeSpecies.setHumidity(EnumHumidity.DAMP); beeSpecies.setTemperature(EnumTemperature.WARM); }, @@ -268,20 +273,16 @@ 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 -> { - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_GTFO, "gtfo_meta_item", 81), 0.05f); // Cucumber - // Slice - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_GTFO, "gtfo_meta_item", 80), 0.05f); // Onion - // Slice - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_GTFO, "gtfo_meta_item", 79), 0.05f); // Tomato - // Slice + beeSpecies.addProduct(Mods.GregTechFoodOption.getItem("gtfo_meta_item", 81), 0.05f); // Cucumber Slice + beeSpecies.addProduct(Mods.GregTechFoodOption.getItem("gtfo_meta_item", 80), 0.05f); // Onion Slice + beeSpecies.addProduct(Mods.GregTechFoodOption.getItem("gtfo_meta_item", 79), 0.05f); // Tomato Slice beeSpecies.addSpecialty(new ItemStack(Items.COOKED_PORKCHOP), 0.05f); beeSpecies.addSpecialty(new ItemStack(Items.COOKED_BEEF), 0.15f); - beeSpecies.addSpecialty(IntegrationUtil.getModItem(GTValues.MODID_GTFO, "gtfo_meta_item", 97), 0.05f); // Cheddar - // Slice + beeSpecies.addSpecialty(Mods.GregTechFoodOption.getItem("gtfo_meta_item", 97), 0.05f); // Cheddar Slice beeSpecies.setHumidity(EnumHumidity.NORMAL); beeSpecies.setTemperature(EnumTemperature.NORMAL); }, @@ -295,14 +296,13 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, FLOWERING, EnumAllele.Flowering.FASTER); }, dis -> { - if (Loader.isModLoaded(GTValues.MODID_MB)) { - dis.registerMutation(BeeDefinition.AGRARIAN, ForestryUtil.getSpecies(GTValues.MODID_MB, "Batty"), - 10); + if (Mods.MagicBees.isModLoaded()) { + dis.registerMutation(BeeDefinition.AGRARIAN, ForestryUtil.getSpecies(Mods.MagicBees, "Batty"), 10); } else { dis.registerMutation(BeeDefinition.AGRARIAN, BeeDefinition.IMPERIAL, 10); } }, - () -> Loader.isModLoaded(GTValues.MODID_GTFO)), + Mods.GregTechFoodOption::isModLoaded), // Gems REDSTONE(GTBranchDefinition.GT_GEM, "Rubrumlapis", true, 0x7D0F0F, 0xD11919, @@ -317,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 -> { @@ -329,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 -> { @@ -341,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 -> { @@ -356,7 +356,7 @@ public enum GTBeeDefinition implements IBeeDefinition { Api.INSTANCE.definitions().blocks().fluixBlock().maybeBlock() .ifPresent(block -> mutation.requireResource(block.getDefaultState())); }, - () -> Loader.isModLoaded(GTValues.MODID_APPENG)), + Mods.AppliedEnergistics2::isModLoaded), DIAMOND(GTBranchDefinition.GT_GEM, "Adamas", false, 0xCCFFFF, 0xA3CCCC, beeSpecies -> { beeSpecies.addProduct(getGTComb(GTCombType.STONE), 0.30f); @@ -368,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 -> { @@ -381,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 -> { @@ -393,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 -> { @@ -417,11 +417,11 @@ 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 -> { - beeSpecies.addProduct(IntegrationUtil.getModItem(GTValues.MODID_MB, "resource", 3), 0.20f); + beeSpecies.addProduct(Mods.MagicBees.getItem("resource", 3), 0.20f); beeSpecies.addSpecialty(getGTComb(GTCombType.SPARKLING), 0.125f); beeSpecies.setHumidity(EnumHumidity.NORMAL); beeSpecies.setTemperature(EnumTemperature.NORMAL); @@ -437,12 +437,12 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation( - ForestryUtil.getSpecies(GTValues.MODID_MB, "Withering"), - ForestryUtil.getSpecies(GTValues.MODID_MB, "Draconic"), 1); - mutation.requireResource("blockNetherStar"); + ForestryUtil.getSpecies(Mods.MagicBees, "Withering"), + ForestryUtil.getSpecies(Mods.MagicBees, "Draconic"), 1); + mutation.addMutationCondition(new MaterialMutationCondition(NetherStar)); mutation.restrictBiomeType(BiomeDictionary.Type.END); }, - () -> Loader.isModLoaded(GTValues.MODID_MB)), + Mods.MagicBees::isModLoaded), // Metals COPPER(GTBranchDefinition.GT_METAL, "Cuprum", true, 0xFF6600, 0xE65C00, @@ -456,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 -> { @@ -469,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 -> { @@ -482,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 -> { @@ -495,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 -> { @@ -508,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, @@ -522,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 -> { @@ -535,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 -> { @@ -548,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 -> { @@ -561,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, @@ -574,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 -> { @@ -587,9 +587,9 @@ public enum GTBeeDefinition implements IBeeDefinition { AlleleHelper.getInstance().set(template, TOLERATES_RAIN, true); }, dis -> { - if (Loader.isModLoaded(GTValues.MODID_MB) && Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.MagicBees.isModLoaded() && Mods.AppliedEnergistics2.isModLoaded()) { // MB Skystone bee is only registered if AE2 is also active - dis.registerMutation(IRON, ForestryUtil.getSpecies(GTValues.MODID_MB, "AESkystone"), 17); + dis.registerMutation(IRON, ForestryUtil.getSpecies(Mods.MagicBees, "AESkystone"), 17); } else { dis.registerMutation(IRON, BeeDefinition.IMPERIAL, 17); } @@ -607,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 -> { @@ -620,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, @@ -634,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 -> { @@ -647,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 -> { @@ -660,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 -> { @@ -673,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 -> { @@ -687,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 -> { @@ -701,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 -> { @@ -714,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 -> { @@ -727,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 -> { @@ -740,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 -> { @@ -760,14 +760,14 @@ 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); }), // Industrial ENERGY(GTBranchDefinition.GT_INDUSTRIAL, "Industria", false, 0xC11F1F, 0xEBB9B9, beeSpecies -> { - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { beeSpecies.addProduct(getExtraBeesComb(14), 0.30f); // STATIC } else { beeSpecies.addProduct(getForestryComb(EnumHoneyComb.SIMMERING), 0.30f); @@ -788,13 +788,13 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { mutation = dis.registerMutation(BeeDefinition.DEMONIC, - ForestryUtil.getSpecies(GTValues.MODID_EB, "volcanic"), 10); + ForestryUtil.getSpecies(Mods.ExtraBees, "volcanic"), 10); } else { mutation = dis.registerMutation(BeeDefinition.DEMONIC, BeeDefinition.FIENDISH, 10); } - mutation.requireResource("blockRedstone"); + mutation.addMutationCondition(new MaterialMutationCondition(Redstone)); }), LAPOTRON(GTBranchDefinition.GT_INDUSTRIAL, "Azureus", false, 0xFFEBC4, 0xE36400, beeSpecies -> { @@ -816,13 +816,12 @@ 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, beeSpecies -> { - beeSpecies.addProduct(new ItemStack(Blocks.TNT), 0.2f); - // todo if we add a ITNT substitute, put it here instead of TNT + beeSpecies.addProduct(new ItemStack(MetaBlocks.ITNT), 0.2f); beeSpecies.setHumidity(EnumHumidity.ARID); beeSpecies.setTemperature(EnumTemperature.HELLISH); beeSpecies.setHasEffect(); @@ -855,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 -> { @@ -873,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 @@ -891,7 +890,7 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IBeeMutationBuilder mutation = dis.registerMutation(BeeDefinition.AVENGING, PLATINUM, 2); - mutation.requireResource("blockUranium"); + mutation.addMutationCondition(new MaterialMutationCondition(Uranium)); }), PLUTONIUM(GTBranchDefinition.GT_RADIOACTIVE, "Plutos", true, 0x570000, 0x240000, beeSpecies -> { @@ -908,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 -> { @@ -925,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 -> { @@ -943,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 -> { @@ -957,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 -> { @@ -972,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 -> { @@ -988,13 +987,13 @@ public enum GTBeeDefinition implements IBeeDefinition { }, dis -> { IMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_EB)) { - mutation = dis.registerMutation(THORIUM, ForestryUtil.getSpecies(GTValues.MODID_EB, "rotten"), 1); + if (Mods.ExtraBees.isModLoaded()) { + mutation = dis.registerMutation(THORIUM, ForestryUtil.getSpecies(Mods.ExtraBees, "rotten"), 1); } else { mutation = dis.registerMutation(THORIUM, BeeDefinition.IMPERIAL, 1); } mutation.setIsSecret(); - mutation.requireResource("blockLutetium"); + mutation.addMutationCondition(new MaterialMutationCondition(Lutetium)); }), AMERICIUM(GTBranchDefinition.GT_RADIOACTIVE, "Libertas", false, 0x287869, 0x0C453A, beeSpecies -> { @@ -1010,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 -> { @@ -1026,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 @@ -1041,9 +1040,9 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.SHORTEST), dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_MB)) { + if (Mods.MagicBees.isModLoaded()) { mutation = dis.registerMutation(STAINLESSSTEEL, - ForestryUtil.getSpecies(GTValues.MODID_MB, "Watery"), 10); + ForestryUtil.getSpecies(Mods.MagicBees, "Watery"), 10); } else { mutation = dis.registerMutation(STAINLESSSTEEL, BeeDefinition.INDUSTRIOUS, 10); } @@ -1060,9 +1059,8 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.SHORTEST), dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_MB)) { - mutation = dis.registerMutation(HELIUM, ForestryUtil.getSpecies(GTValues.MODID_MB, "Supernatural"), - 8); + if (Mods.MagicBees.isModLoaded()) { + mutation = dis.registerMutation(HELIUM, ForestryUtil.getSpecies(Mods.MagicBees, "Supernatural"), 8); } else { mutation = dis.registerMutation(HELIUM, BeeDefinition.IMPERIAL, 8); } @@ -1092,9 +1090,8 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.SHORTEST), dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_MB)) { - mutation = dis.registerMutation(NEON, ForestryUtil.getSpecies(GTValues.MODID_MB, "Supernatural"), - 4); + if (Mods.MagicBees.isModLoaded()) { + mutation = dis.registerMutation(NEON, ForestryUtil.getSpecies(Mods.MagicBees, "Supernatural"), 4); } else { mutation = dis.registerMutation(NEON, BeeDefinition.AVENGING, 4); } @@ -1139,8 +1136,8 @@ public enum GTBeeDefinition implements IBeeDefinition { template -> AlleleHelper.getInstance().set(template, LIFESPAN, EnumAllele.Lifespan.SHORTEST), dis -> { IBeeMutationBuilder mutation; - if (Loader.isModLoaded(GTValues.MODID_MB)) { - mutation = dis.registerMutation(OXYGEN, ForestryUtil.getSpecies(GTValues.MODID_MB, "Watery"), 15); + if (Mods.MagicBees.isModLoaded()) { + mutation = dis.registerMutation(OXYGEN, ForestryUtil.getSpecies(Mods.MagicBees, "Watery"), 15); } else { mutation = dis.registerMutation(OXYGEN, BeeDefinition.INDUSTRIOUS, 15); } @@ -1215,7 +1212,7 @@ public enum GTBeeDefinition implements IBeeDefinition { String name = "for.bees.species." + lowercaseName; this.branch = branch; - this.species = new GTAlleleBeeSpecies(GTValues.MODID, uid, name, "GregTech", description, dominant, + this.species = new GTAlleleBeeSpecies(GTValues.MODID, uid, name, GTValues.MOD_NAME, description, dominant, branch.getBranch(), binomial, primary, secondary); this.generationCondition = generationCondition; } @@ -1233,14 +1230,14 @@ private static ItemStack getForestryComb(EnumHoneyComb type) { return ModuleApiculture.getItems().beeComb.get(type, 1); } - @Optional.Method(modid = GTValues.MODID_EB) + @Optional.Method(modid = Mods.Names.EXTRA_BEES) private static ItemStack getExtraBeesComb(int meta) { - return IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_comb", meta); + return Mods.ExtraBees.getItem("honey_comb", meta); } - @Optional.Method(modid = GTValues.MODID_MB) + @Optional.Method(modid = Mods.Names.MAGIC_BEES) private static ItemStack getMagicBeesComb(int meta) { - return IntegrationUtil.getModItem(GTValues.MODID_MB, "beecomb", meta); + return Mods.MagicBees.getItem("beecomb", meta); } private static ItemStack getGTComb(GTCombType type) { diff --git a/src/main/java/gregtech/integration/forestry/bees/GTCombItem.java b/src/main/java/gregtech/integration/forestry/bees/GTCombItem.java index 0769ad034bf..e037872f2cf 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTCombItem.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTCombItem.java @@ -1,6 +1,7 @@ package gregtech.integration.forestry.bees; import gregtech.api.GTValues; +import gregtech.api.util.Mods; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.creativetab.CreativeTabs; @@ -37,7 +38,7 @@ public GTCombItem() { public void registerModel(@NotNull Item item, IModelManager manager) { manager.registerItemModel(item, 0); for (int i = 0; i < GTCombType.values().length; i++) { - manager.registerItemModel(item, i, GTValues.MODID_FR, "gt.comb"); + manager.registerItemModel(item, i, Mods.Names.FORESTRY, "gt.comb"); } } diff --git a/src/main/java/gregtech/integration/forestry/bees/GTCombType.java b/src/main/java/gregtech/integration/forestry/bees/GTCombType.java index f774e6f68d0..e17fc00a429 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTCombType.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTCombType.java @@ -1,8 +1,6 @@ package gregtech.integration.forestry.bees; -import gregtech.api.GTValues; - -import net.minecraftforge.fml.common.Loader; +import gregtech.api.util.Mods; public enum GTCombType { @@ -27,7 +25,7 @@ public enum GTCombType { // Gem STONE("stone", 0x808080, 0x999999), CERTUS("certus", 0x57CFFB, 0xBBEEFF), - FLUIX("fluix", 0xA375FF, 0xB591FF, Loader.isModLoaded(GTValues.MODID_APPENG)), + FLUIX("fluix", 0xA375FF, 0xB591FF, Mods.AppliedEnergistics2.isModLoaded()), REDSTONE("redstone", 0x7D0F0F, 0xD11919), RAREEARTH("rareearth", 0x555643, 0x343428), LAPIS("lapis", 0x1947D1, 0x476CDA), @@ -38,7 +36,7 @@ public enum GTCombType { EMERALD("emerald", 0x248F24, 0x2EB82E), PYROPE("pyrope", 0x763162, 0x8B8B8B), GROSSULAR("grossular", 0x9B4E00, 0x8B8B8B), - SPARKLING("sparkling", 0x7A007A, 0xFFFFFF, Loader.isModLoaded(GTValues.MODID_MB)), + SPARKLING("sparkling", 0x7A007A, 0xFFFFFF, Mods.MagicBees.isModLoaded()), // Metal SLAG("slag", 0xD4D4D4, 0x58300B), diff --git a/src/main/java/gregtech/integration/forestry/bees/GTDropItem.java b/src/main/java/gregtech/integration/forestry/bees/GTDropItem.java index 45a67068b2a..a8453a6a151 100644 --- a/src/main/java/gregtech/integration/forestry/bees/GTDropItem.java +++ b/src/main/java/gregtech/integration/forestry/bees/GTDropItem.java @@ -1,6 +1,7 @@ package gregtech.integration.forestry.bees; import gregtech.api.GTValues; +import gregtech.api.util.Mods; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; @@ -44,7 +45,7 @@ private void setResearchSuitability(@Nullable ISpeciesRoot speciesRoot) { public void registerModel(@NotNull Item item, @NotNull IModelManager manager) { manager.registerItemModel(item, 0); for (int i = 0; i < GTDropType.VALUES.length; i++) { - manager.registerItemModel(item, i, GTValues.MODID_FR, "gt.honey_drop"); + manager.registerItemModel(item, i, Mods.Names.FORESTRY, "gt.honey_drop"); } } diff --git a/src/main/java/gregtech/integration/forestry/frames/GTItemFrame.java b/src/main/java/gregtech/integration/forestry/frames/GTItemFrame.java index 088c5ed7e73..e8f9a46d45e 100644 --- a/src/main/java/gregtech/integration/forestry/frames/GTItemFrame.java +++ b/src/main/java/gregtech/integration/forestry/frames/GTItemFrame.java @@ -1,6 +1,7 @@ package gregtech.integration.forestry.frames; import gregtech.api.GTValues; +import gregtech.api.util.Mods; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.item.Item; @@ -62,7 +63,7 @@ public IBeeModifier getBeeModifier() { @SuppressWarnings("deprecation") @Override public void registerModel(@NotNull Item item, @NotNull IModelManager manager) { - manager.registerItemModel(item, 0, GTValues.MODID_FR, "gt.frame_" + type.getName().toLowerCase()); + manager.registerItemModel(item, 0, Mods.Names.FORESTRY, "gt.frame_" + type.getName().toLowerCase()); } public ItemStack getItemStack() { diff --git a/src/main/java/gregtech/integration/forestry/mutation/MaterialMutationCondition.java b/src/main/java/gregtech/integration/forestry/mutation/MaterialMutationCondition.java new file mode 100644 index 00000000000..c063f0fbed8 --- /dev/null +++ b/src/main/java/gregtech/integration/forestry/mutation/MaterialMutationCondition.java @@ -0,0 +1,67 @@ +package gregtech.integration.forestry.mutation; + +import gregtech.api.unification.OreDictUnifier; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.ore.OrePrefix; +import gregtech.api.unification.stack.UnificationEntry; +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 org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.Set; + +public class MaterialMutationCondition implements IMutationCondition { + + private final Set acceptedBlocks = new HashSet<>(); + private final String displayName; + + public MaterialMutationCondition(@NotNull Material material) { + this.displayName = LocalizationUtils.format("gregtech.mutation.block_of", material.getLocalizedName()); + String oreDictName = new UnificationEntry(OrePrefix.block, material).toString(); + + 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()); + } + } + } + } + + @Override + public float getChance(@NotNull World world, @NotNull BlockPos pos, @NotNull IAllele allele0, + @NotNull IAllele allele1, @NotNull IGenome genome0, + @NotNull IGenome genome1, @NotNull 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; + } + + @Override + public @NotNull String getDescription() { + return LocalizationUtils.format("for.mutation.condition.resource", this.displayName); + } +} diff --git a/src/main/java/gregtech/integration/forestry/recipes/CombRecipes.java b/src/main/java/gregtech/integration/forestry/recipes/CombRecipes.java index 66df87dc408..d0b851af4ac 100644 --- a/src/main/java/gregtech/integration/forestry/recipes/CombRecipes.java +++ b/src/main/java/gregtech/integration/forestry/recipes/CombRecipes.java @@ -12,8 +12,8 @@ import gregtech.api.unification.material.properties.PropertyKey; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.common.items.MetaItems; -import gregtech.integration.IntegrationUtil; import gregtech.integration.forestry.ForestryUtil; import gregtech.integration.forestry.bees.GTCombItem; import gregtech.integration.forestry.bees.GTCombType; @@ -21,7 +21,6 @@ import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.common.Loader; import appeng.core.Api; import com.google.common.collect.ImmutableMap; @@ -98,8 +97,8 @@ public static void initGTCombs() { ModuleCore.getItems().refractoryWax.getItemStack() }, new int[] { 20 * 100, 50 * 100 }, Voltage.HV, 196); ItemStack wax = ModuleCore.getItems().beeswax.getItemStack(); - if (Loader.isModLoaded(GTValues.MODID_MB)) { - wax = IntegrationUtil.getModItem(GTValues.MODID_MB, "wax", 2); + if (Mods.MagicBees.isModLoaded()) { + wax = Mods.MagicBees.getItem("wax", 2); } addCentrifugeToItemStack(GTCombType.LAPOTRON, new ItemStack[] { OreDictUnifier.get(OrePrefix.dust, Materials.Lapotron), wax }, @@ -248,14 +247,14 @@ public static void initGTCombs() { addProcessGT(GTCombType.ALMANDINE, new Material[] { Materials.Almandine, Materials.Pyrope, Materials.Sapphire, Materials.GreenSapphire }, Voltage.LV); - addProcessGT(GTCombType.URANIUM, new Material[] { Materials.Uranium238, Materials.Pitchblende, + addProcessGT(GTCombType.URANIUM, new Material[] { Materials.Uranium, Materials.Pitchblende, Materials.Uraninite, Materials.Uranium235 }, Voltage.EV); addProcessGT(GTCombType.PLUTONIUM, new Material[] { Materials.Plutonium239, Materials.Uranium235 }, Voltage.EV); addProcessGT(GTCombType.NAQUADAH, new Material[] { Materials.Naquadah, Materials.NaquadahEnriched, Materials.Naquadria }, Voltage.IV); addProcessGT(GTCombType.NAQUADRIA, new Material[] { Materials.Naquadria, Materials.NaquadahEnriched, Materials.Naquadah }, Voltage.LUV); - addProcessGT(GTCombType.THORIUM, new Material[] { Materials.Thorium, Materials.Uranium238, Materials.Coal }, + addProcessGT(GTCombType.THORIUM, new Material[] { Materials.Thorium, Materials.Uranium, Materials.Coal }, Voltage.EV); addProcessGT(GTCombType.LUTETIUM, new Material[] { Materials.Lutetium, Materials.Thorium }, Voltage.IV); addProcessGT(GTCombType.AMERICIUM, new Material[] { Materials.Americium, Materials.Lutetium }, Voltage.LUV); @@ -271,11 +270,10 @@ public static void initGTCombs() { .cleanroom(CleanroomType.CLEANROOM) .duration(3000).EUt(Voltage.UV.getChemicalEnergy()).buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_MB)) { + if (Mods.MagicBees.isModLoaded()) { addProcessGT(GTCombType.SPARKLING, new Material[] { Materials.NetherStar }, Voltage.EV); addCentrifugeToItemStack(GTCombType.SPARKLING, - new ItemStack[] { IntegrationUtil.getModItem(GTValues.MODID_MB, "wax", 0), - IntegrationUtil.getModItem(GTValues.MODID_MB, "resource", 5), + new ItemStack[] { Mods.MagicBees.getItem("wax", 0), Mods.MagicBees.getItem("resource", 5), OreDictUnifier.get(OrePrefix.dustTiny, Materials.NetherStar) }, new int[] { 50 * 100, 10 * 100, 10 * 100 }, Voltage.EV); } @@ -290,7 +288,7 @@ public static void initGTCombs() { addExtractorProcess(GTCombType.HYDROGEN, Materials.Hydrogen.getFluid(500), Voltage.MV, 100); addExtractorProcess(GTCombType.FLUORINE, Materials.Fluorine.getFluid(250), Voltage.MV, 128); - if (Loader.isModLoaded(GTValues.MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { ItemStack fluixDust = OreDictUnifier.get("dustFluix"); if (fluixDust == ItemStack.EMPTY) { fluixDust = Api.INSTANCE.definitions().materials().fluixDust().maybeStack(1).orElse(ItemStack.EMPTY); diff --git a/src/main/java/gregtech/integration/forestry/recipes/ForestryElectrodeRecipes.java b/src/main/java/gregtech/integration/forestry/recipes/ForestryElectrodeRecipes.java index 171f575bc32..72014ca62c6 100644 --- a/src/main/java/gregtech/integration/forestry/recipes/ForestryElectrodeRecipes.java +++ b/src/main/java/gregtech/integration/forestry/recipes/ForestryElectrodeRecipes.java @@ -1,14 +1,13 @@ package gregtech.integration.forestry.recipes; -import gregtech.api.GTValues; import gregtech.api.unification.stack.UnificationEntry; +import gregtech.api.util.Mods; import gregtech.integration.forestry.ForestryModule; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.common.Loader; import forestry.api.recipes.RecipeManagers; import forestry.core.ModuleCore; @@ -137,7 +136,7 @@ public static void addGregTechMachineRecipes() { .output(ForestryModule.ELECTRODE_GOLD, 2) .buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.BinnieCore.isModLoaded()) { CIRCUIT_ASSEMBLER_RECIPES.recipeBuilder().duration(150).EUt(16) .input(ForestryModule.ELECTRODE_IRON) .fluidInputs(Glass.getFluid(100)) @@ -176,7 +175,7 @@ public static void addGregTechMachineRecipes() { .output(ForestryModule.ELECTRODE_OBSIDIAN, 4) .buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_XU2)) { + if (Mods.ExtraUtilities2.isModLoaded()) { CIRCUIT_ASSEMBLER_RECIPES.recipeBuilder().duration(150).EUt(16) .input(ForestryModule.ELECTRODE_ORCHID) .fluidInputs(Glass.getFluid(100)) @@ -191,8 +190,7 @@ public static void addGregTechMachineRecipes() { } // todo mixin forestry to allow this tube always, since we have rubber (once mixin port is done) - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_TR) || - Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.TechReborn.isModLoaded() || Mods.BinnieCore.isModLoaded()) { CIRCUIT_ASSEMBLER_RECIPES.recipeBuilder().duration(150).EUt(16) .input(ForestryModule.ELECTRODE_RUBBER) .fluidInputs(Glass.getFluid(100)) @@ -248,7 +246,7 @@ private static void addForestryMachineRecipes() { '#', new UnificationEntry(wireGtSingle, RedAlloy).toString(), 'X', new UnificationEntry(plate, Bronze).toString()); - if (Loader.isModLoaded(GTValues.MODID_IC2) || Loader.isModLoaded(GTValues.MODID_BINNIE)) { + if (Mods.IndustrialCraft2.isModLoaded() || Mods.BinnieCore.isModLoaded()) { addFabricatorRecipe(EnumElectronTube.IRON, "SXS", "#X#", "XXX", 'S', new UnificationEntry(screw, Iron).toString(), @@ -301,7 +299,7 @@ private static void addForestryMachineRecipes() { '#', new UnificationEntry(plate, EnderEye).toString(), 'X', new ItemStack(Blocks.END_STONE)); - if (Loader.isModLoaded(GTValues.MODID_XU2)) { + if (Mods.ExtraUtilities2.isModLoaded()) { addFabricatorRecipe(EnumElectronTube.ORCHID, " X ", "#X#", "XXX", '#', new ItemStack(Items.REPEATER), diff --git a/src/main/java/gregtech/integration/forestry/recipes/ForestryExtractorRecipes.java b/src/main/java/gregtech/integration/forestry/recipes/ForestryExtractorRecipes.java index 5a57da584cc..e1face8fe9e 100644 --- a/src/main/java/gregtech/integration/forestry/recipes/ForestryExtractorRecipes.java +++ b/src/main/java/gregtech/integration/forestry/recipes/ForestryExtractorRecipes.java @@ -1,16 +1,14 @@ package gregtech.integration.forestry.recipes; -import gregtech.api.GTValues; import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMaps; import gregtech.api.unification.material.Materials; import gregtech.api.util.GTUtility; -import gregtech.integration.IntegrationUtil; +import gregtech.api.util.Mods; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.common.Loader; import forestry.core.fluids.Fluids; @@ -18,171 +16,107 @@ public class ForestryExtractorRecipes { public static void init() { // Commonly used items - ItemStack mulch = IntegrationUtil.getModItem(GTValues.MODID_FR, "mulch", 0); - ItemStack propolis = IntegrationUtil.getModItem(GTValues.MODID_FR, "propolis", 0); + ItemStack mulch = Mods.Forestry.getItem("mulch"); + ItemStack propolis = Mods.Forestry.getItem("propolis"); // Vanilla Fruit Juice items addFruitJuiceRecipe(new ItemStack(Items.CARROT), 200, GTUtility.copy(mulch), 2000); addFruitJuiceRecipe(new ItemStack(Items.APPLE), 200, GTUtility.copy(mulch), 2000); // Forestry fruits - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 0), 50, GTUtility.copy(mulch), 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 1), 180, GTUtility.copy(mulch), 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 2), 220, GTUtility.copy(mulch), 200); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 3), 400, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 4), 100, GTUtility.copy(mulch), - 6000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 5), 50, GTUtility.copy(mulch), - 2000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "fruits", 6), 600, GTUtility.copy(mulch), - 1000); + addSeedOilRecipe(Mods.Forestry.getItem("fruits", 0), 50, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.Forestry.getItem("fruits", 1), 180, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.Forestry.getItem("fruits", 2), 220, GTUtility.copy(mulch), 200); + addFruitJuiceRecipe(Mods.Forestry.getItem("fruits", 3), 400, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.Forestry.getItem("fruits", 4), 100, GTUtility.copy(mulch), 6000); + addFruitJuiceRecipe(Mods.Forestry.getItem("fruits", 5), 50, GTUtility.copy(mulch), 2000); + addFruitJuiceRecipe(Mods.Forestry.getItem("fruits", 6), 600, GTUtility.copy(mulch), 1000); // Honey, Honeydew - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "honey_drop", 0), 100, GTUtility.copy(propolis), - 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_FR, "honeydew", 0), 100); + addHoneyRecipe(Mods.Forestry.getItem("honey_drop"), 100, GTUtility.copy(propolis), 0); + addHoneyRecipe(Mods.Forestry.getItem("honeydew"), 100); - if (Loader.isModLoaded(GTValues.MODID_EB)) { + if (Mods.ExtraBees.isModLoaded()) { // Propolis - addExtractorRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "propolis", 0), - Materials.Water.getFluid(500)); - addExtractorRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "propolis", 1), - Materials.Oil.getFluid(500)); - addExtractorRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "propolis", 2), - Materials.Creosote.getFluid(500)); + addExtractorRecipe(Mods.ExtraBees.getItem("propolis", 0), Materials.Water.getFluid(500)); + addExtractorRecipe(Mods.ExtraBees.getItem("propolis", 1), Materials.Oil.getFluid(500)); + addExtractorRecipe(Mods.ExtraBees.getItem("propolis", 2), Materials.Creosote.getFluid(500)); // Drops - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 3), 200); - addExtractorRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 6), - Fluids.MILK.getFluid(200)); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 13), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 19), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 14), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 20), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 15), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 21), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 16), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 22), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 17), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 24), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 18), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 23), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 19), 200, - IntegrationUtil.getModItem(GTValues.MODID_EB, "misc", 25), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 20), 200, - new ItemStack(Items.DYE, 1, 14), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 21), 200, - new ItemStack(Items.DYE, 1, 6), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 22), 200, - new ItemStack(Items.DYE, 1, 5), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 23), 200, - new ItemStack(Items.DYE, 1, 8), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 24), 200, - new ItemStack(Items.DYE, 1, 12), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 25), 200, - new ItemStack(Items.DYE, 1, 9), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 26), 200, - new ItemStack(Items.DYE, 1, 10), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 27), 200, - new ItemStack(Items.DYE, 1, 13), 0); - addHoneyRecipe(IntegrationUtil.getModItem(GTValues.MODID_EB, "honey_drop", 28), 200, - new ItemStack(Items.DYE, 1, 7), 0); + addFruitJuiceRecipe(Mods.ExtraBees.getItem("honey_drop", 3), 200); + addExtractorRecipe(Mods.ExtraBees.getItem("honey_drop", 6), Fluids.MILK.getFluid(200)); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 13), 200, Mods.ExtraBees.getItem("misc", 19), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 14), 200, Mods.ExtraBees.getItem("misc", 20), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 15), 200, Mods.ExtraBees.getItem("misc", 21), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 16), 200, Mods.ExtraBees.getItem("misc", 22), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 17), 200, Mods.ExtraBees.getItem("misc", 24), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 18), 200, Mods.ExtraBees.getItem("misc", 23), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 19), 200, Mods.ExtraBees.getItem("misc", 25), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 20), 200, new ItemStack(Items.DYE, 1, 14), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 21), 200, new ItemStack(Items.DYE, 1, 6), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 22), 200, new ItemStack(Items.DYE, 1, 5), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 23), 200, new ItemStack(Items.DYE, 1, 8), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 24), 200, new ItemStack(Items.DYE, 1, 12), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 25), 200, new ItemStack(Items.DYE, 1, 9), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 26), 200, new ItemStack(Items.DYE, 1, 10), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 27), 200, new ItemStack(Items.DYE, 1, 13), 0); + addHoneyRecipe(Mods.ExtraBees.getItem("honey_drop", 28), 200, new ItemStack(Items.DYE, 1, 7), 0); } - if (Loader.isModLoaded(GTValues.MODID_ET)) { + if (Mods.ExtraTrees.isModLoaded()) { // Fruits - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 0), 150, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 1), 400, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 2), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 3), 300, GTUtility.copy(mulch), - 1000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 4), 50, GTUtility.copy(mulch), 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 5), 50, GTUtility.copy(mulch), 300); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 6), 50, GTUtility.copy(mulch), 500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 7), 50, GTUtility.copy(mulch), - 500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 8), 100, GTUtility.copy(mulch), - 6000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 9), 80, GTUtility.copy(mulch), 500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 10), 150, GTUtility.copy(mulch), - 4000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 11), 500, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 12), 150, GTUtility.copy(mulch), - 4000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 13), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 14), 400, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 15), 400, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 16), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 17), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 18), 400, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 19), 150, GTUtility.copy(mulch), - 4000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 20), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 21), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 22), 300, GTUtility.copy(mulch), - 2000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 23), 200, GTUtility.copy(mulch), - 1000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 24), 150, GTUtility.copy(mulch), - 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 25), 180, GTUtility.copy(mulch), - 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 26), 100, GTUtility.copy(mulch), - 400); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 27), 50, GTUtility.copy(mulch), 200); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 28), 100, GTUtility.copy(mulch), - 3000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 29), 100, GTUtility.copy(mulch), - 3000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 30), 100, GTUtility.copy(mulch), - 4000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 31), 20, GTUtility.copy(mulch), 200); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 32), 50, GTUtility.copy(mulch), 300); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 33), 50, GTUtility.copy(mulch), 300); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 34), 100, GTUtility.copy(mulch), - 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 35), 50, GTUtility.copy(mulch), 300); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 36), 50, GTUtility.copy(mulch), 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 37), 20, GTUtility.copy(mulch), 200); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 38), 300, GTUtility.copy(mulch), - 1500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 39), 25, GTUtility.copy(mulch), 200); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 46), 50, GTUtility.copy(mulch), - 500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 50), 300, GTUtility.copy(mulch), - 2500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 51), 150, GTUtility.copy(mulch), - 1500); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 52), 300, GTUtility.copy(mulch), - 1500); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 53), 50, GTUtility.copy(mulch), - 1000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 54), 50, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 55), 100, GTUtility.copy(mulch), - 1000); - addSeedOilRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 56), 100, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 57), 400, GTUtility.copy(mulch), - 2000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 58), 300, GTUtility.copy(mulch), - 1000); - addFruitJuiceRecipe(IntegrationUtil.getModItem(GTValues.MODID_ET, "food", 59), 50, GTUtility.copy(mulch), - 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 0), 150, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 1), 400, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 2), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 3), 300, GTUtility.copy(mulch), 1000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 4), 50, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 5), 50, GTUtility.copy(mulch), 300); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 6), 50, GTUtility.copy(mulch), 500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 7), 50, GTUtility.copy(mulch), 500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 8), 100, GTUtility.copy(mulch), 6000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 9), 80, GTUtility.copy(mulch), 500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 10), 150, GTUtility.copy(mulch), 4000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 11), 500, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 12), 150, GTUtility.copy(mulch), 4000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 13), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 14), 400, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 15), 400, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 16), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 17), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 18), 400, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 19), 150, GTUtility.copy(mulch), 4000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 20), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 21), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 22), 300, GTUtility.copy(mulch), 2000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 23), 200, GTUtility.copy(mulch), 1000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 24), 150, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 25), 180, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 26), 100, GTUtility.copy(mulch), 400); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 27), 50, GTUtility.copy(mulch), 200); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 28), 100, GTUtility.copy(mulch), 3000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 29), 100, GTUtility.copy(mulch), 3000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 30), 100, GTUtility.copy(mulch), 4000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 31), 20, GTUtility.copy(mulch), 200); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 32), 50, GTUtility.copy(mulch), 300); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 33), 50, GTUtility.copy(mulch), 300); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 34), 100, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 35), 50, GTUtility.copy(mulch), 300); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 36), 50, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 37), 20, GTUtility.copy(mulch), 200); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 38), 300, GTUtility.copy(mulch), 1500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 39), 25, GTUtility.copy(mulch), 200); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 46), 50, GTUtility.copy(mulch), 500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 50), 300, GTUtility.copy(mulch), 2500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 51), 150, GTUtility.copy(mulch), 1500); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 52), 300, GTUtility.copy(mulch), 1500); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 53), 50, GTUtility.copy(mulch), 1000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 54), 50, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 55), 100, GTUtility.copy(mulch), 1000); + addSeedOilRecipe(Mods.ExtraTrees.getItem("food", 56), 100, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 57), 400, GTUtility.copy(mulch), 2000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 58), 300, GTUtility.copy(mulch), 1000); + addFruitJuiceRecipe(Mods.ExtraTrees.getItem("food", 59), 50, GTUtility.copy(mulch), 1000); } } diff --git a/src/main/java/gregtech/integration/forestry/recipes/ForestryMiscRecipes.java b/src/main/java/gregtech/integration/forestry/recipes/ForestryMiscRecipes.java index 5f4f214c294..85239b0a1a5 100644 --- a/src/main/java/gregtech/integration/forestry/recipes/ForestryMiscRecipes.java +++ b/src/main/java/gregtech/integration/forestry/recipes/ForestryMiscRecipes.java @@ -6,8 +6,8 @@ import gregtech.api.unification.material.Materials; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.common.items.MetaItems; -import gregtech.integration.IntegrationUtil; import gregtech.integration.forestry.ForestryConfig; import gregtech.integration.forestry.ForestryUtil; import gregtech.integration.forestry.bees.GTDropType; @@ -15,7 +15,6 @@ import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.common.Loader; import forestry.api.recipes.RecipeManagers; import forestry.apiculture.ModuleApiculture; @@ -28,7 +27,7 @@ public class ForestryMiscRecipes { public static void init() { - if (ForestryConfig.enableGTBees) { + if (ForestryConfig.enableGTBees && Mods.ForestryApiculture.isModLoaded()) { // Oil Drop ItemStack dropStack = ForestryUtil.getDropStack(GTDropType.OIL); RecipeMaps.EXTRACTOR_RECIPES.recipeBuilder() @@ -45,8 +44,8 @@ public static void init() { // Biomass Drop dropStack = ForestryUtil.getDropStack(GTDropType.BIOMASS); ItemStack propolisStack = ModuleApiculture.getItems().propolis.get(EnumPropolis.NORMAL, 1); - if (Loader.isModLoaded(GTValues.MODID_EB)) { - propolisStack = IntegrationUtil.getModItem(GTValues.MODID_EB, "propolis", 7); + if (Mods.ExtraBees.isModLoaded()) { + propolisStack = Mods.ExtraBees.getItem("propolis", 7); } RecipeMaps.EXTRACTOR_RECIPES.recipeBuilder() .inputs(dropStack) @@ -202,7 +201,7 @@ public static void init() { } // Fertilizer - ItemStack fertilizer = IntegrationUtil.getModItem(GTValues.MODID_FR, "fertilizer_compound", 0); + ItemStack fertilizer = Mods.Forestry.getItem("fertilizer_compound"); RecipeMaps.MIXER_RECIPES.recipeBuilder() .input("sand", 2) .input(OrePrefix.dust, Materials.Apatite) @@ -224,8 +223,8 @@ public static void init() { .outputs(GTUtility.copy(30, fertilizer)) .duration(100).EUt(16).buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_MB)) { - ItemStack concentratedCompound = IntegrationUtil.getModItem(GTValues.MODID_MB, "resource", 2); + if (Mods.MagicBees.isModLoaded()) { + ItemStack concentratedCompound = Mods.MagicBees.getItem("resource", 2); RecipeMaps.MIXER_RECIPES.recipeBuilder() .input("sand", 2) .inputs(GTUtility.copy(concentratedCompound)) @@ -249,7 +248,7 @@ public static void init() { } // Compost - ItemStack compost = IntegrationUtil.getModItem(GTValues.MODID_FR, "fertilizer_bio", 0); + ItemStack compost = Mods.Forestry.getItem("fertilizer_bio"); RecipeMaps.MIXER_RECIPES.recipeBuilder() .input(Blocks.DIRT, 1, true) .input(Items.WHEAT, 4) @@ -279,19 +278,19 @@ public static void init() { // Phosphor RecipeMaps.EXTRACTOR_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "phosphor", 0)) + .inputs(Mods.Forestry.getItem("phosphor")) .chancedOutput(OrePrefix.dust, Materials.Phosphorus, 1000, 0) .fluidOutputs(Materials.Lava.getFluid(800)) .duration(256).EUt(GTValues.VA[GTValues.MV]).buildAndRegister(); // Ice Shard RecipeMaps.MACERATOR_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "crafting_material", 5)) + .inputs(Mods.Forestry.getItem("crafting_material", 5)) .output(OrePrefix.dust, Materials.Ice) .duration(16).EUt(4).buildAndRegister(); // Mulch - ItemStack mulch = IntegrationUtil.getModItem(GTValues.MODID_FR, "mulch", 0); + ItemStack mulch = Mods.Forestry.getItem("mulch"); RecipeMaps.CHEMICAL_BATH_RECIPES.recipeBuilder() .input(MetaItems.BIO_CHAFF) .fluidInputs(Materials.Water.getFluid(750)) @@ -300,9 +299,9 @@ public static void init() { .chancedOutput(GTUtility.copy(4, mulch), 2000, 0) .duration(500).EUt(GTValues.VA[GTValues.LV]).buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_ET)) { + if (Mods.ExtraTrees.isModLoaded()) { RecipeMaps.MIXER_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_ET, "misc", 1)) + .inputs(Mods.ExtraTrees.getItem("misc", 1)) .fluidInputs(Materials.Water.getFluid(500)) .outputs(GTUtility.copy(mulch)) .duration(600).EUt(2).buildAndRegister(); @@ -328,7 +327,7 @@ public static void init() { .duration(900).EUt(10).buildAndRegister(); // Humus - ItemStack humus = IntegrationUtil.getModItem(GTValues.MODID_FR, "humus", 0); + ItemStack humus = Mods.Forestry.getItem("humus"); RecipeMaps.MIXER_RECIPES.recipeBuilder() .inputs(GTUtility.copy(2, mulch)) .input(Blocks.DIRT, 2, true) @@ -362,35 +361,35 @@ public static void init() { .input(OrePrefix.plate, Materials.Tin, 2) .input(Blocks.GLASS_PANE) .circuitMeta(1) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "can", 0)) + .outputs(Mods.Forestry.getItem("can")) .duration(120).EUt(7).buildAndRegister(); RecipeMaps.EXTRUDER_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "beeswax", 0)) + .inputs(Mods.Forestry.getItem("beeswax")) .notConsumable(MetaItems.SHAPE_EXTRUDER_CELL) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "capsule", 0)) + .outputs(Mods.Forestry.getItem("capsule")) .duration(64).EUt(16).buildAndRegister(); RecipeMaps.EXTRUDER_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "refractory_wax", 0)) + .inputs(Mods.Forestry.getItem("refractory_wax")) .notConsumable(MetaItems.SHAPE_EXTRUDER_CELL) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "refractory", 0)) + .outputs(Mods.Forestry.getItem("refractory")) .duration(128).EUt(16).buildAndRegister(); // Propolis RecipeMaps.CENTRIFUGE_RECIPES.recipeBuilder() - .inputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "propolis", 0)) + .inputs(Mods.Forestry.getItem("propolis")) .output(MetaItems.STICKY_RESIN) .duration(128).EUt(5).buildAndRegister(); - if (Loader.isModLoaded(GTValues.MODID_GENETICS)) { + if (Mods.Genetics.isModLoaded()) { // DNA Dye RecipeMaps.MIXER_RECIPES.recipeBuilder() .input(OrePrefix.dust, Materials.Glowstone) .input("dyePurple") .input("dyeBlue") - .outputs(IntegrationUtil.getModItem(GTValues.MODID_GENETICS, "misc", 1, 8)) + .outputs(Mods.Genetics.getItem("misc", 1, 8)) .duration(100).EUt(GTValues.VA[GTValues.LV]).buildAndRegister(); // Fluorescent Dye @@ -398,14 +397,14 @@ public static void init() { .input(OrePrefix.dust, Materials.Glowstone) .input("dyeOrange") .input("dyeYellow") - .outputs(IntegrationUtil.getModItem(GTValues.MODID_GENETICS, "misc", 2, 2)) + .outputs(Mods.Genetics.getItem("misc", 2, 2)) .duration(100).EUt(GTValues.VA[GTValues.LV]).buildAndRegister(); // Growth Medium RecipeMaps.MIXER_RECIPES.recipeBuilder() .input(OrePrefix.dust, Materials.Sugar) .input(OrePrefix.dust, Materials.Bone) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_GENETICS, "misc", 4, 2)) + .outputs(Mods.Genetics.getItem("misc", 4, 2)) .duration(400).EUt(16).buildAndRegister(); } @@ -413,7 +412,7 @@ public static void init() { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_NUGGET) .fluidInputs(Fluids.FOR_HONEY.getFluid(200)) - .outputs(IntegrationUtil.getModItem(GTValues.MODID_FR, "honey_drop", 0)) + .outputs(Mods.Forestry.getItem("honey_drop")) .duration(400).EUt(7).buildAndRegister(); RecipeMaps.CENTRIFUGE_RECIPES.recipeBuilder() @@ -425,7 +424,7 @@ public static void init() { public static void initRemoval() { ModHandler.removeRecipeByName("forestry:sand_to_fertilizer"); ModHandler.removeRecipeByName("forestry:ash_to_fertilizer"); - if (Loader.isModLoaded(GTValues.MODID_MB)) { + if (Mods.MagicBees.isModLoaded()) { ModHandler.removeRecipeByName("magicbees:fertilizer1"); ModHandler.removeRecipeByName("magicbees:fertilizer2"); ModHandler.removeRecipeByName("magicbees:fertilizer3"); @@ -437,7 +436,7 @@ public static void initRemoval() { ModHandler.removeRecipeByName("forestry:tin_can"); ModHandler.removeRecipeByName("forestry:wax_capsule"); ModHandler.removeRecipeByName("forestry:refractory_capsule"); - if (Loader.isModLoaded(GTValues.MODID_GENETICS)) { + if (Mods.Genetics.isModLoaded()) { ModHandler.removeRecipeByName("genetics:dna_dye_from_glowstone"); ModHandler.removeRecipeByName("genetics:dna_dye"); ModHandler.removeRecipeByName("genetics:fluorescent_dye"); diff --git a/src/main/java/gregtech/integration/forestry/tools/ScoopBehavior.java b/src/main/java/gregtech/integration/forestry/tools/ScoopBehavior.java index 221fadaa6f6..6eed93239d8 100644 --- a/src/main/java/gregtech/integration/forestry/tools/ScoopBehavior.java +++ b/src/main/java/gregtech/integration/forestry/tools/ScoopBehavior.java @@ -1,8 +1,8 @@ package gregtech.integration.forestry.tools; -import gregtech.api.GTValues; import gregtech.api.items.toolitem.ToolHelper; import gregtech.api.items.toolitem.behavior.IToolBehavior; +import gregtech.api.util.Mods; import net.minecraft.client.resources.I18n; import net.minecraft.client.util.ITooltipFlag; @@ -13,7 +13,6 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import net.minecraftforge.event.ForgeEventFactory; -import net.minecraftforge.fml.common.Loader; import forestry.api.lepidopterology.EnumFlutterType; import forestry.api.lepidopterology.IAlleleButterflySpecies; @@ -32,7 +31,7 @@ private ScoopBehavior() {/**/} @Override public void hitEntity(@NotNull ItemStack stack, @NotNull EntityLivingBase target, @NotNull EntityLivingBase attacker) { - if (!Loader.isModLoaded(GTValues.MODID_FR)) return; + if (!Mods.Forestry.isModLoaded()) return; if (!(target instanceof IEntityButterfly butterfly)) return; if (!(attacker instanceof EntityPlayer player)) return; if (attacker.world == null || attacker.world.isRemote) return; diff --git a/src/main/java/gregtech/integration/groovy/GrSRecipeHelper.java b/src/main/java/gregtech/integration/groovy/GrSRecipeHelper.java index 9c686f88946..f2f8c4cb67e 100644 --- a/src/main/java/gregtech/integration/groovy/GrSRecipeHelper.java +++ b/src/main/java/gregtech/integration/groovy/GrSRecipeHelper.java @@ -7,7 +7,7 @@ import net.minecraft.item.ItemStack; -import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.ingredient.GroovyScriptCodeConverter; import com.cleanroommc.groovyscript.helper.ingredient.NbtHelper; public class GrSRecipeHelper { @@ -20,7 +20,7 @@ public static String getRecipeRemoveLine(RecipeMap recipeMap, Recipe recipe) .append(recipe.getEUt()) .append(", "); - if (recipe.getInputs().size() > 0) { + if (!recipe.getInputs().isEmpty()) { builder.append("["); for (GTRecipeInput ci : recipe.getInputs()) { String ingredient = getGroovyItemString(ci); @@ -32,10 +32,10 @@ public static String getRecipeRemoveLine(RecipeMap recipeMap, Recipe recipe) builder.append("null, "); } - if (recipe.getFluidInputs().size() > 0) { + if (!recipe.getFluidInputs().isEmpty()) { builder.append("["); for (GTRecipeInput fluidIngredient : recipe.getFluidInputs()) { - builder.append(IngredientHelper.asGroovyCode(fluidIngredient.getInputFluidStack(), false)); + builder.append(GroovyScriptCodeConverter.asGroovyCode(fluidIngredient.getInputFluidStack(), false)); if (fluidIngredient.getAmount() > 1) { builder.append(" * ") @@ -72,7 +72,7 @@ public static String getGroovyItemString(GTRecipeInput recipeInput) { } if (itemStack != null) { if (itemId == null) { - builder.append(IngredientHelper.asGroovyCode(itemStack, false)); + builder.append(GroovyScriptCodeConverter.asGroovyCode(itemStack, false)); } if (itemStack.getTagCompound() != null) { diff --git a/src/main/java/gregtech/integration/groovy/GroovyExpansions.java b/src/main/java/gregtech/integration/groovy/GroovyExpansions.java new file mode 100644 index 00000000000..bd7e01ca643 --- /dev/null +++ b/src/main/java/gregtech/integration/groovy/GroovyExpansions.java @@ -0,0 +1,78 @@ +package gregtech.integration.groovy; + +import gregtech.api.fluids.FluidBuilder; +import gregtech.api.fluids.attribute.FluidAttributes; +import gregtech.api.recipes.RecipeBuilder; +import gregtech.api.unification.Element; +import gregtech.api.unification.Elements; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.event.MaterialEvent; +import gregtech.api.unification.material.properties.ToolProperty; + +import net.minecraft.util.ResourceLocation; + +import com.cleanroommc.groovyscript.GroovyScript; +import com.cleanroommc.groovyscript.api.GroovyLog; + +public class GroovyExpansions { + + public static > RecipeBuilder property(RecipeBuilder builder, String key, + Object value) { + if (!builder.applyPropertyCT(key, value)) { + GroovyLog.get().error("Failed to add property '{}' with '{}' to recipe", key, value); + } + return builder; + } + + public static Material.Builder materialBuilder(MaterialEvent event, int id, ResourceLocation resourceLocation) { + return new Material.Builder(id, resourceLocation); + } + + public static Material.Builder materialBuilder(MaterialEvent event, int id, String domain, String path) { + return materialBuilder(event, id, new ResourceLocation(domain, path)); + } + + public static Material.Builder materialBuilder(MaterialEvent event, int id, String s) { + String domain, path; + if (s.contains(":")) { + String[] parts = s.split(":", 2); + domain = parts[0]; + path = parts[1]; + } else { + domain = GroovyScript.getRunConfig().getPackId(); + path = s; + } + return materialBuilder(event, id, new ResourceLocation(domain, path)); + } + + public static ToolProperty.Builder toolBuilder(MaterialEvent event, float harvestSpeed, float attackDamage, + int durability, int harvestLevel) { + return ToolProperty.Builder.of(harvestSpeed, attackDamage, durability, harvestLevel); + } + + public static ToolProperty.Builder toolBuilder(MaterialEvent event) { + return toolBuilder(event, 1.0F, 1.0F, 100, 2); + } + + public static FluidBuilder fluidBuilder(MaterialEvent event) { + return new FluidBuilder(); + } + + public static Element addElement(MaterialEvent event, long protons, long neutrons, long halfLifeSeconds, + String decayTo, String name, String symbol, boolean isIsotope) { + return Elements.add(protons, neutrons, halfLifeSeconds, decayTo, name, symbol, isIsotope); + } + + public static Element addElement(MaterialEvent event, long protons, long neutrons, String name, String symbol, + boolean isIsotope) { + return Elements.add(protons, neutrons, name, symbol, isIsotope); + } + + public static Element addElement(MaterialEvent event, long protons, long neutrons, String name, String symbol) { + return Elements.add(protons, neutrons, name, symbol); + } + + public static FluidBuilder acidic(FluidBuilder builder) { + return builder.attributes(FluidAttributes.ACID); + } +} diff --git a/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java b/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java index 3f5ea4873f4..f132c8ea481 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java +++ b/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java @@ -8,9 +8,14 @@ import gregtech.api.unification.material.info.MaterialFlag; import gregtech.api.unification.material.info.MaterialIconSet; import gregtech.api.unification.material.properties.BlastProperty; +import gregtech.api.unification.material.properties.ToolProperty; +import gregtech.api.unification.stack.MaterialStack; import net.minecraft.util.ResourceLocation; +import com.cleanroommc.groovyscript.api.GroovyLog; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + import java.util.ArrayList; import java.util.List; @@ -85,22 +90,45 @@ public static Material.Builder blastTemp(Material.Builder builder, int temp, Str public static Material.Builder blastTemp(Material.Builder builder, int temp, String raw, int eutOverride, int durationOverride, int vacuumEUtOverride, int vacuumDurationOverride) { - BlastProperty.GasTier gasTier = null; - String name = raw.toUpperCase(); - for (BlastProperty.GasTier gasTier1 : BlastProperty.GasTier.VALUES) { - if (gasTier1.name().equals(name)) { - gasTier = gasTier1; - break; - } - } - final BlastProperty.GasTier finalGasTier = gasTier; - if (GroovyScriptModule.validateNonNull(gasTier, () -> "Can't find gas tier for " + name + - " in material builder. Valid values are 'low', 'mid', 'high', 'higher', 'highest'!")) { + BlastProperty.GasTier gasTier = GroovyScriptModule.parseAndValidateEnumValue(BlastProperty.GasTier.class, raw, + "gas tier"); + if (gasTier != null) { return builder.blast(b -> b - .temp(temp, finalGasTier) + .temp(temp, gasTier) .blastStats(eutOverride, durationOverride) .vacuumStats(vacuumEUtOverride, vacuumDurationOverride)); } return builder; } + + public static Material.Builder components(Material.Builder builder, Object... objects) { + ObjectArrayList materialStacks = new ObjectArrayList<>(); + for (Object o : objects) { + if (o instanceof MaterialStack materialStack) { + materialStacks.add(materialStack); + } else if (o instanceof Material material) { + materialStacks.add(new MaterialStack(material, 1)); + } else 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.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])); + } + + public static Material.Builder toolStats(Material.Builder builder, ToolProperty.Builder toolBuilder) { + return builder.toolStats(toolBuilder.build()); + } + + public static Material.Builder toolStats(Material.Builder builder, float harvestSpeed, float attackDamage, + int durability, int harvestLevel) { + return builder.toolStats(ToolProperty.Builder.of(harvestSpeed, attackDamage, durability, harvestLevel).build()); + } } diff --git a/src/main/java/gregtech/integration/groovy/GroovyRecipeBuilderExpansion.java b/src/main/java/gregtech/integration/groovy/GroovyRecipeBuilderExpansion.java deleted file mode 100644 index 90a0dc3753b..00000000000 --- a/src/main/java/gregtech/integration/groovy/GroovyRecipeBuilderExpansion.java +++ /dev/null @@ -1,16 +0,0 @@ -package gregtech.integration.groovy; - -import gregtech.api.recipes.RecipeBuilder; - -import com.cleanroommc.groovyscript.api.GroovyLog; - -public class GroovyRecipeBuilderExpansion { - - public static > RecipeBuilder property(RecipeBuilder builder, String key, - Object value) { - if (!builder.applyProperty(key, value)) { - GroovyLog.get().error("Failed to add property '{}' with '{}' to recipe", key, value); - } - return builder; - } -} diff --git a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java index adb308fe4e6..96aa2b92cd1 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java +++ b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java @@ -2,14 +2,24 @@ import gregtech.api.GTValues; import gregtech.api.GregTechAPI; +import gregtech.api.fluids.FluidBuilder; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.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; +import gregtech.api.unification.material.event.MaterialEvent; +import gregtech.api.unification.material.event.PostMaterialEvent; import gregtech.api.unification.material.registry.MaterialRegistry; import gregtech.api.unification.ore.OrePrefix; +import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.common.blocks.BlockCompressed; import gregtech.common.blocks.BlockFrame; import gregtech.common.blocks.MetaBlocks; @@ -17,8 +27,6 @@ import gregtech.common.pipelike.fluidpipe.BlockFluidPipe; import gregtech.common.pipelike.itempipe.BlockItemPipe; import gregtech.integration.IntegrationSubmodule; -import gregtech.integration.crafttweaker.material.MaterialExpansion; -import gregtech.integration.crafttweaker.material.MaterialPropertyExpansion; import gregtech.modules.GregTechModules; import net.minecraft.item.ItemStack; @@ -32,33 +40,44 @@ import com.cleanroommc.groovyscript.GroovyScript; import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.GroovyPlugin; -import com.cleanroommc.groovyscript.api.IGameObjectHandler; +import com.cleanroommc.groovyscript.api.IObjectParser; +import com.cleanroommc.groovyscript.api.Result; import com.cleanroommc.groovyscript.compat.mods.GroovyContainer; -import com.cleanroommc.groovyscript.gameobjects.GameObjectHandlerManager; +import com.cleanroommc.groovyscript.compat.mods.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; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.eclipse.lsp4j.CompletionItem; +import org.eclipse.lsp4j.CompletionItemKind; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Objects; import java.util.function.Supplier; +import java.util.stream.IntStream; -@Optional.Interface(modid = GTValues.MODID_GROOVYSCRIPT, +@Optional.Interface(modid = Mods.Names.GROOVY_SCRIPT, iface = "com.cleanroommc.groovyscript.api.GroovyPlugin", striprefs = true) @GregTechModule( moduleID = GregTechModules.MODULE_GRS, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_GROOVYSCRIPT, + modDependencies = Mods.Names.GROOVY_SCRIPT, name = "GregTech GroovyScript Integration", description = "GroovyScript Integration Module") public class GroovyScriptModule extends IntegrationSubmodule implements GroovyPlugin { private static GroovyContainer modSupportContainer; - private static final Map> metaItems = new Object2ObjectOpenHashMap<>(); + private static final Object2ObjectOpenHashMap> metaItems = new Object2ObjectOpenHashMap<>(); + + private static final ResourceLocation MODULE_ID = GTUtility.gregtechId(GregTechModules.MODULE_GRS); @NotNull @Override @@ -71,11 +90,47 @@ 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(getPackId()); + GregTechAPI.MIGRATIONS.registriesMigrator().migrate(getPackId(), IntStream.rangeClosed(32000, Short.MAX_VALUE)); + } + public static boolean isCurrentlyRunning() { return GregTechAPI.moduleManager.isModuleEnabled(GregTechModules.MODULE_GRS) && GroovyScript.getSandbox().isRunning(); } + public static > T parseAndValidateEnumValue(Class clazz, String raw, String type) { + return parseAndValidateEnumValue(clazz, raw, type, false); + } + + @Contract("_,_,_,true -> !null") + public static > T parseAndValidateEnumValue(Class clazz, String raw, String type, + boolean crash) { + T t = EnumHelper.valueOfNullable(clazz, raw, false); + if (t == null) { + String msg = GroovyLog.format("Can't find {} for {} in material builder. Valid values are {};", + type, + raw, + Arrays.toString(clazz.getEnumConstants())); + if (crash) throw new NoSuchElementException(msg); + GroovyLog.get().error(msg); + return null; + } + return t; + } + + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) public static GroovyContainer getInstance() { return modSupportContainer; } @@ -110,7 +165,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(); } @@ -190,28 +246,101 @@ public static void loadMetaItemBracketHandler() { } @Override - public @NotNull String getModName() { - return "GregTech"; + public @NotNull String getContainerName() { + return GTValues.MOD_NAME; } + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) @Override - public void onCompatLoaded(GroovyContainer groovyContainer) { - modSupportContainer = groovyContainer; - GameObjectHandlerManager.registerGameObjectHandler(GTValues.MODID, "recipemap", - IGameObjectHandler.wrapStringGetter(RecipeMap::getByName)); + public @Nullable GroovyPropertyContainer createGroovyPropertyContainer() { + return new PropertyContainer(); + } - GameObjectHandlerManager.registerGameObjectHandler(GTValues.MODID, "material", - IGameObjectHandler.wrapStringGetter(GregTechAPI.materialManager::getMaterial)); + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) + @Override + public void onCompatLoaded(GroovyContainer container) { + GroovyScriptModule.modSupportContainer = container; + container.objectMapperBuilder("recipemap", RecipeMap.class) + .parser(IObjectParser.wrapStringGetter(RecipeMap::getByName)) + .completerOfNamed(RecipeMap::getRecipeMaps, RecipeMap::getUnlocalizedName) + .register(); + container.objectMapperBuilder("material", Material.class) + .parser(IObjectParser.wrapStringGetter(GregTechAPI.materialManager::getMaterial)) + .completerOfNamed(GregTechAPI.materialManager::getRegisteredMaterials, + mat -> mat.getResourceLocation().toString()) + .register(); + + container.objectMapperBuilder("oreprefix", OrePrefix.class) + .parser(IObjectParser.wrapStringGetter(OrePrefix::getPrefix)) + .completerOfNamed(OrePrefix::values, v -> v.name) + .register(); - GameObjectHandlerManager.registerGameObjectHandler(GTValues.MODID, "oreprefix", - IGameObjectHandler.wrapStringGetter(OrePrefix::getPrefix)); + 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();) { + var entry = iterator.next(); + String mod = entry.getKey(); + for (String key : entry.getValue().keySet()) { + var item = new CompletionItem(mod + ":" + key); + item.setKind(CompletionItemKind.Constant); + items.add(item); + } + } + }) + .register(); - GameObjectHandlerManager.registerGameObjectHandler(GTValues.MODID, "metaitem", - IGameObjectHandler.wrapStringGetter(GroovyScriptModule::getMetaItem), ItemStack.EMPTY); + container.objectMapperBuilder("element", Element.class) + .parser((s, args) -> { + Element element = Elements.get(s); + if (element != null) return Result.some(element); + if (s.length() <= 6) { + for (Element element1 : Elements.getAllElements()) { + if (element1.symbol.equals(s)) { + return Result.some(element1); + } + } + } + return Result.error(); + }) + .completerOfNamed(Elements::getAllElements, Element::getName) + .register(); ExpansionHelper.mixinClass(Material.class, MaterialExpansion.class); ExpansionHelper.mixinClass(Material.class, MaterialPropertyExpansion.class); ExpansionHelper.mixinClass(Material.Builder.class, GroovyMaterialBuilderExpansion.class); - ExpansionHelper.mixinClass(RecipeBuilder.class, GroovyRecipeBuilderExpansion.class); + ExpansionHelper.mixinMethod(RecipeBuilder.class, GroovyExpansions.class, "property"); + ExpansionHelper.mixinMethod(MaterialEvent.class, GroovyExpansions.class, "materialBuilder"); + ExpansionHelper.mixinMethod(MaterialEvent.class, GroovyExpansions.class, "toolBuilder"); + ExpansionHelper.mixinMethod(MaterialEvent.class, GroovyExpansions.class, "fluidBuilder"); + ExpansionHelper.mixinMethod(MaterialEvent.class, GroovyExpansions.class, "addElement"); + ExpansionHelper.mixinMethod(PostMaterialEvent.class, GroovyExpansions.class, "toolBuilder"); + ExpansionHelper.mixinMethod(PostMaterialEvent.class, GroovyExpansions.class, "fluidBuilder"); + ExpansionHelper.mixinMethod(FluidBuilder.class, GroovyExpansions.class, "acidic"); + } + + protected static boolean checkFrozen(String description) { + if (!GregTechAPI.materialManager.canModifyMaterials()) { + GroovyLog.get().error("Cannot {} now, must be done in preInit loadStage and material event", description); + return true; + } + return false; + } + + protected static void logError(Material m, String cause, String type) { + GroovyLog.get().error( + "Cannot {0} of a Material with no {1}! Try calling \"add{1}\" in your late material event first if this is intentional. Material: {2}", + cause, type, m.getUnlocalizedName()); + } + + /** + * @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 new file mode 100644 index 00000000000..6d5f5e7ac2f --- /dev/null +++ b/src/main/java/gregtech/integration/groovy/MaterialExpansion.java @@ -0,0 +1,225 @@ +package gregtech.integration.groovy; + +import gregtech.api.fluids.store.FluidStorageKeys; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.info.MaterialFlag; +import gregtech.api.unification.material.info.MaterialIconSet; +import gregtech.api.unification.material.properties.BlastProperty; +import gregtech.api.unification.material.properties.DustProperty; +import gregtech.api.unification.material.properties.FluidProperty; +import gregtech.api.unification.material.properties.OreProperty; +import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.api.unification.material.properties.ToolProperty; + +import net.minecraft.enchantment.Enchantment; + +import com.cleanroommc.groovyscript.api.GroovyLog; + +import static gregtech.integration.groovy.GroovyScriptModule.checkFrozen; +import static gregtech.integration.groovy.GroovyScriptModule.logError; + +@SuppressWarnings("unused") +public class MaterialExpansion { + + //////////////////////////////////// + // Material Methods // + //////////////////////////////////// + + public static void setFormula(Material m, String formula) { + setFormula(m, formula, false); + } + + public static void setFormula(Material m, String formula, boolean withFormatting) { + if (checkFrozen("set material chemical formula")) return; + m.setFormula(formula, withFormatting); + } + + public static boolean hasFlag(Material m, String flagName) { + return m.hasFlag(MaterialFlag.getByName(flagName)); + } + + public static void setIconSet(Material m, String iconSetName) { + if (checkFrozen("set material icon set")) return; + m.setMaterialIconSet(MaterialIconSet.getByName(iconSetName)); + } + + public static String getIconSet(Material m) { + return m.getMaterialIconSet().getName(); + } + + //////////////////////////////////// + // Fluid Property // + //////////////////////////////////// + + public static boolean isGaseous(Material m) { + FluidProperty prop = m.getProperty(PropertyKey.FLUID); + return prop != null && prop.get(FluidStorageKeys.GAS) != null; + } + + /////////////////////////////////// + // Dust Property // + /////////////////////////////////// + + public static int harvestLevel(Material m) { + DustProperty prop = m.getProperty(PropertyKey.DUST); + if (prop != null) { + return prop.getHarvestLevel(); + } else logError(m, "get the harvest level", "Dust"); + return 0; + } + + public static int burnTime(Material m) { + DustProperty prop = m.getProperty(PropertyKey.DUST); + if (prop != null) { + return prop.getBurnTime(); + } else logError(m, "get the burn time", "Dust"); + return 0; + } + + public static void setHarvestLevel(Material m, int harvestLevel) { + if (checkFrozen("set harvest level")) return; + DustProperty prop = m.getProperty(PropertyKey.DUST); + if (prop != null) { + prop.setHarvestLevel(harvestLevel); + } else logError(m, "set the harvest level", "Dust"); + } + + public static void setBurnTime(Material m, int burnTime) { + if (checkFrozen("set burn time")) return; + DustProperty prop = m.getProperty(PropertyKey.DUST); + if (prop != null) { + prop.setBurnTime(burnTime); + } else logError(m, "set the burn time", "Dust"); + } + + /////////////////////////////////// + // Tool Property // + /////////////////////////////////// + public static float toolSpeed(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolSpeed(); + } else logError(m, "get the tool speed", "Tool"); + return 0; + } + + public static float attackDamage(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolAttackDamage(); + } else logError(m, "get the tool attack damage", "Tool"); + return 0; + } + + public static int toolDurability(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolDurability(); + } else logError(m, "get the tool durability", "Tool"); + return 0; + } + + public static int toolHarvestLevel(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolHarvestLevel(); + } else logError(m, "get the tool harvest level", "Tool"); + return 0; + } + + public static int toolEnchantability(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolEnchantability(); + } else logError(m, "get the tool enchantability", "Tool"); + return 0; + } + + public static void addToolEnchantment(Material m, Enchantment enchantment, int level) { + addScaledToolEnchantment(m, enchantment, level, 0); + } + + public static void addScaledToolEnchantment(Material m, Enchantment enchantment, int level, double levelGrowth) { + if (checkFrozen("add tool enchantment")) return; + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + prop.addEnchantmentForTools(enchantment, level, levelGrowth); + } else logError(m, "change tool enchantments", "Tool"); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + boolean shouldIngoreCraftingTools) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, 0, 0, shouldIngoreCraftingTools); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + int enchantability, boolean shouldIngoreCraftingTools) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, enchantability, 0, shouldIngoreCraftingTools); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, 0, 0, false); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + int enchantability) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, enchantability, 0, false); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + int enchantability, int toolHarvestLevel) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, enchantability, toolHarvestLevel, false); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + int enchantability, int toolHarvestLevel, + boolean shouldIngoreCraftingTools) { + if (checkFrozen("set tool stats")) return; + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + prop.setToolSpeed(toolSpeed); + prop.setToolAttackDamage(toolAttackDamage); + prop.setToolDurability(toolDurability); + prop.setToolHarvestLevel(toolHarvestLevel == 0 ? 2 : toolHarvestLevel); + prop.setToolEnchantability(enchantability == 0 ? 10 : enchantability); + prop.setShouldIgnoreCraftingTools(shouldIngoreCraftingTools); + } else logError(m, "change tool stats", "Tool"); + } + + // Wire/Item Pipe/Fluid Pipe stuff? + + //////////////////////////////////// + // Blast Property // + //////////////////////////////////// + + public static void setBlastTemp(Material m, int blastTemp) { + if (checkFrozen("set blast temperature")) return; + if (blastTemp <= 0) { + GroovyLog.get().error("Blast Temperature must be greater than zero! Material: " + m.getUnlocalizedName()); + return; + } + BlastProperty prop = m.getProperty(PropertyKey.BLAST); + if (prop != null) prop.setBlastTemperature(blastTemp); + else m.setProperty(PropertyKey.BLAST, new BlastProperty(blastTemp)); + } + + public static int blastTemp(Material m) { + BlastProperty prop = m.getProperty(PropertyKey.BLAST); + if (prop != null) { + return prop.getBlastTemperature(); + } else logError(m, "get blast temperature", "Blast"); + return 0; + } + + //////////////////////////////////// + // Ore Property // + //////////////////////////////////// + + public static int oreMultiplier(Material m) { + OreProperty prop = m.getProperty(PropertyKey.ORE); + if (prop != null) { + return prop.getOreMultiplier(); + } else logError(m, "get ore multiplier", "Ore"); + return 0; + } +} diff --git a/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java b/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java new file mode 100644 index 00000000000..79cc7c810aa --- /dev/null +++ b/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java @@ -0,0 +1,355 @@ +package gregtech.integration.groovy; + +import gregtech.api.fluids.FluidBuilder; +import gregtech.api.fluids.FluidState; +import gregtech.api.fluids.attribute.FluidAttributes; +import gregtech.api.fluids.store.FluidStorageKey; +import gregtech.api.fluids.store.FluidStorageKeys; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.properties.BlastProperty; +import gregtech.api.unification.material.properties.DustProperty; +import gregtech.api.unification.material.properties.FluidPipeProperties; +import gregtech.api.unification.material.properties.FluidProperty; +import gregtech.api.unification.material.properties.GemProperty; +import gregtech.api.unification.material.properties.IngotProperty; +import gregtech.api.unification.material.properties.ItemPipeProperties; +import gregtech.api.unification.material.properties.OreProperty; +import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.api.unification.material.properties.ToolProperty; +import gregtech.api.unification.material.properties.WireProperties; +import gregtech.api.unification.material.properties.WoodProperty; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; + +import static gregtech.integration.groovy.GroovyScriptModule.checkFrozen; + +@SuppressWarnings("unused") +public class MaterialPropertyExpansion { + + ///////////////////////////////////// + // Property Checkers // + ///////////////////////////////////// + + public static boolean hasBlastTemp(Material m) { + return m.hasProperty(PropertyKey.BLAST); + } + + public static boolean hasDust(Material m) { + return m.hasProperty(PropertyKey.DUST); + } + + public static boolean hasFluidPipes(Material m) { + return m.hasProperty(PropertyKey.FLUID_PIPE); + } + + public static boolean hasFluid(Material m) { + return m.hasProperty(PropertyKey.FLUID); + } + + public static boolean hasGem(Material m) { + return m.hasProperty(PropertyKey.GEM); + } + + public static boolean hasIngot(Material m) { + return m.hasProperty(PropertyKey.INGOT); + } + + public static boolean hasItemPipes(Material m) { + return m.hasProperty(PropertyKey.ITEM_PIPE); + } + + public static boolean hasOre(Material m) { + return m.hasProperty(PropertyKey.ORE); + } + + public static boolean hasTools(Material m) { + return m.hasProperty(PropertyKey.TOOL); + } + + public static boolean hasWires(Material m) { + return m.hasProperty(PropertyKey.WIRE); + } + + //////////////////////////////////// + // Property Setters // + //////////////////////////////////// + + public static void addBlastTemp(Material m, int blastTemp) { + if (checkFrozen("add blast temperature")) return; + if (m.hasProperty(PropertyKey.BLAST)) m.getProperty(PropertyKey.BLAST).setBlastTemperature(blastTemp); + else m.setProperty(PropertyKey.BLAST, new BlastProperty(blastTemp)); + } + + public static void addBlastProperty(Material m, int blastTemp) { + addBlastProperty(m, blastTemp, null, 0, 0, 0, 0); + } + + public static void addBlastProperty(Material m, int blastTemp, String gasTier) { + addBlastProperty(m, blastTemp, gasTier, 0, 0, 0, 0); + } + + public static void addBlastProperty(Material m, int blastTemp, String gasTier, + int durationOverride) { + addBlastProperty(m, blastTemp, gasTier, durationOverride, 0, 0, 0); + } + + public static void addBlastProperty(Material m, int blastTemp, String gasTier, + int durationOverride, int eutOverride) { + addBlastProperty(m, blastTemp, gasTier, durationOverride, eutOverride, 0, 0); + } + + public static void addBlastProperty(Material m, int blastTemp, String gasTier, + int durationOverride, int eutOverride, + int vacuumDurationOverride, int vacuumEUtOverride) { + if (checkFrozen("add blast property")) return; + if (m.hasProperty(PropertyKey.BLAST)) { + BlastProperty property = m.getProperty(PropertyKey.BLAST); + property.setBlastTemperature(blastTemp); + if (gasTier != null) property.setGasTier(BlastProperty.validateGasTier(gasTier)); + if (durationOverride != 0) property.setDurationOverride(durationOverride); + if (eutOverride != 0) property.setEutOverride(eutOverride); + if (vacuumDurationOverride != 0) property.setVacuumDurationOverride(vacuumDurationOverride); + if (vacuumEUtOverride != 0) property.setVacuumEutOverride(vacuumEUtOverride); + } else { + BlastProperty.Builder builder = new BlastProperty.Builder(); + builder.temp(blastTemp, + gasTier == null ? BlastProperty.GasTier.LOW : BlastProperty.validateGasTier(gasTier)); + builder.blastStats(durationOverride == 0 ? -1 : durationOverride, eutOverride == 0 ? -1 : eutOverride); + builder.vacuumStats(vacuumEUtOverride == 0 ? -1 : vacuumEUtOverride, + vacuumDurationOverride == 0 ? -1 : vacuumDurationOverride); + m.setProperty(PropertyKey.BLAST, builder.build()); + } + } + + public static void addDust(Material m) { + addDust(m, 0, 0); + } + + public static void addDust(Material m, int harvestLevel) { + addDust(m, harvestLevel, 0); + } + + public static void addDust(Material m, int harvestLevel, int burnTime) { + if (checkFrozen("add a dust to a material")) return; + if (harvestLevel == 0) harvestLevel = 2; + if (m.hasProperty(PropertyKey.DUST)) { + m.getProperty(PropertyKey.DUST).setHarvestLevel(harvestLevel); + m.getProperty(PropertyKey.DUST).setBurnTime(burnTime); + } else m.setProperty(PropertyKey.DUST, new DustProperty(harvestLevel, burnTime)); + } + + public static void addWood(Material m) { + if (checkFrozen("add a wood to a material")) return; + if (!m.hasProperty(PropertyKey.WOOD)) { + m.setProperty(PropertyKey.WOOD, new WoodProperty()); + } + } + + public static void addFluidPipes(Material m, int maxFluidTemperature, int throughput, boolean gasProof) { + addFluidPipes(m, maxFluidTemperature, throughput, gasProof, false, false, false); + } + + public static void addFluidPipes(Material m, int maxFluidTemperature, int throughput, boolean gasProof, + boolean acidProof, boolean cryoProof, boolean plasmaProof) { + if (checkFrozen("add fluid pipes to a material")) return; + if (m.hasProperty(PropertyKey.FLUID_PIPE)) { + m.getProperty(PropertyKey.FLUID_PIPE).setMaxFluidTemperature(maxFluidTemperature); + m.getProperty(PropertyKey.FLUID_PIPE).setThroughput(throughput); + m.getProperty(PropertyKey.FLUID_PIPE).setGasProof(gasProof); + m.getProperty(PropertyKey.FLUID_PIPE).setCanContain(FluidAttributes.ACID, acidProof); + m.getProperty(PropertyKey.FLUID_PIPE).setCryoProof(cryoProof); + m.getProperty(PropertyKey.FLUID_PIPE).setPlasmaProof(plasmaProof); + } else { + m.setProperty(PropertyKey.FLUID_PIPE, new FluidPipeProperties(maxFluidTemperature, throughput, gasProof, + acidProof, cryoProof, plasmaProof)); + } + } + + @GroovyBlacklist + private static void addFluidInternal(Material m, FluidStorageKey key, FluidBuilder builder) { + if (checkFrozen("add a Fluid to a material")) return; + FluidProperty property = m.getProperty(PropertyKey.FLUID); + if (property == null) { + property = new FluidProperty(); + m.setProperty(PropertyKey.FLUID, property); + } + property.enqueueRegistration(key, builder); + } + + public static void addLiquid(Material m, FluidBuilder builder) { + addFluidInternal(m, FluidStorageKeys.LIQUID, builder.state(FluidState.LIQUID)); + } + + public static void addLiquid(Material m) { + addLiquid(m, new FluidBuilder()); + } + + public static void addFluid(Material m) { + addLiquid(m); + } + + @Deprecated + public static void addFluid(Material m, String fluidTypeName) { + addFluid(m, fluidTypeName, false); + } + + @Deprecated + public static void addFluid(Material m, String fluidTypeName, boolean hasBlock) { + GroovyLog.get().error("The usage of `material.addFluid(String, boolean)` is strongly discouraged. " + + "Please use `addLiquid()`, `addGas()` or `addPlasma()` with or without `FluidBuilder`."); + if (checkFrozen("add a Fluid to a material")) return; + FluidState type = GroovyScriptModule.parseAndValidateEnumValue(FluidState.class, fluidTypeName, "fluid type", + true); + FluidStorageKey storageKey = switch (type) { + case LIQUID -> FluidStorageKeys.LIQUID; + case GAS -> FluidStorageKeys.GAS; + case PLASMA -> FluidStorageKeys.PLASMA; + }; + FluidBuilder builder = new FluidBuilder(); + builder.state(type); + if (hasBlock) builder.block(); + addFluidInternal(m, storageKey, builder); + } + + public static void addGas(Material m, FluidBuilder builder) { + addFluidInternal(m, FluidStorageKeys.GAS, builder.state(FluidState.GAS)); + } + + public static void addGas(Material m) { + addGas(m, new FluidBuilder()); + } + + public static void addPlasma(Material m, FluidBuilder builder) { + addFluidInternal(m, FluidStorageKeys.PLASMA, builder.state(FluidState.PLASMA)); + } + + public static void addPlasma(Material m) { + addPlasma(m, new FluidBuilder()); + } + + public static void addGem(Material m) { + if (checkFrozen("add a Gem to a material")) return; + if (!m.hasProperty(PropertyKey.GEM)) m.setProperty(PropertyKey.GEM, new GemProperty()); + } + + public static void addIngot(Material m) { + if (checkFrozen("add an Ingot to a material")) return; + if (!m.hasProperty(PropertyKey.INGOT)) m.setProperty(PropertyKey.INGOT, new IngotProperty()); + } + + public static void addOre(Material m) { + addOre(m, false); + } + + public static void addOre(Material m, boolean emissive) { + addOre(m, 0, 0, emissive); + } + + public static void addOre(Material m, int oreMultiplier, int byproductMultiplier) { + addOre(m, oreMultiplier, byproductMultiplier, false); + } + + public static void addOre(Material m, int oreMultiplier, int byproductMultiplier, boolean emissive) { + if (checkFrozen("add an Ore to a material")) return; + oreMultiplier = oreMultiplier == 0 ? 1 : oreMultiplier; + byproductMultiplier = byproductMultiplier == 0 ? 1 : byproductMultiplier; + if (m.hasProperty(PropertyKey.ORE)) { + m.getProperty(PropertyKey.ORE).setOreMultiplier(oreMultiplier); + m.getProperty(PropertyKey.ORE).setByProductMultiplier(byproductMultiplier); + m.getProperty(PropertyKey.ORE).setEmissive(emissive); + } else m.setProperty(PropertyKey.ORE, new OreProperty(oreMultiplier, byproductMultiplier, emissive)); + } + + public static void addItemPipes(Material m, int priority, float transferRate) { + if (checkFrozen("add Item Pipes to a material")) return; + if (m.hasProperty(PropertyKey.ITEM_PIPE)) { + m.getProperty(PropertyKey.ITEM_PIPE).setPriority(priority); + m.getProperty(PropertyKey.ITEM_PIPE).setTransferRate(transferRate); + } else m.setProperty(PropertyKey.ITEM_PIPE, new ItemPipeProperties(priority, transferRate)); + } + + public static void addTools(Material m, ToolProperty.Builder builder) { + addTools(m, builder.build()); + } + + public static void addTools(Material m, ToolProperty prop) { + if (checkFrozen("add Tools to a material")) return; + ToolProperty property = m.getProperty(PropertyKey.TOOL); + if (property != null) { + property.setToolSpeed(prop.getToolSpeed()); + property.setToolAttackDamage(prop.getToolAttackDamage()); + property.setToolDurability(prop.getToolDurability()); + property.setToolHarvestLevel(prop.getToolHarvestLevel()); + property.setToolAttackSpeed(prop.getToolAttackSpeed()); + property.setToolEnchantability(prop.getToolEnchantability()); + property.setMagnetic(prop.isMagnetic()); + property.setUnbreakable(prop.getUnbreakable()); + property.setShouldIgnoreCraftingTools(prop.getShouldIgnoreCraftingTools()); + property.setDurabilityMultiplier(prop.getDurabilityMultiplier()); + } else { + m.setProperty(PropertyKey.TOOL, prop); + } + } + + public static void addTools(Material m, float toolSpeed, float toolAttackDamage, float toolAttackSpeed, + int toolDurability) { + addTools(m, toolSpeed, toolAttackDamage, toolAttackSpeed, toolDurability, 0, 10, 1); + } + + public static void addTools(Material m, float toolSpeed, float toolAttackDamage, float toolAttackSpeed, + int toolDurability, int toolHarvestLevel) { + addTools(m, toolSpeed, toolAttackDamage, toolAttackSpeed, toolDurability, toolHarvestLevel, 10, 1); + } + + public static void addTools(Material m, float toolSpeed, float toolAttackDamage, float toolAttackSpeed, + int toolDurability, int toolHarvestLevel, int toolEnchantability) { + addTools(m, toolSpeed, toolAttackDamage, toolAttackSpeed, toolDurability, toolHarvestLevel, toolEnchantability, + 1); + } + + public static void addTools(Material m, float toolSpeed, float toolAttackDamage, float toolAttackSpeed, + int toolDurability, int toolHarvestLevel, int toolEnchantability, + int durabilityMultiplier) { + if (toolEnchantability == 0) toolEnchantability = 10; + if (durabilityMultiplier <= 0) durabilityMultiplier = 1; + addTools(m, ToolProperty.Builder.of(toolSpeed, toolAttackDamage, toolDurability, toolHarvestLevel) + .attackSpeed(toolAttackSpeed) + .enchantability(toolEnchantability) + .durabilityMultiplier(durabilityMultiplier)); + } + + public static void addWires(Material m, int voltage, int baseAmperage, int lossPerBlock) { + addWires(m, voltage, baseAmperage, lossPerBlock, false, 0); + } + + public static void addWires(Material m, int voltage, int baseAmperage, int lossPerBlock, boolean isSuperCon) { + addWires(m, voltage, baseAmperage, lossPerBlock, isSuperCon, 0); + } + + public static void addWires(Material m, int voltage, int baseAmperage, int lossPerBlock, boolean isSuperCon, + int criticalTemp) { + if (checkFrozen("add Wires to a material")) return; + if (m.hasProperty(PropertyKey.WIRE)) { + m.getProperty(PropertyKey.WIRE).setVoltage(voltage); + m.getProperty(PropertyKey.WIRE).setAmperage(baseAmperage); + m.getProperty(PropertyKey.WIRE).setLossPerBlock(lossPerBlock); + m.getProperty(PropertyKey.WIRE).setSuperconductor(isSuperCon); + m.getProperty(PropertyKey.WIRE).setSuperconductorCriticalTemperature(criticalTemp); + } else m.setProperty(PropertyKey.WIRE, + new WireProperties(voltage, baseAmperage, lossPerBlock, isSuperCon, criticalTemp)); + } + + public static void addCables(Material m, int voltage, int baseAmperage, int lossPerBlock) { + addWires(m, voltage, baseAmperage, lossPerBlock, false, 0); + } + + public static void addCables(Material m, int voltage, int baseAmperage, int lossPerBlock, boolean isSuperCon) { + addWires(m, voltage, baseAmperage, lossPerBlock, isSuperCon, 0); + } + + public static void addCables(Material m, int voltage, int baseAmperage, int lossPerBlock, boolean isSuperCon, + int criticalTemp) { + addWires(m, voltage, baseAmperage, lossPerBlock, isSuperCon, criticalTemp); + } +} diff --git a/src/main/java/gregtech/integration/groovy/PropertyContainer.java b/src/main/java/gregtech/integration/groovy/PropertyContainer.java new file mode 100644 index 00000000000..bbafd3c7d92 --- /dev/null +++ b/src/main/java/gregtech/integration/groovy/PropertyContainer.java @@ -0,0 +1,47 @@ +package gregtech.integration.groovy; + +import gregtech.api.unification.material.event.MaterialEvent; +import gregtech.api.unification.material.event.PostMaterialEvent; + +import net.minecraftforge.fml.common.eventhandler.EventPriority; + +import com.cleanroommc.groovyscript.GroovyScript; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.compat.mods.GroovyPropertyContainer; +import com.cleanroommc.groovyscript.event.EventBusType; +import com.cleanroommc.groovyscript.event.GroovyEventManager; +import com.cleanroommc.groovyscript.sandbox.ClosureHelper; +import com.cleanroommc.groovyscript.sandbox.LoadStage; +import groovy.lang.Closure; +import groovy.lang.DelegatesTo; + +public class PropertyContainer extends GroovyPropertyContainer { + + public void materialEvent(EventPriority priority, @DelegatesTo(MaterialEvent.class) Closure eventListener) { + if (GroovyScriptModule.isCurrentlyRunning() && + GroovyScript.getSandbox().getCurrentLoader() != LoadStage.PRE_INIT) { + GroovyLog.get().error("GregTech's material event can only be used in pre init!"); + return; + } + ClosureHelper.withEnvironment(eventListener, new MaterialEvent(), true); + GroovyEventManager.INSTANCE.listen(priority, EventBusType.MAIN, MaterialEvent.class, eventListener); + } + + public void materialEvent(Closure eventListener) { + materialEvent(EventPriority.NORMAL, eventListener); + } + + public void lateMaterialEvent(EventPriority priority, Closure eventListener) { + if (GroovyScriptModule.isCurrentlyRunning() && + GroovyScript.getSandbox().getCurrentLoader() != LoadStage.PRE_INIT) { + GroovyLog.get().error("GregTech's material event can only be used in pre init!"); + return; + } + GroovyEventManager.INSTANCE.listen(priority, EventBusType.MAIN, PostMaterialEvent.class, + eventListener); + } + + public void lateMaterialEvent(Closure eventListener) { + lateMaterialEvent(EventPriority.NORMAL, eventListener); + } +} diff --git a/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java b/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java index a2dbf7a3d55..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().getVirtualizedRegistrar().addRegistry(this); + GroovyScriptModule.getInstance().addProperty(this); } @Override diff --git a/src/main/java/gregtech/integration/hwyla/HWYLAModule.java b/src/main/java/gregtech/integration/hwyla/HWYLAModule.java index bce36365fc0..a604d6331e1 100644 --- a/src/main/java/gregtech/integration/hwyla/HWYLAModule.java +++ b/src/main/java/gregtech/integration/hwyla/HWYLAModule.java @@ -2,6 +2,7 @@ import gregtech.api.GTValues; import gregtech.api.modules.GregTechModule; +import gregtech.api.util.Mods; import gregtech.integration.IntegrationSubmodule; import gregtech.integration.hwyla.provider.*; import gregtech.modules.GregTechModules; @@ -17,7 +18,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_HWYLA, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_HWYLA, + modDependencies = Mods.Names.HWYLA, name = "GregTech HWYLA Integration", description = "HWYLA (WAILA) Integration Module") public class HWYLAModule extends IntegrationSubmodule implements IWailaPlugin { @@ -39,6 +40,8 @@ public void register(IWailaRegistrar registrar) { // one day, if cover provider is ported to waila, register it right here BlockOreDataProvider.INSTANCE.register(registrar); LampDataProvider.INSTANCE.register(registrar); + ActiveTransformerDataProvider.INSTANCE.register(registrar); + BatteryBufferDataProvider.INSTANCE.register(registrar); } /** Render an ItemStack. */ diff --git a/src/main/java/gregtech/integration/hwyla/provider/ActiveTransformerDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/ActiveTransformerDataProvider.java new file mode 100644 index 00000000000..d1b20e6ddfd --- /dev/null +++ b/src/main/java/gregtech/integration/hwyla/provider/ActiveTransformerDataProvider.java @@ -0,0 +1,70 @@ +package gregtech.integration.hwyla.provider; + +import gregtech.api.GTValues; +import gregtech.api.capability.GregtechCapabilities; +import gregtech.api.capability.IMultiblockController; +import gregtech.api.util.TextFormattingUtil; +import gregtech.common.metatileentities.multi.electric.MetaTileEntityActiveTransformer; + +import net.minecraft.client.resources.I18n; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.capabilities.Capability; + +import mcp.mobius.waila.api.IWailaConfigHandler; +import mcp.mobius.waila.api.IWailaDataAccessor; +import mcp.mobius.waila.api.IWailaRegistrar; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class ActiveTransformerDataProvider extends CapabilityDataProvider { + + public static final ActiveTransformerDataProvider INSTANCE = new ActiveTransformerDataProvider(); + + @Override + public void register(@NotNull IWailaRegistrar registrar) { + registrar.registerBodyProvider(this, TileEntity.class); + registrar.registerNBTProvider(this, TileEntity.class); + registrar.addConfig(GTValues.MOD_NAME, "gregtech.multiblock.activetransformer"); + } + + @Override + protected @NotNull Capability getCapability() { + return GregtechCapabilities.CAPABILITY_MULTIBLOCK_CONTROLLER; + } + + @Override + protected NBTTagCompound getNBTData(IMultiblockController capability, NBTTagCompound tag) { + if (capability instanceof MetaTileEntityActiveTransformer activeTransformer) { + if (activeTransformer.isStructureFormed() && activeTransformer.isActive()) { + NBTTagCompound subTag = new NBTTagCompound(); + + subTag.setLong("AverageIO", activeTransformer.getAverageIOLastSec()); + + tag.setTag("gregtech.IMultiblockController.ActiveTransformer", subTag); + } + } + return tag; + } + + @Override + @NotNull + public List getWailaBody(ItemStack itemStack, List tooltip, IWailaDataAccessor accessor, + IWailaConfigHandler config) { + if (!config.getConfig("gregtech.multiblock") || accessor.getTileEntity() == null) { + return tooltip; + } + + if (accessor.getNBTData().hasKey("gregtech.IMultiblockController.ActiveTransformer")) { + NBTTagCompound tag = accessor.getNBTData() + .getCompoundTag("gregtech.IMultiblockController.ActiveTransformer"); + + tooltip.add(I18n.format("gregtech.waila.active_transformer.average_io", + TextFormattingUtil.formatNumbers(tag.getLong("AverageIO")))); + } + + return tooltip; + } +} diff --git a/src/main/java/gregtech/integration/hwyla/provider/BatteryBufferDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/BatteryBufferDataProvider.java new file mode 100644 index 00000000000..67f08fd7737 --- /dev/null +++ b/src/main/java/gregtech/integration/hwyla/provider/BatteryBufferDataProvider.java @@ -0,0 +1,79 @@ +package gregtech.integration.hwyla.provider; + +import gregtech.api.GTValues; +import gregtech.api.capability.GregtechCapabilities; +import gregtech.api.capability.IEnergyContainer; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.util.TextFormattingUtil; +import gregtech.common.metatileentities.electric.MetaTileEntityBatteryBuffer; + +import net.minecraft.client.resources.I18n; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.capabilities.Capability; + +import mcp.mobius.waila.api.IWailaConfigHandler; +import mcp.mobius.waila.api.IWailaDataAccessor; +import mcp.mobius.waila.api.IWailaRegistrar; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class BatteryBufferDataProvider extends CapabilityDataProvider { + + public static final BatteryBufferDataProvider INSTANCE = new BatteryBufferDataProvider(); + + @Override + public void register(@NotNull IWailaRegistrar registrar) { + registrar.registerBodyProvider(this, TileEntity.class); + registrar.registerNBTProvider(this, TileEntity.class); + registrar.addConfig(GTValues.MOD_NAME, "gregtech.battery-buffer"); + } + + @Override + protected @NotNull Capability getCapability() { + return GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER; + } + + @Override + protected NBTTagCompound getNBTData(IEnergyContainer capability, NBTTagCompound tag) { + NBTTagCompound subTag = new NBTTagCompound(); + subTag.setLong("InputPerSec", capability.getInputPerSec()); + subTag.setLong("OutputPerSec", capability.getOutputPerSec()); + tag.setTag("gregtech.BatteryBuffer", subTag); + return tag; + } + + @Override + @NotNull + public List getWailaBody(ItemStack itemStack, List tooltip, IWailaDataAccessor accessor, + IWailaConfigHandler config) { + if (!config.getConfig("gregtech.battery-buffer") || accessor.getTileEntity() == null) { + return tooltip; + } + + if (accessor.getNBTData().hasKey("gregtech.BatteryBuffer")) { + NBTTagCompound batteryTag = accessor.getNBTData().getCompoundTag("gregtech.BatteryBuffer"); + + if (accessor.getTileEntity() instanceof IGregTechTileEntity iGregTechTileEntity) { + MetaTileEntity metaTileEntity = iGregTechTileEntity.getMetaTileEntity(); + + if (metaTileEntity instanceof MetaTileEntityBatteryBuffer) { + long averageIn = batteryTag.getLong("InputPerSec") / 20; + String averageInFormatted = I18n.format("gregtech.waila.energy_input", + TextFormattingUtil.formatNumbers(averageIn)); + tooltip.add(averageInFormatted); + + long averageOut = batteryTag.getLong("OutputPerSec") / 20; + String averageOutFormatted = I18n.format("gregtech.waila.energy_output", + TextFormattingUtil.formatNumbers(averageOut)); + tooltip.add(averageOutFormatted); + } + } + } + + return tooltip; + } +} diff --git a/src/main/java/gregtech/integration/hwyla/provider/BlockOreDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/BlockOreDataProvider.java index b8d6512742b..98654be839f 100644 --- a/src/main/java/gregtech/integration/hwyla/provider/BlockOreDataProvider.java +++ b/src/main/java/gregtech/integration/hwyla/provider/BlockOreDataProvider.java @@ -8,7 +8,10 @@ import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; -import mcp.mobius.waila.api.*; +import mcp.mobius.waila.api.IWailaConfigHandler; +import mcp.mobius.waila.api.IWailaDataAccessor; +import mcp.mobius.waila.api.IWailaDataProvider; +import mcp.mobius.waila.api.IWailaRegistrar; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -19,7 +22,7 @@ public class BlockOreDataProvider implements IWailaDataProvider { public void register(@NotNull IWailaRegistrar registrar) { registrar.registerBodyProvider(this, BlockOre.class); - registrar.addConfig(GTValues.MODID, "gregtech.block_ore"); + registrar.addConfig(GTValues.MOD_NAME, "gregtech.block_ore"); } @NotNull diff --git a/src/main/java/gregtech/integration/hwyla/provider/ControllableDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/ControllableDataProvider.java index 20791ab3e34..84d8151c6bd 100644 --- a/src/main/java/gregtech/integration/hwyla/provider/ControllableDataProvider.java +++ b/src/main/java/gregtech/integration/hwyla/provider/ControllableDataProvider.java @@ -26,7 +26,7 @@ public class ControllableDataProvider extends CapabilityDataProvider getWailaBody(ItemStack itemStack, List tooltip, IWai NBTTagCompound energyTag = accessor.getNBTData().getCompoundTag("gregtech.IEnergyContainer"); long stored = energyTag.getLong("Stored"); long capacity = energyTag.getLong("Capacity"); - tooltip.add(I18n.format("gregtech.waila.energy_stored", stored, capacity)); + tooltip.add(I18n.format("gregtech.waila.energy_stored", + TextFormattingUtil.formatNumbers(stored), + TextFormattingUtil.formatNumbers(capacity))); } return tooltip; } diff --git a/src/main/java/gregtech/integration/hwyla/provider/LampDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/LampDataProvider.java index a4473efa17a..0f000fdc527 100644 --- a/src/main/java/gregtech/integration/hwyla/provider/LampDataProvider.java +++ b/src/main/java/gregtech/integration/hwyla/provider/LampDataProvider.java @@ -21,7 +21,7 @@ public class LampDataProvider implements IWailaDataProvider { public void register(@NotNull IWailaRegistrar registrar) { registrar.registerBodyProvider(this, BlockLamp.class); - registrar.addConfig(GTValues.MODID, "gregtech.block_lamp"); + registrar.addConfig(GTValues.MOD_NAME, "gregtech.block_lamp"); } @NotNull diff --git a/src/main/java/gregtech/integration/hwyla/provider/MaintenanceDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/MaintenanceDataProvider.java index c776176fc2d..38719913fd4 100644 --- a/src/main/java/gregtech/integration/hwyla/provider/MaintenanceDataProvider.java +++ b/src/main/java/gregtech/integration/hwyla/provider/MaintenanceDataProvider.java @@ -37,7 +37,7 @@ public class MaintenanceDataProvider extends CapabilityDataProvider getWailaBody(ItemStack itemStack, List tooltip, IWai if (accessor.getNBTData().hasKey("gregtech.IPrimitivePump")) { NBTTagCompound tag = accessor.getNBTData().getCompoundTag("gregtech.IPrimitivePump"); int production = tag.getInteger("Production"); - tooltip.add(I18n.format("gregtech.top.primitive_pump_production") + " " + TextFormatting.AQUA + production + + tooltip.add(I18n.format("gregtech.top.primitive_pump_production") + " " + TextFormatting.AQUA + + TextFormattingUtil.formatNumbers(production) + TextFormatting.RESET + " L/s"); } return tooltip; diff --git a/src/main/java/gregtech/integration/hwyla/provider/RecipeLogicDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/RecipeLogicDataProvider.java index f1a2a6b5a4c..08391814820 100644 --- a/src/main/java/gregtech/integration/hwyla/provider/RecipeLogicDataProvider.java +++ b/src/main/java/gregtech/integration/hwyla/provider/RecipeLogicDataProvider.java @@ -3,12 +3,14 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.impl.AbstractRecipeLogic; +import gregtech.api.capability.impl.PrimitiveRecipeLogic; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.SteamMetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.RecipeMapSteamMultiblockController; import gregtech.api.unification.material.Materials; import gregtech.api.util.GTUtility; +import gregtech.api.util.TextFormattingUtil; import gregtech.common.metatileentities.multi.MetaTileEntityLargeBoiler; import net.minecraft.client.resources.I18n; @@ -33,7 +35,7 @@ public class RecipeLogicDataProvider extends CapabilityDataProvider getWailaBody(ItemStack itemStack, List tooltip, IWai if (accessor.getNBTData().hasKey("gregtech.AbstractRecipeLogic")) { NBTTagCompound tag = accessor.getNBTData().getCompoundTag("gregtech.AbstractRecipeLogic"); if (tag.getBoolean("Working")) { - int EUt = tag.getInteger("RecipeEUt"); - int absEUt = Math.abs(EUt); - boolean consumer = EUt > 0; + long eut = tag.getLong("RecipeEUt"); + boolean consumer = false; String endText = null; if (accessor.getTileEntity() instanceof IGregTechTileEntity gtte) { MetaTileEntity mte = gtte.getMetaTileEntity(); if (mte instanceof SteamMetaTileEntity || mte instanceof MetaTileEntityLargeBoiler || mte instanceof RecipeMapSteamMultiblockController) { - endText = ": " + absEUt + TextFormatting.RESET + " L/t " + + endText = ": " + TextFormattingUtil.formatNumbers(eut) + TextFormatting.RESET + " L/t " + I18n.format(Materials.Steam.getUnlocalizedName()); } AbstractRecipeLogic arl = mte.getRecipeLogic(); @@ -81,11 +82,11 @@ public List getWailaBody(ItemStack itemStack, List tooltip, IWai } } if (endText == null) { - endText = ": " + absEUt + TextFormatting.RESET + " EU/t (" + - GTValues.VNF[GTUtility.getTierByVoltage(absEUt)] + TextFormatting.RESET + ")"; + endText = ": " + TextFormattingUtil.formatNumbers(eut) + TextFormatting.RESET + " EU/t (" + + GTValues.VOCNF[GTUtility.getOCTierByVoltage(eut)] + TextFormatting.RESET + ")"; } - if (EUt == 0) return tooltip; + if (eut == 0) return tooltip; if (consumer) { tooltip.add(I18n.format("gregtech.top.energy_consumption") + endText); diff --git a/src/main/java/gregtech/integration/hwyla/provider/SteamBoilerDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/SteamBoilerDataProvider.java index 85a3f738ca0..8b46ab78309 100644 --- a/src/main/java/gregtech/integration/hwyla/provider/SteamBoilerDataProvider.java +++ b/src/main/java/gregtech/integration/hwyla/provider/SteamBoilerDataProvider.java @@ -3,6 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.unification.material.Materials; +import gregtech.api.util.TextFormattingUtil; import gregtech.common.metatileentities.steam.boiler.SteamBoiler; import net.minecraft.client.resources.I18n; @@ -28,7 +29,7 @@ public class SteamBoilerDataProvider implements IWailaDataProvider { public void register(@NotNull IWailaRegistrar registrar) { registrar.registerBodyProvider(this, IGregTechTileEntity.class); registrar.registerNBTProvider(this, IGregTechTileEntity.class); - registrar.addConfig(GTValues.MODID, "gregtech.steam_boiler"); + registrar.addConfig(GTValues.MOD_NAME, "gregtech.steam_boiler"); } @NotNull @@ -65,7 +66,8 @@ public List getWailaBody(ItemStack itemStack, List tooltip, IWai // Creating steam if (steamRate > 0 && hasWater) { - tooltip.add(I18n.format("gregtech.top.energy_production") + ": " + (steamRate / 10) + " L/t " + + tooltip.add(I18n.format("gregtech.top.energy_production") + ": " + + TextFormattingUtil.formatNumbers(steamRate / 10) + " L/t " + I18n.format(Materials.Steam.getUnlocalizedName())); } diff --git a/src/main/java/gregtech/integration/hwyla/provider/TransformerDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/TransformerDataProvider.java index 49da30bf2da..19cd6698f58 100644 --- a/src/main/java/gregtech/integration/hwyla/provider/TransformerDataProvider.java +++ b/src/main/java/gregtech/integration/hwyla/provider/TransformerDataProvider.java @@ -4,6 +4,7 @@ import gregtech.api.capability.IEnergyContainer; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.util.GTUtility; +import gregtech.api.util.TextFormattingUtil; import gregtech.common.metatileentities.electric.MetaTileEntityTransformer; import net.minecraft.client.resources.I18n; @@ -28,7 +29,7 @@ public class TransformerDataProvider extends ElectricContainerDataProvider { public void register(@NotNull IWailaRegistrar registrar) { registrar.registerBodyProvider(this, TileEntity.class); registrar.registerNBTProvider(this, TileEntity.class); - registrar.addConfig(GTValues.MODID, "gregtech.transformer"); + registrar.addConfig(GTValues.MOD_NAME, "gregtech.transformer"); } @Override @@ -82,7 +83,7 @@ public List getWailaBody(ItemStack itemStack, List tooltip, IWai .append(GTValues.VNF[GTUtility.getTierByVoltage(inputVoltage)]) .append(TextFormatting.RESET) .append(" (") - .append(inputAmperage) + .append(TextFormattingUtil.formatNumbers(inputAmperage)) .append("A)"); StringBuilder output = new StringBuilder() @@ -90,7 +91,7 @@ public List getWailaBody(ItemStack itemStack, List tooltip, IWai .append(GTValues.VNF[GTUtility.getTierByVoltage(outputVoltage)]) .append(TextFormatting.RESET) .append(" (") - .append(outputAmperage) + .append(TextFormattingUtil.formatNumbers(outputAmperage)) .append("A)"); // Step Up/Step Down line diff --git a/src/main/java/gregtech/integration/hwyla/provider/WorkableDataProvider.java b/src/main/java/gregtech/integration/hwyla/provider/WorkableDataProvider.java index febcc67b9f0..bc1c4cb9e27 100644 --- a/src/main/java/gregtech/integration/hwyla/provider/WorkableDataProvider.java +++ b/src/main/java/gregtech/integration/hwyla/provider/WorkableDataProvider.java @@ -26,7 +26,7 @@ public class WorkableDataProvider extends CapabilityDataProvider { public void register(@NotNull IWailaRegistrar registrar) { registrar.registerBodyProvider(this, TileEntity.class); registrar.registerNBTProvider(this, TileEntity.class); - registrar.addConfig(GTValues.MODID, "gregtech.workable"); + registrar.addConfig(GTValues.MOD_NAME, "gregtech.workable"); } @Override diff --git a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java index be7c1bd50ca..5ce3cff1cb9 100644 --- a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java +++ b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java @@ -10,16 +10,19 @@ 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; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.api.util.Mods; import gregtech.api.worldgen.config.BedrockFluidDepositDefinition; import gregtech.api.worldgen.config.OreDepositDefinition; import gregtech.api.worldgen.config.WorldGenRegistry; @@ -74,10 +77,10 @@ import org.jetbrains.annotations.NotNull; import java.lang.reflect.Field; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -85,7 +88,7 @@ @GregTechModule( moduleID = GregTechModules.MODULE_JEI, containerID = GTValues.MODID, - modDependencies = GTValues.MODID_JEI, + modDependencies = Mods.Names.JUST_ENOUGH_ITEMS, name = "GregTech JEI Integration", description = "JustEnoughItems Integration Module") public class JustEnoughItemsModule extends IntegrationSubmodule implements IModPlugin { @@ -112,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 @@ -189,32 +194,49 @@ 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 CopyOnWriteArrayList<>(); + List oreByproductList = new ArrayList<>(); for (Material material : GregTechAPI.materialManager.getRegisteredMaterials()) { if (material.hasProperty(PropertyKey.ORE)) { oreByproductList.add(new OreByProduct(material)); @@ -222,7 +244,7 @@ public void register(IModRegistry registry) { } String oreByProductId = GTValues.MODID + ":" + "ore_by_product"; registry.addRecipes(oreByproductList, oreByProductId); - MetaTileEntity[][] machineLists = new MetaTileEntity[][] { + MetaTileEntity[][] machineLists = { MetaTileEntities.MACERATOR, MetaTileEntities.ORE_WASHER, MetaTileEntities.CENTRIFUGE, @@ -237,7 +259,7 @@ public void register(IModRegistry registry) { } // Material Tree - List materialTreeList = new CopyOnWriteArrayList<>(); + List materialTreeList = new ArrayList<>(); for (Material material : GregTechAPI.materialManager.getRegisteredMaterials()) { if (material.hasProperty(PropertyKey.DUST)) { materialTreeList.add(new MaterialTree(material)); @@ -247,7 +269,7 @@ public void register(IModRegistry registry) { // Ore Veins List oreVeins = WorldGenRegistry.getOreDeposits(); - List oreInfoList = new CopyOnWriteArrayList<>(); + List oreInfoList = new ArrayList<>(); for (OreDepositDefinition vein : oreVeins) { oreInfoList.add(new GTOreInfo(vein)); } @@ -261,7 +283,7 @@ public void register(IModRegistry registry) { // Fluid Veins List fluidVeins = WorldGenRegistry.getBedrockVeinDeposits(); - List fluidVeinInfos = new CopyOnWriteArrayList<>(); + List fluidVeinInfos = new ArrayList<>(); for (BedrockFluidDepositDefinition fluidVein : fluidVeins) { fluidVeinInfos.add(new GTFluidVeinInfo(fluidVein)); } @@ -295,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() { @@ -307,7 +332,7 @@ private void setupInputHandler() { showsRecipeFocuses.add(new MultiblockInfoRecipeFocusShower()); - } catch (Exception e) { + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException | SecurityException e) { getLogger().error("Could not reflect JEI Internal inputHandler", e); } } diff --git a/src/main/java/gregtech/integration/jei/basic/GTOreInfo.java b/src/main/java/gregtech/integration/jei/basic/GTOreInfo.java index 0f5bd90bf9f..75d8c11f81a 100644 --- a/src/main/java/gregtech/integration/jei/basic/GTOreInfo.java +++ b/src/main/java/gregtech/integration/jei/basic/GTOreInfo.java @@ -4,6 +4,7 @@ import gregtech.api.unification.material.Material; import gregtech.api.util.FileUtility; import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import gregtech.api.worldgen.config.FillerConfigUtils; import gregtech.api.worldgen.config.OreDepositDefinition; import gregtech.api.worldgen.filler.BlockFiller; @@ -26,7 +27,6 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.IFluidBlock; -import net.minecraftforge.fml.common.Loader; import com.google.common.collect.ImmutableList; import mezz.jei.api.ingredients.IIngredients; @@ -41,7 +41,6 @@ import java.util.function.Function; import static gregtech.api.GTValues.M; -import static gregtech.api.GTValues.MODID_CC; public class GTOreInfo implements IRecipeWrapper { @@ -64,7 +63,7 @@ public GTOreInfo(OreDepositDefinition definition) { // Don't default to vanilla Maximums and minimums if the values are not defined and Cubic Chunks is loaded // This could be improved to use the actual minimum and maximum heights, at the cost of including the CC Api - if (Loader.isModLoaded(MODID_CC)) { + if (Mods.CubicChunks.isModLoaded()) { this.maxHeight = definition.getMaximumHeight() == Integer.MAX_VALUE ? Integer.MAX_VALUE : definition.getMaximumHeight(); this.minHeight = definition.getMinimumHeight() == Integer.MIN_VALUE ? Integer.MIN_VALUE : diff --git a/src/main/java/gregtech/integration/jei/basic/MaterialTree.java b/src/main/java/gregtech/integration/jei/basic/MaterialTree.java index 3babd634779..82cc58d5dab 100644 --- a/src/main/java/gregtech/integration/jei/basic/MaterialTree.java +++ b/src/main/java/gregtech/integration/jei/basic/MaterialTree.java @@ -6,6 +6,7 @@ import gregtech.api.unification.ore.OrePrefix; import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import com.google.common.collect.ImmutableList; @@ -74,7 +75,10 @@ public MaterialTree(Material material) { List matFluidsStack = new ArrayList<>(); if (material.hasProperty(PropertyKey.FLUID)) { - matFluidsStack.add(material.getFluid(1000)); + Fluid fluid = material.getFluid(); + if (fluid != null) { + matFluidsStack.add(new FluidStack(fluid, 1000)); + } } this.fluidInputs.add(matFluidsStack); diff --git a/src/main/java/gregtech/integration/jei/basic/MaterialTreeCategory.java b/src/main/java/gregtech/integration/jei/basic/MaterialTreeCategory.java index 16a26032f73..b3c8b6e10b2 100644 --- a/src/main/java/gregtech/integration/jei/basic/MaterialTreeCategory.java +++ b/src/main/java/gregtech/integration/jei/basic/MaterialTreeCategory.java @@ -2,7 +2,7 @@ import gregtech.api.GTValues; import gregtech.api.gui.GuiTextures; -import gregtech.api.recipes.recipeproperties.TemperatureProperty; +import gregtech.api.recipes.properties.impl.TemperatureProperty; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Materials; import gregtech.api.unification.ore.OrePrefix; diff --git a/src/main/java/gregtech/integration/jei/basic/OreByProduct.java b/src/main/java/gregtech/integration/jei/basic/OreByProduct.java index fb1af11438b..8e062d069c0 100755 --- a/src/main/java/gregtech/integration/jei/basic/OreByProduct.java +++ b/src/main/java/gregtech/integration/jei/basic/OreByProduct.java @@ -1,6 +1,5 @@ package gregtech.integration.jei.basic; -import gregtech.api.GTValues; import gregtech.api.recipes.chance.output.impl.ChancedItemOutput; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Material; @@ -30,10 +29,14 @@ import java.util.ArrayList; import java.util.List; +import static gregtech.api.GTValues.LV; + public class OreByProduct implements IRecipeWrapper { private static final List ORES = new ArrayList<>(); + private static final int NUM_INPUTS = 21; + public static void addOreByProductPrefix(OrePrefix orePrefix) { if (!ORES.contains(orePrefix)) { ORES.add(orePrefix); @@ -62,14 +65,14 @@ public static void addOreByProductPrefix(OrePrefix orePrefix) { public OreByProduct(Material material) { if (ALWAYS_MACHINES == null) { ALWAYS_MACHINES = ImmutableList.of( - MetaTileEntities.MACERATOR[GTValues.LV].getStackForm(), - MetaTileEntities.MACERATOR[GTValues.LV].getStackForm(), - MetaTileEntities.CENTRIFUGE[GTValues.LV].getStackForm(), - MetaTileEntities.ORE_WASHER[GTValues.LV].getStackForm(), - MetaTileEntities.THERMAL_CENTRIFUGE[GTValues.LV].getStackForm(), - MetaTileEntities.MACERATOR[GTValues.LV].getStackForm(), - MetaTileEntities.MACERATOR[GTValues.LV].getStackForm(), - MetaTileEntities.CENTRIFUGE[GTValues.LV].getStackForm()); + MetaTileEntities.MACERATOR[LV].getStackForm(), + MetaTileEntities.MACERATOR[LV].getStackForm(), + MetaTileEntities.CENTRIFUGE[LV].getStackForm(), + MetaTileEntities.ORE_WASHER[LV].getStackForm(), + MetaTileEntities.THERMAL_CENTRIFUGE[LV].getStackForm(), + MetaTileEntities.MACERATOR[LV].getStackForm(), + MetaTileEntities.MACERATOR[LV].getStackForm(), + MetaTileEntities.CENTRIFUGE[LV].getStackForm()); } OreProperty property = material.getProperty(PropertyKey.ORE); int oreMultiplier = property.getOreMultiplier(); @@ -97,7 +100,7 @@ public OreByProduct(Material material) { // set up machines as inputs List simpleWashers = new ArrayList<>(); simpleWashers.add(new ItemStack(Items.CAULDRON)); - simpleWashers.add(MetaTileEntities.ORE_WASHER[GTValues.LV].getStackForm()); + simpleWashers.add(MetaTileEntities.ORE_WASHER[LV].getStackForm()); if (!material.hasProperty(PropertyKey.BLAST)) { addToInputs(new ItemStack(Blocks.FURNACE)); @@ -116,19 +119,19 @@ public OreByProduct(Material material) { if (washedIn != null && washedIn.getKey() != null) { hasChemBath = true; - addToInputs(MetaTileEntities.CHEMICAL_BATH[GTValues.LV].getStackForm()); + addToInputs(MetaTileEntities.CHEMICAL_BATH[LV].getStackForm()); } else { addToInputs(ItemStack.EMPTY); } if (separatedInto != null && !separatedInto.isEmpty()) { hasSeparator = true; - addToInputs(MetaTileEntities.ELECTROMAGNETIC_SEPARATOR[GTValues.LV].getStackForm()); + addToInputs(MetaTileEntities.ELECTROMAGNETIC_SEPARATOR[LV].getStackForm()); } else { addToInputs(ItemStack.EMPTY); } if (material.hasProperty(PropertyKey.GEM)) { hasSifter = true; - addToInputs(MetaTileEntities.SIFTER[GTValues.LV].getStackForm()); + addToInputs(MetaTileEntities.SIFTER[LV].getStackForm()); } else { addToInputs(ItemStack.EMPTY); } @@ -141,7 +144,7 @@ public OreByProduct(Material material) { } // total number of inputs added - currentSlot += 21; + currentSlot += NUM_INPUTS; // BASIC PROCESSING @@ -256,8 +259,6 @@ public OreByProduct(Material material) { // sifter if (hasSifter) { boolean highOutput = material.hasFlag(MaterialFlags.HIGH_SIFTER_OUTPUT); - ItemStack flawedStack = OreDictUnifier.get(OrePrefix.gemFlawed, material); - ItemStack chippedStack = OreDictUnifier.get(OrePrefix.gemChipped, material); addToOutputs(material, OrePrefix.gemExquisite, 1); addGemChance(300, 100, 500, 150, highOutput); @@ -267,19 +268,10 @@ public OreByProduct(Material material) { addGemChance(3500, 500, 5000, 1000, highOutput); addToOutputs(material, OrePrefix.dustPure, 1); addGemChance(5000, 750, 2500, 500, highOutput); - - if (!flawedStack.isEmpty()) { - addToOutputs(flawedStack); - addGemChance(2500, 300, 2000, 500, highOutput); - } else { - addEmptyOutputs(1); - } - if (!chippedStack.isEmpty()) { - addToOutputs(chippedStack); - addGemChance(3500, 400, 3000, 350, highOutput); - } else { - addEmptyOutputs(1); - } + addToOutputs(material, OrePrefix.gemFlawed, 1); + addGemChance(2500, 300, 2000, 500, highOutput); + addToOutputs(material, OrePrefix.gemChipped, 1); + addGemChance(3500, 400, 3000, 350, highOutput); } else { addEmptyOutputs(6); } @@ -345,8 +337,11 @@ private void addToInputs(ItemStack stack) { } private void addChance(int base, int tier) { - // this is solely for the chance overlay and tooltip, neither of which care about the ItemStack - chances.put(currentSlot - 1, new ChancedItemOutput(ItemStack.EMPTY, base, tier)); + // hacky check to not add a chance for empty stacks + if (!outputs.get(currentSlot - 1 - NUM_INPUTS).get(0).isEmpty()) { + // this is solely for the chance overlay and tooltip, neither of which care about the ItemStack + chances.put(currentSlot - 1, new ChancedItemOutput(ItemStack.EMPTY, base, tier)); + } } // make the code less :weary: diff --git a/src/main/java/gregtech/integration/jei/basic/OreByProductCategory.java b/src/main/java/gregtech/integration/jei/basic/OreByProductCategory.java index 635526f3114..db4f2bc6345 100644 --- a/src/main/java/gregtech/integration/jei/basic/OreByProductCategory.java +++ b/src/main/java/gregtech/integration/jei/basic/OreByProductCategory.java @@ -154,7 +154,7 @@ public void setRecipe(IRecipeLayout recipeLayout, @NotNull OreByProduct recipeWr new ItemStackTextRenderer(recipeWrapper.getChance(i / 2 + itemInputs.size()), ChancedOutputLogic.OR), ITEM_OUTPUT_LOCATIONS.get(i) + 1, ITEM_OUTPUT_LOCATIONS.get(i + 1) + 1, 16, 16, 0, 0); - itemOutputExists.add(itemOutputs.get(i / 2).size() > 0); + itemOutputExists.add(!itemOutputs.get(i / 2).isEmpty()); } List> fluidInputs = ingredients.getInputs(VanillaTypes.FLUID); @@ -162,7 +162,7 @@ public void setRecipe(IRecipeLayout recipeLayout, @NotNull OreByProduct recipeWr for (int i = 0; i < FLUID_LOCATIONS.size(); i += 2) { fluidStackGroup.init(i / 2, true, new FluidStackTextRenderer(1, false, 16, 16, null), FLUID_LOCATIONS.get(i) + 1, FLUID_LOCATIONS.get(i + 1) + 1, 16, 16, 0, 0); - fluidInputExists.add(fluidInputs.get(i / 2).size() > 0); + fluidInputExists.add(!fluidInputs.get(i / 2).isEmpty()); } itemStackGroup.addTooltipCallback(recipeWrapper::addTooltip); @@ -208,7 +208,7 @@ public void drawExtras(@NotNull Minecraft minecraft) { for (int i = 0; i < ITEM_OUTPUT_LOCATIONS.size(); i += 2) { // stupid hack to show all sifter slots if the first one exists - if (itemOutputExists.get(i / 2) || (i > 28 * 2 && itemOutputExists.get(28) && hasSifter)) { + if (itemOutputExists.get(i / 2) || (i >= 28 * 2 && hasSifter)) { slot.draw(minecraft, ITEM_OUTPUT_LOCATIONS.get(i), ITEM_OUTPUT_LOCATIONS.get(i + 1)); } } diff --git a/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java b/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java index d0074db661c..b746f67a2cd 100644 --- a/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java +++ b/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java @@ -527,7 +527,12 @@ private static Collection gatherStructureBlocks(World world, @NotNull stack = ((IGregTechTileEntity) tileEntity).getMetaTileEntity().getStackForm(); } if (stack.isEmpty()) { - // try the itemstack constructor if we're not a GT machine + // first, see what the block has to say for itself before forcing it to use a particular meta value + stack = block.getPickBlock(state, new RayTraceResult(Vec3d.ZERO, EnumFacing.UP, pos), world, pos, + new GregFakePlayer(world)); + } + if (stack.isEmpty()) { + // try the default itemstack constructor if we're not a GT machine stack = GTUtility.toItem(state); } if (stack.isEmpty()) { @@ -541,11 +546,6 @@ private static Collection gatherStructureBlocks(World world, @NotNull } } } - if (stack.isEmpty()) { - // if everything else doesn't work, try the not great getPickBlock() with some dummy values - stack = block.getPickBlock(state, new RayTraceResult(Vec3d.ZERO, EnumFacing.UP, pos), world, pos, - new GregFakePlayer(world)); - } // if we got a stack, add it to the set and map if (!stack.isEmpty()) { diff --git a/src/main/java/gregtech/integration/jei/recipe/GTRecipeWrapper.java b/src/main/java/gregtech/integration/jei/recipe/GTRecipeWrapper.java index 9c1382a453d..4d88c1f1e5b 100644 --- a/src/main/java/gregtech/integration/jei/recipe/GTRecipeWrapper.java +++ b/src/main/java/gregtech/integration/jei/recipe/GTRecipeWrapper.java @@ -16,13 +16,14 @@ import gregtech.api.recipes.ingredients.GTRecipeInput; import gregtech.api.recipes.machines.IResearchRecipeMap; import gregtech.api.recipes.machines.IScannerRecipeMap; -import gregtech.api.recipes.recipeproperties.ComputationProperty; -import gregtech.api.recipes.recipeproperties.RecipeProperty; -import gregtech.api.recipes.recipeproperties.ScanProperty; -import gregtech.api.recipes.recipeproperties.TotalComputationProperty; +import gregtech.api.recipes.properties.RecipeProperty; +import gregtech.api.recipes.properties.impl.ComputationProperty; +import gregtech.api.recipes.properties.impl.ScanProperty; +import gregtech.api.recipes.properties.impl.TotalComputationProperty; import gregtech.api.util.AssemblyLineManager; import gregtech.api.util.ClipboardUtil; import gregtech.api.util.GTUtility; +import gregtech.api.util.LocalizationUtils; import gregtech.api.util.TextFormattingUtil; import gregtech.client.utils.TooltipHelper; import gregtech.integration.RecipeCompatUtil; @@ -40,7 +41,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; import java.util.function.BooleanSupplier; import java.util.stream.Collectors; @@ -235,7 +239,8 @@ public void addIngredientTooltips(@NotNull Collection tooltip, boolean n @Override public void drawInfo(@NotNull Minecraft minecraft, int recipeWidth, int recipeHeight, int mouseX, int mouseY) { super.drawInfo(minecraft, recipeWidth, recipeHeight, mouseX, mouseY); - var properties = recipe.getPropertyTypes(); + var storage = recipe.propertyStorage(); + var properties = storage.values(); boolean drawTotalEU = properties.isEmpty() || properties.stream().noneMatch(RecipeProperty::hideTotalEU); boolean drawEUt = properties.isEmpty() || properties.stream().noneMatch(RecipeProperty::hideEUt); boolean drawDuration = properties.isEmpty() || properties.stream().noneMatch(RecipeProperty::hideDuration); @@ -245,15 +250,18 @@ public void drawInfo(@NotNull Minecraft minecraft, int recipeWidth, int recipeHe if (drawEUt) defaultLines++; if (drawDuration) defaultLines++; - int yPosition = recipeHeight - ((recipe.getUnhiddenPropertyCount() + defaultLines) * 10 - 3); + int unhiddenCount = (int) storage.entrySet().stream() + .filter((property) -> !property.getKey().isHidden()) + .count(); + int yPosition = recipeHeight - ((unhiddenCount + defaultLines) * 10 - 3); // Default entries if (drawTotalEU) { - long eu = Math.abs((long) recipe.getEUt()) * recipe.getDuration(); + long eu = recipe.getEUt() * recipe.getDuration(); // sadly we still need a custom override here, since computation uses duration and EU/t very differently - if (recipe.hasProperty(TotalComputationProperty.getInstance()) && - recipe.hasProperty(ComputationProperty.getInstance())) { - int minimumCWUt = recipe.getProperty(ComputationProperty.getInstance(), 1); + if (storage.contains(TotalComputationProperty.getInstance()) && + storage.contains(ComputationProperty.getInstance())) { + int minimumCWUt = storage.get(ComputationProperty.getInstance(), 1); minecraft.fontRenderer.drawString(I18n.format("gregtech.recipe.max_eu", eu / minimumCWUt), 0, yPosition, 0x111111); } else { @@ -262,22 +270,24 @@ public void drawInfo(@NotNull Minecraft minecraft, int recipeWidth, int recipeHe } if (drawEUt) { minecraft.fontRenderer.drawString( - I18n.format(recipe.getEUt() >= 0 ? "gregtech.recipe.eu" : "gregtech.recipe.eu_inverted", - Math.abs(recipe.getEUt()), GTValues.VN[GTUtility.getTierByVoltage(recipe.getEUt())]), + I18n.format( + recipeMap.getRecipeMapUI().isGenerator() ? "gregtech.recipe.eu_inverted" : + "gregtech.recipe.eu", + recipe.getEUt(), GTValues.VN[GTUtility.getTierByVoltage(recipe.getEUt())]), 0, yPosition += LINE_HEIGHT, 0x111111); } if (drawDuration) { minecraft.fontRenderer.drawString( I18n.format("gregtech.recipe.duration", - TextFormattingUtil.formatNumbers(recipe.getDuration() / 20d)), + TextFormattingUtil.formatNumbers(recipe.getDuration() / 20.0)), 0, yPosition += LINE_HEIGHT, 0x111111); } // Property custom entries - for (Map.Entry, Object> propertyEntry : recipe.getPropertyValues()) { + for (var propertyEntry : storage.entrySet()) { if (!propertyEntry.getKey().isHidden()) { RecipeProperty property = propertyEntry.getKey(); - Object value = propertyEntry.getValue(); + var value = propertyEntry.getValue(); property.drawInfo(minecraft, 0, yPosition += property.getInfoHeight(value), 0x111111, value, mouseX, mouseY); } @@ -288,7 +298,7 @@ public void drawInfo(@NotNull Minecraft minecraft, int recipeWidth, int recipeHe @Override public List getTooltipStrings(int mouseX, int mouseY) { List tooltips = new ArrayList<>(); - for (var entry : recipe.getPropertyValues()) { + for (var entry : recipe.propertyStorage().entrySet()) { if (!entry.getKey().isHidden()) { RecipeProperty property = entry.getKey(); Object value = entry.getValue(); @@ -300,15 +310,22 @@ public List getTooltipStrings(int mouseX, int mouseY) { @Override public void initExtras() { - // do not add the X button if no tweaker mod is present + // do not add the info or X button if no tweaker mod is present if (!RecipeCompatUtil.isTweakerLoaded()) return; - BooleanSupplier creativePlayerCtPredicate = () -> Minecraft.getMinecraft().player != null && + BooleanSupplier creativePlayerPredicate = () -> Minecraft.getMinecraft().player != null && Minecraft.getMinecraft().player.isCreative(); + BooleanSupplier creativeTweaker = () -> creativePlayerPredicate.getAsBoolean() && + (recipe.getIsCTRecipe() || recipe.isGroovyRecipe()); + BooleanSupplier creativeDefault = () -> creativePlayerPredicate.getAsBoolean() && !recipe.getIsCTRecipe() && + !recipe.isGroovyRecipe(); + + // X Button buttons.add(new JeiButton(166, 2, 10, 10) .setTextures(GuiTextures.BUTTON_CLEAR_GRID) - .setTooltipBuilder(lines -> lines.add("Copies a " + RecipeCompatUtil.getTweakerName() + - " script, to remove this recipe, to the clipboard")) + .setTooltipBuilder(lines -> lines.add( + LocalizationUtils.format("gregtech.jei.remove_recipe.tooltip", + RecipeCompatUtil.getTweakerName()))) .setClickAction((minecraft, mouseX, mouseY, mouseButton) -> { String recipeLine = RecipeCompatUtil.getRecipeRemoveLine(recipeMap, recipe); String output = RecipeCompatUtil.getFirstOutputString(recipe); @@ -321,7 +338,16 @@ public void initExtras() { new TextComponentString("Copied [\u00A76" + recipeLine + "\u00A7r] to the clipboard")); return true; }) - .setActiveSupplier(creativePlayerCtPredicate)); + .setActiveSupplier(creativeDefault)); + + // CT/GS Info + buttons.add(new JeiButton(166, 2, 10, 10) + .setTextures(GuiTextures.INFO_ICON) + .setTooltipBuilder(lines -> lines.add(recipe.isGroovyRecipe() ? + LocalizationUtils.format("gregtech.jei.gs_recipe.tooltip") : + LocalizationUtils.format("gregtech.jei.ct_recipe.tooltip"))) + .setClickAction((mc, x, y, button) -> false) + .setActiveSupplier(creativeTweaker)); } public ChancedItemOutput getOutputChance(int slot) { diff --git a/src/main/java/gregtech/integration/jei/recipe/RecipeMapCategory.java b/src/main/java/gregtech/integration/jei/recipe/RecipeMapCategory.java index 52039a21b07..31dde8f7874 100644 --- a/src/main/java/gregtech/integration/jei/recipe/RecipeMapCategory.java +++ b/src/main/java/gregtech/integration/jei/recipe/RecipeMapCategory.java @@ -12,8 +12,8 @@ import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.RecipeMaps; import gregtech.api.recipes.category.GTRecipeCategory; -import gregtech.api.recipes.recipeproperties.ResearchProperty; -import gregtech.api.recipes.recipeproperties.ResearchPropertyData; +import gregtech.api.recipes.properties.impl.ResearchProperty; +import gregtech.api.recipes.properties.impl.ResearchPropertyData; import gregtech.api.util.AssemblyLineManager; import gregtech.api.util.GTUtility; import gregtech.api.util.LocalizationUtils; @@ -213,9 +213,9 @@ public void setRecipe(IRecipeLayout recipeLayout, @NotNull GTRecipeWrapper recip if (data != null) { List dataItems = new ArrayList<>(); for (ResearchPropertyData.ResearchEntry entry : data) { - ItemStack dataStick = entry.getDataItem().copy(); + ItemStack dataStick = entry.dataItem().copy(); AssemblyLineManager.writeResearchToNBT(GTUtility.getOrCreateNbtCompound(dataStick), - entry.getResearchId()); + entry.researchId()); dataItems.add(dataStick); } itemStackGroup.set(16, dataItems); diff --git a/src/main/java/gregtech/integration/jei/utils/JEIResourceDepositCategoryUtils.java b/src/main/java/gregtech/integration/jei/utils/JEIResourceDepositCategoryUtils.java index 77ee3c8bcb7..bc5042b0d64 100644 --- a/src/main/java/gregtech/integration/jei/utils/JEIResourceDepositCategoryUtils.java +++ b/src/main/java/gregtech/integration/jei/utils/JEIResourceDepositCategoryUtils.java @@ -1,6 +1,7 @@ package gregtech.integration.jei.utils; import gregtech.api.util.GTLog; +import gregtech.api.util.Mods; import gregtech.api.worldgen.config.OreDepositDefinition; import net.minecraft.client.Minecraft; @@ -10,7 +11,6 @@ import net.minecraft.world.WorldProvider; import net.minecraft.world.biome.Biome; import net.minecraftforge.common.DimensionManager; -import net.minecraftforge.fml.common.Loader; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.IntArrayList; @@ -27,8 +27,6 @@ import java.util.function.Function; import java.util.function.Predicate; -import static gregtech.api.GTValues.MODID_AR; - /** * Common util methods shared between {@link gregtech.integration.jei.basic.GTOreCategory} * and {@link gregtech.integration.jei.basic.GTFluidVeinCategory} @@ -139,7 +137,7 @@ public static int[] getAllRegisteredDimensions(@Nullable Predicate { + + @Override + public String getID() { + return GTValues.MODID + ":active_transformer_info_provider"; + } + + @Override + protected boolean allowDisplaying(@NotNull IMultiblockController capability) { + return capability instanceof MetaTileEntityActiveTransformer activeTransformer && activeTransformer.isActive(); + } + + @Override + protected @NotNull Capability getCapability() { + return GregtechCapabilities.CAPABILITY_MULTIBLOCK_CONTROLLER; + } + + @Override + protected void addProbeInfo(IMultiblockController capability, IProbeInfo probeInfo, EntityPlayer player, + TileEntity tileEntity, IProbeHitData data) { + long averageIO = ((MetaTileEntityActiveTransformer) capability).getAverageIOLastSec(); + ITextComponent text = TextComponentUtil.translationWithColor( + TextFormatting.AQUA, + "gregtech.multiblock.active_transformer.average_io", + TextComponentUtil.stringWithColor(TextFormatting.WHITE, + player.isSneaking() || averageIO < 10_000 ? + TextFormattingUtil.formatNumbers(averageIO) + " EU/t" : + ElementProgress.format(averageIO, NumberFormat.COMPACT, "EU/t"))); + + probeInfo.text(text.getFormattedText()); + } +} diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/BatteryBufferInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/BatteryBufferInfoProvider.java new file mode 100644 index 00000000000..0c990604954 --- /dev/null +++ b/src/main/java/gregtech/integration/theoneprobe/provider/BatteryBufferInfoProvider.java @@ -0,0 +1,67 @@ +package gregtech.integration.theoneprobe.provider; + +import gregtech.api.GTValues; +import gregtech.api.capability.GregtechCapabilities; +import gregtech.api.capability.IEnergyContainer; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.util.TextComponentUtil; +import gregtech.api.util.TextFormattingUtil; +import gregtech.common.metatileentities.electric.MetaTileEntityBatteryBuffer; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.common.capabilities.Capability; + +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 BatteryBufferInfoProvider extends CapabilityInfoProvider { + + @Override + public String getID() { + return GTValues.MODID + ":battery_buffer_provider"; + } + + @Override + protected @NotNull Capability getCapability() { + return GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER; + } + + @Override + protected void addProbeInfo(IEnergyContainer capability, IProbeInfo probeInfo, EntityPlayer player, + TileEntity tileEntity, IProbeHitData data) { + if (tileEntity instanceof IGregTechTileEntity iGregTechTileEntity) { + MetaTileEntity metaTileEntity = iGregTechTileEntity.getMetaTileEntity(); + + if (metaTileEntity instanceof MetaTileEntityBatteryBuffer) { + long averageIn = capability.getInputPerSec() / 20; + ITextComponent averageInFormatted = TextComponentUtil.translationWithColor( + TextFormatting.GREEN, + "gregtech.battery_buffer.average_input.top", + TextComponentUtil.stringWithColor( + TextFormatting.WHITE, + player.isSneaking() || averageIn < 10_000 ? + TextFormattingUtil.formatNumbers(averageIn) + " EU/t" : + ElementProgress.format(averageIn, NumberFormat.COMPACT, "EU/t"))); + probeInfo.text(averageInFormatted.getFormattedText()); + + long averageOut = capability.getOutputPerSec() / 20; + ITextComponent averageOutFormatted = TextComponentUtil.translationWithColor( + TextFormatting.RED, + "gregtech.battery_buffer.average_output.top", + TextComponentUtil.stringWithColor( + TextFormatting.WHITE, + player.isSneaking() || averageOut < 10_000 ? + TextFormattingUtil.formatNumbers(averageOut) + " EU/t" : + ElementProgress.format(averageOut, NumberFormat.COMPACT, "EU/t"))); + probeInfo.text(averageOutFormatted.getFormattedText()); + } + } + } +} diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/ConverterInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/ConverterInfoProvider.java index 4a635e9058a..2ef4b0e3e05 100644 --- a/src/main/java/gregtech/integration/theoneprobe/provider/ConverterInfoProvider.java +++ b/src/main/java/gregtech/integration/theoneprobe/provider/ConverterInfoProvider.java @@ -5,6 +5,7 @@ import gregtech.api.capability.GregtechCapabilities; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.util.GTUtility; +import gregtech.api.util.TextFormattingUtil; import gregtech.common.metatileentities.converter.ConverterTrait; import net.minecraft.entity.player.EntityPlayer; @@ -45,18 +46,22 @@ protected void addProbeInfo(@NotNull ConverterTrait capability, @NotNull IProbeI if (capability.isFeToEu()) { if (data.getSideHit() == facing) { probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.transform_output*} " + voltageN + - TextFormatting.GREEN + " (" + amperage + "A)"); + TextFormatting.GREEN + " (" + TextFormattingUtil.formatNumbers(amperage) + "A)"); } else { probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.transform_input*} " + TextFormatting.RED + - FeCompat.toFe(capability.getVoltage() * amperage, FeCompat.ratio(true)) + " FE"); + TextFormattingUtil.formatNumbers( + FeCompat.toFe(capability.getVoltage() * amperage, FeCompat.ratio(true))) + + " FE"); } } else { if (data.getSideHit() == facing) { probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.transform_output*} " + TextFormatting.RED + - FeCompat.toFe(capability.getVoltage() * amperage, FeCompat.ratio(false)) + " FE"); + TextFormattingUtil.formatNumbers( + FeCompat.toFe(capability.getVoltage() * amperage, FeCompat.ratio(false))) + + " FE"); } else { probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.transform_input*} " + voltageN + - TextFormatting.GREEN + " (" + amperage + "A)"); + TextFormatting.GREEN + " (" + TextFormattingUtil.formatNumbers(amperage) + "A)"); } } } diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/CoverInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/CoverInfoProvider.java index 645e6774d3b..377ff7a51d7 100644 --- a/src/main/java/gregtech/integration/theoneprobe/provider/CoverInfoProvider.java +++ b/src/main/java/gregtech/integration/theoneprobe/provider/CoverInfoProvider.java @@ -6,10 +6,12 @@ import gregtech.api.cover.CoverHolder; import gregtech.api.util.TextFormattingUtil; import gregtech.common.covers.*; +import gregtech.common.covers.ender.CoverEnderFluidLink; import gregtech.common.covers.filter.*; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IStringSerializable; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.common.capabilities.Capability; @@ -57,22 +59,25 @@ protected void addProbeInfo(@NotNull CoverHolder capability, @NotNull IProbeInfo * @param conveyor the conveyor to get data from */ private static void conveyorInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverConveyor conveyor) { - String rateUnit = " {*cover.conveyor.transfer_rate*}"; + String rateUnit = lang("cover.conveyor.transfer_rate"); if (conveyor instanceof CoverItemVoiding) { itemVoidingInfo(probeInfo, (CoverItemVoiding) conveyor); - } else if (!(conveyor instanceof CoverRoboticArm) || - ((CoverRoboticArm) conveyor).getTransferMode() == TransferMode.TRANSFER_ANY) { + } else if (!(conveyor instanceof CoverRoboticArm arm) || + arm.getTransferMode() == TransferMode.TRANSFER_ANY) { // only display the regular rate if the cover does not have a specialized rate - transferRateText(probeInfo, conveyor.getConveyorMode(), rateUnit, conveyor.getTransferRate()); + transferRateText(probeInfo, conveyor.getConveyorMode(), " " + rateUnit, conveyor.getTransferRate()); } ItemFilterContainer filter = conveyor.getItemFilterContainer(); if (conveyor instanceof CoverRoboticArm roboticArm) { - transferModeText(probeInfo, roboticArm.getTransferMode(), rateUnit, filter.getTransferStackSize(), - filter.getFilterWrapper().getItemFilter() != null); + if (roboticArm.getTransferMode() != TransferMode.TRANSFER_ANY) + rateUnit = lang("cover.robotic_arm.exact"); + + transferModeText(probeInfo, roboticArm.getTransferMode(), rateUnit, + filter.getTransferSize(), filter.hasFilter()); } - itemFilterText(probeInfo, filter.getFilterWrapper().getItemFilter()); + itemFilterText(probeInfo, filter.getFilter()); } /** @@ -82,13 +87,13 @@ private static void conveyorInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverCo * @param voiding the voiding cover to get data from */ private static void itemVoidingInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverItemVoiding voiding) { - String unit = " {*gregtech.top.unit.items*}"; + String unit = lang("gregtech.top.unit.items"); ItemFilterContainer container = voiding.getItemFilterContainer(); if (voiding instanceof CoverItemVoidingAdvanced advanced) { VoidingMode mode = advanced.getVoidingMode(); - voidingText(probeInfo, mode, unit, container.getTransferStackSize(), - container.getFilterWrapper().getItemFilter() != null); + voidingText(probeInfo, mode, unit, container.getTransferSize(), + container.hasFilter() && !container.isBlacklistFilter()); } } @@ -99,12 +104,14 @@ private static void itemVoidingInfo(@NotNull IProbeInfo probeInfo, @NotNull Cove * @param pump the pump to get data from */ private static void pumpInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverPump pump) { - String rateUnit = IProbeInfo.STARTLOC + pump.getBucketMode().getName() + IProbeInfo.ENDLOC; + String rateUnit = lang(pump.getBucketMode() == CoverPump.BucketMode.BUCKET ? + "cover.bucket.mode.bucket_rate" : + "cover.bucket.mode.milli_bucket_rate"); if (pump instanceof CoverFluidVoiding) { fluidVoidingInfo(probeInfo, (CoverFluidVoiding) pump); - } else if (!(pump instanceof CoverFluidRegulator) || - ((CoverFluidRegulator) pump).getTransferMode() == TransferMode.TRANSFER_ANY) { + } else if (!(pump instanceof CoverFluidRegulator regulator) || + regulator.getTransferMode() == TransferMode.TRANSFER_ANY) { // do not display the regular rate if the cover has a specialized rate transferRateText(probeInfo, pump.getPumpMode(), " " + rateUnit, pump.getBucketMode() == CoverPump.BucketMode.BUCKET ? pump.getTransferRate() / 1000 : @@ -113,10 +120,15 @@ private static void pumpInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverPump p FluidFilterContainer filter = pump.getFluidFilterContainer(); if (pump instanceof CoverFluidRegulator regulator) { - transferModeText(probeInfo, regulator.getTransferMode(), rateUnit, regulator.getTransferAmount(), - filter.getFilterWrapper().getFluidFilter() != null); + if (regulator.getTransferMode() != TransferMode.TRANSFER_ANY) + rateUnit = lang(regulator.getBucketMode() == CoverPump.BucketMode.BUCKET ? + "gregtech.top.unit.fluid_buckets" : + "gregtech.top.unit.fluid_milibuckets"); + + transferModeText(probeInfo, regulator.getTransferMode(), rateUnit, regulator + .getFluidFilterContainer().getTransferSize(), filter.hasFilter() && !filter.isBlacklistFilter()); } - fluidFilterText(probeInfo, filter.getFilterWrapper().getFluidFilter()); + fluidFilterText(probeInfo, filter.getFilter()); } /** @@ -126,8 +138,10 @@ private static void pumpInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverPump p * @param voiding the voiding cover to get data from */ private static void fluidVoidingInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverFluidVoiding voiding) { - String unit = voiding.getBucketMode() == CoverPump.BucketMode.BUCKET ? " {*gregtech.top.unit.fluid_buckets*}" : - " {*gregtech.top.unit.fluid_milibuckets*}"; + String unit = lang(voiding.getBucketMode() == CoverPump.BucketMode.BUCKET ? + "gregtech.top.unit.fluid_buckets" : + "gregtech.top.unit.fluid_milibuckets"); + var container = voiding.getFluidFilterContainer(); if (voiding instanceof CoverFluidVoidingAdvanced advanced) { VoidingMode mode = advanced.getVoidingMode(); @@ -135,7 +149,7 @@ private static void fluidVoidingInfo(@NotNull IProbeInfo probeInfo, @NotNull Cov voidingText(probeInfo, mode, unit, voiding.getBucketMode() == CoverPump.BucketMode.BUCKET ? advanced.getTransferAmount() / 1000 : advanced.getTransferAmount(), - voiding.getFluidFilterContainer().getFilterWrapper().getFluidFilter() != null); + container.hasFilter() && !container.isBlacklistFilter()); } } @@ -147,7 +161,7 @@ private static void fluidVoidingInfo(@NotNull IProbeInfo probeInfo, @NotNull Cov */ private static void itemFilterInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverItemFilter itemFilter) { filterModeText(probeInfo, itemFilter.getFilterMode()); - itemFilterText(probeInfo, itemFilter.getItemFilter().getItemFilter()); + itemFilterText(probeInfo, itemFilter.getFilter()); } /** @@ -158,7 +172,7 @@ private static void itemFilterInfo(@NotNull IProbeInfo probeInfo, @NotNull Cover */ private static void fluidFilterInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverFluidFilter fluidFilter) { filterModeText(probeInfo, fluidFilter.getFilterMode()); - fluidFilterText(probeInfo, fluidFilter.getFluidFilter().getFluidFilter()); + fluidFilterText(probeInfo, fluidFilter.getFilter()); } /** @@ -168,12 +182,13 @@ private static void fluidFilterInfo(@NotNull IProbeInfo probeInfo, @NotNull Cove * @param enderFluidLink the ender fluid link cover to get data from */ private static void enderFluidLinkInfo(@NotNull IProbeInfo probeInfo, @NotNull CoverEnderFluidLink enderFluidLink) { - transferRateText(probeInfo, enderFluidLink.getPumpMode(), " {*cover.bucket.mode.milli_bucket*}", - enderFluidLink.isIOEnabled() ? CoverEnderFluidLink.TRANSFER_RATE : 0); - fluidFilterText(probeInfo, enderFluidLink.getFluidFilterContainer().getFilterWrapper().getFluidFilter()); + transferRateText(probeInfo, enderFluidLink.getPumpMode(), " " + lang("cover.ender_fluid_link.transfer_unit"), + enderFluidLink.isIoEnabled() ? CoverEnderFluidLink.TRANSFER_RATE : 0); + fluidFilterText(probeInfo, enderFluidLink.getFluidFilterContainer().getFilter()); if (!enderFluidLink.getColorStr().isEmpty()) { - probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.link_cover.color*} " + enderFluidLink.getColorStr()); + probeInfo.text( + TextStyleClass.INFO + lang("gregtech.top.link_cover.color") + " " + enderFluidLink.getColorStr()); } } @@ -187,7 +202,8 @@ private static void enderFluidLinkInfo(@NotNull IProbeInfo probeInfo, @NotNull C */ private static void transferRateText(@NotNull IProbeInfo probeInfo, @NotNull IIOMode mode, @NotNull String rateUnit, int rate) { - String modeText = mode.isImport() ? "{*gregtech.top.mode.import*} " : "{*gregtech.top.mode.export*} "; + String modeText = mode.isImport() ? lang("gregtech.top.mode.import") : lang("gregtech.top.mode.export"); + modeText += " "; probeInfo.text(TextStyleClass.OK + modeText + TextStyleClass.LABEL + TextFormattingUtil.formatNumbers(rate) + rateUnit); } @@ -197,14 +213,15 @@ private static void transferRateText(@NotNull IProbeInfo probeInfo, @NotNull IIO * * @param probeInfo the info to add the text to * @param mode the transfer mode of the cover - * @param rateUnit the unit of what is transferred * @param rate the transfer rate of the mode * @param hasFilter whether the cover has a filter installed */ private static void transferModeText(@NotNull IProbeInfo probeInfo, @NotNull TransferMode mode, @NotNull String rateUnit, int rate, boolean hasFilter) { - String text = TextStyleClass.OK + IProbeInfo.STARTLOC + mode.getName() + IProbeInfo.ENDLOC; - if (!hasFilter && mode != TransferMode.TRANSFER_ANY) text += TextStyleClass.LABEL + " " + rate + rateUnit; + String text = TextStyleClass.OK + lang(mode.getName()); + if (!hasFilter && mode != TransferMode.TRANSFER_ANY) + text += TextStyleClass.LABEL + " " + TextFormattingUtil.formatNumbers(rate) + " " + rateUnit; + probeInfo.text(text); } @@ -219,45 +236,49 @@ private static void transferModeText(@NotNull IProbeInfo probeInfo, @NotNull Tra */ private static void voidingText(@NotNull IProbeInfo probeInfo, @NotNull VoidingMode mode, @NotNull String unit, int amount, boolean hasFilter) { - String text = TextFormatting.RED + IProbeInfo.STARTLOC + mode.getName() + IProbeInfo.ENDLOC; - if (mode != VoidingMode.VOID_ANY && !hasFilter) text += " " + amount + unit; + String text = TextFormatting.RED + lang(mode.getName()); + if (mode != VoidingMode.VOID_ANY && !hasFilter) + text += " " + TextFormattingUtil.formatNumbers(amount) + " " + unit; probeInfo.text(text); } /** - * Displays text for {@link IFilterMode} covers + * Displays text for {@link net.minecraft.util.IStringSerializable} covers * * @param probeInfo the info to add the text to * @param mode the filter mode of the cover */ - private static void filterModeText(@NotNull IProbeInfo probeInfo, @NotNull IFilterMode mode) { - probeInfo.text(TextStyleClass.WARNING + IProbeInfo.STARTLOC + mode.getName() + IProbeInfo.ENDLOC); + private static void filterModeText(@NotNull IProbeInfo probeInfo, @NotNull IStringSerializable mode) { + probeInfo.text(TextStyleClass.WARNING + lang(mode.getName())); } /** - * Displays text for {@link ItemFilter} covers + * Displays text for {@link BaseFilter} item covers * * @param probeInfo the info to add the text to * @param filter the filter to display info from */ - private static void itemFilterText(@NotNull IProbeInfo probeInfo, @Nullable ItemFilter filter) { - String label = TextStyleClass.INFO + "{*gregtech.top.filter.label*} "; + private static void itemFilterText(@NotNull IProbeInfo probeInfo, @Nullable BaseFilter filter) { + String label = TextStyleClass.INFO + lang("gregtech.top.filter.label"); if (filter instanceof OreDictionaryItemFilter) { String expression = ((OreDictionaryItemFilter) filter).getExpression(); if (!expression.isEmpty()) probeInfo.text(label + expression); - } else if (filter instanceof SmartItemFilter) { - probeInfo.text(label + IProbeInfo.STARTLOC + ((SmartItemFilter) filter).getFilteringMode().getName() + - IProbeInfo.ENDLOC); + } else if (filter instanceof SmartItemFilter smartItemFilter) { + probeInfo.text(label + lang(smartItemFilter.getFilteringMode().getName())); } } /** - * Displays text for {@link FluidFilter} covers + * Displays text for {@link BaseFilter} fluid covers * * @param probeInfo the info to add the text to * @param filter the filter to display info from */ - private static void fluidFilterText(@NotNull IProbeInfo probeInfo, @Nullable FluidFilter filter) { + private static void fluidFilterText(@NotNull IProbeInfo probeInfo, @Nullable BaseFilter filter) { // TODO If more unique fluid filtration is added, providers for it go here } + + private static String lang(String lang) { + return IProbeInfo.STARTLOC + lang + IProbeInfo.ENDLOC; + } } diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/ElectricContainerInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/ElectricContainerInfoProvider.java index 7252ebbca23..b80350912d8 100644 --- a/src/main/java/gregtech/integration/theoneprobe/provider/ElectricContainerInfoProvider.java +++ b/src/main/java/gregtech/integration/theoneprobe/provider/ElectricContainerInfoProvider.java @@ -3,6 +3,7 @@ import gregtech.api.GTValues; import gregtech.api.capability.GregtechCapabilities; import gregtech.api.capability.IEnergyContainer; +import gregtech.api.capability.ILaserContainer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; @@ -10,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 { @@ -27,16 +30,22 @@ 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(" / " + maxStorage + " EU") + .numberFormat(player.isSneaking() || stored < 10000 ? + NumberFormat.COMMAS : + NumberFormat.COMPACT) + .suffix(" / " + (player.isSneaking() || maxStorage < 10000 ? + ElementProgress.format(maxStorage, NumberFormat.COMMAS, " EU") : + ElementProgress.format(maxStorage, NumberFormat.COMPACT, "EU"))) .filledColor(0xFFEEE600) .alternateFilledColor(0xFFEEE600) .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 d75c6a7c8eb..af1ba0bca7d 100644 --- a/src/main/java/gregtech/integration/theoneprobe/provider/LaserContainerInfoProvider.java +++ b/src/main/java/gregtech/integration/theoneprobe/provider/LaserContainerInfoProvider.java @@ -10,6 +10,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 LaserContainerInfoProvider extends CapabilityInfoProvider { @@ -29,9 +31,12 @@ 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(" / " + 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)); diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/PrimitivePumpInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/PrimitivePumpInfoProvider.java index ea20f8be8a8..3c7d3d79004 100644 --- a/src/main/java/gregtech/integration/theoneprobe/provider/PrimitivePumpInfoProvider.java +++ b/src/main/java/gregtech/integration/theoneprobe/provider/PrimitivePumpInfoProvider.java @@ -4,6 +4,7 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IPrimitivePump; +import gregtech.api.util.TextFormattingUtil; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; @@ -32,7 +33,9 @@ public void addProbeInfo(@NotNull ProbeMode mode, @NotNull IProbeInfo probeInfo, if (metaTileEntity instanceof IPrimitivePump) { probeInfo.text( TextStyleClass.INFO + "{*gregtech.top.primitive_pump_production*} " + TextFormatting.AQUA + - ((IPrimitivePump) metaTileEntity).getFluidProduction() + TextFormatting.RESET + " L/s"); + TextFormattingUtil + .formatNumbers(((IPrimitivePump) metaTileEntity).getFluidProduction()) + + TextFormatting.RESET + " L/s"); } } } diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/QuantumStorageProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/QuantumStorageProvider.java new file mode 100644 index 00000000000..792be0ac4e5 --- /dev/null +++ b/src/main/java/gregtech/integration/theoneprobe/provider/QuantumStorageProvider.java @@ -0,0 +1,68 @@ +package gregtech.integration.theoneprobe.provider; + +import gregtech.api.GTValues; +import gregtech.api.capability.IQuantumController; +import gregtech.api.capability.IQuantumStorage; +import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.util.GTUtility; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.world.World; + +import mcjty.theoneprobe.api.IProbeHitData; +import mcjty.theoneprobe.api.IProbeInfo; +import mcjty.theoneprobe.api.IProbeInfoProvider; +import mcjty.theoneprobe.api.ProbeMode; +import mcjty.theoneprobe.api.TextStyleClass; +import org.jetbrains.annotations.NotNull; + +public class QuantumStorageProvider implements IProbeInfoProvider { + + @Override + public String getID() { + return ":quantum_storage_provider"; + } + + @Override + public void addProbeInfo(ProbeMode mode, IProbeInfo probeInfo, EntityPlayer player, World world, + IBlockState blockState, IProbeHitData data) { + if (blockState.getBlock().hasTileEntity(blockState) && + world.getTileEntity(data.getPos()) instanceof IGregTechTileEntity gtte) { + if (gtte.getMetaTileEntity() instanceof IQuantumController controller) { + if (controller.getCount(IQuantumStorage.Type.ENERGY) == 0) { + probeInfo.text("{*gregtech.top.quantum_controller.no_hatches*}"); + } else if (!controller.isPowered()) { + probeInfo.text("{*gregtech.top.quantum_controller.no_power*}"); + } else { + long usage = controller.getEnergyUsage(); + configureEnergyUsage(usage / 10, probeInfo); + } + } else if (gtte.getMetaTileEntity() instanceof IQuantumStoragestorage && + (storage.getType() == IQuantumStorage.Type.ITEM || + storage.getType() == IQuantumStorage.Type.FLUID)) { + probeInfo.text(getConnectionStatus(storage)); + } + } + } + + private static @NotNull String getConnectionStatus(IQuantumStorage storage) { + var qcontroller = storage.getQuantumController(); + String status = "gregtech.top.quantum_status.disconnected"; + if (qcontroller != null) { + status = qcontroller.isPowered() ? + "gregtech.top.quantum_status.powered" : + "gregtech.top.quantum_status.connected"; + } + return TextStyleClass.INFO + "{*gregtech.top.quantum_status.label*} " + + "{*" + status + "*}"; + } + + public void configureEnergyUsage(long EUs, IProbeInfo probeInfo) { + if (EUs == 0) return; + String text = TextFormatting.RED.toString() + EUs + TextStyleClass.INFO + " EU/t" + TextFormatting.GREEN + + " (" + GTValues.VNF[GTUtility.getTierByVoltage(EUs)] + TextFormatting.GREEN + ")"; + probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.energy_consumption*} " + text); + } +} diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/RecipeLogicInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/RecipeLogicInfoProvider.java index 8ea1a0ac3c7..3c69af74b50 100644 --- a/src/main/java/gregtech/integration/theoneprobe/provider/RecipeLogicInfoProvider.java +++ b/src/main/java/gregtech/integration/theoneprobe/provider/RecipeLogicInfoProvider.java @@ -10,6 +10,7 @@ import gregtech.api.metatileentity.multiblock.RecipeMapSteamMultiblockController; import gregtech.api.unification.material.Materials; import gregtech.api.util.GTUtility; +import gregtech.api.util.TextFormattingUtil; import gregtech.common.metatileentities.multi.MetaTileEntityLargeBoiler; import net.minecraft.entity.player.EntityPlayer; @@ -44,8 +45,7 @@ protected void addProbeInfo(@NotNull AbstractRecipeLogic capability, @NotNull IP if (capability instanceof PrimitiveRecipeLogic) { return; // do not show info for primitive machines, as they are supposed to appear powerless } - int EUt = capability.getInfoProviderEUt(); - int absEUt = Math.abs(EUt); + long eut = capability.getInfoProviderEUt(); String text = null; if (tileEntity instanceof IGregTechTileEntity) { @@ -53,18 +53,20 @@ protected void addProbeInfo(@NotNull AbstractRecipeLogic capability, @NotNull IP MetaTileEntity mte = gtTileEntity.getMetaTileEntity(); if (mte instanceof SteamMetaTileEntity || mte instanceof MetaTileEntityLargeBoiler || mte instanceof RecipeMapSteamMultiblockController) { - text = TextFormatting.AQUA.toString() + absEUt + TextStyleClass.INFO + " L/t {*" + + text = TextFormatting.AQUA + TextFormattingUtil.formatNumbers(eut) + + TextStyleClass.INFO + " L/t {*" + Materials.Steam.getUnlocalizedName() + "*}"; } } if (text == null) { // Default behavior, if this TE is not a steam machine (or somehow not instanceof // IGregTechTileEntity...) - text = TextFormatting.RED.toString() + absEUt + TextStyleClass.INFO + " EU/t" + TextFormatting.GREEN + - " (" + GTValues.VNF[GTUtility.getTierByVoltage(absEUt)] + TextFormatting.GREEN + ")"; + text = TextFormatting.RED + TextFormattingUtil.formatNumbers(eut) + TextStyleClass.INFO + + " EU/t" + TextFormatting.GREEN + + " (" + GTValues.VOCNF[GTUtility.getOCTierByVoltage(eut)] + TextFormatting.GREEN + ")"; } - if (EUt == 0) return; // idk what to do for 0 eut + if (eut == 0) return; // do not display 0 eut if (capability.consumesEnergy()) { probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.energy_consumption*} " + text); diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/SteamBoilerInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/SteamBoilerInfoProvider.java index 4ccdc7125d0..25decb1cba7 100644 --- a/src/main/java/gregtech/integration/theoneprobe/provider/SteamBoilerInfoProvider.java +++ b/src/main/java/gregtech/integration/theoneprobe/provider/SteamBoilerInfoProvider.java @@ -4,6 +4,7 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.unification.material.Materials; +import gregtech.api.util.TextFormattingUtil; import gregtech.common.metatileentities.steam.boiler.SteamBoiler; import net.minecraft.block.state.IBlockState; @@ -29,21 +30,29 @@ public void addProbeInfo(ProbeMode mode, IProbeInfo probeInfo, EntityPlayer play if (te instanceof IGregTechTileEntity igtte) { MetaTileEntity mte = igtte.getMetaTileEntity(); if (mte instanceof SteamBoiler boiler) { - if (boiler.isBurning()) { - // Boiler is active - int steamOutput = boiler.getTotalSteamOutput(); - + int steamOutput = boiler.getTotalSteamOutput(); + // If we are producing steam, or we have fuel + if (steamOutput > 0 || boiler.isBurning()) { // Creating steam if (steamOutput > 0 && boiler.hasWater()) { probeInfo.text(TextStyleClass.INFO + "{*gregtech.top.energy_production*} " + - TextFormatting.AQUA + (steamOutput / 10) + TextStyleClass.INFO + " L/t" + " {*" + + TextFormatting.AQUA + TextFormattingUtil.formatNumbers(steamOutput / 10) + + TextStyleClass.INFO + " L/t" + " {*" + Materials.Steam.getUnlocalizedName() + "*}"); } + // Cooling Down + if (!boiler.isBurning()) { + probeInfo.text(TextStyleClass.INFO.toString() + TextFormatting.RED + + "{*gregtech.top.steam_cooling_down*}"); + } + // Initial heat-up - if (steamOutput <= 0) { + if (steamOutput <= 0 && boiler.getCurrentTemperature() > 0) { + // Current Temperature = the % until the boiler reaches 100 probeInfo.text(TextStyleClass.INFO.toString() + TextFormatting.RED + - "{*gregtech.top.steam_heating_up*}"); + "{*gregtech.top.steam_heating_up*} " + + TextFormattingUtil.formatNumbers(boiler.getCurrentTemperature()) + "%"); } // No water diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/TransformerInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/TransformerInfoProvider.java index cf77786cc15..0cf94adc4bd 100644 --- a/src/main/java/gregtech/integration/theoneprobe/provider/TransformerInfoProvider.java +++ b/src/main/java/gregtech/integration/theoneprobe/provider/TransformerInfoProvider.java @@ -5,6 +5,7 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.util.GTUtility; +import gregtech.api.util.TextFormattingUtil; import gregtech.common.metatileentities.electric.MetaTileEntityTransformer; import net.minecraft.entity.player.EntityPlayer; @@ -33,14 +34,14 @@ protected void addProbeInfo(@NotNull IEnergyContainer capability, @NotNull IProb .append(GTValues.VNF[GTUtility.getTierByVoltage(capability.getInputVoltage())]) .append(TextFormatting.GREEN) .append(" (") - .append(capability.getInputAmperage()) + .append(TextFormattingUtil.formatNumbers(capability.getInputAmperage())) .append("A)"); StringBuilder output = new StringBuilder() .append(GTValues.VNF[GTUtility.getTierByVoltage(capability.getOutputVoltage())]) .append(TextFormatting.GREEN) .append(" (") - .append(capability.getOutputAmperage()) + .append(TextFormattingUtil.formatNumbers(capability.getOutputAmperage())) .append("A)"); // Step Up/Step Down line diff --git a/src/main/java/gregtech/integration/theoneprobe/provider/WorkableInfoProvider.java b/src/main/java/gregtech/integration/theoneprobe/provider/WorkableInfoProvider.java index 5d3c500e81e..ac6254aa8b5 100644 --- a/src/main/java/gregtech/integration/theoneprobe/provider/WorkableInfoProvider.java +++ b/src/main/java/gregtech/integration/theoneprobe/provider/WorkableInfoProvider.java @@ -4,6 +4,7 @@ import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IWorkable; import gregtech.api.capability.impl.ComputationRecipeLogic; +import gregtech.api.util.TextFormattingUtil; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; @@ -11,6 +12,7 @@ import mcjty.theoneprobe.api.IProbeHitData; import mcjty.theoneprobe.api.IProbeInfo; +import mcjty.theoneprobe.api.NumberFormat; import org.jetbrains.annotations.NotNull; public class WorkableInfoProvider extends CapabilityInfoProvider { @@ -52,7 +54,7 @@ protected void addProbeInfo(@NotNull IWorkable capability, @NotNull IProbeInfo p } else { currentProgress = Math.round(currentProgress / 20.0F); maxProgress = Math.round(maxProgress / 20.0F); - text = " / " + maxProgress + " s"; + text = " / " + TextFormattingUtil.formatNumbers(maxProgress) + " s"; } if (maxProgress > 0) { @@ -61,7 +63,7 @@ protected void addProbeInfo(@NotNull IWorkable capability, @NotNull IProbeInfo p .suffix(text) .filledColor(color) .alternateFilledColor(color) - .borderColor(0xFF555555)); + .borderColor(0xFF555555).numberFormat(NumberFormat.COMMAS)); } } } diff --git a/src/main/java/gregtech/loaders/WoodTypeEntry.java b/src/main/java/gregtech/loaders/WoodTypeEntry.java index 7a086b1b55e..dd75a07cdb7 100644 --- a/src/main/java/gregtech/loaders/WoodTypeEntry.java +++ b/src/main/java/gregtech/loaders/WoodTypeEntry.java @@ -52,6 +52,8 @@ public final class WoodTypeEntry { public final String fenceGateRecipeName; @NotNull public final ItemStack stairs; + @Nullable + public final String stairsRecipeName; public final boolean addStairsCraftingRecipe; @NotNull public final ItemStack boat; @@ -83,13 +85,14 @@ private WoodTypeEntry(@NotNull String modid, @NotNull String woodName, @NotNull @NotNull ItemStack slab, @Nullable String slabRecipeName, boolean addSlabCraftingRecipe, @NotNull ItemStack fence, @Nullable String fenceRecipeName, @NotNull ItemStack fenceGate, @Nullable String fenceGateRecipeName, @NotNull ItemStack stairs, - boolean addStairsCraftingRecipe, @NotNull ItemStack boat, @Nullable String boatRecipeName, - @Nullable Material material, boolean addLogOreDict, boolean addPlanksOreDict, - boolean addDoorsOreDict, boolean addSlabsOreDict, boolean addFencesOreDict, - boolean addFenceGatesOreDict, boolean addStairsOreDict, boolean addPlanksUnificationInfo, - boolean addDoorsUnificationInfo, boolean addSlabsUnificationInfo, - boolean addFencesUnificationInfo, boolean addFenceGatesUnificationInfo, - boolean addStairsUnificationInfo, boolean addBoatsUnificationInfo) { + @Nullable String stairsRecipeName, boolean addStairsCraftingRecipe, @NotNull ItemStack boat, + @Nullable String boatRecipeName, @Nullable Material material, boolean addLogOreDict, + boolean addPlanksOreDict, boolean addDoorsOreDict, boolean addSlabsOreDict, + boolean addFencesOreDict, boolean addFenceGatesOreDict, boolean addStairsOreDict, + boolean addPlanksUnificationInfo, boolean addDoorsUnificationInfo, + boolean addSlabsUnificationInfo, boolean addFencesUnificationInfo, + boolean addFenceGatesUnificationInfo, boolean addStairsUnificationInfo, + boolean addBoatsUnificationInfo) { this.modid = modid; this.woodName = woodName; this.log = log; @@ -107,6 +110,7 @@ private WoodTypeEntry(@NotNull String modid, @NotNull String woodName, @NotNull this.fenceGate = fenceGate; this.fenceGateRecipeName = fenceGateRecipeName; this.stairs = stairs; + this.stairsRecipeName = stairsRecipeName; this.addStairsCraftingRecipe = addStairsCraftingRecipe; this.boat = boat; this.boatRecipeName = boatRecipeName; @@ -153,6 +157,7 @@ public static class Builder { private ItemStack fenceGate = ItemStack.EMPTY; private String fenceGateRecipeName; private ItemStack stairs = ItemStack.EMPTY; + private String stairsRecipeName; private boolean addStairsCraftingRecipe; private ItemStack boat = ItemStack.EMPTY; private String boatRecipeName; @@ -294,11 +299,13 @@ public Builder fenceGate(@NotNull ItemStack fenceGate, @Nullable String fenceGat /** * Add an entry for stairs * - * @param stairs the stairs to add + * @param stairs the stairs to add + * @param stairsRecipeName the recipe name for crafting the stairs * @return this */ - public Builder stairs(@NotNull ItemStack stairs) { + public Builder stairs(@NotNull ItemStack stairs, @Nullable String stairsRecipeName) { this.stairs = stairs; + this.stairsRecipeName = stairsRecipeName; return this; } @@ -410,12 +417,11 @@ public WoodTypeEntry build() { Preconditions.checkArgument(!planks.isEmpty(), "Planks cannot be empty."); return new WoodTypeEntry(modid, woodName, log, removeCharcoalRecipe, addCharcoalRecipe, planks, planksRecipeName, door, doorRecipeName, slab, slabRecipeName, addSlabsCraftingRecipe, fence, - fenceRecipeName, - fenceGate, fenceGateRecipeName, stairs, addStairsCraftingRecipe, boat, boatRecipeName, material, - addLogOreDict, addPlanksOreDict, addDoorsOreDict, addSlabsOreDict, addFencesOreDict, - addFenceGatesOreDict, addStairsOreDict, addPlanksUnificationInfo, addDoorsUnificationInfo, - addSlabsUnificationInfo, addFencesUnificationInfo, addFenceGatesUnificationInfo, - addStairsUnificationInfo, addBoatsUnificationInfo); + fenceRecipeName, fenceGate, fenceGateRecipeName, stairs, stairsRecipeName, addStairsCraftingRecipe, + boat, boatRecipeName, material, addLogOreDict, addPlanksOreDict, addDoorsOreDict, addSlabsOreDict, + addFencesOreDict, addFenceGatesOreDict, addStairsOreDict, addPlanksUnificationInfo, + addDoorsUnificationInfo, addSlabsUnificationInfo, addFencesUnificationInfo, + addFenceGatesUnificationInfo, addStairsUnificationInfo, addBoatsUnificationInfo); } } } diff --git a/src/main/java/gregtech/loaders/recipe/CraftingComponent.java b/src/main/java/gregtech/loaders/recipe/CraftingComponent.java index f6c8898f9d9..1d1debf9b6f 100644 --- a/src/main/java/gregtech/loaders/recipe/CraftingComponent.java +++ b/src/main/java/gregtech/loaders/recipe/CraftingComponent.java @@ -390,7 +390,7 @@ public static void initializeComponents() { { 4, new UnificationEntry(OrePrefix.pipeLargeFluid, Materials.Titanium) }, { 5, new UnificationEntry(OrePrefix.pipeLargeFluid, Materials.TungstenSteel) }, { 6, new UnificationEntry(OrePrefix.pipeLargeFluid, Materials.NiobiumTitanium) }, - { 7, new UnificationEntry(OrePrefix.pipeLargeFluid, Materials.Ultimet) }, + { 7, new UnificationEntry(OrePrefix.pipeLargeFluid, Materials.Iridium) }, { 8, new UnificationEntry(OrePrefix.pipeLargeFluid, Materials.Naquadah) }, }).collect(Collectors.toMap(data -> (Integer) data[0], data -> data[1]))); diff --git a/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java index 0b0d513a7f7..8b18ba7a811 100644 --- a/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/CraftingRecipeLoader.java @@ -336,6 +336,11 @@ private static void loadCraftingRecipes() { new UnificationEntry(OrePrefix.wireGtQuadruple, Osmium), 'P', new UnificationEntry(OrePrefix.plateDouble, Iridium), 'O', MetaItems.ENERGY_LAPOTRONIC_ORB.getStackForm()); + + ModHandler.addShapedRecipe("powderbarrel", new ItemStack(MetaBlocks.POWDERBARREL), "PSP", "GGG", "PGP", + 'P', new UnificationEntry(OrePrefix.plate, Wood), + 'S', new ItemStack(Items.STRING), + 'G', new UnificationEntry(OrePrefix.dust, Gunpowder)); } private static void registerFacadeRecipe(Material material, int facadeAmount) { diff --git a/src/main/java/gregtech/loaders/recipe/FuelRecipes.java b/src/main/java/gregtech/loaders/recipe/FuelRecipes.java index 740521e8657..e717d9716d3 100644 --- a/src/main/java/gregtech/loaders/recipe/FuelRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/FuelRecipes.java @@ -12,91 +12,91 @@ public static void registerFuels() { RecipeMaps.COMBUSTION_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Naphtha.getFluid(1)) .duration(10) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.COMBUSTION_GENERATOR_FUELS.recipeBuilder() .fluidInputs(SulfuricLightFuel.getFluid(4)) .duration(5) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.COMBUSTION_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Methanol.getFluid(4)) .duration(8) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.COMBUSTION_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Ethanol.getFluid(1)) .duration(6) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.COMBUSTION_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Octane.getFluid(2)) .duration(5) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.COMBUSTION_GENERATOR_FUELS.recipeBuilder() .fluidInputs(BioDiesel.getFluid(1)) .duration(8) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.COMBUSTION_GENERATOR_FUELS.recipeBuilder() .fluidInputs(LightFuel.getFluid(1)) .duration(10) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.COMBUSTION_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Diesel.getFluid(1)) .duration(15) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.COMBUSTION_GENERATOR_FUELS.recipeBuilder() .fluidInputs(CetaneBoostedDiesel.getFluid(2)) .duration(45) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.COMBUSTION_GENERATOR_FUELS.recipeBuilder() .fluidInputs(RocketFuel.getFluid(16)) .duration(125) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.COMBUSTION_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Gasoline.getFluid(1)) .duration(50) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.COMBUSTION_GENERATOR_FUELS.recipeBuilder() .fluidInputs(HighOctaneGasoline.getFluid(1)) .duration(100) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.COMBUSTION_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Toluene.getFluid(1)) .duration(10) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.COMBUSTION_GENERATOR_FUELS.recipeBuilder() .fluidInputs(OilLight.getFluid(32)) .duration(5) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.COMBUSTION_GENERATOR_FUELS.recipeBuilder() .fluidInputs(RawOil.getFluid(64)) .duration(15) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); // steam generator fuels @@ -104,159 +104,159 @@ public static void registerFuels() { .fluidInputs(Steam.getFluid(640)) .fluidOutputs(DistilledWater.getFluid(4)) .duration(10) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); // gas turbine fuels RecipeMaps.GAS_TURBINE_FUELS.recipeBuilder() .fluidInputs(NaturalGas.getFluid(8)) .duration(5) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.GAS_TURBINE_FUELS.recipeBuilder() .fluidInputs(WoodGas.getFluid(8)) .duration(6) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.GAS_TURBINE_FUELS.recipeBuilder() .fluidInputs(SulfuricGas.getFluid(32)) .duration(25) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.GAS_TURBINE_FUELS.recipeBuilder() .fluidInputs(SulfuricNaphtha.getFluid(4)) .duration(5) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.GAS_TURBINE_FUELS.recipeBuilder() .fluidInputs(CoalGas.getFluid(1)) .duration(3) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.GAS_TURBINE_FUELS.recipeBuilder() .fluidInputs(Methane.getFluid(2)) .duration(7) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.GAS_TURBINE_FUELS.recipeBuilder() .fluidInputs(Ethylene.getFluid(1)) .duration(4) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.GAS_TURBINE_FUELS.recipeBuilder() .fluidInputs(RefineryGas.getFluid(1)) .duration(5) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.GAS_TURBINE_FUELS.recipeBuilder() .fluidInputs(Ethane.getFluid(4)) .duration(21) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.GAS_TURBINE_FUELS.recipeBuilder() .fluidInputs(Propene.getFluid(1)) .duration(6) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.GAS_TURBINE_FUELS.recipeBuilder() .fluidInputs(Butadiene.getFluid(16)) .duration(102) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.GAS_TURBINE_FUELS.recipeBuilder() .fluidInputs(Propane.getFluid(4)) .duration(29) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.GAS_TURBINE_FUELS.recipeBuilder() .fluidInputs(Butene.getFluid(1)) .duration(8) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.GAS_TURBINE_FUELS.recipeBuilder() .fluidInputs(Phenol.getFluid(1)) .duration(9) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.GAS_TURBINE_FUELS.recipeBuilder() .fluidInputs(Benzene.getFluid(1)) .duration(11) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.GAS_TURBINE_FUELS.recipeBuilder() .fluidInputs(Butane.getFluid(4)) .duration(37) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.GAS_TURBINE_FUELS.recipeBuilder() .fluidInputs(LPG.getFluid(1)) .duration(10) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.GAS_TURBINE_FUELS.recipeBuilder() // TODO Too OP pls nerf .fluidInputs(Nitrobenzene.getFluid(1)) .duration(40) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); // semi-fluid fuels, like creosote RecipeMaps.SEMI_FLUID_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Creosote.getFluid(16)) .duration(1) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.SEMI_FLUID_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Biomass.getFluid(4)) .duration(1) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.SEMI_FLUID_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Oil.getFluid(2)) .duration(1) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.SEMI_FLUID_GENERATOR_FUELS.recipeBuilder() .fluidInputs(OilHeavy.getFluid(16)) .duration(5) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.SEMI_FLUID_GENERATOR_FUELS.recipeBuilder() .fluidInputs(SulfuricHeavyFuel.getFluid(16)) .duration(5) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.SEMI_FLUID_GENERATOR_FUELS.recipeBuilder() .fluidInputs(HeavyFuel.getFluid(8)) .duration(15) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); RecipeMaps.SEMI_FLUID_GENERATOR_FUELS.recipeBuilder() .fluidInputs(FishOil.getFluid(16)) .duration(1) - .EUt((int) V[LV]) + .EUt(V[LV]) .buildAndRegister(); // plasma turbine @@ -264,56 +264,56 @@ public static void registerFuels() { .fluidInputs(Helium.getPlasma(1)) .fluidOutputs(Helium.getFluid(1)) .duration(40) - .EUt((int) V[EV]) + .EUt(V[EV]) .buildAndRegister(); RecipeMaps.PLASMA_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Oxygen.getPlasma(1)) .fluidOutputs(Oxygen.getFluid(1)) .duration(48) - .EUt((int) V[EV]) + .EUt(V[EV]) .buildAndRegister(); RecipeMaps.PLASMA_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Nitrogen.getPlasma(1)) .fluidOutputs(Nitrogen.getFluid(1)) .duration(64) - .EUt((int) V[EV]) + .EUt(V[EV]) .buildAndRegister(); RecipeMaps.PLASMA_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Argon.getPlasma(1)) .fluidOutputs(Argon.getFluid(1)) .duration(96) - .EUt((int) V[EV]) + .EUt(V[EV]) .buildAndRegister(); RecipeMaps.PLASMA_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Iron.getPlasma(1)) .fluidOutputs(Iron.getFluid(1)) .duration(112) - .EUt((int) V[EV]) + .EUt(V[EV]) .buildAndRegister(); RecipeMaps.PLASMA_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Tin.getPlasma(1)) .fluidOutputs(Tin.getFluid(1)) .duration(128) - .EUt((int) V[EV]) + .EUt(V[EV]) .buildAndRegister(); RecipeMaps.PLASMA_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Nickel.getPlasma(1)) .fluidOutputs(Nickel.getFluid(1)) .duration(192) - .EUt((int) V[EV]) + .EUt(V[EV]) .buildAndRegister(); RecipeMaps.PLASMA_GENERATOR_FUELS.recipeBuilder() .fluidInputs(Americium.getPlasma(1)) .fluidOutputs(Americium.getFluid(1)) .duration(320) - .EUt((int) V[EV]) + .EUt(V[EV]) .buildAndRegister(); } } diff --git a/src/main/java/gregtech/loaders/recipe/FusionLoader.java b/src/main/java/gregtech/loaders/recipe/FusionLoader.java index 49515136876..792449373fd 100644 --- a/src/main/java/gregtech/loaders/recipe/FusionLoader.java +++ b/src/main/java/gregtech/loaders/recipe/FusionLoader.java @@ -128,7 +128,7 @@ public static void init() { RecipeMaps.FUSION_RECIPES.recipeBuilder() .fluidInputs(Materials.Gold.getFluid(16)) .fluidInputs(Materials.Aluminium.getFluid(16)) - .fluidOutputs(Materials.Uranium238.getFluid(16)) + .fluidOutputs(Materials.Uranium.getFluid(16)) .duration(128) .EUt(24576) .EUToStart(140_000_000) diff --git a/src/main/java/gregtech/loaders/recipe/MachineRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/MachineRecipeLoader.java index eb820fbe624..13606711c42 100644 --- a/src/main/java/gregtech/loaders/recipe/MachineRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/MachineRecipeLoader.java @@ -15,6 +15,7 @@ import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.MaterialStack; import gregtech.api.unification.stack.UnificationEntry; +import gregtech.api.util.Mods; import gregtech.common.ConfigHolder; import gregtech.common.blocks.*; import gregtech.common.blocks.BlockMachineCasing.MachineCasingType; @@ -34,7 +35,6 @@ import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.oredict.OreDictionary; import java.util.Arrays; @@ -1029,25 +1029,6 @@ private static void registerBlastFurnaceRecipes() { BLAST_RECIPES.recipeBuilder().duration(320).EUt(100).input(gem, Sapphire).output(nugget, Aluminium, 3) .blastFurnaceTemp(1200).buildAndRegister(); - // Titanium tetrachloride - BLAST_RECIPES.recipeBuilder().duration(800).EUt(VA[HV]) - .input(dust, Magnesium, 2) - .fluidInputs(TitaniumTetrachloride.getFluid(1000)) - .output(ingotHot, Titanium) - .output(dust, MagnesiumChloride, 6) - .blastFurnaceTemp(Titanium.getBlastTemperature() + 200) - .buildAndRegister(); - - // Rutile from ilmenite - BLAST_RECIPES.recipeBuilder() - .input(dust, Ilmenite, 10) - .input(dust, Carbon, 4) - .output(ingot, WroughtIron, 2) - .output(dust, Rutile, 4) - .fluidOutputs(CarbonDioxide.getFluid(2000)) - .blastFurnaceTemp(1700) - .duration(1600).EUt(VA[HV]).buildAndRegister(); - // Tempered Glass BLAST_RECIPES.recipeBuilder() .input(block, Glass) @@ -1214,7 +1195,7 @@ private static void registerRecyclingRecipes() { MACERATOR_RECIPES.recipeBuilder() .input(stone, GraniteRed) .output(dust, GraniteRed) - .chancedOutput(dust, Uranium238, 10, 5) + .chancedOutput(dust, Uranium, 10, 5) .buildAndRegister(); MACERATOR_RECIPES.recipeBuilder() @@ -1405,6 +1386,16 @@ private static void registerNBTRemoval() { ModHandler.addShapelessNBTClearingRecipe("data_module_nbt", TOOL_DATA_MODULE.getStackForm(), TOOL_DATA_MODULE.getStackForm()); + // Filters + ModHandler.addShapelessNBTClearingRecipe("clear_item_filter", + ITEM_FILTER.getStackForm(), ITEM_FILTER); + ModHandler.addShapelessNBTClearingRecipe("clear_fluid_filter", + FLUID_FILTER.getStackForm(), FLUID_FILTER); + ModHandler.addShapelessNBTClearingRecipe("clear_smart_filter", + SMART_FILTER.getStackForm(), SMART_FILTER); + ModHandler.addShapelessNBTClearingRecipe("clear_oredict_filter", + ORE_DICTIONARY_FILTER.getStackForm(), ORE_DICTIONARY_FILTER); + // Jetpacks ModHandler.addShapelessRecipe("fluid_jetpack_clear", SEMIFLUID_JETPACK.getStackForm(), SEMIFLUID_JETPACK.getStackForm()); @@ -1461,7 +1452,7 @@ private static void ConvertHatchToHatch() { } } - if (Loader.isModLoaded(MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { ModHandler.addShapedRecipe("me_fluid_hatch_output_to_input", FLUID_IMPORT_HATCH_ME.getStackForm(), "d", "B", 'B', FLUID_EXPORT_HATCH_ME.getStackForm()); ModHandler.addShapedRecipe("me_fluid_hatch_input_to_output", FLUID_EXPORT_HATCH_ME.getStackForm(), "d", "B", diff --git a/src/main/java/gregtech/loaders/recipe/MetaTileEntityLoader.java b/src/main/java/gregtech/loaders/recipe/MetaTileEntityLoader.java index 9cb0e321a0e..840fd0077d8 100644 --- a/src/main/java/gregtech/loaders/recipe/MetaTileEntityLoader.java +++ b/src/main/java/gregtech/loaders/recipe/MetaTileEntityLoader.java @@ -898,7 +898,8 @@ public static void init() { ROTOR); registerMachineRecipe(ArrayUtils.subarray(MetaTileEntities.DIODES, GTValues.ULV, GTValues.HV), "CDC", "DHD", - "PDP", 'H', HULL, 'D', MetaItems.DIODE, 'P', PLATE, 'C', CABLE_QUAD); + "PDP", 'H', HULL, 'D', new UnificationEntry(OrePrefix.component, MarkerMaterials.Component.Diode), 'P', + PLATE, 'C', CABLE_QUAD); registerMachineRecipe(ArrayUtils.subarray(MetaTileEntities.DIODES, GTValues.HV, GTValues.LuV), "CDC", "DHD", "PDP", 'H', HULL, 'D', MetaItems.SMD_DIODE, 'P', PLATE, 'C', CABLE_QUAD); registerMachineRecipe( @@ -1000,6 +1001,35 @@ public static void init() { "PPP", "PFP", "PPP", 'P', new UnificationEntry(OrePrefix.plate, Materials.Neutronium), 'F', new UnificationEntry(OrePrefix.pipeLargeFluid, Materials.Duranium)); + // Quantum Storage Controller + ModHandler.addShapedRecipe(true, "quantum_storage_controller", + MetaTileEntities.QUANTUM_STORAGE_CONTROLLER.getStackForm(), + "PCP", "EHS", "CFC", + 'C', new UnificationEntry(OrePrefix.circuit, Tier.MV), + 'P', new UnificationEntry(OrePrefix.plate, Materials.Steel), + 'H', MetaTileEntities.HULL[GTValues.MV].getStackForm(), + 'F', MetaItems.FIELD_GENERATOR_MV.getStackForm(), + 'E', MetaItems.EMITTER_MV.getStackForm(), + 'S', MetaItems.SENSOR_MV.getStackForm()); + + // Quantum Storage Proxy + ModHandler.addShapedRecipe(true, "quantum_storage_proxy", + MetaTileEntities.QUANTUM_STORAGE_PROXY.getStackForm(), + "PEP", "ACA", "PHP", + 'P', new UnificationEntry(OrePrefix.plate, Materials.Steel), + 'E', MetaItems.EMITTER_MV.getStackForm(), + 'C', new UnificationEntry(OrePrefix.pipeHugeItem, Materials.SterlingSilver), + 'A', MetaItems.ROBOT_ARM_MV.getStackForm(), + 'H', MetaTileEntities.HULL[GTValues.MV].getStackForm()); + + // Quantum Storage Extender + ModHandler.addShapedRecipe(true, "quantum_storage_extender", + MetaTileEntities.QUANTUM_STORAGE_EXTENDER.getStackForm(4), + "PPP", "CHC", "PPP", + 'P', new UnificationEntry(OrePrefix.plate, Materials.Steel), + 'C', new UnificationEntry(OrePrefix.pipeSmallItem, Materials.SterlingSilver), + 'H', MetaTileEntities.HULL[GTValues.MV].getStackForm()); + // Super / Quantum Chests ModHandler.addShapedRecipe(true, "super_chest_lv", MetaTileEntities.QUANTUM_CHEST[0].getStackForm(), "CPC", "PFP", "CPC", 'C', new UnificationEntry(OrePrefix.circuit, Tier.LV), 'P', diff --git a/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java index cc01014c03a..1f99174cb3b 100644 --- a/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java @@ -1,14 +1,18 @@ package gregtech.loaders.recipe; import gregtech.api.GTValues; +import gregtech.api.items.OreDictNames; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.recipes.ModHandler; +import gregtech.api.recipes.ingredients.GTRecipeInput; +import gregtech.api.recipes.ingredients.GTRecipeItemInput; +import gregtech.api.recipes.ingredients.GTRecipeOreInput; import gregtech.api.unification.stack.UnificationEntry; +import gregtech.api.util.GTUtility; +import gregtech.api.util.Mods; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.common.registry.GameRegistry; import static gregtech.api.GTValues.*; import static gregtech.api.recipes.RecipeMaps.ASSEMBLER_RECIPES; @@ -19,7 +23,6 @@ import static gregtech.common.blocks.MetaBlocks.LD_FLUID_PIPE; import static gregtech.common.blocks.MetaBlocks.LD_ITEM_PIPE; import static gregtech.common.items.MetaItems.*; -import static gregtech.common.items.MetaItems.SENSOR_UV; import static gregtech.common.metatileentities.MetaTileEntities.*; public class MetaTileEntityMachineRecipeLoader { @@ -243,8 +246,8 @@ public static void init() { .duration(300).EUt(VA[EV]).buildAndRegister(); // Item Buses - registerHatchBusRecipe(ULV, ITEM_IMPORT_BUS[ULV], ITEM_EXPORT_BUS[ULV], new ItemStack(Blocks.CHEST)); - registerHatchBusRecipe(LV, ITEM_IMPORT_BUS[LV], ITEM_EXPORT_BUS[LV], new ItemStack(Blocks.CHEST)); + registerHatchBusRecipe(ULV, ITEM_IMPORT_BUS[ULV], ITEM_EXPORT_BUS[ULV], OreDictNames.chestWood.toString()); + registerHatchBusRecipe(LV, ITEM_IMPORT_BUS[LV], ITEM_EXPORT_BUS[LV], OreDictNames.chestWood.toString()); registerHatchBusRecipe(MV, ITEM_IMPORT_BUS[MV], ITEM_EXPORT_BUS[MV], BRONZE_CRATE.getStackForm()); registerHatchBusRecipe(HV, ITEM_IMPORT_BUS[HV], ITEM_EXPORT_BUS[HV], STEEL_CRATE.getStackForm()); registerHatchBusRecipe(EV, ITEM_IMPORT_BUS[EV], ITEM_EXPORT_BUS[EV], ALUMINIUM_CRATE.getStackForm()); @@ -989,11 +992,11 @@ public static void init() { // ME Parts - if (Loader.isModLoaded(MODID_APPENG)) { + if (Mods.AppliedEnergistics2.isModLoaded()) { - ItemStack fluidInterface = GameRegistry.makeItemStack(MODID_APPENG + ":fluid_interface", 0, 1, null); - ItemStack normalInterface = GameRegistry.makeItemStack(MODID_APPENG + ":interface", 0, 1, null); - ItemStack accelerationCard = GameRegistry.makeItemStack(MODID_APPENG + ":material", 30, 2, null); + ItemStack fluidInterface = Mods.AppliedEnergistics2.getItem("fluid_interface"); + ItemStack normalInterface = Mods.AppliedEnergistics2.getItem("interface"); + ItemStack accelerationCard = Mods.AppliedEnergistics2.getItem("material", 30, 2); ASSEMBLER_RECIPES.recipeBuilder() .input(FLUID_EXPORT_HATCH[EV]) @@ -1022,11 +1025,38 @@ public static void init() { .inputs(accelerationCard.copy()) .output(ITEM_IMPORT_BUS_ME) .duration(300).EUt(VA[HV]).buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder() + .input(ITEM_IMPORT_BUS[IV]) + .inputs(normalInterface.copy()) + .input(CONVEYOR_MODULE_IV) + .input(SENSOR_IV) + .inputs(GTUtility.copy(4, accelerationCard)) + .output(STOCKING_BUS_ME) + .duration(300).EUt(VA[IV]).buildAndRegister(); + + ASSEMBLER_RECIPES.recipeBuilder() + .input(FLUID_IMPORT_HATCH[IV]) + .inputs(fluidInterface.copy()) + .input(ELECTRIC_PUMP_IV) + .input(SENSOR_IV) + .inputs(GTUtility.copy(4, accelerationCard)) + .output(STOCKING_HATCH_ME) + .duration(300).EUt(VA[IV]).buildAndRegister(); } } private static void registerHatchBusRecipe(int tier, MetaTileEntity inputBus, MetaTileEntity outputBus, - ItemStack extra) { + Object extraInput) { + GTRecipeInput extra; + if (extraInput instanceof ItemStack stack) { + extra = new GTRecipeItemInput(stack); + } else if (extraInput instanceof String oreName) { + extra = new GTRecipeOreInput(oreName); + } else { + throw new IllegalArgumentException("extraInput must be ItemStack or GTRecipeInput"); + } + // Glue recipe for ULV and LV // 250L for ULV, 500L for LV if (tier <= GTValues.LV) { @@ -1115,29 +1145,18 @@ private static void registerHatchBusRecipe(int tier, MetaTileEntity inputBus, Me } private static int getFluidAmount(int offsetTier) { - switch (offsetTier) { - case 0: - return 4; - case 1: - return 9; - case 2: - return 18; - case 3: - return 36; - case 4: - return 72; - case 5: - return 144; - case 6: - return 288; - case 7: - return 432; - case 8: - return 576; - case 9: - default: - return 720; - } + return switch (offsetTier) { + case 0 -> 4; + case 1 -> 9; + case 2 -> 18; + case 3 -> 36; + case 4 -> 72; + case 5 -> 144; + case 6 -> 288; + case 7 -> 432; + case 8 -> 576; + default -> 720; + }; } // TODO clean this up with a CraftingComponent rework @@ -1150,7 +1169,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_IV) .input(cableGtSingle, Platinum, 4) .circuitMeta(1) - .output(LASER_INPUT_HATCH_256[0]) + .output(LASER_OUTPUT_HATCH_256[0]) .duration(300).EUt(VA[IV]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1160,7 +1179,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_LuV) .input(cableGtSingle, NiobiumTitanium, 4) .circuitMeta(1) - .output(LASER_INPUT_HATCH_256[1]) + .output(LASER_OUTPUT_HATCH_256[1]) .duration(300).EUt(VA[LuV]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1170,7 +1189,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_ZPM) .input(cableGtSingle, VanadiumGallium, 4) .circuitMeta(1) - .output(LASER_INPUT_HATCH_256[2]) + .output(LASER_OUTPUT_HATCH_256[2]) .duration(300).EUt(VA[ZPM]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1180,7 +1199,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_UV) .input(cableGtSingle, YttriumBariumCuprate, 4) .circuitMeta(1) - .output(LASER_INPUT_HATCH_256[3]) + .output(LASER_OUTPUT_HATCH_256[3]) .duration(300).EUt(VA[UV]).buildAndRegister(); // 256A Laser Target Hatches @@ -1191,7 +1210,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_IV) .input(cableGtSingle, Platinum, 4) .circuitMeta(1) - .output(LASER_OUTPUT_HATCH_256[0]) + .output(LASER_INPUT_HATCH_256[0]) .duration(300).EUt(VA[IV]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1201,7 +1220,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_LuV) .input(cableGtSingle, NiobiumTitanium, 4) .circuitMeta(1) - .output(LASER_OUTPUT_HATCH_256[1]) + .output(LASER_INPUT_HATCH_256[1]) .duration(300).EUt(VA[LuV]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1211,7 +1230,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_ZPM) .input(cableGtSingle, VanadiumGallium, 4) .circuitMeta(1) - .output(LASER_OUTPUT_HATCH_256[2]) + .output(LASER_INPUT_HATCH_256[2]) .duration(300).EUt(VA[ZPM]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1221,7 +1240,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_UV) .input(cableGtSingle, YttriumBariumCuprate, 4) .circuitMeta(1) - .output(LASER_OUTPUT_HATCH_256[3]) + .output(LASER_INPUT_HATCH_256[3]) .duration(300).EUt(VA[UV]).buildAndRegister(); // 1024A Laser Source Hatches @@ -1232,7 +1251,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_IV, 2) .input(cableGtDouble, Platinum, 4) .circuitMeta(2) - .output(LASER_INPUT_HATCH_1024[0]) + .output(LASER_OUTPUT_HATCH_1024[0]) .duration(600).EUt(VA[IV]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1242,7 +1261,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_LuV, 2) .input(cableGtDouble, NiobiumTitanium, 4) .circuitMeta(2) - .output(LASER_INPUT_HATCH_1024[1]) + .output(LASER_OUTPUT_HATCH_1024[1]) .duration(600).EUt(VA[LuV]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1252,7 +1271,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_ZPM, 2) .input(cableGtDouble, VanadiumGallium, 4) .circuitMeta(2) - .output(LASER_INPUT_HATCH_1024[2]) + .output(LASER_OUTPUT_HATCH_1024[2]) .duration(600).EUt(VA[ZPM]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1262,7 +1281,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_UV, 2) .input(cableGtDouble, YttriumBariumCuprate, 4) .circuitMeta(2) - .output(LASER_INPUT_HATCH_1024[3]) + .output(LASER_OUTPUT_HATCH_1024[3]) .duration(600).EUt(VA[UV]).buildAndRegister(); // 1024A Laser Target Hatches @@ -1273,7 +1292,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_IV, 2) .input(cableGtDouble, Platinum, 4) .circuitMeta(2) - .output(LASER_OUTPUT_HATCH_1024[0]) + .output(LASER_INPUT_HATCH_1024[0]) .duration(600).EUt(VA[IV]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1283,7 +1302,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_LuV, 2) .input(cableGtDouble, NiobiumTitanium, 4) .circuitMeta(2) - .output(LASER_OUTPUT_HATCH_1024[1]) + .output(LASER_INPUT_HATCH_1024[1]) .duration(600).EUt(VA[LuV]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1293,7 +1312,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_ZPM, 2) .input(cableGtDouble, VanadiumGallium, 4) .circuitMeta(2) - .output(LASER_OUTPUT_HATCH_1024[2]) + .output(LASER_INPUT_HATCH_1024[2]) .duration(600).EUt(VA[ZPM]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1303,7 +1322,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_UV, 2) .input(cableGtDouble, YttriumBariumCuprate, 4) .circuitMeta(2) - .output(LASER_OUTPUT_HATCH_1024[3]) + .output(LASER_INPUT_HATCH_1024[3]) .duration(600).EUt(VA[UV]).buildAndRegister(); // 4096A Laser Source Hatches @@ -1314,7 +1333,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_IV, 4) .input(cableGtQuadruple, Platinum, 4) .circuitMeta(3) - .output(LASER_INPUT_HATCH_4096[0]) + .output(LASER_OUTPUT_HATCH_4096[0]) .duration(1200).EUt(VA[IV]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1324,7 +1343,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_LuV, 4) .input(cableGtQuadruple, NiobiumTitanium, 4) .circuitMeta(3) - .output(LASER_INPUT_HATCH_4096[1]) + .output(LASER_OUTPUT_HATCH_4096[1]) .duration(1200).EUt(VA[LuV]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1334,7 +1353,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_ZPM, 4) .input(cableGtQuadruple, VanadiumGallium, 4) .circuitMeta(3) - .output(LASER_INPUT_HATCH_4096[2]) + .output(LASER_OUTPUT_HATCH_4096[2]) .duration(1200).EUt(VA[ZPM]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1344,7 +1363,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_UV, 4) .input(cableGtQuadruple, YttriumBariumCuprate, 4) .circuitMeta(3) - .output(LASER_INPUT_HATCH_4096[3]) + .output(LASER_OUTPUT_HATCH_4096[3]) .duration(1200).EUt(VA[UV]).buildAndRegister(); // 4096A Laser Target Hatches @@ -1355,7 +1374,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_IV, 4) .input(cableGtQuadruple, Platinum, 4) .circuitMeta(3) - .output(LASER_OUTPUT_HATCH_4096[0]) + .output(LASER_INPUT_HATCH_4096[0]) .duration(1200).EUt(VA[IV]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1365,7 +1384,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_LuV, 4) .input(cableGtQuadruple, NiobiumTitanium, 4) .circuitMeta(3) - .output(LASER_OUTPUT_HATCH_4096[1]) + .output(LASER_INPUT_HATCH_4096[1]) .duration(1200).EUt(VA[LuV]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1375,7 +1394,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_ZPM, 4) .input(cableGtQuadruple, VanadiumGallium, 4) .circuitMeta(3) - .output(LASER_OUTPUT_HATCH_4096[2]) + .output(LASER_INPUT_HATCH_4096[2]) .duration(1200).EUt(VA[ZPM]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1385,7 +1404,7 @@ private static void registerLaserRecipes() { .input(ELECTRIC_PUMP_UV, 4) .input(cableGtQuadruple, YttriumBariumCuprate, 4) .circuitMeta(3) - .output(LASER_OUTPUT_HATCH_4096[3]) + .output(LASER_INPUT_HATCH_4096[3]) .duration(1200).EUt(VA[UV]).buildAndRegister(); } } diff --git a/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java index fb06348d385..953649972d8 100644 --- a/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/WoodRecipeLoader.java @@ -49,7 +49,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(Blocks.WOODEN_SLAB), "oak_wooden_slab") .fence(new ItemStack(Blocks.OAK_FENCE), "fence") .fenceGate(new ItemStack(Blocks.OAK_FENCE_GATE), "fence_gate") - .stairs(new ItemStack(Blocks.OAK_STAIRS)) + .stairs(new ItemStack(Blocks.OAK_STAIRS), "oak_stairs") .boat(new ItemStack(Items.BOAT), "boat") .registerAllUnificationInfo() .build(), @@ -60,7 +60,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(Blocks.WOODEN_SLAB, 1, 1), "spruce_wooden_slab") .fence(new ItemStack(Blocks.SPRUCE_FENCE), "spruce_fence") .fenceGate(new ItemStack(Blocks.SPRUCE_FENCE_GATE), "spruce_fence_gate") - .stairs(new ItemStack(Blocks.SPRUCE_STAIRS)) + .stairs(new ItemStack(Blocks.SPRUCE_STAIRS), "spruce_stairs") .boat(new ItemStack(Items.SPRUCE_BOAT), "spruce_boat") .registerAllUnificationInfo() .build(), @@ -71,7 +71,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(Blocks.WOODEN_SLAB, 1, 2), "birch_wooden_slab") .fence(new ItemStack(Blocks.BIRCH_FENCE), "birch_fence") .fenceGate(new ItemStack(Blocks.BIRCH_FENCE_GATE), "birch_fence_gate") - .stairs(new ItemStack(Blocks.BIRCH_STAIRS)) + .stairs(new ItemStack(Blocks.BIRCH_STAIRS), "birch_stairs") .boat(new ItemStack(Items.BIRCH_BOAT), "birch_boat") .registerAllUnificationInfo() .build(), @@ -82,7 +82,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(Blocks.WOODEN_SLAB, 1, 3), "jungle_wooden_slab") .fence(new ItemStack(Blocks.JUNGLE_FENCE), "jungle_fence") .fenceGate(new ItemStack(Blocks.JUNGLE_FENCE_GATE), "jungle_fence_gate") - .stairs(new ItemStack(Blocks.JUNGLE_STAIRS)) + .stairs(new ItemStack(Blocks.JUNGLE_STAIRS), "jungle_stairs") .boat(new ItemStack(Items.JUNGLE_BOAT), "jungle_boat") .registerAllUnificationInfo() .build(), @@ -93,7 +93,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(Blocks.WOODEN_SLAB, 1, 4), "acacia_wooden_slab") .fence(new ItemStack(Blocks.ACACIA_FENCE), "acacia_fence") .fenceGate(new ItemStack(Blocks.ACACIA_FENCE_GATE), "acacia_fence_gate") - .stairs(new ItemStack(Blocks.ACACIA_STAIRS)) + .stairs(new ItemStack(Blocks.ACACIA_STAIRS), "acacia_stairs") .boat(new ItemStack(Items.ACACIA_BOAT), "acacia_boat") .registerAllUnificationInfo() .build(), @@ -104,7 +104,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(Blocks.WOODEN_SLAB, 1, 5), "dark_oak_wooden_slab") .fence(new ItemStack(Blocks.DARK_OAK_FENCE), "dark_oak_fence") .fenceGate(new ItemStack(Blocks.DARK_OAK_FENCE_GATE), "dark_oak_fence_gate") - .stairs(new ItemStack(Blocks.DARK_OAK_STAIRS)) + .stairs(new ItemStack(Blocks.DARK_OAK_STAIRS), "dark_oak_stairs") .boat(new ItemStack(Items.DARK_OAK_BOAT), "dark_oak_boat") .registerAllUnificationInfo() .build(), @@ -115,7 +115,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(MetaBlocks.WOOD_SLAB), null).addSlabRecipe() .fence(new ItemStack(MetaBlocks.RUBBER_WOOD_FENCE), null) .fenceGate(new ItemStack(MetaBlocks.RUBBER_WOOD_FENCE_GATE), null) - .stairs(new ItemStack(MetaBlocks.RUBBER_WOOD_STAIRS)).addStairsRecipe() + .stairs(new ItemStack(MetaBlocks.RUBBER_WOOD_STAIRS), null).addStairsRecipe() .boat(MetaItems.RUBBER_WOOD_BOAT.getStackForm(), null) .registerAllOres() .registerAllUnificationInfo() @@ -126,7 +126,7 @@ private static List getDefaultEntries() { .slab(new ItemStack(MetaBlocks.WOOD_SLAB, 1, 1), null).addSlabRecipe() .fence(new ItemStack(MetaBlocks.TREATED_WOOD_FENCE), null) .fenceGate(new ItemStack(MetaBlocks.TREATED_WOOD_FENCE_GATE), null) - .stairs(new ItemStack(MetaBlocks.TREATED_WOOD_STAIRS)).addStairsRecipe() + .stairs(new ItemStack(MetaBlocks.TREATED_WOOD_STAIRS), null).addStairsRecipe() .boat(MetaItems.TREATED_WOOD_BOAT.getStackForm(), null) .material(TreatedWood) .registerAllOres() @@ -326,8 +326,10 @@ public static void registerWoodTypeRecipe(@NotNull WoodTypeEntry entry) { // stairs if (!entry.stairs.isEmpty()) { + final boolean hasStairRecipe = entry.stairsRecipeName != null; if (entry.addStairsCraftingRecipe) { - ModHandler.addShapedRecipe(name + "_stairs", GTUtility.copy(4, entry.stairs), + ModHandler.addShapedRecipe(hasStairRecipe ? entry.stairsRecipeName : name + "_stairs", + GTUtility.copy(4, entry.stairs), "P ", "PP ", "PPP", 'P', entry.planks.copy()); } @@ -482,7 +484,7 @@ private static void registerGTWoodRecipes() { 'L', MetaBlocks.PLANKS.getItemVariant(BlockGregPlanks.BlockType.TREATED_PLANK)); if (ConfigHolder.recipes.nerfWoodCrafting) { ModHandler.addShapedRecipe("treated_wood_stick_saw", OreDictUnifier.get(OrePrefix.stick, TreatedWood, 4), - "s", "L", + "s", "L", "L", 'L', MetaBlocks.PLANKS.getItemVariant(BlockGregPlanks.BlockType.TREATED_PLANK)); } } diff --git a/src/main/java/gregtech/loaders/recipe/chemistry/AssemblerRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/chemistry/AssemblerRecipeLoader.java index 44be226b0c8..2b0eed5633c 100644 --- a/src/main/java/gregtech/loaders/recipe/chemistry/AssemblerRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/chemistry/AssemblerRecipeLoader.java @@ -158,7 +158,7 @@ public static void init() { ASSEMBLER_RECIPES.recipeBuilder().duration(200).EUt(VA[EV]) .input(stick, NeodymiumMagnetic) - .input(wireFine, TungstenSteel, 16) + .input(wireFine, Platinum, 16) .circuitMeta(1) .outputs(VOLTAGE_COIL_EV.getStackForm()) .buildAndRegister(); diff --git a/src/main/java/gregtech/loaders/recipe/chemistry/ChemistryRecipes.java b/src/main/java/gregtech/loaders/recipe/chemistry/ChemistryRecipes.java index 0a44f0a8b66..41ff3ac887a 100644 --- a/src/main/java/gregtech/loaders/recipe/chemistry/ChemistryRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/chemistry/ChemistryRecipes.java @@ -29,6 +29,7 @@ public static void init() { PlatGroupMetalsRecipes.init(); NaquadahRecipes.init(); AcidRecipes.init(); + TitaniumRecipes.init(); // A Few Random Recipes FLUID_HEATER_RECIPES.recipeBuilder() @@ -107,23 +108,5 @@ public static void init() { .fluidOutputs(EnderAir.getFluid(10000)) .dimension(1) .duration(200).EUt(256).buildAndRegister(); - - // CaCO3 + 2NaCl -> Na2CO3 + CaCl2 - BLAST_RECIPES.recipeBuilder() - .input(dust, Calcite, 5) - .input(dust, Salt, 4) - .output(dust, SodaAsh, 6) - .output(dust, CalciumChloride, 3) - .duration(120).EUt(VA[MV]).blastFurnaceTemp(1500) - .buildAndRegister(); - - // 2NaOH + CO2 -> Na2CO3 + H20 - CHEMICAL_RECIPES.recipeBuilder() - .input(dust, SodiumHydroxide, 6) - .fluidInputs(CarbonDioxide.getFluid(1000)) - .output(dust, SodaAsh, 6) - .fluidOutputs(Water.getFluid(1000)) - .duration(80).EUt(VA[HV]) - .buildAndRegister(); } } diff --git a/src/main/java/gregtech/loaders/recipe/chemistry/MixerRecipes.java b/src/main/java/gregtech/loaders/recipe/chemistry/MixerRecipes.java index f4ae4d431af..c0edbab21b7 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) @@ -527,7 +534,7 @@ public static void init() { .buildAndRegister(); MIXER_RECIPES.recipeBuilder().duration(200).EUt(VA[EV]) - .input(dust, Uranium238) + .input(dust, Uranium) .input(dust, Platinum, 3) .circuitMeta(4) .output(dust, UraniumTriplatinum, 4) @@ -554,7 +561,7 @@ public static void init() { .buildAndRegister(); MIXER_RECIPES.recipeBuilder().duration(150).EUt(VA[ZPM]) - .input(dust, Uranium238) + .input(dust, Uranium) .input(dust, Rhodium) .input(dust, Naquadah, 2) .circuitMeta(4) @@ -587,5 +594,23 @@ public static void init() { .circuitMeta(1) .output(dust, RTMAlloy, 7) .buildAndRegister(); + + MIXER_RECIPES.recipeBuilder().duration(600).EUt(VA[EV]) + .input(dust, Zirconium, 16) + .input(dust, Tin, 2) + .input(dust, Chrome, 1) + .circuitMeta(1) + .output(dust, Zircaloy4, 19) + .buildAndRegister(); + + MIXER_RECIPES.recipeBuilder().duration(400).EUt(VA[EV]) + .input(dust, Nickel, 5) + .input(dust, Chrome, 2) + .input(dust, Iron, 2) + .input(dust, Niobium) + .input(dust, Molybdenum) + .circuitMeta(4) + .output(dust, Inconel718, 11) + .buildAndRegister(); } } diff --git a/src/main/java/gregtech/loaders/recipe/chemistry/NuclearRecipes.java b/src/main/java/gregtech/loaders/recipe/chemistry/NuclearRecipes.java index 08d8567299b..2133853d789 100644 --- a/src/main/java/gregtech/loaders/recipe/chemistry/NuclearRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/chemistry/NuclearRecipes.java @@ -4,10 +4,12 @@ import static gregtech.api.recipes.RecipeMaps.*; import static gregtech.api.unification.material.Materials.*; import static gregtech.api.unification.ore.OrePrefix.dust; +import static gregtech.api.unification.ore.OrePrefix.ingotHot; public class NuclearRecipes { public static void init() { + // uranium isotopes CHEMICAL_RECIPES.recipeBuilder().duration(200).EUt(VA[LV]) .input(dust, Uraninite, 3) .fluidInputs(HydrofluoricAcid.getFluid(4000)) @@ -22,6 +24,12 @@ public static void init() { .fluidOutputs(DepletedUraniumHexafluoride.getFluid(900)) .buildAndRegister(); + ELECTROLYZER_RECIPES.recipeBuilder().duration(160).EUt(VA[MV]) + .fluidInputs(UraniumHexafluoride.getFluid(1000)) + .output(dust, Uranium) + .fluidOutputs(Fluorine.getFluid(6000)) + .buildAndRegister(); + ELECTROLYZER_RECIPES.recipeBuilder().duration(160).EUt(VA[MV]) .fluidInputs(EnrichedUraniumHexafluoride.getFluid(1000)) .output(dust, Uranium235) @@ -33,5 +41,48 @@ public static void init() { .output(dust, Uranium238) .fluidOutputs(Fluorine.getFluid(6000)) .buildAndRegister(); + + // zirconium and hafnium + // ZrSiO4 -> ZrO2 + SiO2 + BLAST_RECIPES.recipeBuilder().duration(200).EUt(VA[MV]).blastFurnaceTemp(3073) + .input(dust, Zircon, 6) + .output(dust, SiliconDioxide, 3) + .output(dust, Zirconia, 3) + .chancedOutput(dust, Hafnia, 3333, 0) + .buildAndRegister(); + + // ZrO2 + C + 4Cl -> ZrCl4 + CO2 + CHEMICAL_RECIPES.recipeBuilder().duration(400).EUt(VA[HV]) + .input(dust, Zirconia, 3) + .input(dust, Carbon) + .fluidInputs(Chlorine.getFluid(4000)) + .output(dust, ZirconiumTetrachloride, 5) + .fluidOutputs(CarbonDioxide.getFluid(1000)) + .buildAndRegister(); + + // ZrCl4 + 2Mg -> Zr + 2MgCl2 + BLAST_RECIPES.recipeBuilder().duration(800).EUt(VA[EV]).blastFurnaceTemp(2125) + .input(dust, ZirconiumTetrachloride, 5) + .input(dust, Magnesium, 2) + .output(ingotHot, Zirconium) + .output(dust, MagnesiumChloride, 6) + .buildAndRegister(); + + // HfO2 + C + 4Cl -> HfCl4 + CO2 + CHEMICAL_RECIPES.recipeBuilder().duration(400).EUt(VA[HV]) + .input(dust, Hafnia, 3) + .input(dust, Carbon) + .fluidInputs(Chlorine.getFluid(4000)) + .output(dust, HafniumTetrachloride, 5) + .fluidOutputs(CarbonDioxide.getFluid(1000)) + .buildAndRegister(); + + // HfCl4 + 2Mg -> Hf + 2MgCl2 + BLAST_RECIPES.recipeBuilder().duration(2000).EUt(VA[EV]).blastFurnaceTemp(2227) + .input(dust, HafniumTetrachloride, 5) + .input(dust, Magnesium, 2) + .output(ingotHot, Hafnium) + .output(dust, MagnesiumChloride, 6) + .buildAndRegister(); } } diff --git a/src/main/java/gregtech/loaders/recipe/chemistry/ReactorRecipes.java b/src/main/java/gregtech/loaders/recipe/chemistry/ReactorRecipes.java index 7871a518e8c..7178cadecbf 100644 --- a/src/main/java/gregtech/loaders/recipe/chemistry/ReactorRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/chemistry/ReactorRecipes.java @@ -3,6 +3,7 @@ import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.MarkerMaterials; import gregtech.api.unification.material.Materials; +import gregtech.common.blocks.MetaBlocks; import gregtech.common.items.MetaItems; import net.minecraft.init.Blocks; @@ -11,8 +12,7 @@ import net.minecraftforge.oredict.OreDictionary; import static gregtech.api.GTValues.*; -import static gregtech.api.recipes.RecipeMaps.CHEMICAL_RECIPES; -import static gregtech.api.recipes.RecipeMaps.LARGE_CHEMICAL_RECIPES; +import static gregtech.api.recipes.RecipeMaps.*; import static gregtech.api.unification.material.Materials.*; import static gregtech.api.unification.ore.OrePrefix.*; @@ -82,14 +82,6 @@ public static void init() { .fluidOutputs(SiliconeRubber.getFluid(1296)) .duration(600).EUt(VA[LV]).buildAndRegister(); - CHEMICAL_RECIPES.recipeBuilder() - .input(dust, Carbon, 2) - .input(dust, Rutile) - .fluidInputs(Chlorine.getFluid(4000)) - .fluidOutputs(CarbonMonoxide.getFluid(2000)) - .fluidOutputs(TitaniumTetrachloride.getFluid(1000)) - .duration(400).EUt(VA[HV]).buildAndRegister(); - CHEMICAL_RECIPES.recipeBuilder() .fluidInputs(Dimethyldichlorosilane.getFluid(1000)) .fluidInputs(Water.getFluid(1000)) @@ -503,25 +495,12 @@ public static void init() { .output(dust, Calcite, 5) .duration(500).EUt(VA[LV]).buildAndRegister(); - CHEMICAL_RECIPES.recipeBuilder() - .input(dust, Quicklime, 2) - .fluidInputs(CarbonDioxide.getFluid(1000)) - .output(dust, Calcite, 5) - .duration(80).EUt(VA[LV]).buildAndRegister(); - CHEMICAL_RECIPES.recipeBuilder() .input(dust, Magnesia, 2) .fluidInputs(CarbonDioxide.getFluid(1000)) .output(dust, Magnesite, 5) .duration(80).EUt(VA[LV]).buildAndRegister(); - CHEMICAL_RECIPES.recipeBuilder() - .circuitMeta(1) - .input(dust, Calcite, 5) - .output(dust, Quicklime, 2) - .fluidOutputs(CarbonDioxide.getFluid(1000)) - .duration(240).EUt(VA[LV]).buildAndRegister(); - CHEMICAL_RECIPES.recipeBuilder() .input(dust, Magnesite, 5) .output(dust, Magnesia, 2) @@ -570,6 +549,13 @@ public static void init() { .outputs(new ItemStack(Blocks.TNT)) .duration(200).EUt(24).buildAndRegister(); + CHEMICAL_RECIPES.recipeBuilder() + .inputs(MetaItems.GELLED_TOLUENE.getStackForm(4)) + .fluidInputs(NitrationMixture.getFluid(200)) + .outputs(new ItemStack(MetaBlocks.ITNT)) + .fluidOutputs(DilutedSulfuricAcid.getFluid(150)) + .duration(80).EUt(VA[HV]).buildAndRegister(); + CHEMICAL_RECIPES.recipeBuilder() .input(dust, SodiumHydroxide, 6) .fluidInputs(Dichlorobenzene.getFluid(1000)) diff --git a/src/main/java/gregtech/loaders/recipe/chemistry/SeparationRecipes.java b/src/main/java/gregtech/loaders/recipe/chemistry/SeparationRecipes.java index fc433308a0d..59f27762319 100644 --- a/src/main/java/gregtech/loaders/recipe/chemistry/SeparationRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/chemistry/SeparationRecipes.java @@ -174,18 +174,6 @@ public static void init() { .output(dust, Carbon, 2) .buildAndRegister(); - CENTRIFUGE_RECIPES.recipeBuilder().duration(800).EUt(320) - .input(dust, Uranium238) - .chancedOutput(dustTiny, Plutonium239, 200, 80) - .chancedOutput(dustTiny, Uranium235, 2000, 350) - .buildAndRegister(); - - CENTRIFUGE_RECIPES.recipeBuilder().duration(1600).EUt(320) - .input(dust, Plutonium239) - .chancedOutput(dustTiny, Uranium238, 3000, 450) - .chancedOutput(dust, Plutonium241, 2000, 300) - .buildAndRegister(); - CENTRIFUGE_RECIPES.recipeBuilder().duration(320).EUt(20) .input(dust, Endstone) .chancedOutput(new ItemStack(Blocks.SAND), 9000, 300) diff --git a/src/main/java/gregtech/loaders/recipe/chemistry/TitaniumRecipes.java b/src/main/java/gregtech/loaders/recipe/chemistry/TitaniumRecipes.java new file mode 100644 index 00000000000..b8ed97b96a8 --- /dev/null +++ b/src/main/java/gregtech/loaders/recipe/chemistry/TitaniumRecipes.java @@ -0,0 +1,176 @@ +package gregtech.loaders.recipe.chemistry; + +import static gregtech.api.GTValues.*; +import static gregtech.api.recipes.RecipeMaps.*; +import static gregtech.api.recipes.RecipeMaps.BLAST_RECIPES; +import static gregtech.api.unification.material.Materials.*; +import static gregtech.api.unification.material.Materials.Water; +import static gregtech.api.unification.ore.OrePrefix.*; + +public class TitaniumRecipes { + + public static void init() { + titaniumProcess(); + solvayProcess(); + bauxiteProcess(); + ilmeniteProcess(); + } + + // Ilmenite and Rutile Processing + private static void titaniumProcess() { + // Rutile extraction from Ilmenite + // FeTiO3 + C -> Fe + TiO2 + CO + BLAST_RECIPES.recipeBuilder() + .input(dust, Ilmenite, 5) + .input(dust, Carbon) + .output(ingot, WroughtIron) + .output(dust, Rutile, 3) + .fluidOutputs(CarbonMonoxide.getFluid(1000)) + .blastFurnaceTemp(1700) + .duration(1600).EUt(VA[HV]).buildAndRegister(); + + // Chloride Process + // TiO2 + 2C + 4Cl -> TiCl4 + 2CO + CHEMICAL_RECIPES.recipeBuilder() + .input(dust, Carbon, 2) + .input(dust, Rutile) + .fluidInputs(Chlorine.getFluid(4000)) + .fluidOutputs(CarbonMonoxide.getFluid(2000)) + .fluidOutputs(TitaniumTetrachloride.getFluid(1000)) + .duration(400).EUt(VA[HV]).buildAndRegister(); + + // Kroll Process + // TiCl4 + 2Mg -> Ti + 2MgCl2 + BLAST_RECIPES.recipeBuilder().duration(800).EUt(VA[HV]) + .input(dust, Magnesium, 2) + .fluidInputs(TitaniumTetrachloride.getFluid(1000)) + .output(ingotHot, Titanium) + .output(dust, MagnesiumChloride, 6) + .blastFurnaceTemp(Titanium.getBlastTemperature() + 200) + .buildAndRegister(); + + CHEMICAL_RECIPES.recipeBuilder().duration(200).EUt(VA[HV]) + .input(dust, Sodium, 2) + .input(dust, MagnesiumChloride, 3) + .output(dust, Magnesium) + .output(dust, Salt, 4) + .buildAndRegister(); + } + + // The production of Soda Ash and Calcium Chloride from Salt and Calcite + // Used in the Bauxite Process + private static void solvayProcess() { + // CaCO3 -> CaO + CO2 + CHEMICAL_RECIPES.recipeBuilder() + .circuitMeta(1) + .input(dust, Calcite, 5) + .output(dust, Quicklime, 2) + .fluidOutputs(CarbonDioxide.getFluid(1000)) + .duration(200).EUt(VA[LV]).buildAndRegister(); + + // NaCl(H2O) + CO2 + NH3 -> NH4Cl + NaHCO3 + CHEMICAL_RECIPES.recipeBuilder() + .input(dust, Salt, 4) + .fluidInputs(CarbonDioxide.getFluid(1000)) + .fluidInputs(Ammonia.getFluid(1000)) + .fluidInputs(Water.getFluid(1000)) + .output(dust, AmmoniumChloride, 2) + .output(dust, SodiumBicarbonate, 6) + .duration(400).EUt(VA[MV]).buildAndRegister(); + + // 2NaHCO3 -> Na2CO3 + CO2 + H2O + ELECTROLYZER_RECIPES.recipeBuilder() + .input(dust, SodiumBicarbonate, 12) + .output(dust, SodaAsh, 6) + .fluidOutputs(CarbonDioxide.getFluid(1000)) + .fluidOutputs(Water.getFluid(1000)) + .duration(200).EUt(VA[MV]).buildAndRegister(); + + // 2NH4Cl + CaO -> CaCl2 + 2NH3 + H2O + CHEMICAL_RECIPES.recipeBuilder() + .input(dust, AmmoniumChloride, 4) + .input(dust, Quicklime, 2) + .output(dust, CalciumChloride, 3) + .fluidOutputs(Ammonia.getFluid(2000)) + .fluidOutputs(Water.getFluid(1000)) + .duration(200).EUt(VA[MV]).buildAndRegister(); + } + + // Advanced separation process for Bauxite + private static void bauxiteProcess() { + // Bauxite (crushed) + Soda Ash + Calcium Chloride -> Bauxite Slurry + MIXER_RECIPES.recipeBuilder() + .input(crushed, Bauxite, 32) + .input(dust, SodaAsh, 12) + .input(dust, CalciumChloride, 6) + .fluidInputs(Water.getFluid(4000)) + .fluidOutputs(BauxiteSlurry.getFluid(4000)) + .duration(500).EUt(VA[HV]).buildAndRegister(); + + // Bauxite (washed) + Soda Ash + Calcium Chloride -> Bauxite Slurry + MIXER_RECIPES.recipeBuilder() + .input(crushedPurified, Bauxite, 32) + .input(dust, SodaAsh, 12) + .input(dust, CalciumChloride, 6) + .fluidInputs(Water.getFluid(4000)) + .fluidOutputs(BauxiteSlurry.getFluid(4000)) + .duration(500).EUt(VA[HV]).buildAndRegister(); + + // Bauxite Slurry -> Cracked Bauxite Slurry + CRACKING_RECIPES.recipeBuilder() + .circuitMeta(1) + .fluidInputs(BauxiteSlurry.getFluid(16000)) + .fluidInputs(Steam.getFluid(1000)) + .fluidOutputs(CrackedBauxiteSlurry.getFluid(16000)) + .duration(500).EUt(VA[HV]).buildAndRegister(); + + // Bauxite Slurry + Sulfuric -> Aluminium, Slag, Sludge, and SO3 (for looping back to Sulfuric Acid) + LARGE_CHEMICAL_RECIPES.recipeBuilder() + .fluidInputs(CrackedBauxiteSlurry.getFluid(4000)) + .fluidInputs(SulfuricAcid.getFluid(1000)) + .output(dust, Aluminium, 24) + .output(dust, BauxiteSlag, 8) + .fluidOutputs(BauxiteSludge.getFluid(2500)) + .fluidOutputs(SulfurTrioxide.getFluid(1000)) + .duration(500).EUt(VA[HV]).buildAndRegister(); + + // Bauxite Slag -> Salt (looped) + Nd + Cr (byproducts) + ELECTROMAGNETIC_SEPARATOR_RECIPES.recipeBuilder() + .input(dust, BauxiteSlag) + .output(dust, Salt) + .chancedOutput(dust, Neodymium, 2000, 250) + .chancedOutput(dust, Chrome, 1000, 250) + .duration(50).EUt(VA[MV]).buildAndRegister(); + + // Bauxite Sludge -> Calcite (looped) + Decalcified Bauxite Sludge + DISTILLERY_RECIPES.recipeBuilder() + .circuitMeta(1) + .fluidInputs(BauxiteSludge.getFluid(500)) + .output(dust, Calcite, 2) + .fluidOutputs(DecalcifiedBauxiteSludge.getFluid(500)) + .duration(100).EUt(VA[MV]).buildAndRegister(); + + // Decalcified Bauxite Sludge -> Rutile, Gallium, SiO2, Iron, Water + CENTRIFUGE_RECIPES.recipeBuilder() + .fluidInputs(DecalcifiedBauxiteSludge.getFluid(250)) + .output(dust, Rutile, 2) + .chancedOutput(dust, Gallium, 5000, 550) + .chancedOutput(dust, Gallium, 3000, 800) + .chancedOutput(dust, Gallium, 1000, 1000) + .chancedOutput(dust, SiliconDioxide, 9000, 250) + .chancedOutput(dust, Iron, 8000, 250) + .fluidOutputs(Water.getFluid(250)) + .duration(100).EUt(VA[MV]).buildAndRegister(); + } + + // Byproduct separation for Ilmenite + private static void ilmeniteProcess() { + ELECTROMAGNETIC_SEPARATOR_RECIPES.recipeBuilder() + .input(dust, IlmeniteSlag) + .chancedOutput(dust, Iron, 8000, 0) + .chancedOutput(dust, Zircon, 2500, 0) + .chancedOutput(dust, Tantalum, 2000, 0) + .chancedOutput(dust, Niobium, 500, 0) + .duration(50).EUt(VA[MV]).buildAndRegister(); + } +} diff --git a/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java b/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java index ac915b45dc7..3b048b093c6 100644 --- a/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java +++ b/src/main/java/gregtech/loaders/recipe/handlers/MaterialRecipeHandler.java @@ -13,6 +13,7 @@ import gregtech.api.unification.stack.UnificationEntry; import gregtech.api.util.GTUtility; import gregtech.common.ConfigHolder; +import gregtech.common.blocks.MetaBlocks; import gregtech.common.items.MetaItems; import gregtech.loaders.recipe.CraftingComponent; @@ -90,14 +91,28 @@ public static void processDust(OrePrefix dustPrefix, Material mat, DustProperty .inputs(GTUtility.copy(4, dustStack)) .outputs(GTUtility.copy(3, gemStack)) .chancedOutput(dust, Materials.DarkAsh, 2500, 0) - .explosivesAmount(2) + .explosives(new ItemStack(MetaBlocks.POWDERBARREL, 8)) .buildAndRegister(); RecipeMaps.IMPLOSION_RECIPES.recipeBuilder() .inputs(GTUtility.copy(4, dustStack)) .outputs(GTUtility.copy(3, gemStack)) .chancedOutput(dust, Materials.DarkAsh, 2500, 0) - .explosivesType(MetaItems.DYNAMITE.getStackForm()) + .explosives(4) + .buildAndRegister(); + + RecipeMaps.IMPLOSION_RECIPES.recipeBuilder() + .inputs(GTUtility.copy(4, dustStack)) + .outputs(GTUtility.copy(3, gemStack)) + .chancedOutput(dust, Materials.DarkAsh, 2500, 0) + .explosives(MetaItems.DYNAMITE.getStackForm(2)) + .buildAndRegister(); + + RecipeMaps.IMPLOSION_RECIPES.recipeBuilder() + .inputs(GTUtility.copy(4, dustStack)) + .outputs(GTUtility.copy(3, gemStack)) + .chancedOutput(dust, Materials.DarkAsh, 2500, 0) + .explosives(new ItemStack(MetaBlocks.ITNT)) .buildAndRegister(); } @@ -286,10 +301,10 @@ public static void processIngot(OrePrefix ingotPrefix, Material material, IngotP } } - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_INGOT) - .fluidInputs(material.getFluid(L)) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom(L)) .outputs(OreDictUnifier.get(ingotPrefix, material)) .duration(20).EUt(VA[ULV]) .buildAndRegister(); @@ -424,10 +439,10 @@ public static void processNugget(OrePrefix orePrefix, Material material, DustPro .output(ingot, material) .buildAndRegister(); - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_NUGGET) - .fluidInputs(material.getFluid(L)) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom(L)) .outputs(OreDictUnifier.get(orePrefix, material, 9)) .duration((int) material.getMass()) .EUt(VA[ULV]) @@ -465,10 +480,11 @@ public static void processFrame(OrePrefix framePrefix, Material material, DustPr public static void processBlock(OrePrefix blockPrefix, Material material, DustProperty property) { ItemStack blockStack = OreDictUnifier.get(blockPrefix, material); long materialAmount = blockPrefix.getMaterialAmount(material); - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_BLOCK) - .fluidInputs(material.getFluid((int) (materialAmount * L / M))) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom( + ((int) (materialAmount * L / M)))) .outputs(blockStack) .duration((int) material.getMass()).EUt(VA[ULV]) .buildAndRegister(); diff --git a/src/main/java/gregtech/loaders/recipe/handlers/PartsRecipeHandler.java b/src/main/java/gregtech/loaders/recipe/handlers/PartsRecipeHandler.java index 24ec5349133..ddff63fd34a 100644 --- a/src/main/java/gregtech/loaders/recipe/handlers/PartsRecipeHandler.java +++ b/src/main/java/gregtech/loaders/recipe/handlers/PartsRecipeHandler.java @@ -200,11 +200,12 @@ public static void processGear(OrePrefix gearPrefix, Material material, DustProp } } - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { boolean isSmall = gearPrefix == OrePrefix.gearSmall; RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(isSmall ? MetaItems.SHAPE_MOLD_GEAR_SMALL : MetaItems.SHAPE_MOLD_GEAR) - .fluidInputs(material.getFluid(L * (isSmall ? 1 : 4))) + .fluidInputs( + material.getProperty(PropertyKey.FLUID).solidifiesFrom(L * (isSmall ? 1 : 4))) .outputs(stack) .duration(isSmall ? 20 : 100) .EUt(VA[ULV]) @@ -285,10 +286,10 @@ public static void processLens(OrePrefix lensPrefix, Material material, GemPrope } public static void processPlate(OrePrefix platePrefix, Material material, DustProperty property) { - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_PLATE) - .fluidInputs(material.getFluid(L)) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom(L)) .outputs(OreDictUnifier.get(platePrefix, material)) .duration(40) .EUt(VA[ULV]) @@ -399,10 +400,10 @@ public static void processRotor(OrePrefix rotorPrefix, Material material, IngotP 'S', new UnificationEntry(screw, material), 'R', new UnificationEntry(ring, material)); - if (material.hasFluid()) { + if (material.hasFluid() && material.getProperty(PropertyKey.FLUID).solidifiesFrom() != null) { RecipeMaps.FLUID_SOLIDFICATION_RECIPES.recipeBuilder() .notConsumable(MetaItems.SHAPE_MOLD_ROTOR) - .fluidInputs(material.getFluid(L * 4)) + .fluidInputs(material.getProperty(PropertyKey.FLUID).solidifiesFrom(L * 4)) .outputs(GTUtility.copy(stack)) .duration(120) .EUt(20) diff --git a/src/main/java/gregtech/loaders/recipe/handlers/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/loaders/recipe/handlers/ToolRecipeHandler.java b/src/main/java/gregtech/loaders/recipe/handlers/ToolRecipeHandler.java index 4b6ec9210b2..1997631a38c 100644 --- a/src/main/java/gregtech/loaders/recipe/handlers/ToolRecipeHandler.java +++ b/src/main/java/gregtech/loaders/recipe/handlers/ToolRecipeHandler.java @@ -287,6 +287,10 @@ private static void processElectricTool(OrePrefix prefix, Material material, Too .EUt(8 * voltageMultiplier) .buildAndRegister(); } + + // wirecutter + addElectricWirecutterRecipe(material, + new IGTTool[] { ToolItems.WIRECUTTER_LV, ToolItems.WIRECUTTER_HV, ToolItems.WIRECUTTER_IV }); } // screwdriver @@ -316,6 +320,21 @@ public static void addElectricToolRecipe(OrePrefix toolHead, Material material, } } + public static void addElectricWirecutterRecipe(Material material, IGTTool[] toolItems) { + for (IGTTool toolItem : toolItems) { + int tier = toolItem.getElectricTier(); + ItemStack powerUnitStack = powerUnitItems.get(tier).getStackForm(); + IElectricItem powerUnit = powerUnitStack.getCapability(GregtechCapabilities.CAPABILITY_ELECTRIC_ITEM, null); + ItemStack tool = toolItem.get(material, 0, powerUnit.getMaxCharge()); + ModHandler.addShapedEnergyTransferRecipe(String.format("%s_%s", toolItem.getToolId(), material), tool, + Ingredient.fromStacks(powerUnitStack), true, true, + "PfP", "hPd", "RUR", + 'P', new UnificationEntry(OrePrefix.plate, material), + 'U', powerUnitStack, + 'R', new UnificationEntry(OrePrefix.stick, material)); + } + } + public static void addToolRecipe(@NotNull Material material, @NotNull IGTTool tool, boolean mirrored, Object... recipe) { if (mirrored) { diff --git a/src/main/java/gregtech/mixins/GregTechLateMixinLoadingPlugin.java b/src/main/java/gregtech/mixins/GregTechLateMixinLoadingPlugin.java new file mode 100644 index 00000000000..f429a9d749e --- /dev/null +++ b/src/main/java/gregtech/mixins/GregTechLateMixinLoadingPlugin.java @@ -0,0 +1,39 @@ +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"); + configs.add("mixins.gregtech.nothirium.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(); + case "mixins.gregtech.nothirium.json" -> Mods.Nothirium.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/BlockRenderLayerMixin.java b/src/main/java/gregtech/mixins/minecraft/BlockRenderLayerMixin.java new file mode 100644 index 00000000000..d3c352a94dd --- /dev/null +++ b/src/main/java/gregtech/mixins/minecraft/BlockRenderLayerMixin.java @@ -0,0 +1,31 @@ +package gregtech.mixins.minecraft; + +import net.minecraft.util.BlockRenderLayer; + +import org.apache.commons.lang3.ArrayUtils; +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.gen.Invoker; + +@Mixin(BlockRenderLayer.class) +public class BlockRenderLayerMixin { + + @Final + @Shadow + @Mutable + private static BlockRenderLayer[] $VALUES; + + @SuppressWarnings("all") + @Invoker("") + private static BlockRenderLayer create(String name, int ordinal, String directoryName) { + throw new IllegalStateException("Unreachable"); + } + + static { + BlockRenderLayer bloom = create("BLOOM", $VALUES.length, "Bloom"); + + $VALUES = ArrayUtils.add($VALUES, bloom); + } +} 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/nothirium/ChunkRenderPassMixin.java b/src/main/java/gregtech/mixins/nothirium/ChunkRenderPassMixin.java new file mode 100644 index 00000000000..9785abe9978 --- /dev/null +++ b/src/main/java/gregtech/mixins/nothirium/ChunkRenderPassMixin.java @@ -0,0 +1,35 @@ +package gregtech.mixins.nothirium; + +import meldexun.nothirium.api.renderer.chunk.ChunkRenderPass; +import org.apache.commons.lang3.ArrayUtils; +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.gen.Invoker; + +@Mixin(ChunkRenderPass.class) +public class ChunkRenderPassMixin { + + @Final + @Mutable + @Shadow(remap = false) + public static ChunkRenderPass[] $VALUES; + + @Final + @Mutable + @Shadow(remap = false) + public static ChunkRenderPass[] ALL; + + @SuppressWarnings("all") + @Invoker(value = "") + private static ChunkRenderPass create(String name, int ordinal) { + throw new IllegalStateException("Unreachable"); + } + + static { + ChunkRenderPass bloom = create("BLOOM", $VALUES.length); + $VALUES = ArrayUtils.add($VALUES, bloom); + ALL = ChunkRenderPass.values(); + } +} 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..731128ddca0 --- /dev/null +++ b/src/main/java/gregtech/mixins/vintagium/BlockRenderPassMixin.java @@ -0,0 +1,48 @@ +package gregtech.mixins.vintagium; + +import gregtech.client.utils.BloomEffectUtil; + +import net.minecraft.util.BlockRenderLayer; + +import me.jellysquid.mods.sodium.client.render.chunk.passes.BlockRenderPass; +import me.jellysquid.mods.sodium.client.util.BufferSizeUtil; +import org.apache.commons.lang3.ArrayUtils; +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.gen.Invoker; + +@Mixin(BlockRenderPass.class) +public abstract class BlockRenderPassMixin { + + @Final + @Mutable + @Shadow(remap = false) + public static BlockRenderPass[] $VALUES; + + @Final + @Mutable + @Shadow(remap = false) + public static BlockRenderPass[] VALUES; + + @Final + @Mutable + @Shadow(remap = false) + public static int COUNT; + + @SuppressWarnings("all") + @Invoker("") + private static BlockRenderPass create(String name, int ordinal, BlockRenderLayer layer, boolean translucent) { + throw new IllegalStateException("Unreachable"); + } + + static { + BufferSizeUtil.BUFFER_SIZES.put(BloomEffectUtil.getBloomLayer(), 131072); + + BlockRenderPass bloom = create("BLOOM", $VALUES.length, BloomEffectUtil.getBloomLayer(), true); + $VALUES = ArrayUtils.add($VALUES, bloom); + 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/itnt.json b/src/main/resources/assets/gregtech/blockstates/itnt.json new file mode 100644 index 00000000000..79c7d216ccb --- /dev/null +++ b/src/main/resources/assets/gregtech/blockstates/itnt.json @@ -0,0 +1,16 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:cube_bottom_top", + "textures": { + "bottom": "minecraft:blocks/tnt_bottom", + "top": "minecraft:blocks/tnt_top", + "side": "gregtech:blocks/misc/itnt" + } + }, + "variants": { + "normal": [ + {} + ] + } +} diff --git a/src/main/resources/assets/gregtech/blockstates/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/blockstates/powderbarrel.json b/src/main/resources/assets/gregtech/blockstates/powderbarrel.json new file mode 100644 index 00000000000..60d676619f5 --- /dev/null +++ b/src/main/resources/assets/gregtech/blockstates/powderbarrel.json @@ -0,0 +1,14 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:cube_all", + "textures": { + "all": "gregtech:blocks/misc/powderbarrel" + } + }, + "variants": { + "normal": [ + {} + ] + } +} diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 114a53d8f06..a16c5cab361 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -39,6 +39,10 @@ death.attack.screwdriver_lv=%s had their screws removed by %s enchantment.disjunction=Disjunction +gregtech.jei.remove_recipe.tooltip=Copies a %s Snippet to Remove this Recipe +gregtech.jei.ct_recipe.tooltip=CraftTweaker Recipe +gregtech.jei.gs_recipe.tooltip=GroovyScript Recipe + gregtech.machine.steam_grinder.name=Steam Grinder gregtech.multiblock.steam_grinder.description=A Multiblock Macerator at the Steam Age. Requires at least 14 Bronze Casings to form. Cannot use normal Input/Output busses, nor Fluid Hatches other than the Steam Hatch. gregtech.multiblock.steam.low_steam=Not enough Steam to run! @@ -53,6 +57,13 @@ gregtech.multiblock.steam_oven.description=A Multi Smelter at the Steam Age. Req gregtech.multiblock.require_steam_parts=Requires Steam Hatches and Buses! gregtech.multiblock.steam_.duration_modifier=Takes §f1.5x §7base duration to process, not affected by number of items. +gregtech.top.quantum_status.label=Status: +gregtech.top.quantum_status.powered=§bOnline +gregtech.top.quantum_status.connected=§cNo Power +gregtech.top.quantum_status.disconnected=Not connected +gregtech.top.quantum_controller.no_hatches=§cNo Energy Hatches Connected +gregtech.top.quantum_controller.no_power=§cNo Power + gregtech.top.working_disabled=Working Disabled gregtech.top.energy_consumption=Using @@ -62,7 +73,8 @@ gregtech.top.transform_up=Step Up gregtech.top.transform_down=Step Down gregtech.top.transform_input=Input: gregtech.top.transform_output=Output: -gregtech.top.steam_heating_up=Heating up +gregtech.top.steam_heating_up=Heating Up: +gregtech.top.steam_cooling_down=Cooling Down gregtech.top.steam_no_water=No Water gregtech.top.convert_eu=Converting §eEU§r -> §cFE§r @@ -104,11 +116,29 @@ gregtech.top.ld_pipe_output=Output gregtech.top.ld_pipe_input_endpoint=Input Endpoint: gregtech.top.ld_pipe_output_endpoint=Output Endpoint: -gregtech.waila.energy_stored=Energy: %d EU / %d EU +option.gregtech.block_ore=Ore Blocks +option.gregtech.controllable=Controllable Machines +option.gregtech.converter=Energy Converters +option.gregtech.diode=Diodes +option.gregtech.energy=Energy Containers +option.gregtech.block_lamp=Lamp Blocks +option.gregtech.maintenance=Maintenance Problems +option.gregtech.multi_recipemap=Machine Modes +option.gregtech.multiblock=Multiblocks +option.gregtech.primitive_pump=Primitive Pump +option.gregtech.recipe_logic=Recipes +option.gregtech.steam_boiler=Steam Boilers +option.gregtech.transformer=Transformers +option.gregtech.workable=Workable Machines + +gregtech.waila.energy_stored=Energy: %s EU / %s EU +gregtech.waila.energy_input=Input: %s EU/t +gregtech.waila.energy_output=Output: %s EU/t gregtech.waila.progress_idle=Idle gregtech.waila.progress_tick=Progress: %d t / %d t gregtech.waila.progress_sec=Progress: %d s / %d s gregtech.waila.progress_computation=Computation: %s / %s +gregtech.waila.active_transformer.average_io=Average I/O: %s EU/t gregtech.multiblock.title=Multiblock Pattern gregtech.multiblock.primitive_blast_furnace.bronze.description=The Primitive Blast Furnace (PBF) is a multiblock structure used for cooking steel in the early game. Although not very fast, it will provide you with steel for your first setups. @@ -822,6 +852,7 @@ metaitem.fluid_filter.name=Fluid Filter metaitem.fluid_filter.tooltip=Filters §fFluid§7 I/O as §fCover§7./nCan be used as an §fElectric Pump§7 and §fFluid Regulator§7 upgrade. metaitem.smart_item_filter.name=Smart Item Filter metaitem.smart_item_filter.tooltip=Filters §fItem§7 I/O with §fMachine Recipes§7 as §fCover§7./nCan be used as a §fConveyor Module§7 and §fRobotic Arm§7 upgrade. +behaviour.filter_ui_manager=§fRight-Click§7 to configure, §fShift Right-Click§7 to clear configuration metaitem.cover.controller.name=Machine Controller metaitem.cover.controller.tooltip=Turns Machines §fON/OFF§7 as §fCover§7. @@ -1008,6 +1039,9 @@ item.gt.tool.screwdriver_lv.name=%s Screwdriver (LV) item.gt.tool.screwdriver_lv.tooltip=§8Adjusts Covers and Machines item.gt.tool.plunger.name=%s Plunger item.gt.tool.plunger.tooltip=§8Removes Fluids from Machines +item.gt.tool.wire_cutter_lv.name=%s Wire Cutter (LV) +item.gt.tool.wire_cutter_hv.name=%s Wire Cutter (HV) +item.gt.tool.wire_cutter_iv.name=%s Wire Cutter (IV) item.gt.tool.tooltip.crafting_uses=§a%s Crafting Uses @@ -1175,7 +1209,9 @@ cover.filter.blacklist.disabled=Whitelist cover.filter.blacklist.enabled=Blacklist cover.ore_dictionary_filter.title=Ore Dictionary Filter -cover.ore_dictionary_filter.info=§bAccepts complex expressions/n§6a & b§r = AND/n§6a | b§r = OR/n§6a ^ b§r = XOR/n§6! abc§r = NOT/n§6( abc )§r for grouping/n§6*§r for wildcard (i.e. 0 or more characters)/n§6?§r for any 1 character/n§6()§r for matching empty entry (including items with no ore dictionary)/n§bExample:/n§6dust*Gold | (plate* & !*Double*)/nWill match all gold dusts of all sizes or all plates, but not double plates +cover.ore_dictionary_filter.info=§bAccepts complex expressions\n§6a & b§r = AND\n§6a | b§r = OR\n§6a ^ b§r = XOR\n§6! abc§r = NOT\n§6( abc )§r for grouping\n§6*§r for wildcard (i.e. 0 or more characters)\n§6?§r for any 1 character\n§6()§r for matching empty entry (including items with no ore dictionary)\n§bExample:\n§6dust*Gold | (plate* & !*Double*)\nWill match all gold dusts of all sizes or all plates, but not double plates +cover.ore_dictionary_filter.match_all=Match All: %s +cover.ore_dictionary_filter.case_sensitive=Case Sensitive: %s cover.ore_dictionary_filter.test_slot.info=Insert a item to test if it matches the filter expression cover.ore_dictionary_filter.test_slot.matches=§a* %s cover.ore_dictionary_filter.test_slot.matches_not=§c* %s @@ -1240,6 +1276,7 @@ cover.fluid_filter.mode.filter_drain=Filter Drain cover.fluid_filter.mode.filter_both=Filter Fill & Drain cover.item_filter.title=Item Filter +cover.filter.mode.title=Filter Mode cover.filter.mode.filter_insert=Filter Insert cover.filter.mode.filter_extract=Filter Extract cover.filter.mode.filter_both=Filter Insert/Extract @@ -1247,9 +1284,11 @@ cover.item_filter.ignore_damage.enabled=Ignore Damage cover.item_filter.ignore_damage.disabled=Respect Damage cover.item_filter.ignore_nbt.enabled=Ignore NBT cover.item_filter.ignore_nbt.disabled=Respect NBT +cover.item_filter.config_amount=Scroll wheel up increases amount, down decreases.\nShift[§6x4§r], Ctrl[§ex16§r], Alt[§ax64§r]\nRight click increases amount, left click decreases.\nShift Left-Click to clear cover.voiding.voiding_mode.void_any=Void Matching cover.voiding.voiding_mode.void_overflow=Void Overflow +cover.voiding.voiding_mode=Voiding Mode cover.voiding.voiding_mode.description=§eVoid Matching§r will void anything matching the filter. /n§eVoid Overflow§r will void anything matching the filter, up to the specified amount. cover.fluid.voiding.title=Fluid Voiding Settings cover.fluid.voiding.advanced.title=Advanced Fluid Voiding Settings @@ -1270,13 +1309,18 @@ cover.smart_item_filter.filtering_mode.centrifuge=Centrifuge cover.smart_item_filter.filtering_mode.sifter=Sifter cover.smart_item_filter.filtering_mode.description=Select Machine this Smart Filter will use for filtering./nIt will automatically pick right portions of items for robotic arm. +cover.generic.transfer_mode=Transfer Mode +cover.generic.manual_io=Manual IO Mode +cover.generic.io=IO Mode +cover.pump.mode=Pump Mode cover.conveyor.title=Conveyor Cover Settings (%s) cover.conveyor.transfer_rate=§7items/sec cover.conveyor.mode.export=Mode: Export cover.conveyor.mode.import=Mode: Import -cover.conveyor.distribution.round_robin_enhanced=Distribution Mode/n§bEnhanced Round Robin§r/n§7Splits items equally to all inventories -cover.conveyor.distribution.round_robin=Distribution Mode/n§bRound Robin§r with Priority/n§7Tries to split items equally to inventories -cover.conveyor.distribution.first_insert=Distribution Mode/n§bFirst Insert§r/n§7Will insert into the first inventory it finds +cover.conveyor.distribution.name=Distribution Mode +cover.conveyor.distribution.round_robin_enhanced=§bEnhanced Round Robin§r\n§7Splits items equally to all inventories +cover.conveyor.distribution.round_robin=§bRound Robin§r with Priority\n§7Tries to split items equally to inventories +cover.conveyor.distribution.first_insert=§bFirst Insert§r\n§7Will insert into the first inventory it finds cover.conveyor.blocks_input.enabled=If enabled, items will not be inserted when cover is set to pull items from the inventory into pipe./n§aEnabled cover.conveyor.blocks_input.disabled=If enabled, items will not be inserted when cover is set to pull items from the inventory into pipe./n§cDisabled cover.universal.manual_import_export.mode.disabled=Manual I/O: Disabled @@ -1287,6 +1331,7 @@ cover.conveyor.item_filter.title=Item Filter cover.conveyor.ore_dictionary.title=Ore Dictionary Name cover.conveyor.ore_dictionary.title2=(use * for wildcard) cover.robotic_arm.title=Robotic Arm Settings (%s) +cover.robotic_arm.exact=§7items cover.robotic_arm.transfer_mode.transfer_any=Transfer Any cover.robotic_arm.transfer_mode.transfer_exact=Supply Exact cover.robotic_arm.transfer_mode.keep_exact=Keep Exact @@ -1297,18 +1342,17 @@ cover.pump.transfer_rate=%s cover.pump.mode.export=Mode: Export cover.pump.mode.import=Mode: Import cover.pump.fluid_filter.title=Fluid Filter -cover.bucket.mode.bucket=kL/s -cover.bucket.mode.milli_bucket=L/s +cover.bucket.mode.bucket=Bucket Mode: kL +cover.bucket.mode.milli_bucket=Bucket Mode: L +cover.bucket.mode.bucket_rate=kL/s +cover.bucket.mode.bucket_exact=kL +cover.bucket.mode.milli_bucket_rate=L/s +cover.bucket.mode.milli_bucket_exact=L cover.fluid_regulator.title=Fluid Regulator Settings (%s) cover.fluid_regulator.transfer_mode.description=§eTransfer Any§r - in this mode, cover will transfer as many fluids matching its filter as possible./n§eSupply Exact§r - in this mode, cover will supply fluids in portions specified in the window underneath this button. If amount of fluids is less than portion size, fluids won't be moved./n§eKeep Exact§r - in this mode, cover will keep specified amount of fluids in the destination inventory, supplying additional amount of fluids if required./n§7Tip: shift click will multiply increase/decrease amounts by 10 and ctrl click will multiply by 100. cover.fluid_regulator.supply_exact=Supply Exact: %s cover.fluid_regulator.keep_exact=Keep Exact: %s -cover.machine_controller.title=Machine Controller Settings -cover.machine_controller.normal=Normal -cover.machine_controller.inverted=Inverted -cover.machine_controller.inverted.description=§eNormal§r - in this mode, the cover will require a signal weaker than the set redstone level to run/n§eInverted§r - in this mode, the cover will require a signal stronger than the set redstone level to run -cover.machine_controller.redstone=Min Redstone Strength: %,d cover.machine_controller.mode.machine=Control Machine cover.machine_controller.mode.cover_up=Control Cover (Top) cover.machine_controller.mode.cover_down=Control Cover (Bottom) @@ -1316,13 +1360,26 @@ cover.machine_controller.mode.cover_south=Control Cover (South) cover.machine_controller.mode.cover_north=Control Cover (North) cover.machine_controller.mode.cover_east=Control Cover (East) cover.machine_controller.mode.cover_west=Control Cover (West) +cover.machine_controller.this_cover=§cThis cover +cover.machine_controller.cover_not_controllable=§cNo controllable cover +cover.machine_controller.machine_not_controllable=§cMachine not controllable +cover.machine_controller.control=Control: +cover.machine_controller.enable_with_redstone=Enable with Redstone +cover.machine_controller.disable_with_redstone=Disable with Redstone cover.ender_fluid_link.title=Ender Fluid Link cover.ender_fluid_link.iomode.enabled=I/O Enabled cover.ender_fluid_link.iomode.disabled=I/O Disabled -cover.ender_fluid_link.private.tooltip.disabled=Switch to private tank mode/nPrivate mode uses the player who originally placed the cover +cover.ender_fluid_link.private.tooltip.disabled=Switch to private tank mode\nPrivate mode uses the player who originally placed the cover cover.ender_fluid_link.private.tooltip.enabled=Switch to public tank mode cover.ender_fluid_link.incomplete_hex=Inputted color is incomplete!/nIt will be applied once complete (all 8 hex digits)/nClosing the gui will lose edits! +cover.ender_fluid_link.transfer_unit=L/t + +cover.generic.ender.known_channels=Known Channels +cover.generic.ender.open_selector=Open Entry Selector +cover.generic.ender.set_description.tooltip=Set Description +cover.generic.ender.set_description.title=Set Description [%s] +cover.generic.ender.delete_entry=Delete Entry cover.generic.advanced_detector.latched=Latched cover.generic.advanced_detector.continuous=Continuous @@ -1537,7 +1594,8 @@ gregtech.material.palladium=Palladium gregtech.material.phosphorus=Phosphorus gregtech.material.polonium=Polonium gregtech.material.platinum=Platinum -gregtech.material.plutonium=Plutonium 239 +gregtech.material.plutonium=Plutonium +gregtech.material.plutonium_239=Plutonium 239 gregtech.material.plutonium_241=Plutonium 241 gregtech.material.potassium=Potassium gregtech.material.praseodymium=Praseodymium @@ -1572,8 +1630,9 @@ gregtech.material.tin=Tin gregtech.material.titanium=Titanium gregtech.material.tritium=Tritium gregtech.material.tungsten=Tungsten -gregtech.material.uranium=Uranium 238 +gregtech.material.uranium=Uranium gregtech.material.uranium_235=Uranium 235 +gregtech.material.uranium_238=Uranium 238 gregtech.material.vanadium=Vanadium gregtech.material.xenon=Xenon gregtech.material.ytterbium=Ytterbium @@ -1793,6 +1852,14 @@ gregtech.material.enriched_naquadah_sulfate=Enriched Naquadah Sulfate gregtech.material.naquadria_sulfate=Naquadria Sulfate gregtech.material.pyrochlore=Pyrochlore gregtech.material.rtm_alloy=RTM Alloy +gregtech.material.ilmenite_slag=Ilmenite Slag +gregtech.material.zircon=Zircon +gregtech.material.zirconia=Zirconia +gregtech.material.zirconium_tetrachloride=Zirconium Tetrachloride +gregtech.material.hafnia=Hafnia +gregtech.material.hafnium_tetrachloride=Hafnium Tetrachloride +gregtech.material.zircaloy_4=Zircaloy-4 +gregtech.material.inconel_718=Inconel-718 # Organic Chemistry Materials @@ -2006,6 +2073,11 @@ gregtech.material.acidic_naquadria_solution=Acidic Naquadria Solution gregtech.material.naquadria_waste=Naquadria Waste gregtech.material.lapotron=Lapotron gregtech.material.uu_matter=UU-Matter +gregtech.material.bauxite_slurry=Bauxite Slurry +gregtech.material.cracked_bauxite_slurry=Cracked Bauxite Slurry +gregtech.material.bauxite_sludge=Bauxite Sludge +gregtech.material.decalcified_bauxite_sludge=Decalcified Bauxite Sludge +gregtech.material.bauxite_slag=Bauxite Slag # Second Degree Materials @@ -2347,6 +2419,17 @@ tile.treated_wood_fence.name=Treated Wood Fence tile.rubber_wood_fence_gate.name=Rubber Wood Fence Gate tile.treated_wood_fence_gate.name=Treated Wood Fence Gate +tile.gt_explosive.breaking_tooltip=Primes explosion when mined, sneak mine to pick back up +tile.gt_explosive.lighting_tooltip=Cannot be lit with Redstone + +tile.powderbarrel.name=Powderbarrel +tile.powderbarrel.drops_tooltip=Slightly larger than TNT, drops all destroyed Blocks as Items +entity.Powderbarrel.name=Powderbarrel + +tile.itnt.name=Industrial TNT +tile.itnt.drops_tooltip=Much larger than TNT, drops all destroyed Blocks as Items +entity.ITNT.name=Industrial TNT + tile.brittle_charcoal.name=Brittle Charcoal tile.brittle_charcoal.tooltip.1=Produced by the Charcoal Pile Igniter. tile.brittle_charcoal.tooltip.2=Mine this to get Charcoal. @@ -2405,6 +2488,13 @@ behavior.tricorder.debug_machine_invalid_null=invalid! MetaTileEntity == null! behavior.tricorder.debug_cpu_load=Average CPU load of ~%sns over %s ticks with worst time of %sns. behavior.tricorder.debug_cpu_load_seconds=This is %s seconds. behavior.tricorder.debug_lag_count=Caused %s Lag Spike Warnings (anything taking longer than %sms) on the Server. +behavior.tricorder.mte_owner=Owner: %s +behavior.tricorder.mte_owner_offline=Owner is Offline or Offworld! +behavior.tricorder.mte_owner_null=This wasn't placed by a player! +behavior.tricorder.quantum_controller.usage=Using %s EU/t (%s) +behavior.tricorder.quantum_controller.connected_items=Connected item storages: %s +behavior.tricorder.quantum_controller.connected_fluids=Connected fluid storages: %s +behavior.tricorder.quantum_storage.usage=Contributing %s EU/t to Quantum Controller metaitem.item_magnet.lv.name=Low Voltage Item Magnet metaitem.item_magnet.hv.name=High Voltage Item Magnet @@ -4089,6 +4179,8 @@ gregtech.machine.battery_buffer.max.16.name=Maximum Voltage 16x Battery Buffer gregtech.battery_buffer.average_input=Average input: %s EU/t gregtech.battery_buffer.average_output=Average output: %s EU/t +gregtech.battery_buffer.average_input.top=Input: %s +gregtech.battery_buffer.average_output.top=Output: %s # Transformers gregtech.machine.transformer.description=Transforms Energy between voltage tiers @@ -4279,6 +4371,7 @@ gregtech.machine.alarm.tooltip=Plays a Sound when given a Redstone signal #Quantum Chests gregtech.machine.quantum_chest.tooltip=Better than Storage Drawers +gregtech.machine.super_chest.ulv.name=Primitive Chest I gregtech.machine.super_chest.lv.name=Super Chest I gregtech.machine.super_chest.mv.name=Super Chest II gregtech.machine.super_chest.hv.name=Super Chest III @@ -4294,6 +4387,7 @@ gregtech.machine.quantum_chest.items_stored=Item Amount: #Quantum Tanks gregtech.machine.quantum_tank.tooltip=Compact place to store all your fluids gregtech.machine.quantum_tank.tooltip.voiding_enabled=Excess Fluid Voiding §aEnabled +gregtech.machine.super_tank.ulv.name=Primitive Tank I gregtech.machine.super_tank.lv.name=Super Tank I gregtech.machine.super_tank.mv.name=Super Tank II gregtech.machine.super_tank.hv.name=Super Tank III @@ -4305,6 +4399,16 @@ gregtech.machine.quantum_tank.zpm.name=Quantum Tank III gregtech.machine.quantum_tank.uv.name=Quantum Tank IV gregtech.machine.quantum_tank.uhv.name=Quantum Tank V +#Quantum Storage Controller +gregtech.machine.quantum_storage_controller.name=Quantum Storage Controller +gregtech.machine.quantum_storage_controller.tooltip=Heart of the Quantum Storage Network/nConnect Energy Hatches to power the Quantum Storage Network +gregtech.machine.quantum_storage_proxy.name=Quantum Storage Proxy +gregtech.machine.quantum_storage_proxy.tooltip=Proxies the Quantum Storage Network's inventory +gregtech.machine.quantum_storage_extender.name=Quantum Storage Extender +gregtech.machine.quantum_storage_extender.tooltip=Extends the Quantum Storage Network to other chests/tanks +gregtech.machine.quantum_storage.connected=Connected to Quantum Controller at [%d, %d, %d]/n/nClick to highlight the controller +gregtech.machine.quantum_storage.disconnected=Not Connected + #Buffers gregtech.machine.buffer.tooltip=A Small Buffer to store Items and Fluids gregtech.machine.buffer.lv.name=Basic Buffer @@ -4785,6 +4889,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. @@ -4818,6 +4923,9 @@ gregtech.machine.active_transformer.tooltip3=Can transmit power at incredible di gregtech.machine.active_transformer.tooltip3.5= Lasers§7. gregtech.multiblock.active_transformer.description=The Active Transformer is a multiblock structure that can accept any number or tier of Energy Hatches, and transform them into any number or tier of Dynamo Hatches. They can be chained with Laser Source and Target Hatches, allowing long distance power transportation without any losses. Lasers must be in a straight line, otherwise they will not send energy. gregtech.machine.active_transformer.routing=Routing. +gregtech.multiblock.active_transformer.max_in=Max Input: %s +gregtech.multiblock.active_transformer.max_out=Max Output: %s +gregtech.multiblock.active_transformer.average_io=Average I/O: %s gregtech.machine.research_station.name=Research Station gregtech.machine.research_station.tooltip.1=More than just a Multiblock Scanner @@ -5242,15 +5350,35 @@ gregtech.machine.laser_hatch.tooltip2=§cLaser Cables must be in a straight line gregtech.machine.fluid_tank.max_multiblock=Max Multiblock Size: %,dx%,dx%,d gregtech.machine.fluid_tank.fluid=Contains %s L of %s -gregtech.machine.me_export_fluid_hatch.name=ME Output Hatch +# ME Parts +gregtech.machine.me_import_item_bus.name=ME Input Bus +gregtech.machine.me.item_import.tooltip=Extracts specified items from the ME network +gregtech.machine.me_stocking_item_bus.name=ME Stocking Input Bus +gregtech.machine.me.stocking_item.tooltip=Retrieves items directly from the ME network +gregtech.machine.me.stocking_item.tooltip.2=Auto-Pull from ME mode will automatically stock the first 16 items in the ME system, updated every 5 seconds. +gregtech.machine.me_import_item_hatch.configs.tooltip=Keeps 16 item types in stock +gregtech.machine.me_import_fluid_hatch.name=ME Input Hatch +gregtech.machine.me.fluid_import.tooltip=Extracts specified fluids from ME network +gregtech.machine.me_stocking_fluid_hatch.name=ME Stocking Input Hatch +gregtech.machine.me.stocking_fluid.tooltip=Retrieves fluids directly from the ME network +gregtech.machine.me.stocking_fluid.tooltip.2=Auto-Pull from ME mode will automatically stock the first 16 fluids in the ME system, updated every 5 seconds. +gregtech.machine.me_import_fluid_hatch.configs.tooltip=Keeps 16 fluid types in stock gregtech.machine.me_export_item_bus.name=ME Output Bus -gregtech.machine.me_import_fluid_hatch.name=ME Stocking Input Hatch -gregtech.machine.me_import_item_bus.name=ME Stocking Input Bus -gregtech.machine.me.fluid_export.tooltip=Stores fluid directly into ME network. -gregtech.machine.me.item_export.tooltip=Stores item directly into ME network. -gregtech.machine.me.fluid_import.tooltip=Fetch fluids from ME network automatically. -gregtech.machine.me.item_import.tooltip=Fetch items from ME network automatically. -gregtech.machine.me.export.tooltip=It has infinite capacity before connecting to ME network. +gregtech.machine.me.item_export.tooltip=Stores items directly into the ME network +gregtech.machine.me.item_export.tooltip.2=Can cache an infinite amount of items +gregtech.machine.me_export_fluid_hatch.name=ME Output Hatch +gregtech.machine.me.fluid_export.tooltip=Stores fluids directly into the ME network +gregtech.machine.me.fluid_export.tooltip.2=Can cache an infinite amount of fluid +gregtech.machine.me.stocking_auto_pull_enabled=Auto-Pull Enabled +gregtech.machine.me.stocking_auto_pull_disabled=Auto-Pull Disabled +gregtech.machine.me.copy_paste.tooltip=Left-click with Data Stick to copy settings, right-click to apply +gregtech.machine.me.import_copy_settings=Saved settings to Data Stick +gregtech.machine.me.import_paste_settings=Applied settings from Data Stick +gregtech.machine.me.item_import.data_stick.name=§oME Input Bus Configuration Data +gregtech.machine.me.fluid_import.data_stick.name=§oME Input Hatch Configuration Data +gregtech.machine.me.extra_connections.enabled=Allow connections from all sides +gregtech.machine.me.extra_connections.disabled=Allow connection only on front face +gregtech.machine.me.extra_connections.tooltip=Right-click with wire cutters to allow connecting to AE2 on all sides # Universal tooltips gregtech.universal.tooltip.voltage_in=§aVoltage IN: §f%,d EU/t (%s§f) @@ -5310,6 +5438,7 @@ gregtech.recipe.temperature=Temperature: %,dK (%s) gregtech.recipe.explosive=Explosive: %s gregtech.recipe.eu_to_start=Energy To Start: %sEU gregtech.recipe.dimensions=Dimensions: %s +gregtech.recipe.dimensions_blocked=Blocked Dimensions: %s gregtech.recipe.cleanroom=Requires %s gregtech.recipe.cleanroom.display_name=Cleanroom gregtech.recipe.cleanroom_sterile.display_name=Sterile Cleanroom @@ -5367,6 +5496,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 @@ -5391,8 +5522,12 @@ gregtech.gui.me_network.offline=Network Status: §4Offline§r gregtech.gui.waiting_list=Sending Queue: gregtech.gui.config_slot=§fConfig Slot§r gregtech.gui.config_slot.set=§7Click to §bset/select§7 config slot.§r +gregtech.gui.config_slot.set_only=§7Click to §bset§7 config slot.§r gregtech.gui.config_slot.scroll=§7Scroll wheel to §achange§7 config amount.§r gregtech.gui.config_slot.remove=§7Right click to §4clear§7 config slot.§r +gregtech.gui.config_slot.auto_pull_managed=§4Disabled:§7 Managed by Auto-Pull +gregtech.gui.me_bus.extra_slot=Extra Slot/n§7Put extra items for recipes here, like Molds or Lenses +gregtech.gui.me_bus.auto_pull_button=Click to toggle automatic item pulling from ME gregtech.gui.alarm.radius=Radius: @@ -5646,8 +5781,10 @@ gregtech.multiblock.computation.not_enough_computation=Machine needs more comput gregtech.multiblock.power_substation.stored=Stored: %s gregtech.multiblock.power_substation.capacity=Capacity: %s gregtech.multiblock.power_substation.passive_drain=Passive Drain: %s -gregtech.multiblock.power_substation.average_io=Avg. I/O: %s -gregtech.multiblock.power_substation.average_io_hover=The average change in energy of the Power Substation's internal energy bank +gregtech.multiblock.power_substation.average_in=Avg. EU IN: %s +gregtech.multiblock.power_substation.average_out=Avg. EU OUT: %s +gregtech.multiblock.power_substation.average_in_hover=The average EU/t input into the Power Substation's internal energy bank +gregtech.multiblock.power_substation.average_out_hover=The average EU/t output from the Power Substation's internal energy bank, both passive loss and outputs gregtech.multiblock.power_substation.time_to_fill=Time to fill: %s gregtech.multiblock.power_substation.time_to_drain=Time to drain: %s gregtech.multiblock.power_substation.time_seconds=%s Seconds @@ -5680,7 +5817,7 @@ gregtech.multiblock.hpca.info_coolant_name=PCB Coolant gregtech.multiblock.hpca.info_bridging_enabled=Bridging Enabled gregtech.multiblock.hpca.info_bridging_disabled=Bridging Disabled -gregtech.command.usage=Usage: /gregtech +gregtech.command.usage=Usage: /gregtech gregtech.command.worldgen.usage=Usage: /gregtech worldgen gregtech.command.worldgen.reload.usage=Usage: /gregtech worldgen reload gregtech.command.worldgen.reload.success=Worldgen successfully reloaded from config. @@ -5707,6 +5844,12 @@ gregtech.command.copy.copied_and_click=copied to clipboard. Click to copy again gregtech.command.copy.click_to_copy=Click to copy gregtech.command.copy.copied_start=Copied [ gregtech.command.copy.copied_end=] to the clipboard +gregtech.command.datafix.usage=Usage: /gregtech datafix +gregtech.command.datafix.bqu.usage=Usage: /gregtech datafix bqu [confirm] +gregtech.command.datafix.bqu.backup=Backup your save and BQu config dir, then rerun with the 'confirm' arg +gregtech.command.datafix.bqu.start=Started Migrating BQu Quest Database... +gregtech.command.datafix.bqu.complete=Finished Migrating BQu Quest Database +gregtech.command.datafix.bqu.failed=Failed Migrating BQu Quest Database. Restore your backups! gregtech.chat.cape=§5Congrats: you just unlocked a new cape! See the Cape Selector terminal app to use it.§r @@ -6217,6 +6360,11 @@ 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 + ### Ex Nihilo Integration item.gtPebble.basalt.name=Basalt Pebble item.gtPebble.black_granite.name=Black Granite Pebble diff --git a/src/main/resources/assets/gregtech/lang/ja_jp.lang b/src/main/resources/assets/gregtech/lang/ja_jp.lang index 648aa40ec41..a1ed0f8ebbc 100644 --- a/src/main/resources/assets/gregtech/lang/ja_jp.lang +++ b/src/main/resources/assets/gregtech/lang/ja_jp.lang @@ -109,7 +109,7 @@ gregtech.top.ld_pipe_output=搬出 gregtech.top.ld_pipe_input_endpoint=搬入口: gregtech.top.ld_pipe_output_endpoint=搬出口: -gregtech.waila.energy_stored=エネルギー: %d EU / %d EU +gregtech.waila.energy_stored=エネルギー: %s EU / %s EU gregtech.waila.progress_idle=停止中 gregtech.waila.progress_tick=進捗: %d t / %d t gregtech.waila.progress_sec=進捗: %d s / %d s @@ -1538,7 +1538,8 @@ gregtech.material.palladium=パラジウム gregtech.material.phosphorus=リン gregtech.material.polonium=ポロニウム gregtech.material.platinum=プラチナ -gregtech.material.plutonium=プルトニウム239 +gregtech.material.plutonium=プルトニウム +gregtech.material.plutonium_239=プルトニウム239 gregtech.material.plutonium_241=プルトニウム241 gregtech.material.potassium=カリウム gregtech.material.praseodymium=プラセオジム @@ -1573,8 +1574,9 @@ gregtech.material.tin=錫 gregtech.material.titanium=チタン gregtech.material.tritium=三重水素 gregtech.material.tungsten=タングステン -gregtech.material.uranium=ウラン238 +gregtech.material.uranium=ウラン gregtech.material.uranium_235=ウラン235 +gregtech.material.uranium_238=ウラン238 gregtech.material.vanadium=バナジウム gregtech.material.xenon=キセノン gregtech.material.ytterbium=イッテルビウム diff --git a/src/main/resources/assets/gregtech/lang/ru_ru.lang b/src/main/resources/assets/gregtech/lang/ru_ru.lang index 6150191749e..971b6fc8d3a 100644 --- a/src/main/resources/assets/gregtech/lang/ru_ru.lang +++ b/src/main/resources/assets/gregtech/lang/ru_ru.lang @@ -39,11 +39,11 @@ enchantment.disjunction=Разъединение gregtech.machine.steam_grinder.name=Паровой измельчитель gregtech.multiblock.steam_grinder.description=Многоблочный измельчитель в паровой эпохе. Требует как минимум 14 бронзовых машинных корпусов. Может использовать только паровые люки. gregtech.multiblock.steam.low_steam=Недостаточно пара для работы! -gregtech.multiblock.steam.steam_stored=Пар: %s / %s mB +gregtech.multiblock.steam.steam_stored=Пар: %s 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_import_bus.name=Паровой входной люк +gregtech.machine.steam_export_bus.name=Паровой выходной люк gregtech.machine.steam_bus.tooltip=Не работает с электрическими многоблочными структурами gregtech.machine.steam_oven.name=Паровая мультиплавильня gregtech.multiblock.steam_oven.description=Мультиплавильня в паровой эпохе. Требует как минимум 6 бронзовых машинных корпусов. Может использовать только паровые люки. Паровой люк должен находится на нижнем слое и он может быть только один. @@ -52,7 +52,7 @@ gregtech.multiblock.steam_.duration_modifier=Работает в §f1.5x §7ра gregtech.top.working_disabled=Работа остановлена gregtech.top.energy_consumption=Использует gregtech.top.energy_production=Производит -gregtech.top.transform_up=§cПовышает§r +gregtech.top.transform_up=Повышает gregtech.top.transform_down=§aПонижает§r gregtech.top.transform_input=Вход: gregtech.top.transform_output=Выход: @@ -86,7 +86,7 @@ gregtech.top.ld_pipe_input=Ввод gregtech.top.ld_pipe_output=Вывод gregtech.top.ld_pipe_input_endpoint=Входная конечная точка: gregtech.top.ld_pipe_output_endpoint=Выходная конечная точка: -gregtech.waila.energy_stored=Энергия: %d EU / %d EU +gregtech.waila.energy_stored=Энергия: %s EU / %s EU gregtech.waila.progress_idle=Простой gregtech.waila.progress_tick=Прогресс: %d t / %d t gregtech.waila.progress_sec=Прогресс: %d s / %d s @@ -102,7 +102,7 @@ gregtech.multiblock.extreme_combustion_engine.description=Улучшенный gregtech.multiblock.distillation_tower.description=Ректификационная колонна - представляет собой многоблочную структуру, используемую для перегонки различных типов нефти и некоторых их побочных продуктов. gregtech.multiblock.electric_blast_furnace.description=Электрическая доменная печь (ЭДП) - это многоблочная структура, используемая для выплавки сплавов, приготовления металлов и переработки руд. Она необходима для получения высокоуровневых сплавов и металлов, таких как алюминий, нержавеющая сталь и титан, сплав наквада. gregtech.multiblock.multi_furnace.description=Мульти-плавильный завод - это многоблочная структура, используемая для одновременной выплавки большого количества изделий. Различные уровни катушек обеспечивают увеличение скорости и повышение энергоэффективности. 32 - это базовое значение предметов, выплавляемых за одну операцию, и его можно умножить, используя катушки более высокого уровня. -gregtech.multiblock.large_boiler.description=Большой котел - представляет собой многоблочную структуру, которая генерируют пар из источника энергии и воды. Обычно либо твердое топливо, либо горючая жидкость высокой плотности действует как источник энергии для большого котла. Уровни отличаются только количеством вырабатываемого пара. +gregtech.multiblock.large_boiler.description=Большой котел - представляет собой многоблочную структуру, которая генерируют пар из источника энергии и воды. Обычно либо твердое топливо, либо горючая жидкость высокой плотности действует как источник энергии для большого котла. Уровни отличаются только кол-вом вырабатываемого пара. gregtech.multiblock.large_turbine.description=Большая турбина - это многоблочная структура, которые вырабатывают энергию из пара, газов и плазмы, вращая ротор турбины. Выход энергии зависит от КПД ротора и текущей скорости турбины. gregtech.multiblock.assembly_line.description=Сборочная линия представляет собой большую многоблочную конструкцию, состоящую из 5-16 «кусочков». Теоретически это большая сборочная машина, используемая для создания продвинутых компонентов для крафта. gregtech.multiblock.fusion_reactor.luv.description=Термоядерный реактор модель 1 - это большая многоблочная структура использующаяся для термоядерного синтеза двух элементов в один. Может использовать LuV+ энергетические разъемы. За каждый энергетический разъём, внутренний буфер увеличивается на 10млн. EU, максимум энергии для старта 160млн. EU. @@ -110,17 +110,17 @@ gregtech.multiblock.fusion_reactor.zpm.description=Термоядерный ре gregtech.multiblock.fusion_reactor.uv.description=Термоядерный реактор модель 3 - это большая многоблочная структура использующаяся для термоядерного синтеза двух элементов в один. Может использовать UV+ энергетические разъемы. За каждый энергетический разъём, внутренний буфер увеличивается на 40млн. EU, максимум энергии для старта 640млн. EU. gregtech.multiblock.fusion_reactor.heat=Нагрев: %d gregtech.multiblock.large_chemical_reactor.description=Многоблочная версия химического реактора выполняющий операции в больших объёмах с удвоенной эффективностью. Ускорение умножает скорость и энергию на 4. Для мультиблочной структуры требуется ровно 1 блок купроникелевой катушки, который должен быть размещен рядом с корпусом ПТФЭ трубы, расположенным в центре. -gregtech.multiblock.primitive_water_pump.description=Примитивная водяная помпа — это многоблочная структура до Паровой Эпохи, который собирает воду раз в секунду, в зависимости от биома, в котором он находится. Он может использовать насос, выходной люк ULV или LV, увеличивая количество воды от уровня. Выполняется по формуле: Коэффициент биома * Множитель люка. -gregtech.multiblock.primitive_water_pump.extra1=Коэффициент биома:/n Океан, Река: 1000 л/с/н Болото: 800 л/с/н Джунгли: 350 л/с/н Снежный: 300 л/с/н Равнины, Лес: 250 л/с/н Тайга : 175 л/с/н Пляж: 170 л/с/н Другое: 100 л/с +gregtech.multiblock.primitive_water_pump.description=Примитивная водяная помпа — это многоблочная структура до Паровой Эпохи, который собирает воду раз в секунду, в зависимости от биома, в котором он находится. Он может использовать насос, выходной люк ULV или LV, увеличивая кол-во воды от уровня. Выполняется по формуле: Коэф. биома * Множитель люка. +gregtech.multiblock.primitive_water_pump.extra1=Коэф. биома:/n Океан, Река: 1000 Л/с/n Болото: 800 Л/с/n Джунгли: 350 Л/с/n Снежный: 300 Л/с/н Равнины, Лес: 250 Л/с/n Тайга : 175 Л/с/n Пляж: 170 Л/с/n Другое: 100 Л/с gregtech.multiblock.primitive_water_pump.extra2=Множители люка:/n Люк насоса: 1x/n Выходной люк ULV: 2x/n LV Выходной люк: 4xn/nВо время дождя в биомах работы насоса добыча воды будет увеличена на 50%%. gregtech.multiblock.processing_array.description=Массив машин объединяет до 16 одноблочных машин в одном многоблоке. gregtech.multiblock.advanced_processing_array.description=Массив машин объединяет до 64 одноблочных машин в одном многоблоке. item.invalid.name=Недопустимый предмет fluid.empty=Пусто -gregtech.tooltip.hold_shift=Зажмите SHIFT для дополнительной информации -gregtech.tooltip.hold_ctrl=Нажмите CTRL, чтобы увидеть больше информации -gregtech.tooltip.fluid_pipe_hold_shift=Зажмите SHIFT что-бы посмотреть Информацию о Хранимой Жидкости -gregtech.tooltip.tool_fluid_hold_shift=Зажмите SHIFT что-бы посмотреть Информацию о Инструменте или Хранимой Жидкости +gregtech.tooltip.hold_shift=Зажмите SHIFT для Информации +gregtech.tooltip.hold_ctrl=Зажмите CTRL для Информации +gregtech.tooltip.fluid_pipe_hold_shift=Зажмите SHIFT для Информации о Жидкости +gregtech.tooltip.tool_fluid_hold_shift=Зажмите SHIFT для Информации о Инструменте или Жидкости metaitem.generic.fluid_container.tooltip=%d/%dЛ %s metaitem.generic.electric_item.tooltip=%d/%d EU - Уровень §e%d metaitem.electric.discharge_mode.enabled=§eРежим разрядки Включен @@ -130,19 +130,19 @@ metaitem.dust.tooltip.purify=Бросьте в котел, чтобы получ metaitem.crushed.tooltip.purify=Бросьте в котел, чтобы получить очищенную руду metaitem.int_circuit.configuration=§aКонфигурация: §f%d§7 metaitem.credit.copper.name=Медный кредит -metaitem.credit.copper.tooltip=0,125 кредита +metaitem.credit.copper.tooltip=0,125 Кредита metaitem.credit.cupronickel.name=Купроникелевый кредит -metaitem.credit.cupronickel.tooltip=1 кредит +metaitem.credit.cupronickel.tooltip=1 Кредит metaitem.credit.silver.name=Серебряный кредит -metaitem.credit.silver.tooltip=8 кредитов +metaitem.credit.silver.tooltip=8 Кредитов metaitem.credit.gold.name=Золотой кредит -metaitem.credit.gold.tooltip=64 кредита +metaitem.credit.gold.tooltip=64 Кредита metaitem.credit.platinum.name=Платиновый кредит -metaitem.credit.platinum.tooltip=512 кредитов +metaitem.credit.platinum.tooltip=512 Кредитов metaitem.credit.osmium.name=Осмиевый кредит -metaitem.credit.osmium.tooltip=4096 кредитов +metaitem.credit.osmium.tooltip=4096 Кредитов metaitem.credit.naquadah.name=Наквадовый кредит -metaitem.credit.naquadah.tooltip=32768 кредитов +metaitem.credit.naquadah.tooltip=32768 Кредитов metaitem.credit.neutronium.name=Нейтрониевый кредит metaitem.credit.neutronium.tooltip=262144 Кредитов metaitem.coin.gold.ancient.name=Древняя золотая монета @@ -164,7 +164,7 @@ metaitem.nano_saber.tooltip=Ryujin no ken wo kurae! metaitem.shape.mold.plate.name=Форма (Пластина) metaitem.shape.mold.plate.tooltip=Форма для изготовления пластин metaitem.shape.mold.casing.name=Форма (Корпус) -metaitem.shape.mold.casing.tooltip=Форма для изготовления оболочек +metaitem.shape.mold.casing.tooltip=Форма для изготовления корпусов metaitem.shape.mold.gear.name=Форма (Шестерня) metaitem.shape.mold.gear.tooltip=Форма для изготовления шестерней metaitem.shape.mold.credit.name=Форма (Чеканка) @@ -177,7 +177,7 @@ metaitem.shape.mold.ball.name=Форма (Шар) metaitem.shape.mold.ball.tooltip=Форма для изготовления шариков metaitem.shape.mold.block.name=Форма (Блок) metaitem.shape.mold.block.tooltip=Форма для изготовления блоков -metaitem.shape.mold.nugget.name=Форма (Самородки) +metaitem.shape.mold.nugget.name=Форма (Самородок) metaitem.shape.mold.nugget.tooltip=Форма для изготовления самородков metaitem.shape.mold.cylinder.name=Форма (Цилиндр) metaitem.shape.mold.cylinder.tooltip=Форма для формирования цилиндров @@ -186,7 +186,7 @@ metaitem.shape.mold.anvil.tooltip=Форма для формирования н metaitem.shape.mold.name.name=Форма (Имя) metaitem.shape.mold.name.tooltip=Форма для наименования предметов (переименуйте форму с помощью наковальни) metaitem.shape.mold.gear.small.name=Форма (Малая шестерня) -metaitem.shape.mold.gear.small.tooltip=Форма для изготовления маленьких зубчатых колес +metaitem.shape.mold.gear.small.tooltip=Форма для изготовления маленьких шестерней metaitem.shape.mold.rotor.name=Форма (Ротор) metaitem.shape.mold.rotor.tooltip=Форма для изготовления роторов metaitem.shape.extruder.plate.name=Форма экструдера (Пластина) @@ -197,16 +197,16 @@ metaitem.shape.extruder.bolt.name=Форма экструдера (Болт) metaitem.shape.extruder.bolt.tooltip=Форма экструдера для изготовления болтов metaitem.shape.extruder.ring.name=Форма экструдера (Кольцо) metaitem.shape.extruder.ring.tooltip=Форма экструдера для изготовления колец -metaitem.shape.extruder.cell.name=Форма экструдера (Ячейка) -metaitem.shape.extruder.cell.tooltip=Форма экструдера для изготовления клеток +metaitem.shape.extruder.cell.name=Форма экструдера (Капсула) +metaitem.shape.extruder.cell.tooltip=Форма экструдера для изготовления капсул metaitem.shape.extruder.ingot.name=Форма экструдера (Слиток) -metaitem.shape.extruder.ingot.tooltip=Форма экструдера, подожди, мы не можем просто использовать печь? +metaitem.shape.extruder.ingot.tooltip=Форма экструдера, подожди, может просто использовать печь? metaitem.shape.extruder.wire.name=Форма экструдера (Проволока) metaitem.shape.extruder.wire.tooltip=Форма экструдера для изготовления проводов metaitem.shape.extruder.casing.name=Форма экструдера (Корпус) -metaitem.shape.extruder.casing.tooltip=Форма экструдера для изготовления оболочек -metaitem.shape.extruder.pipe.tiny.name=Форма экструдера (Трубка) -metaitem.shape.extruder.pipe.tiny.tooltip=Форма экструдера для изготовления трубок +metaitem.shape.extruder.casing.tooltip=Форма экструдера для изготовления корпусов +metaitem.shape.extruder.pipe.tiny.name=Форма экструдера (Очень маленькая труба) +metaitem.shape.extruder.pipe.tiny.tooltip=Форма экструдера для изготовления очень маленьких труб metaitem.shape.extruder.pipe.small.name=Форма экструдера (Малая труба) metaitem.shape.extruder.pipe.small.tooltip=Форма экструдера для изготовления небольших труб metaitem.shape.extruder.pipe.normal.name=Форма экструдера (Средняя труба) @@ -234,15 +234,15 @@ metaitem.shape.extruder.file.tooltip=Форма экструдера для из metaitem.shape.extruder.saw.name=Форма экструдера (Пильный диск) metaitem.shape.extruder.saw.tooltip=Форма экструдера для изготовления пил metaitem.shape.extruder.gear.name=Форма экструдера (Шестерня) -metaitem.shape.extruder.gear.tooltip=Форма экструдера для изготовления зубчатых колес +metaitem.shape.extruder.gear.tooltip=Форма экструдера для изготовления шестерней metaitem.shape.extruder.bottle.name=Форма экструдера (Бутылка) metaitem.shape.extruder.bottle.tooltip=Форма экструдера для изготовления бутылок metaitem.shape.extruder.gear_small.name=Форма экструдера (маленькая шестеренка) -metaitem.shape.extruder.gear_small.tooltip=Форма экструдера для производства маленьких шестеренок +metaitem.shape.extruder.gear_small.tooltip=Форма экструдера для производства маленьких шестереней metaitem.shape.extruder.foil.name=Форма экструдера (Фольга) metaitem.shape.extruder.foil.tooltip=Форма экструдера для производства фольги из неметаллов metaitem.shape.extruder.rod_long.name=Форма экструдера (Длинный прут) -metaitem.shape.extruder.rod_long.tooltip=Форма экструдера для производства длинных прутов +metaitem.shape.extruder.rod_long.tooltip=Форма экструдера для производства прутьев metaitem.shape.extruder.rotor.name=Форма экструдера (Ротор) metaitem.shape.extruder.rotor.tooltip=Форма экструдера для производства роторов metaitem.spray.empty.name=Баллончик (Пустой) @@ -386,7 +386,7 @@ metaitem.fluid.regulator.iv.name=Регулятор жидкости (§1IV§r) metaitem.fluid.regulator.luv.name=Регулятор жидкости (§dLuV§r) metaitem.fluid.regulator.zpm.name=Регулятор жидкости (§fZPM§r) metaitem.fluid.regulator.uv.name=Регулятор жидкости (§3UV§r) -metaitem.fluid.regulator.tooltip=Ограничивает передачу §fЖидкостей§7 заданным количеством как §fУлучшение машины§7. +metaitem.fluid.regulator.tooltip=Ограничивает передачу §fЖидкостей§7 заданным кол-вом как §fУлучшение машины§7. metaitem.conveyor.module.lv.name=Конвейерный модуль (§7LV§r) metaitem.conveyor.module.mv.name=Конвейерный модуль (§bMV§r) metaitem.conveyor.module.hv.name=Конвейерный модуль (§6HV§r) @@ -427,7 +427,7 @@ metaitem.robot.arm.uev.name=Роботизированный манипулят metaitem.robot.arm.uiv.name=Роботизированный манипулятор (§2UIV§r) metaitem.robot.arm.uxv.name=Роботизированный манипулятор (§eUXV§r) metaitem.robot.arm.opv.name=Роботизированный манипулятор (§9OpV§r) -metaitem.robot.arm.tooltip=Ограничивает передачу §fПредметов§7 заданным количеством как §fУлучшение механизма§7. +metaitem.robot.arm.tooltip=Ограничивает передачу §fПредметов§7 заданным кол-вом как §fУлучшение механизма§7. metaitem.field.generator.lv.name=Генератор поля (§7LV§r) metaitem.field.generator.mv.name=Генератор поля (§bMV§r) metaitem.field.generator.hv.name=Генератор поля (§6HV§r) @@ -511,7 +511,7 @@ metaitem.wafer.naquadah.name=Плаcтина легированная наква metaitem.wafer.naquadah.tooltip=Необработанная схема metaitem.wafer.neutronium.name=Пластина легированная нейтронием metaitem.wafer.neutronium.tooltip=Необработанная схема -metaitem.board.coated.name=Прорезиненая подложка +metaitem.board.coated.name=Прорезиненная подложка metaitem.board.coated.tooltip=Подложка с покрытием metaitem.board.phenolic.name=Профеноленая подложка metaitem.board.phenolic.tooltip=Хорошая подложка @@ -521,7 +521,7 @@ metaitem.board.epoxy.name=Эпоксидная подложка metaitem.board.epoxy.tooltip=Продвинутая подложка metaitem.board.fiber_reinforced.name=Укрепленная эпоксидная подложка metaitem.board.fiber_reinforced.tooltip=Улучшенная подложка -metaitem.board.multilayer.fiber_reinforced.name=Многослойная текстолитовая печатная плата +metaitem.board.multilayer.fiber_reinforced.name=Многослойная текстолитовая подложка metaitem.board.multilayer.fiber_reinforced.tooltip=Превосходная подложка metaitem.board.wetware.name=Питательная подложка metaitem.board.wetware.tooltip=Подложка, которая хранит жизнь @@ -572,9 +572,9 @@ metaitem.component.advanced_smd.resistor.name=Улучшенный SMD рези metaitem.component.advanced_smd.resistor.tooltip=Улучшенный электронный компонент metaitem.component.advanced_smd.inductor.name=Улучшенный SMD индуктор metaitem.component.advanced_smd.inductor.tooltip=Улучшенный электронный компонент -metaitem.wafer.highly_advanced_system_on_chip.name=Пластина HASoC -metaitem.wafer.highly_advanced_system_on_chip.tooltip=Необработанная высоковольтажная микросхема -metaitem.wafer.advanced_system_on_chip.name=Пластина ASoC +metaitem.wafer.highly_advanced_system_on_chip.name=Пластина ОУСнК +metaitem.wafer.highly_advanced_system_on_chip.tooltip=Необработанная очень продвинутая микросхема +metaitem.wafer.advanced_system_on_chip.name=Пластина УСнК metaitem.wafer.advanced_system_on_chip.tooltip=Необработанная продвинутая микросхема metaitem.wafer.integrated_logic_circuit.name=Пластина IC metaitem.wafer.integrated_logic_circuit.tooltip=Необработанная интегральная микросхема @@ -592,17 +592,17 @@ metaitem.wafer.low_power_integrated_circuit.name=Пластина LPIC metaitem.wafer.low_power_integrated_circuit.tooltip=Необработанная низковольтажная микросхема metaitem.wafer.power_integrated_circuit.name=Пластина PIC metaitem.wafer.power_integrated_circuit.tooltip=Необработанная силовая микросхема -metaitem.wafer.nano_central_processing_unit.name=Пластина Нано-процессора +metaitem.wafer.nano_central_processing_unit.name=Пластина нано-процессора metaitem.wafer.nano_central_processing_unit.tooltip=Необработанная нано-микросхема metaitem.wafer.nor_memory_chip.name=Пластина NOR-памяти metaitem.wafer.nor_memory_chip.tooltip=Необработанная логическая схема -metaitem.wafer.qbit_central_processing_unit.name=Пластина Qubit процессора -metaitem.wafer.qbit_central_processing_unit.tooltip=Необработанная Qubit микросхема +metaitem.wafer.qbit_central_processing_unit.name=Пластина кубитного процессора +metaitem.wafer.qbit_central_processing_unit.tooltip=Необработанная кубитная микросхема metaitem.wafer.random_access_memory.name=Пластина RAM metaitem.wafer.random_access_memory.tooltip=Необработанная память -metaitem.wafer.system_on_chip.name=Пластина SoC +metaitem.wafer.system_on_chip.name=Пластина СнК metaitem.wafer.system_on_chip.tooltip=Необработанная обычная микросхема -metaitem.wafer.simple_system_on_chip.name=Простая пластина SoC +metaitem.wafer.simple_system_on_chip.name=Простая пластина СнК metaitem.wafer.simple_system_on_chip.tooltip=Необработанная простая микросхема metaitem.engraved.crystal_chip.name=Гравированный кристальный чип metaitem.engraved.crystal_chip.tooltip=Требуется для микросхем @@ -613,12 +613,12 @@ metaitem.crystal.raw_chip.tooltip=Компонент необработанно metaitem.engraved.lapotron_chip.name=Гравированный лапотронный кристальный чип metaitem.crystal.central_processing_unit.name=Кристалл CPU metaitem.crystal.central_processing_unit.tooltip=Кристалл блока обработки -metaitem.crystal.system_on_chip.name=Кристальный SoC -metaitem.crystal.system_on_chip.tooltip=Кристаллическая система на чипе -metaitem.plate.advanced_system_on_chip.name=ASoC -metaitem.plate.advanced_system_on_chip.tooltip=Улучшенная система в чипе -metaitem.plate.highly_advanced_system_on_chip.name=HASoC -metaitem.plate.highly_advanced_system_on_chip.tooltip=Очень улучшенная система в чипе +metaitem.crystal.system_on_chip.name=Кристальный СнК +metaitem.crystal.system_on_chip.tooltip=Кристаллическая система на кристалле +metaitem.plate.advanced_system_on_chip.name=УСнК +metaitem.plate.advanced_system_on_chip.tooltip=Улучшенная система на кристалле +metaitem.plate.highly_advanced_system_on_chip.name=ОУСнК +metaitem.plate.highly_advanced_system_on_chip.tooltip=Очень улучшенная система на кристалле metaitem.plate.integrated_logic_circuit.name=Интегральная схема metaitem.plate.integrated_logic_circuit.tooltip=Интегральная логическая схема metaitem.plate.central_processing_unit.name=Центральный процессор @@ -643,10 +643,10 @@ metaitem.plate.qbit_central_processing_unit.name=Кубитный процесс metaitem.plate.qbit_central_processing_unit.tooltip=Кубитный центральный процессор metaitem.plate.random_access_memory.name=ОЗУ metaitem.plate.random_access_memory.tooltip=Оперативная память -metaitem.plate.system_on_chip.name=SoC -metaitem.plate.system_on_chip.tooltip=Система в чипе -metaitem.plate.simple_system_on_chip.name=Обычная SoC -metaitem.plate.simple_system_on_chip.tooltip=Простая система на чипе +metaitem.plate.system_on_chip.name=СнК +metaitem.plate.system_on_chip.tooltip=Система на кристалле +metaitem.plate.simple_system_on_chip.name=Обычная СнК +metaitem.plate.simple_system_on_chip.tooltip=Простая система на кристалле # T1: Electronic @@ -667,7 +667,7 @@ metaitem.circuit.advanced_integrated.tooltip=Меньше и мощнее/n§6HV metaitem.circuit.nand_chip.name=NAND чип metaitem.circuit.nand_chip.tooltip=Превосходная простая микросхема/n§6ULV уровень metaitem.circuit.microprocessor.name=Микропроцессор -metaitem.circuit.microprocessor.tooltip=Улучшенная обычная микросхема/n§eLV уровень +metaitem.circuit.microprocessor.tooltip=Совершенная обычная микросхема/n§eLV уровень # T3: Processor metaitem.circuit.processor.name=Интегральный микропроцессор @@ -759,11 +759,11 @@ metaitem.cover.fluid.detector.tooltip=Выдает §fЗаполнение жи metaitem.cover.fluid.detector.advanced.name=Улучшенный детектор жидкости (Улучшение) metaitem.cover.fluid.detector.advanced.tooltip=Позволяет §fRS-триггеру§7 управлять §fСостоянием Хранилища жидкости§7 как редстоунов, в качестве §fКрышки§7. metaitem.cover.item.detector.name=Детектор предметов (Улучшение) -metaitem.cover.item.detector.tooltip=Выдает §fКоличество предметов§7 Сигналом Красного камня как §fУлучшение механизма§7. +metaitem.cover.item.detector.tooltip=Выдает §fКол-во предметов§7 Сигналом Красного камня как §fУлучшение механизма§7. metaitem.cover.item.detector.advanced.name=Улучшенный детектор предметов (Улучшение) metaitem.cover.item.detector.advanced.tooltip=Позволяет §fRS-триггеру§7 управлять §fСостоянием Хранилища предметов§7 как редстоунов, в качестве §fКрышки§7. metaitem.cover.energy.detector.name=Детектор энергии (Улучшение) -metaitem.cover.energy.detector.tooltip=Выдает §fКоличество энергии§7 Сигналом Красного камня как §fУлучшение механизма§7. +metaitem.cover.energy.detector.tooltip=Выдает §fКол-во энергии§7 Сигналом Красного камня как §fУлучшение механизма§7. metaitem.cover.energy.detector.advanced.name=Улучшенный детектор энергии (Улучшение) metaitem.cover.energy.detector.advanced.tooltip=Даёт §fRS-триггерный контроль за Уровнем энергии§7 Сигналом Красного камня как §fУлучшение механизма§7. metaitem.cover.fluid.voiding.name=Удаление жидкостей (Улучшение) @@ -777,7 +777,7 @@ metaitem.cover.item.voiding.advanced.tooltip=Удаляет §fПредметы metaitem.cover.storage.name=Хранилище (Улучшение) metaitem.cover.storage.tooltip=Небольшое хранилище для хранения мелочей metaitem.cover.maintenance.detector.name=Детектор неисправностей (Улучшение) -metaitem.cover.maintenance.detector.tooltip=Выдает §Количество Неисправностей§7 Сигналом Красного камня как §fУлучшение механизма§7. +metaitem.cover.maintenance.detector.tooltip=Выдает §Кол-во Неисправностей§7 Сигналом Красного камня как §fУлучшение механизма§7. metaitem.cover.facade.name=Фасад (%s) metaitem.cover.facade.tooltip=Декоративный элемент. metaitem.cover.screen.name=Компьютерный монитор (Улучшение) @@ -827,7 +827,7 @@ metaitem.plant_ball.name=Комок биомассы metaitem.tool_parts_box.name=Ящик для инструментов metaitem.tool_parts_box.tooltip=Для хранения инструментов/nЩелкните правой кнопкой, чтобы открыть metaitem.foam_sprayer.name=Пенный распылитель -metaitem.foam_sprayer.tooltip=Распыляет строительную пену/nЩелкните правой кнопкой, чтобы запенить соединенные рамки./nИспользуйте металл для создания армированного бетона/nПена может быть цветной +metaitem.foam_sprayer.tooltip=Распыляет строительную пену/nЩелкните правой кнопкой, чтобы запенить соединенные Каркасы./nИспользуйте металл для создания армированного бетона/nПена может быть цветной metaitem.energium_dust.name=Энергетическая пыль metaitem.compressed.clay.name=Сжатая глина metaitem.compressed.fireclay.name=Сжатая шамотная глина @@ -937,7 +937,7 @@ item.gt.tool.harvest_level.3=§bАлмаз item.gt.tool.harvest_level.4=§dУльтимет item.gt.tool.harvest_level.5=§9Дураний item.gt.tool.harvest_level.6=§cНейтроний -item.gt.tool.tooltip.repair_info=Удерживайте SHIFT для информации о Ремонте +item.gt.tool.tooltip.repair_info=Зажмите SHIFT для Информации о Ремонте item.gt.tool.tooltip.repair_material=Чинится: §a%s item.gt.tool.aoe.rows=Рядов item.gt.tool.aoe.columns=Столбцов @@ -1051,14 +1051,14 @@ metaitem.nan.certificate.tooltip=Вызов принят! metaitem.fertilizer.name=Удобрение metaitem.blacklight.name=Черный свет metaitem.blacklight.tooltip=Источник длинноволнового §dультрафиолетового§7 излучения -gui.widget.incrementButton.default_tooltip=Удерживайте Shift, Ctrl или оба, чтобы изменить количество +gui.widget.incrementButton.default_tooltip=Удерживайте Shift, Ctrl или оба, чтобы изменить кол-во gui.widget.recipeProgressWidget.default_tooltip=Показать рецепт gregtech.recipe_memory_widget.tooltip.2=§7Нажмите Shift, чтобы заблокировать/разблокировать этот рецепт gregtech.recipe_memory_widget.tooltip.1=§7Щелкните левой кнопкой мыши, чтобы автоматически добавить этот рецепт в сетку крафта cover.filter.blacklist.disabled=Белый список cover.filter.blacklist.enabled=Черный список cover.ore_dictionary_filter.title=Фильтр по словарю руд -cover.ore_dictionary_filter.info=§bПринимает сложные выражения/n§6a & b§r = AND/n§6a | b§r = OR/n§6a ^ b§r = XOR/n§6! abc§r = NOT/n§6( abc )§r для группировки/n§6*§r для подстановочного знака/n§6?§r для любого 1 символа/n§6()§r для пустого места (включая предметы из словаря руд)/n§6$c§r для начала выражения с учетов регистра/n§bПример:/n§6dust*Gold | (plate* & !*Double*)/nПодходит для всей золотой пыли всех размеров или всех пластин, но не для двойных пластин +cover.ore_dictionary_filter.info=§bПринимает сложные выражения/n§6a & b§r = AND/n§6a | b§r = OR/n§6a ^ b§r = XOR/n§6! abc§r = NOT/n§6( abc )§r для группировки/n§6*§r для подстановочного знака/n§6?§r для любого 1 символа/n§6()§r для пустого места (включая предметы из словаря руд)/n§bПример:/n§6dust*Gold | (plate* & !*Double*)/nПодходит для всей золотой пыли всех размеров или всех пластин, но не для двойных пластин cover.ore_dictionary_filter.test_slot.info=Вставьте элемент, чтобы проверить, соответствует ли он выражению фильтра cover.ore_dictionary_filter.test_slot.matches=§a* %s cover.ore_dictionary_filter.test_slot.matches_not=§c* %s @@ -1070,7 +1070,7 @@ cover.ore_dictionary_filter.status.warn=§7%s предупреждение(я) cover.ore_dictionary_filter.status.no_issues=§aНет проблем cover.ore_dictionary_filter.status.explain=Объяснение фильтра руды: cover.fluid_filter.title=Жидкостный фильтр -cover.fluid_filter.config_amount=Колесо прокрутки вверх увеличивает количество, вниз уменьшает./nShift[§6x10§r],Ctrl[§ex100§r],Shift+Ctrl[§ax1000§r]/nПравый клик увеличивает количество, левый уменьшает./nУдерживайте Shift, чтобы удвоить/уполовинить./nЩелкните средней кнопкой, чтобы очистить +cover.fluid_filter.config_amount=Колесо прокрутки вверх увеличивает количество, вниз уменьшает./nShift[§6x10§r],Ctrl[§ex100§r],Shift+Ctrl[§ax1000§r]/nПравый клик увеличивает кол-во, левый уменьшает./nУдерживайте Shift, чтобы удвоить/уполовинить./nЩелкните средней кнопкой, чтобы очистить cover.fluid_filter.mode.filter_fill=Фильтрует при наполнении cover.fluid_filter.mode.filter_drain=Фильтрует при сливе cover.fluid_filter.mode.filter_both=Фильтрует при сливе и наполнении @@ -1098,7 +1098,7 @@ cover.smart_item_filter.title=Умный предметный фильтр cover.smart_item_filter.filtering_mode.electrolyzer=Электролизер cover.smart_item_filter.filtering_mode.centrifuge=Центрифуга cover.smart_item_filter.filtering_mode.sifter=Просеиватель -cover.smart_item_filter.filtering_mode.description=Выберите механизм для которой будут/не будут фильтроваться предметы для роботической руки. +cover.smart_item_filter.filtering_mode.description=Выберите машину, которую этот Умный фильтр будет использовать для фильтрации./nОн автоматически отберет нужное кол-во предметов для роб. манипулятора. cover.conveyor.title=Настройки улучшения конвейера (%s) cover.conveyor.transfer_rate=§7предметов/с cover.conveyor.mode.export=Режим: Экспорт @@ -1115,7 +1115,7 @@ cover.conveyor.item_filter.title=Фильтр предметов cover.conveyor.ore_dictionary.title=Название по словарю руд cover.conveyor.ore_dictionary.title2=(используйте * как подстановочный знак) cover.robotic_arm.title=Настройки роб. манипулятора (%s) -cover.robotic_arm.transfer_mode.transfer_any=Перемещение любое количество +cover.robotic_arm.transfer_mode.transfer_any=Перемещение любое кол-во cover.robotic_arm.transfer_mode.transfer_exact=Перемещать ровно cover.robotic_arm.transfer_mode.keep_exact=Поддерживать ровно cover.robotic_arm.transfer_mode.description=§eПеремещение любых предметов§r - в этом режиме улучшение будет передавать как можно больше предметов, соответствующих фильтру./n§eПодавать точно§r - в этом режиме улучшение будет поставлять предметы порциями, указанными в слотах фильтра предметов (или скоростью передачи для §bФильтра Словаря руды§r). Если количество предметов меньше размера порции, предметы не будут перемещены ./n§eСохранять точно§r - в этом режиме обложка сохранит указанное количество предметов в целевом инвентаре, предоставляя дополнительное количество предметов, если это необходимо./n§7Подсказка: щелкните Лкм или Пкм на слотах фильтра, чтобы изменить количество предметов, используйте Shift, чтобы изменять количество быстрее. @@ -1130,11 +1130,6 @@ cover.fluid_regulator.title=Настройки регулятора жидкос cover.fluid_regulator.transfer_mode.description=§eПеремещать всё§r — в этом режиме улучшение будет перекачивать столько жидкостей, сколько возможно для ее фильтра./n§eПеремещать точно§r — в этом режиме улучшение будет подавать жидкости порциями, указанными в окне под этой кнопкой. Если количество жидкости меньше размера порции, жидкости не будут перемещены./n§eСохранять точно§r — в этом режиме улучшение будет хранить указанное количество жидкости в инвентаре назначения, при необходимости добавляя дополнительное количество жидкости./ n§7Совет: щелчок Shift умножит увеличение/уменьшение на 10, а щелчок Ctrl умножит на 100. cover.fluid_regulator.supply_exact=Подавать: %s cover.fluid_regulator.keep_exact=Хранить: %s -cover.machine_controller.title=Настройки контроллера механизма -cover.machine_controller.normal=Нормально -cover.machine_controller.inverted=Инверт. -cover.machine_controller.inverted.description=§eНормально§r — в этом режиме для работы улучшения требуется сигнал слабее установленного уровня редстоуна/n§eИнвертировано§r — в этом режиме для работы улучшения требуется сигнал сильнее установленного уровня редстоуна -cover.machine_controller.redstone=Минимальный Редстоун сигнал: %d cover.machine_controller.mode.machine=Контролирует работу механизма cover.machine_controller.mode.cover_up=Контроллер машины (Верх) cover.machine_controller.mode.cover_down=Контроллер машины (Низ) @@ -1162,7 +1157,7 @@ cover.advanced_fluid_detector.label=Улучшенный детектор жид cover.advanced_fluid_detector.max=Макс. жидкости: cover.advanced_fluid_detector.min=Мин. жидкости: cover.advanced_item_detector.label=Улучшенный детектор предметов -cover.advanced_item_detector.invert_tooltip=Переключите, чтобы инвертировать логику красного камня./nПо умолчанию красный камень перестает испускать сигнал, когда количество предметов меньше минимального, и начинает испускать сигнал, при превышении минимального количества предметов до установленного максимума +cover.advanced_item_detector.invert_tooltip=Переключите, чтобы инвертировать логику красного камня./nПо умолчанию красный камень перестает испускать сигнал, когда кол-во предметов меньше мин., и начинает испускать сигнал, при превышении мин. кол-ва предметов до установленного макс cover.advanced_item_detector.max=Макс. предметов: cover.advanced_item_detector.min=Мин. предметов: cover.storage.title=Хранилище (Улучшение) @@ -1203,8 +1198,8 @@ item.material.oreprefix.plateDouble=%s (Двойная пластина) item.material.oreprefix.plate=%s (Пластина) item.material.oreprefix.plank=Доска (%s) item.material.oreprefix.foil=%s (Фольга) -item.material.oreprefix.stick=%s (Прут) -item.material.oreprefix.stickLong=%s (Стержень) +item.material.oreprefix.stick=%s (Стержень) +item.material.oreprefix.stickLong=%s (Прут) item.material.oreprefix.round=%s (Шарик) item.material.oreprefix.bolt=%s (Болт) item.material.oreprefix.screw=%s (Винт) @@ -1264,7 +1259,7 @@ item.material.oreprefix.polymer.plate=%s (Лист) item.material.oreprefix.polymer.foil=%s (Фольга) item.material.oreprefix.polymer.nugget=%s (Осколок) item.material.oreprefix.polymer.plateDense=%s (Плотный лист) -item.material.oreprefix.polymer.plateDouble=%s (Плотный лист) +item.material.oreprefix.polymer.plateDouble=%s (Двойной лист) item.material.oreprefix.polymer.dustTiny=%s (Крохотная кучка) item.material.oreprefix.polymer.dustSmall=%s (Маленькая кучка) item.material.oreprefix.polymer.dust=%s (Пыль) @@ -1320,7 +1315,7 @@ gregtech.material.hydrogen=Водород gregtech.material.helium=Гелий gregtech.material.helium_3=Гелий-3 gregtech.material.indium=Индий -gregtech.material.iodine=Иод +gregtech.material.iodine=Йод gregtech.material.iridium=Иридий gregtech.material.iron=Железо gregtech.material.krypton=Криптон @@ -1352,7 +1347,8 @@ gregtech.material.palladium=Палладий gregtech.material.phosphorus=Фосфор gregtech.material.polonium=Полоний gregtech.material.platinum=Платина -gregtech.material.plutonium=Плутоний-239 +gregtech.material.plutonium=Плутоний +gregtech.material.plutonium_239=Плутоний-239 gregtech.material.plutonium_241=Плутоний-241 gregtech.material.potassium=Калий gregtech.material.praseodymium=Празеодим @@ -1387,8 +1383,9 @@ gregtech.material.tin=Олово gregtech.material.titanium=Титан gregtech.material.tritium=Тритий gregtech.material.tungsten=Вольфрам -gregtech.material.uranium=Уран-238 +gregtech.material.uranium=Уран gregtech.material.uranium_235=Уран-235 +gregtech.material.uranium_238=Уран-238 gregtech.material.vanadium=Ванадий gregtech.material.xenon=Ксенон gregtech.material.ytterbium=Иттербий @@ -1786,9 +1783,9 @@ gregtech.material.wood=Дерево gregtech.material.treated_wood=Обработанное дерево gregtech.material.paper=Бумага gregtech.material.fish_oil=Рыбий жир -gregtech.material.ruby_slurry=Рубиновый шлам -gregtech.material.sapphire_slurry=Сапфирный шлам -gregtech.material.green_sapphire_slurry=Шлам зелёного сапфира +gregtech.material.ruby_slurry=Рубиновая суспензия +gregtech.material.sapphire_slurry=Сапфировая суспензия +gregtech.material.green_sapphire_slurry=Суспензия зелёного сапфира gregtech.material.dye_black=Черный краситель gregtech.material.dye_red=Красный краситель gregtech.material.dye_green=Зеленый краситель @@ -1942,7 +1939,7 @@ item.gregtech.material.cassiterite_sand.dustImpure=Грязная кучка к item.gregtech.material.cassiterite_sand.dustPure=Очищеная кучка касситеритного песка item.gregtech.material.cassiterite_sand.dust=Касситеритовый песок item.gregtech.material.dark_ash.dustTiny=Крошечная кучка пепла -item.gregtech.material.dark_ash.dustSmall=Маленькая кучка темного пепла +item.gregtech.material.dark_ash.dustSmall=Маленькая кучка пепла item.gregtech.material.dark_ash.dust=Пепел item.gregtech.material.ice.dustTiny=Крошечная кучка колотого льда item.gregtech.material.ice.dustSmall=Маленькая кучка колотого льда @@ -2006,9 +2003,9 @@ item.gregtech.material.bentonite.dustPure=Очищеный кучка бенто item.gregtech.material.bentonite.dustSmall=Маленькая кучка бентонита item.gregtech.material.bentonite.dustTiny=Крошечная кучка бентонита item.gregtech.material.bentonite.dust=Бентонит -item.gregtech.material.fullers_earth.dustSmall=Маленькая кучка странной земли -item.gregtech.material.fullers_earth.dustTiny=Крошечная кучка странной земли -item.gregtech.material.fullers_earth.dust=Странная земля +item.gregtech.material.fullers_earth.dustSmall=Маленькая кучка смектической глины +item.gregtech.material.fullers_earth.dustTiny=Крошечная кучка cмектической глины +item.gregtech.material.fullers_earth.dust=Смектическая глина item.gregtech.material.pitchblende.crushed=Измельчённый уранит item.gregtech.material.pitchblende.crushedCentrifuged=Центрифугированный уранит item.gregtech.material.pitchblende.crushedPurified=Очищеный уранит @@ -2187,7 +2184,7 @@ behavior.tricorder.bedrock_fluid.amount=Жидкость в месторожде 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.amp_per_sec=За последнюю секунду прошло %s A behavior.tricorder.workable_consumption=Примерно использует: %s EU/t при %s A behavior.tricorder.workable_production=Примерно производит: %s EU/т при %s A behavior.tricorder.workable_progress=Прогресс: %s с / %s с @@ -2239,7 +2236,7 @@ tile.casing.ev=Корпус машины (§5EV§r) tile.casing.iv=Корпус машины (§1IV§r) # Wire coil blocks -tile.wire_coil.tooltip_extended_info=Зажмите SHIFT для просмотра Бонуса Катушек +tile.wire_coil.tooltip_extended_info=Зажмите SHIFT для Информации о Бонуса Катушек tile.wire_coil.tooltip_heat=§cТеплоемкость: §f%,d K tile.wire_coil.tooltip_smelter=§8Мультиплавильня: tile.wire_coil.tooltip_parallel_smelter=§5Параллелей: §f%s @@ -2365,10 +2362,10 @@ tile.machine_casing.overpowered_voltage.name=Корпус машины (OpV) tile.machine_casing.maximum_voltage.name=Корпус машины (MAX) # Steam casing blocks -tile.steam_casing.bronze_hull.name=Бронзовый корпус -tile.steam_casing.bronze_bricks_hull.name=Бронзовый кирпичный корпус -tile.steam_casing.steel_hull.name=Стальной корпус -tile.steam_casing.steel_bricks_hull.name=Кирпичный корпус из кованого железа +tile.steam_casing.bronze_hull.name=Бронзовая оболочка +tile.steam_casing.bronze_bricks_hull.name=Бронзовая кирпичная оболочка +tile.steam_casing.steel_hull.name=Стальная оболочка +tile.steam_casing.steel_bricks_hull.name=Кирпичная оболочка из кованого железа tile.steam_casing.bronze.tooltip=Для ваших первых паровых машин tile.steam_casing.steel.tooltip=Для улучшенных паровых машин tile.steam_casing.pump_deck.name=Насосная палуба @@ -2924,7 +2921,7 @@ gregtech.machine.canner.uhv.name=Идеальный наполнитель gregtech.machine.canner.uhv.tooltip=Электроконсерватор gregtech.machine.canner.uev.name=Идеальный наполнитель II gregtech.machine.canner.uev.tooltip=Электроконсерватор -gregtech.machine.canner.uiv.name=Идеальный наполнитель II +gregtech.machine.canner.uiv.name=Идеальный наполнитель III gregtech.machine.canner.uiv.tooltip=Электроконсерватор gregtech.machine.canner.uxv.name=Идеальный наполнитель IV gregtech.machine.canner.uxv.tooltip=Электроконсерватор @@ -3082,7 +3079,7 @@ gregtech.machine.distillery.zpm.name=Превосходный дистиллят gregtech.machine.distillery.uv.name=Безупречный дистиллятор gregtech.machine.distillery.uhv.name=Идеальный дистиллятор gregtech.machine.distillery.uev.name=Идеальный дистиллятор II -gregtech.machine.distillery.uiv.name=Идеальный дистиллятор II +gregtech.machine.distillery.uiv.name=Идеальный дистиллятор III gregtech.machine.distillery.uxv.name=Идеальный дистиллятор IV gregtech.machine.distillery.lv.tooltip=Извлечение наиболее важных частей жидкостей gregtech.machine.distillery.mv.tooltip=Извлечение наиболее важных частей жидкостей @@ -3472,7 +3469,7 @@ gregtech.machine.polarizer.zpm.name=Превосходный поляризат gregtech.machine.polarizer.uv.name=Безупречный поляризатор gregtech.machine.polarizer.uhv.name=Идеальный поляризатор gregtech.machine.polarizer.uev.name=Идеальный поляризатор II -gregtech.machine.polarizer.uiv.name=Идеальный поляризатор II +gregtech.machine.polarizer.uiv.name=Идеальный поляризатор III gregtech.machine.polarizer.uxv.name=Идеальный поляризатор IV gregtech.machine.polarizer.lv.tooltip=Биполяризация ваших магнитов gregtech.machine.polarizer.mv.tooltip=Биполяризация ваших магнитов @@ -3722,21 +3719,21 @@ gregtech.creative_tooltip.3=§7 чтобы использовать это # Machine hulls gregtech.machine.hull.tooltip=§7Вам просто нужно §5В§dо§4о§cб§eр§aа§bж§3е§7н§1и§5е§7 чтобы использовать это -gregtech.machine.hull.ulv.name=Корпус машины (§8ULV§r) -gregtech.machine.hull.lv.name=Корпус машины (§7LV§r) -gregtech.machine.hull.mv.name=Корпус машины (§bMV§r) -gregtech.machine.hull.hv.name=Корпус машины (§6HV§r) -gregtech.machine.hull.ev.name=Корпус машины (§5EV§r) -gregtech.machine.hull.iv.name=Корпус машины (§1IV§r) -gregtech.machine.hull.luv.name=Корпус машины (§dLuV§r) -gregtech.machine.hull.zpm.name=Корпус машины (§fZPM§r) -gregtech.machine.hull.uv.name=Корпус машины (§3UV§r) -gregtech.machine.hull.uhv.name=Корпус машины (§4UHV§r) -gregtech.machine.hull.uev.name=Корпус машины (§aUEV§r) -gregtech.machine.hull.uiv.name=Корпус машины (§2UIV§r) -gregtech.machine.hull.uxv.name=Корпус машины (§eUXV§r) -gregtech.machine.hull.opv.name=Корпус машины (§9OpV§r) -gregtech.machine.hull.max.name=Корпус машины (§cMAX§r) +gregtech.machine.hull.ulv.name=Оболочка машины (§8ULV§r) +gregtech.machine.hull.lv.name=Оболочка машины (§7LV§r) +gregtech.machine.hull.mv.name=Оболочка машины (§bMV§r) +gregtech.machine.hull.hv.name=Оболочка машины (§6HV§r) +gregtech.machine.hull.ev.name=Оболочка машины (§5EV§r) +gregtech.machine.hull.iv.name=Оболочка машины (§1IV§r) +gregtech.machine.hull.luv.name=Оболочка машины (§dLuV§r) +gregtech.machine.hull.zpm.name=Оболочка машины (§fZPM§r) +gregtech.machine.hull.uv.name=Оболочка машины (§3UV§r) +gregtech.machine.hull.uhv.name=Оболочка машины (§4UHV§r) +gregtech.machine.hull.uev.name=Оболочка машины (§aUEV§r) +gregtech.machine.hull.uiv.name=Оболочка машины (§2UIV§r) +gregtech.machine.hull.uxv.name=Оболочка машины (§eUXV§r) +gregtech.machine.hull.opv.name=Оболочка машины (§9OpV§r) +gregtech.machine.hull.max.name=Оболочка машины (§cMAX§r) # Battery buffers gregtech.machine.battery_buffer.ulv.4.name=Батарейный буфер (4 ячейки §8ULV§r) @@ -3789,7 +3786,7 @@ gregtech.battery_buffer.average_input=Ввод в среднем: %s EU/t # Transformers gregtech.machine.transformer.description=Преобразует энергию между уровнями напряжения -gregtech.machine.transformer.higher_amp.description=Преобразует энергию между уровнями напряжения, теперь с большим количеством ампер! +gregtech.machine.transformer.higher_amp.description=Преобразует энергию между уровнями напряжения, теперь с большим кол-вом ампер! gregtech.machine.transformer.tooltip_tool_usage=По умолчанию §fПонижающий режим§7, используйте киянку чтобы инвертировать режим gregtech.machine.transformer.tooltip_transform_down=§aПонижающий режим: §f%dA %d EU (%s§f) -> %dA %d EU (%s§f) gregtech.machine.transformer.message_transform_down=Понижает напряжение, вход: %d EU %dA, выход: %d EU %dA @@ -4263,8 +4260,8 @@ gregtech.advancement.extreme_voltage.50_nano_processor.name=Нано-проце gregtech.advancement.extreme_voltage.50_nano_processor.desc=Получите нано-процессор. gregtech.advancement.extreme_voltage.51_large_combustion_engine.name=Большой дизельный генератор gregtech.advancement.extreme_voltage.51_large_combustion_engine.desc=Соберите большой дизельный генератор, снабдите его смазкой и ускорьте кислородом. -gregtech.advancement.extreme_voltage.52_soc_wafer.name=Пластина SoC -gregtech.advancement.extreme_voltage.52_soc_wafer.desc=Сделайте Пластину SoC для более дешёвого производства микропроцессоров и интегральных микросхем. +gregtech.advancement.extreme_voltage.52_soc_wafer.name=Пластина СНК +gregtech.advancement.extreme_voltage.52_soc_wafer.desc=Сделайте Пластину СНК для более дешёвого производства микропроцессоров и интегральных микросхем. gregtech.advancement.root_iv.name=Безумный вольтаж gregtech.advancement.root_iv.desc=Охладите горячую вольфрамовую сталь. gregtech.advancement.insane_voltage.53_plutonium_239.name=Плутоний-239 @@ -4295,8 +4292,8 @@ gregtech.advancement.ludicrous_voltage.65_naquadah.name=Материал зве gregtech.advancement.ludicrous_voltage.65_naquadah.desc=Охладите горячий слиток наквады. gregtech.advancement.ludicrous_voltage.66_naquadah_coil.name=Улучшите ваши катушки до уровня VI gregtech.advancement.ludicrous_voltage.66_naquadah_coil.desc=Создайте катушку из наквады. -gregtech.advancement.ludicrous_voltage.67_asoc_wafer.name=Пластина ASoC -gregtech.advancement.ludicrous_voltage.67_asoc_wafer.desc=Сделайте Пластину SoC для более дешёвого производства нано-процессоров и квантовых процессоров. +gregtech.advancement.ludicrous_voltage.67_asoc_wafer.name=Пластина УСНК +gregtech.advancement.ludicrous_voltage.67_asoc_wafer.desc=Сделайте Пластину СНК для более дешёвого производства нано-процессоров и квантовых процессоров. gregtech.advancement.ludicrous_voltage.68_large_plasma_turbine.name=Большая плазменная турбина gregtech.advancement.ludicrous_voltage.68_large_plasma_turbine.desc=Создайте плазменную турбину, использующую плазму как топливо. gregtech.advancement.root_zpm.name=Модуль нулевой точки @@ -4325,8 +4322,8 @@ gregtech.advancement.ultimate_voltage.76_neutronium.name=Как можно пл gregtech.advancement.ultimate_voltage.76_neutronium.desc=Получите нейтроний. gregtech.advancement.ultimate_voltage.77_ultimate_battery.name=И что теперь? gregtech.advancement.ultimate_voltage.77_ultimate_battery.desc=Создайте безупречную батарею. -gregtech.advancement.ultimate_voltage.78_hasoc_wafer.name=Пластина HASoC -gregtech.advancement.ultimate_voltage.78_hasoc_wafer.desc=Сделайте пластину HASoC для более дешёвого производства органических микросхем. +gregtech.advancement.ultimate_voltage.78_hasoc_wafer.name=Пластина ОУСнК +gregtech.advancement.ultimate_voltage.78_hasoc_wafer.desc=Сделайте пластину СУСНК для более дешёвого производства органических микросхем. gregtech.advancement.ultimate_voltage.79_tritanium_coil.name=Финальная катушка gregtech.advancement.ultimate_voltage.79_tritanium_coil.desc=Изготовьте нагревательную катушку из Тритания. @@ -4431,14 +4428,14 @@ gregtech.machine.cleanroom.tooltip.1=Установите машины внут gregtech.machine.cleanroom.tooltip.2=Использует §f30 EU/t§7 когда загрязнена, §f4 EU/t§7 когда очищена. gregtech.machine.cleanroom.tooltip.3=Разгон увеличивает очистку за один цикл. gregtech.machine.cleanroom.tooltip.4=§bРазмер: от §f5x5x5 до 15x15x15 -gregtech.machine.cleanroom.tooltip.hold_ctrl=Зажмите CTRL для просмотра дополнительной информации о структуре +gregtech.machine.cleanroom.tooltip.hold_ctrl=Зажмите CTRL для Дополнительной информации о структуре gregtech.machine.cleanroom.tooltip.5=Требует установку §fКорпуса фильтра §7в любом месте потолка кроме его граней. gregtech.machine.cleanroom.tooltip.6=Позволяет установить до §f4 дверей§7! Требует повторную очистку при открытой двери. gregtech.machine.cleanroom.tooltip.7=Генераторы, глушители, буры и примитивные машины слишком грязные для чистой комнаты! -gregtech.machine.cleanroom.tooltip.8=Подавайте питание через §fКорпуса §7или §fДиоды §7в стенах. +gregtech.machine.cleanroom.tooltip.8=Подавайте питание через §fОболочку §7или §fДиоды §7в стенах. gregtech.machine.cleanroom.tooltip.9=Отправляйте предметы и жидкости с помощью §fСквозных люков§7в стенах. -gregtech.machine.cleanroom.tooltip.ae2.channels=Отправляйте до §f8 AE2 каналов §7через §fКорпуса§7 в стенах. -gregtech.machine.cleanroom.tooltip.ae2.no_channels=Отправляйте §aAE2 сеть§7 через §fКорпуса§7 в стенах. +gregtech.machine.cleanroom.tooltip.ae2.channels=Отправляйте до §f8 AE2 каналов §7через §fОболочку§7 в стенах. +gregtech.machine.cleanroom.tooltip.ae2.no_channels=Отправляйте §aAE2 сеть§7 через §fОболочку§7 в стенах. gregtech.multiblock.cleanroom.dirty_state=Статус: §4ЗАГРЯЗНЕНА gregtech.multiblock.cleanroom.clean_state=Статус: §aЧИСТАЯ gregtech.machine.charcoal_pile.name=Воспламенитель угольной ямы @@ -4463,10 +4460,10 @@ gregtech.machine.power_substation.tooltip5=Ограниченно §f%,d EU/t§7 gregtech.multiblock.power_substation.description=Силовая Подстанция представляет собой многоблочную структуру, используемую для хранения огромного количества Энергии. Способен вместить до 18 слоев батарей. Также можно использовать пустые Накопители для заполнения пространства, так как слои должны быть полностью заполнены. gregtech.machine.active_transformer.name=Активный Трансформатор gregtech.machine.active_transformer.tooltip1=Трансформеры: Замаскированные лазеры -gregtech.machine.active_transformer.tooltip2=Может комбинировать любое количество Энергетических §fВходных§7 разъемов в любое количество Энергетических §fВыходных§7 разъемов. +gregtech.machine.active_transformer.tooltip2=Может комбинировать любое кол-во Энергетических §fВходных§7 разъемов в любое кол-во Энергетических §fВыходных§7 разъемов. gregtech.machine.active_transformer.tooltip3=Может передавать энергию на невероятное расстояние с помощью gregtech.machine.active_transformer.tooltip3.5=Лазеров§7. -gregtech.multiblock.active_transformer.description=Активный Трансформатор представляет собой многоблочную структуру, которая может принимать любое количество или уровень энергетических входных разъемов преобразовывать их в любое количество или уровень энергетических выходных разъемов. Они могут быть соединены с Люком для Лазерного Источника и Люком для Лазерного Приемника, что позволяет передавать энергию на большие расстояния без каких-либо потерь. Лазеры должны располагаться по прямой, иначе они не будут посылать энергию. +gregtech.multiblock.active_transformer.description=Активный Трансформатор представляет собой многоблочную структуру, которая может принимать любое кол-во или уровень энергетических входных разъемов преобразовывать их в любое кол-во или уровень энергетических выходных разъемов. Они могут быть соединены с Люком для Лазерного Источника и Люком для Лазерного Приемника, что позволяет передавать энергию на большие расстояния без каких-либо потерь. Лазеры должны располагаться по прямой, иначе они не будут посылать энергию. gregtech.machine.research_station.name=Станция исследований gregtech.machine.research_station.tooltip.1=Больше чем Многоблочный Сканнер gregtech.machine.research_station.tooltip.2=Используется для сканирования §fСфер данных§7 или §fМодулей данных§7. @@ -4475,13 +4472,13 @@ gregtech.multiblock.research_station.description=Исследовательск gregtech.machine.network_switch.name=Коммутатор gregtech.machine.network_switch.tooltip.1=Ethernet-концентратор gregtech.machine.network_switch.tooltip.2=Используется для маршрутизации и распределения §fВычислений§7. -gregtech.machine.network_switch.tooltip.3=Можно объединить любое количество §fПриемников§7 Вычислений в любое количество §fПередатчиков§7 Вычислений. -gregtech.multiblock.network_switch.description=Коммутатор представляет собой многоблочную структуру, используемую для распределения вычислительных ресурсов из многих источников во многие пункты назначения. Он может принимать любое количество Люков Приема или Передачи вычислительных данных. Это необходимо для Исследовательских Данных, которые требуют гораздо больших Вычислений, поскольку исследовательская станция может принимать только один люк для приема данных вычислений. HPCA должен иметь Компонент Моста, чтобы сетевой коммутатор мог получить доступ к своим вычислениям. +gregtech.machine.network_switch.tooltip.3=Можно объединить любое кол-во §fПриемников§7 Вычислений в любое кол-во §fПередатчиков§7 Вычислений. +gregtech.multiblock.network_switch.description=Коммутатор представляет собой многоблочную структуру, используемую для распределения вычислительных ресурсов из многих источников во многие пункты назначения. Он может принимать любое кол-во Люков Приема или Передачи вычислительных данных. Это необходимо для Исследовательских Данных, которые требуют гораздо больших Вычислений, поскольку исследовательская станция может принимать только один люк для приема данных вычислений. HPCA должен иметь Компонент Моста, чтобы сетевой коммутатор мог получить доступ к своим вычислениям. gregtech.machine.high_performance_computing_array.name=Высокопроизводительный вычислительный массив gregtech.machine.high_performance_computing_array.tooltip.1=Просто самый обычный Суперкомпьютер gregtech.machine.high_performance_computing_array.tooltip.2=Используется для генерации §fВычислений§7 (и тепла). gregtech.machine.high_performance_computing_array.tooltip.3=Требуются компоненты HPCA для создания §fCWU/t§7 (Вычислительные Рабочие Единицы). -gregtech.multiblock.high_performance_computing_array.description=Высокопроизводительный Вычислительный Массив (HPCA) представляет собой многоблочную структуру, используемую для создания Вычислительные Рабочие Единицы (CWU/t) для более Сложных Данных Исследования Cборочной Линии. Структура имеет гибкую область 3x3, которая может быть заполнена компонентами HPCA любым способом. Различные компоненты могут обеспечивать разное количество вычислений, охлаждения, а также затрат на энергию, стоимость охлаждающей жидкости и производство тепла. При использовании с компонентом моста HPCA может подключаться к сетевым коммутаторам для объединения и маршрутизации вычислений из нескольких источников в одно или несколько мест назначения. +gregtech.multiblock.high_performance_computing_array.description=Высокопроизводительный Вычислительный Массив (HPCA) представляет собой многоблочную структуру, используемую для создания Вычислительные Рабочие Единицы (CWU/t) для более Сложных Данных Исследования Cборочной Линии. Структура имеет гибкую область 3x3, которая может быть заполнена компонентами HPCA любым способом. Различные компоненты могут обеспечивать разное ко-во вычислений, охлаждения, а также затрат на энергию, стоимость охлаждающей жидкости и производство тепла. При использовании с компонентом моста HPCA может подключаться к сетевым коммутаторам для объединения и маршрутизации вычислений из нескольких источников в одно или несколько мест назначения. gregtech.machine.central_monitor.name=Центральный монитор gregtech.multiblock.central_monitor.low_power=Недостаточно энергии gregtech.multiblock.central_monitor.height=Высота экрана: @@ -4573,7 +4570,6 @@ gregtech.machine.item_bus.export.uv.name=Предметный выходной gregtech.machine.item_bus.export.uhv.name=Предметный выходной люк (§4UHV§r) gregtech.bus.collapse_true=Люк будет совмещать Предметы gregtech.bus.collapse_false=Люк не будет совмещать Предметы -gregtech.bus.collapse.error=Люк должен быть сперва добавлен в многоблочную структуру gregtech.machine.fluid_hatch.import.tooltip=Для подачи жидкости в многоблочную структуру gregtech.machine.fluid_hatch.import.ulv.name=Жидкостный входной люк (§8ULV§r) gregtech.machine.fluid_hatch.import.lv.name=Жидкостный входной люк (§7LV§r) @@ -4694,7 +4690,7 @@ gregtech.maintenance.configurable_time=Время: %fx gregtech.maintenance.configurable_time.unchanged_description=Проблемы с обслуживанием будут возникать с обычной частотой. Измените конфигурацию для обновления. gregtech.maintenance.configurable_time.changed_description=Проблемы с обслуживанием будут возникать в %f раз чаще. gregtech.maintenance.configurable.tooltip_basic=Ускоряет время работы машины за счет более частых проблем с обслуживанием -gregtech.maintenance.configurable.tooltip_more_info=Зажмите SHIFT для особого взаимодействия +gregtech.maintenance.configurable.tooltip_more_info=Зажмите SHIFT для Особого взаимодействия gregtech.maintenance.configurable.tooltip_pss_header=§8Силовая Подстанция: gregtech.maintenance.configurable.tooltip_pss_info=§fУменьшает пассивную утечку энергии gregtech.machine.muffler_hatch.tooltip1=Восстанавливает отходы от машин @@ -4750,7 +4746,6 @@ gregtech.machine.me.fluid_export.tooltip=Отправляет жидкости gregtech.machine.me.item_export.tooltip=Отправляет предметы напрямую в ME Сеть. gregtech.machine.me.fluid_import.tooltip=Получает жидкости из сети ME автоматически. gregtech.machine.me.item_import.tooltip=Получает предметы из сети ME автоматически. -gregtech.machine.me.export.tooltip=Имеет бесконечный объем перед подключением в ME Сеть. # Universal tooltips gregtech.universal.tooltip.voltage_in=§aПотребляемое напряжение: §f%,d EU/т (%s§f) @@ -4778,7 +4773,7 @@ gregtech.universal.tooltip.fluid_stored=§dОбъем жидкости: §f%s, % gregtech.universal.tooltip.fluid_transfer_rate=§bСкорость передачи: §f%,d Л/т gregtech.universal.tooltip.parallel=§dПаралеллей: §f%d gregtech.universal.tooltip.working_area=§bРабочая область: §f%,dx%,d -gregtech.universal.tooltip.working_area_max=§bМаксимальная рабочая область: §f%,dx%,d +gregtech.universal.tooltip.working_area_max=§bМакс. рабочая область: §f%,dx%,d gregtech.universal.tooltip.working_area_chunks_max=§bMax Working Area: §f%,dx%,d Chunks gregtech.universal.tooltip.uses_per_tick=Потребляет §f%,d EU/т §7когда работает gregtech.universal.tooltip.uses_per_tick_steam=Потребляет §f%,d Л/т §7 Пара когда работает @@ -4810,7 +4805,7 @@ gregtech.recipe.computation_per_tick=Мин. Вычисления: %,d CWU/t gregtech.fluid.click_to_fill=§7Нажмите с хралищем для жидкости, чтобы §bзаполнить §7резервуар. gregtech.fluid.click_to_empty=§7Нажмите с хралищем для жидкости, чтобы §cопустошить §7резервуар. gregtech.fluid.click_combined=§7Нажмите с хралищем для жидкости, чтобы §bзаполнить §7или §cопустошить §7резервуар. -gregtech.tool_action.show_tooltips=Зажмите SHIFT для просмотра информации Инструмента +gregtech.tool_action.show_tooltips=Зажмите SHIFT для Информации о Инструменте gregtech.tool_action.screwdriver.auto_output=§8Используйте отвертку, чтобы переключить Авто-Вывод gregtech.tool_action.screwdriver.toggle_mode_covers=§8Используйте отвертку, чтобы переключить Режим или настроить улучшения gregtech.tool_action.screwdriver.access_covers=§8Используйте отвертку, чтобы настроить улучшения @@ -4829,8 +4824,8 @@ gregtech.tool_action.tape=§8Используйте Клейкую Ленту д gregtech.fluid.generic=%s gregtech.fluid.plasma=Плазма (%s) gregtech.fluid.empty=Пустой -gregtech.fluid.amount=§7%,d/%,d -gregtech.fluid.temperature=§7Температура: %dK +gregtech.fluid.amount=§9Количество: %,d/%,d Л +gregtech.fluid.temperature=§cТемпература: %dK gregtech.fluid.temperature.cryogenic=§bКриогенный! Соблюдайте осторожность! gregtech.fluid.state_gas=§7Состояние: Газообразный gregtech.fluid.state_liquid=§7Состояние: Жидкость @@ -4838,7 +4833,7 @@ gregtech.fluid.state_plasma=§7Состояние: Плазма gregtech.fluid.type_acid.tooltip=§6Кислота! Соблюдайте осторожность! gregtech.gui.fuel_amount=Кол. топлива: gregtech.gui.fluid_amount=Кол. жидкости: -gregtech.gui.amount_raw=Количество: +gregtech.gui.amount_raw=Кол-во: gregtech.gui.toggle_view.disabled=Переключить вид (Жидкости) gregtech.gui.toggle_view.enabled=Переключить вид (Предметы) gregtech.gui.overclock.enabled=Ускорение включено./nНажмите, чтобы отключить @@ -4851,7 +4846,7 @@ gregtech.gui.fluid_auto_output.tooltip.disabled=Авто. вывод жидко gregtech.gui.item_auto_output.tooltip.enabled=Авто. вывод предметов включен gregtech.gui.item_auto_output.tooltip.disabled=Авто. вывод предметов отключен gregtech.gui.charger_slot.tooltip=§fСлот двухстороннего питания§r/n§7Может потреблять энергию от %s §7аккумуляторов либо-же отдавать -gregtech.gui.configurator_slot.tooltip=§fСлот Конфигурации§r/n§aУстановить Значение: §f%d§7/n/n§7ЛКМ/ПКМ/Прокрутка для переключения по листу/n§7Shift-ПКМ для очистка +gregtech.gui.configurator_slot.tooltip=§fСлот Конфигурации§r\n§aУстановить Значение: §f%d§7\n\n§7ЛКМ/ПКМ/Прокрутка для переключения по листу\n§7Shift-ЛКМ чтобы выбрать селектор\n§7Shift-ПКМ для очистка gregtech.gui.fluid_lock.tooltip.enabled=Блокировка жидкости включена gregtech.gui.fluid_lock.tooltip.disabled=Блокировка жидкости выключена gregtech.gui.fluid_voiding.tooltip.enabled=Удаление избытков жидкости Включен @@ -4866,7 +4861,7 @@ gregtech.gui.me_network.offline=Статус Сети: §2Не в Сети§r gregtech.gui.waiting_list=Очередь на отправку: gregtech.gui.config_slot=§fНастройка§r gregtech.gui.config_slot.set=§7Нажмите для §bвыбора/настройкиt§7 слота.§r -gregtech.gui.config_slot.scroll=§7Колесо мыши §aизменяет§7 количество.§r +gregtech.gui.config_slot.scroll=§7Колесо мыши §aизменяет§7 кол-во.§r gregtech.gui.config_slot.remove=§7Правая кнопка для §4очистки§7 слота настройки.§r ore.spawnlocation.name=Информация о появлении руды gregtech.jei.ore.surface_rock_1=Поверхностные залежи с этим материалом обозначают места появления жил. @@ -4899,8 +4894,8 @@ fluid.spawnlocation.name=Информация о жидкостном место gregtech.jei.materials.average_mass=Средняя масса: %,d -gregtech.jei.materials.average_neutrons=Среднее количество нейтронов: %,d -gregtech.jei.materials.average_protons=Среднее количество протонов: %,d +gregtech.jei.materials.average_neutrons=Ср. кол-во нейтронов: %,d +gregtech.jei.materials.average_protons=Ср. кол-во протонов: %,d gregtech.item_filter.empty_item=Пусто (нет предмета) gregtech.item_filter.footer=§eНажмите с предметом, чтобы переопределить gregtech.cable.voltage=§aВольтаж: §f%,d §f(%s§f) @@ -4924,12 +4919,12 @@ gregtech.multiblock.not_enough_energy_output=§eСовет:§f Энергети gregtech.multiblock.progress=Прогресс: %s%% gregtech.multiblock.invalid_structure=Неверная структура. gregtech.multiblock.invalid_structure.tooltip=Этот блок является контроллером многоблочной структуры. для получения справки по созданию см. шаблон структуры в JEI. -gregtech.multiblock.validation_failed=Неверное количество входов/выходов. +gregtech.multiblock.validation_failed=Неверное кол-во входов/выходов. gregtech.multiblock.max_energy_per_tick=Макс. EU/т: §a%s (%s§r) gregtech.multiblock.generation_eu=Генерирует:§a%s EU/t gregtech.multiblock.universal.no_problems=Механизм работает исправно! gregtech.multiblock.universal.has_problems=Механизм неисправен! -gregtech.multiblock.universal.has_problems_header=Исправьте следующие проблемы в люке обслуживания: +gregtech.multiblock.universal.has_problems_header=Исправьте следующие проблемы в Люке обслуживания: gregtech.multiblock.universal.problem.wrench=%s§7Труба расшатана. (§aКлюч§7) gregtech.multiblock.universal.problem.screwdriver=%s§7Винты не закручены. (§aОтвертка§7) gregtech.multiblock.universal.problem.soft_mallet=%s§7Что-то заклинило. (§aКиянка§7) @@ -4941,7 +4936,7 @@ gregtech.multiblock.universal.distinct_enabled=Раздельные люки: § gregtech.multiblock.universal.distinct_disabled=Раздельные люки: §aВsключено§r/nКаждый входной люк будет рассматриваться как комбинированный ввод для поиска рецепта. gregtech.multiblock.universal.distinct_not_supported=Эту структура не поддерживает Раздельные Люки gregtech.multiblock.universal.no_flex_button=Эта структура не имеет дополнительных функций с этой кнопкой. -gregtech.multiblock.parallel=Параллельное выполнение до %d рецептов +gregtech.multiblock.parallel=Макс. Параллелей: %s gregtech.multiblock.multiple_recipemaps.header=Режим машины: gregtech.multiblock.multiple_recipemaps.tooltip=Нажмите отвёрткой по контроллеру, чтобы изменить режим машины. gregtech.multiblock.multiple_recipemaps_recipes.tooltip=Режим машин: §e%s§r @@ -4971,9 +4966,9 @@ gregtech.multiblock.blast_furnace.max_temperature=Максимальная те gregtech.multiblock.multi_furnace.heating_coil_discount=EU усиление нагревательной катушки: %sx gregtech.multiblock.distillation_tower.distilling_fluid=Дистилляция %s gregtech.multiblock.large_combustion_engine.no_lubricant=Нет Смазки. -gregtech.multiblock.large_combustion_engine.lubricant_amount=Количество смазки: %smB -gregtech.multiblock.large_combustion_engine.oxygen_amount=Количество кислорода: %smB -gregtech.multiblock.large_combustion_engine.liquid_oxygen_amount=Количество жидкого кислорода: %smB +gregtech.multiblock.large_combustion_engine.lubricant_amount=Кол-во смазки: %smB +gregtech.multiblock.large_combustion_engine.oxygen_amount=Кол-во кислорода: %smB +gregtech.multiblock.large_combustion_engine.liquid_oxygen_amount=Кол-во жид. кислорода: %smB gregtech.multiblock.large_combustion_engine.oxygen_boosted=§bКислород добавлен. gregtech.multiblock.large_combustion_engine.liquid_oxygen_boosted=§bЖидкий кислород добавлен. gregtech.multiblock.large_combustion_engine.supply_oxygen_to_boost=Принимает кислород для ускорения. @@ -4981,11 +4976,11 @@ gregtech.multiblock.large_combustion_engine.supply_liquid_oxygen_to_boost=При gregtech.multiblock.large_combustion_engine.obstructed=Что-то мешает воздухозаборнику двигателя. gregtech.multiblock.turbine.fuel_amount=Топлива: %smB (%s) gregtech.multiblock.turbine.rotor_speed=Скорость: %s/%s об/мин -gregtech.multiblock.turbine.rotor_durability=Прочность ротора: %s%% +gregtech.multiblock.turbine.rotor_durability=Прочность ротора: %s gregtech.multiblock.turbine.rotor_durability_low=Прочность ротора низкая! gregtech.multiblock.turbine.no_rotor=Нет Ротора в Держателе ротора. gregtech.multiblock.turbine.fuel_needed=Потребляет %s за %s тиков -gregtech.multiblock.turbine.efficiency=Эффективность турбины: %s%% +gregtech.multiblock.turbine.efficiency=Эффективность турбины: %s gregtech.multiblock.turbine.energy_per_tick=Выход: %s/%s EU/t gregtech.multiblock.turbine.obstructed=Поверхность турбины заблокирована gregtech.multiblock.turbine.efficiency_tooltip=Каждый держатель ротора выше %s§7 добавляет §f10%% эффективности§7. @@ -5023,8 +5018,6 @@ gregtech.multiblock.computation.not_enough_computation=§cВНИМАНИЕ:§f gregtech.multiblock.power_substation.stored=Хранит: %s EU gregtech.multiblock.power_substation.capacity=Вместимость: %s EU gregtech.multiblock.power_substation.passive_drain=Пассивный отток: %s EU/t -gregtech.multiblock.power_substation.average_io=Срд. I/O: %s EU/t -gregtech.multiblock.power_substation.average_io_hover=Среднее изменение энергии внутреннего энергобанка подстанции gregtech.multiblock.power_substation.time_to_fill=Время до заполнения: %s gregtech.multiblock.power_substation.time_to_drain=Время до опустошения: %s gregtech.multiblock.power_substation.time_seconds=%s Секунд @@ -5045,7 +5038,7 @@ gregtech.multiblock.hpca.warning_structure_header=Подсказки по стр gregtech.multiblock.hpca.warning_multiple_bridges=- Множество мостов в структуре (не дают дополнительных преимущество) gregtech.multiblock.hpca.warning_no_computation=- Не проводятся вычисления gregtech.multiblock.hpca.warning_low_cooling=- Не достаточно хладогента -gregtech.command.usage=Применение: /gregtech +gregtech.command.usage=Применение: /gregtech gregtech.command.worldgen.usage=Применение: /gregtech worldgen gregtech.command.worldgen.reload.usage=Применение: /gregtech worldgen reload gregtech.command.worldgen.reload.success=Генератор мира успешно перезагрузился из настроек. @@ -5071,7 +5064,7 @@ gregtech.command.copy.click_to_copy=Нажмите для копирования gregtech.command.copy.copied_start=Скопировано [ gregtech.command.copy.copied_end=] в буфер обмена gregtech.chat.cape=§5Поздравляю: вы только что разблокировали новый плащ! Откройте в терминале Переключатель плащей для подробной информации.§r -gregtech.universal.clear_nbt_recipe.tooltip=§cЭто уничтожить весь контент! +gregtech.universal.clear_nbt_recipe.tooltip=§cЭто уничтожит весь контент! gregtech.cover.detector_base.message_inverted_state=Статус детектора: Инвертированный gregtech.cover.detector_base.message_normal_state=Статус детектора: Обычный gregtech.creative.chest.item=Предмет @@ -5901,3 +5894,112 @@ for.bees.species.fluorine=Фторовая # Bee Descriptions (many more to do) for.bees.description.clay=Органическая пчела, известная своей трудолюбивостью и усердием. Ходят слухи, что их можно найти грязь в нужном биоме.|Пчеловодство 101 +gregtech.gui.item_auto_collapse.tooltip.disabled=Авто-совмещение предметов выключено +gregtech.gui.item_auto_collapse.tooltip.enabled=Авто-совмещение предметов включено +gregtech.gui.configurator_slot.unavailable.tooltip=Слот Интегральной схемы недоступен +cover.ore_dictionary_filter.button.case_sensitive.enabled=С учетом регистра +cover.ore_dictionary_filter.button.match_all.disabled=Любая из записей из Словаря руд +cover.ore_dictionary_filter.button.match_all.enabled=Все записи из Словаря руд +cover.ore_dictionary_filter.button.case_sensitive.disabled=Без учета регистра +option.gregtech.multi_recipemap=Режимы работы +option.gregtech.primitive_pump=Примитивная помпа +option.gregtech.recipe_logic=Рецепты +option.gregtech.steam_boiler=Паровые котлы +option.gregtech.transformer=Трансформаторы +option.gregtech.workable=Механизмы +item.gt.tool.wire_cutter_lv.name=Электрокусачки (%s §7LV§f) +item.gt.tool.wire_cutter_hv.name=Электрокусачки (%s §6HV§r) +item.gt.tool.wire_cutter_iv.name=Электрокусачки (%s §eIV§r) +cover.voiding.voiding_mode=Режим очистки +tile.powderbarrel.name=Пороховая бочка +entity.ITNT.name=Промышленный динамит +gregtech.machine.me_import_fluid_hatch.configs.tooltip=Держит 16 жидкостей в наличии +gregtech.machine.me.item_export.tooltip.2=Может удерживать в себе бесконечное количество предмета +gregtech.machine.me.fluid_export.tooltip.2=Может удерживать в себе бесконечное количество жидкости +gregtech.machine.me.stocking_auto_pull_disabled=Авто-вытягивание выкл +record.sus=Leonz - Among Us Drip +option.gregtech.diode=Диоды +cover.robotic_arm.exact=§7Пред. +cover.bucket.mode.milli_bucket_exact=Л +option.gregtech.converter=Энерго-преобразователи +option.gregtech.energy=Энергохранилища +option.gregtech.block_lamp=Лампы +option.gregtech.maintenance=Неисправености +option.gregtech.block_ore=Блоки руды +option.gregtech.controllable=Управляемые машины +option.gregtech.multiblock=Мультиблочные структуры +cover.conveyor.distribution.name=Режим распространения +cover.bucket.mode.milli_bucket_rate=Л/с +gregtech.machine.me.stocking_item.tooltip=Извлекает предметы непосредственно из сети ME +gregtech.machine.me_import_item_hatch.configs.tooltip=Держит 16 предметов в наличии +tile.gt_explosive.breaking_tooltip=При обычной добыче взрывается, добудьте с SHIFT, чтобы забрать обратно +gregtech.machine.me.stocking_fluid.tooltip=Извлекает жидкости непосредственно из сети ME +gregtech.machine.me.copy_paste.tooltip=ЛКМ с Флешкой для копирования, ПКМ для применения +gregtech.machine.me.import_copy_settings=Настройки сохранены в Флешку +gregtech.machine.me.import_paste_settings=Настройки из Флешки применены +gregtech.machine.me.fluid_import.data_stick.name=§oНастройки ME Накопительного жидкостного люка +gregtech.recipe.dimensions_blocked=Заблокированные измерения: %s +gregtech.gui.item_auto_input.tooltip.enabled=Авто. ввод предметов включен +gregtech.gui.config_slot.set_only=§7Нажмите для §bНастройки§7.§r +gregtech.gui.me_bus.auto_pull_button=Нажмите для переключения авто. вытягивания предметов из МЕ сети +gregtech.multiblock.power_substation.average_out=Сред. выход. EU: %s + +# Mutation +gregtech.mutation.block_of=%s (Блок) +cover.item_filter.config_amount=Колесо прокрутки вверх увеличивает количество, вниз уменьшает.\nShift[§6x4§r],Ctrl[§ex16§r],Shift+Ctrl[§ax64§r]\nПравый клик увеличивает кол-во, левый уменьшает.\nShift+ЛКМ для очистки +tile.gt_explosive.lighting_tooltip=Нельзя зажечь с помощью Редстоуна +gregtech.multiblock.power_substation.average_in_hover=Средний приход EU/t в внутреннее хранилище вашей Силовой Подстанции +gregtech.machine.me.stocking_item.tooltip.2=Авто-вытягивание из МЕ сети будет автоматически пополнять первые 16 предметов в МЕ сети, обновляясь раз в 5 сек. +gregtech.machine.me.stocking_fluid.tooltip.2=Авто-вытягивание из МЕ сети будет автоматически пополнять первые 16 слотов жидкости в МЕ сети, обновляясь раз в 5 сек. +gregtech.gui.config_slot.auto_pull_managed=§4Отключено:§7 Управляется Авто-вытягиванием +tile.itnt.drops_tooltip=Намного мощнее, чем TNT. Все взорванные блоки выпадают как предметы +gregtech.multiblock.cleanroom.low_tier=Уровень вольтажа слишком низкий, требуется %s или выше! +gregtech.gui.item_auto_input.tooltip.disabled=Авто. ввод предметов выключен +gregtech.gui.me_bus.extra_slot=Доп. Слот/n§7Вложите доп. предмет для рецептов, например Линзы или Формы +gregtech.multiblock.power_substation.average_in=Сред. вход. EU: %s +gregtech.multiblock.power_substation.average_out_hover=Средний отток EU/t из внутреннего хранилище вашей Силовой Подстанции. Включая пассивные потери +gregtech.machine.me.item_import.data_stick.name=§oНастройки ME Накопительного предметного люка +gregtech.machine.me_stocking_item_bus.name=ME Накопительный предметный люк +gregtech.machine.me_stocking_fluid_hatch.name=ME Накопительный жидкостный люк +behaviour.filter_ui_manager=§fПКМ§7 для настроек, §fShift ПКС§7 для очистки +cover.ore_dictionary_filter.match_all=Совпадают все: %s +cover.ore_dictionary_filter.case_sensitive=С учетом регистра: %s +cover.filter.mode.title=Режим фильтра +cover.generic.transfer_mode=Режим передачи +cover.generic.manual_io=Ручной ввод/вывод +cover.generic.io=Режим ввода +cover.pump.mode=Режим помпы +cover.bucket.mode.bucket_rate=кЛ/с +cover.bucket.mode.bucket_exact=кЛ +cover.machine_controller.enable_with_redstone=Включить от Редстоуна +cover.machine_controller.disable_with_redstone=Выключить от Редстоуна +cover.machine_controller.machine_not_controllable=§cМеханизм не управляемый +tile.powderbarrel.drops_tooltip=Немного мощнее, чем TNT. Все взорванные блоки выпадают как предметы +entity.Powderbarrel.name=Пороховая бочка +tile.itnt.name=Промышленный динамит +gregtech.machine.me.stocking_auto_pull_enabled=Авто-вытягивание вкл +cover.machine_controller.this_cover=§cЭто улучшение +cover.machine_controller.cover_not_controllable=§cНет управляемых улучшений +cover.machine_controller.control=Управление: +gregtech.material.ilmenite_slag=Ильменитовый шлак +gregtech.material.zirconia=Оксид циркония +gregtech.command.datafix.usage=Применение: /gregtech datafix +gregtech.material.decalcified_bauxite_sludge=Декальцинированный шлам боксита +gregtech.material.zircon=Циркон +gregtech.material.zirconium_tetrachloride=Тетрахлорид циркония +gregtech.material.hafnia=Гафнии +gregtech.material.hafnium_tetrachloride=Тетрахлорид гафния +gregtech.material.zircaloy_4=Циркалой-4 +gregtech.material.inconel_718=Инконель-718 +gregtech.material.bauxite_sludge=Шлам боксита +gregtech.material.bauxite_slurry=Бокситовая суспензия +gregtech.material.cracked_bauxite_slurry=Бокситовая суспензия прошедшая крекинг +gregtech.material.bauxite_slag=Бокситовый шлак +gregtech.command.datafix.bqu.usage=Применение: /gregtech datafix bqu [confirm] +gregtech.command.datafix.bqu.backup=Скопируйте ваши сохранения и папку настроек BQu, а после перезапустите с 'confirm' аргументов +gregtech.command.datafix.bqu.start=Начинается перенос BQu Базы данных Квестов... +gregtech.command.datafix.bqu.complete=Закончен перенос Базы данных Квестов +gregtech.command.datafix.bqu.failed=Перенос Базы данных Квестов был произведен с ошибкой. Восстановите ваши сохранения! +behavior.tricorder.mte_owner=Владелец: %s +behavior.tricorder.mte_owner_offline=Владелец Не в сети или Не в этом мире! +behavior.tricorder.mte_owner_null=Это установлено не игроком! diff --git a/src/main/resources/assets/gregtech/lang/uk_UA.lang b/src/main/resources/assets/gregtech/lang/uk_UA.lang new file mode 100644 index 00000000000..46667cc7db0 --- /dev/null +++ b/src/main/resources/assets/gregtech/lang/uk_UA.lang @@ -0,0 +1,1090 @@ + + +death.attack.heat= +death.attack.chemical=%s потрапив у хімічний інцидент +death.attack.electric=%s був убитий струмом +death.attack.radiation=%s тепер світиться від радості +death.attack.turbine=%s засунув голову в турбіну +death.attack.explosion=%s вибухнув +death.attack.explosion.player=%s вибухнув з допомогою %s +death.attack.heat.player=%s був зварений живцем з допомогою %s +death.attack.shovel=%s було викопано з допомогою %s +death.attack.axe=%s було порубано на шматки з допомогою %s +death.attack.hammer=%s був розчавлений з допомогою %s +death.attack.mallet=%s був забитий до смерті з допомогою %s +death.attack.mining_hammer=%s був помилково прийнятий за руду %s +death.attack.wrench=%s вдарив %s гайковим ключем! +death.attack.frost=%s досліджував кріогенні технології +death.attack.mortar=%s було розтерто на порох з допомогою %s +death.attack.wire_cutter=кабель життєзабезпечення %s був перерізаний %s +death.attack.knife=%s був ніжно вдарений ножем з допомогою %s +death.attack.drill_lv=%s був пробурений при напрузі 32V з допомогою %s +death.attack.wrench_iv=До планів %s несподівано був доданий гайковий ключ %s +death.attack.buzzsaw=%s був розпиляний з допомогою %s +enchantment.disjunction=Роз'єднання +gregtech.machine.steam_grinder.name=Парова дробарка +death.attack.drill_hv=%s був пробурений при напрузі 512V з допомогою %s +death.attack.drill_iv=%s був пробурений при напрузі 8192V з допомогою %s +death.attack.chainsaw_lv=%s був розпиляний з допомогою %s +gregtech.multiblock.steam.low_steam=Не вистачає пари для роботи! +gregtech.machine.steam_hatch.name=Паровий люк +gregtech.multiblock.steam.steam_stored=Пар: %s +gregtech.machine.steam.steam_hatch.tooltip=§eМожливі рідини: §fПар +gregtech.machine.steam_import_bus.name=Парова вхідна шина +gregtech.machine.steam_export_bus.name=Парови вихідна шина +gregtech.machine.steam_oven.name=Парова мультиплавильна піч +gregtech.multiblock.require_steam_parts=Потребує парові люки та шини! +gregtech.multiblock.steam_.duration_modifier=Потребує в §f1.5x §7більше часу, не залежить від кількості предметів. +gregtech.top.energy_production=Виготовляє +gregtech.top.transform_down=Знижувати +gregtech.top.transform_input=Вхід: +gregtech.top.transform_output=Вихід: +gregtech.top.steam_heating_up=Нагрівання +gregtech.top.steam_no_water=Немає води +gregtech.top.convert_fe=Конвертація §cFE§r -> §eEU§r +gregtech.top.invalid_structure=Структура незавершена +gregtech.top.obstructed_structure=Структура заблокована +gregtech.top.maintenance_fixed=Технічне обслуговування непотрібне +gregtech.top.maintenance.wrench=Труба ослаблена +gregtech.top.maintenance.screwdriver=Гвинти ослаблені +gregtech.top.maintenance.hard_hammer=Обшивка має вм'ятини +gregtech.top.maintenance.crowbar=Щось там не повинно бути +gregtech.top.mode.export=Експортуємо +gregtech.top.unit.items=Предмети +gregtech.top.unit.fluid_milibuckets=МЛ +gregtech.top.unit.fluid_buckets=Л +gregtech.top.block_drops=Випадає +gregtech.top.ld_pipe_incomplete=Незавершений трубопровід +gregtech.top.ld_pipe_length=Довжина: +option.gregtech.converter=Енергетичні конвертори +option.gregtech.diode=Діоди +option.gregtech.energy=Енергосховища +option.gregtech.block_lamp=Лампи +option.gregtech.multi_recipemap=Режими роботи +option.gregtech.multiblock=Багатоблочні конструкції +option.gregtech.primitive_pump=Примітивний насос +option.gregtech.transformer=Трансформатори +gregtech.waila.progress_idle=Холостий +gregtech.waila.progress_sec=Прогрес: %d s / %d s +gregtech.waila.progress_computation=Розрахунок: %s / %s +gregtech.multiblock.title=Схема багатоблокової структури +gregtech.multiblock.assembly_line.description=Складальна лінія - це велика багатоблочна конструкція, що складається з 5 до 16 "шматочків". Теоретично, це велика складальна машина, що використовується для виготовлення покращених компонентів. +gregtech.multiblock.fusion_reactor.uv.description=Термоядерний реактор модель 3 - це велика багатоблочна конструкція, яка використовується для злиття елементів у більш важкі. Може використовувати лише енергетичні люки типу UV. З кожним люком буфер енергії збільшується на 40 млн EU, і має максимум у 640 млн EU. +gregtech.multiblock.fusion_reactor.heat=Тепло: %s +metaitem.coin.doge.name=Догкоін +metaitem.shape.empty.name=Порожня форма +metaitem.dynamite.name=Динаміт +metaitem.power_unit.lv.name=Блок живлення (LV) +metaitem.power_unit.mv.name=Блок живлення (MV) +metaitem.power_unit.hv.name=Блок живлення (HV) +metaitem.nano_saber.name=Наношабля +metaitem.nano_saber.tooltip=Ryujin no ken wo kurae! +metaitem.shape.mold.plate.tooltip=Форма для виготовлення пластин +metaitem.shape.mold.plate.name=Форма (Пластина) +metaitem.shape.mold.gear.tooltip=Форма для виготовлення шестерень +metaitem.shape.mold.gear.name=Форма (Шестерня) +metaitem.shape.mold.bottle.name=Форма (Пляшка) +metaitem.shape.mold.bottle.tooltip=Форма для виготовлення пляшок +metaitem.shape.mold.ingot.name=Форма (Злиток) +metaitem.shape.mold.ball.name=Форма (Куля) +metaitem.shape.mold.ball.tooltip=Форма для виготовлення куль +metaitem.shape.mold.block.name=Форма (Блок) +metaitem.shape.mold.nugget.name=Форма (самородки) +metaitem.shape.mold.cylinder.name=Форма (Циліндр) +metaitem.shape.mold.name.name=Форма (Назва) +metaitem.shape.mold.cylinder.tooltip=Форма для формування циліндрів +metaitem.shape.mold.gear.small.tooltip=Форма для виготовлення малих шестерень +metaitem.shape.mold.rotor.name=Форма (Ротор) +metaitem.shape.extruder.plate.name=Форма екструдера (пластина) +metaitem.shape.extruder.plate.tooltip=Форма екструдера для виготовлення пластин +metaitem.shape.extruder.bolt.name=Форма екструдера (Болт) +metaitem.shape.extruder.ring.tooltip=Форма екструдера для виготовлення кілець +metaitem.shape.extruder.cell.name=Форма екструдера (Капсула) +metaitem.shape.extruder.casing.name=Форма екструдера (Корпус) +metaitem.shape.extruder.pipe.tiny.name=Форма екструдера (Крихітна трубка) +metaitem.shape.extruder.pipe.small.name=Форма екструдера (маленька труба) +metaitem.shape.extruder.pipe.normal.tooltip=Форма екструдера для виготовлення труб +metaitem.shape.extruder.pipe.large.name=Форма екструдера (Велика труба) +metaitem.shape.extruder.pipe.huge.tooltip=Форма екструдера для виготовлення величезних труб +metaitem.shape.extruder.block.name=Форма екструдера (Блок) +metaitem.shape.extruder.block.tooltip=Форма екструдера для виготовлення блоків +metaitem.shape.extruder.shovel.tooltip=Форма екструдера для виготовлення лопат +metaitem.shape.extruder.hoe.name=Форма екструдера (Головка мотики) +metaitem.shape.extruder.hoe.tooltip=Форма екструдера для виготовлення мотик +metaitem.shape.extruder.saw.name=Форма екструдера (Пильний диск) +metaitem.shape.extruder.saw.tooltip=Форма екструдера для виготовлення пилок +metaitem.shape.extruder.gear.name=Форма екструдера (Шестерня) +death.attack.pickaxe=мізки %s було вибито з допомогою %s +death.attack.hoe=%s був проораний з допомогою %s +death.attack.wrench_hv=Труби %s були послаблені з допомогою %s +gregtech.multiblock.steam_grinder.description=Багатоблочний подрібнювач парової епохи. Для побудови потрібно щонайменше 14 бронзових корпусів. Не може використовувати звичайні вхідні/вихідні шини, або рідині люки. Може використовувати тільки парові люки. +gregtech.multiblock.steam_oven.description=Мультиплавильна піч парової епохи. Для побудови потрібно щонайменше 6 бронзових корпусів. Не може використовувати звичайні вхідні/вихідні шини, або рідині люки. Може використовувати тільки парові люки. Паровий люк має бути на першому рівні, та не має бути більше одного. +gregtech.top.working_disabled=Робота призупинена +gregtech.top.transform_up=Підвищує +gregtech.top.convert_eu=Конвертація §eEU§r -> §cFE§r +gregtech.top.valid_structure=Структура завершена +gregtech.top.maintenance.wire_cutter=Дроти перегоріли +gregtech.top.mode.import=Імпортуємо +gregtech.top.ld_pipe_no_network=Не знайдено жодного трубопроводу +gregtech.top.ld_pipe_connected=Трубопровід під'єднано +gregtech.top.ld_pipe_output=Вихід +gregtech.top.ld_pipe_input_endpoint=Кінцева точка входу: +gregtech.top.ld_pipe_output_endpoint=Кінцева точка виходу: +option.gregtech.controllable=Керовані машини +option.gregtech.maintenance=Проблеми з технічним обслуговуванням +option.gregtech.recipe_logic=Рецепти +option.gregtech.steam_boiler=Парові котли +gregtech.waila.energy_stored=Енергія: %d EU / %d EU +death.attack.spade=%s був розкопаний з допомогою %s +death.attack.screwdriver_lv=Гвинти %s були відкручені з допомогою %s +gregtech.top.energy_consumption=Використовує +gregtech.top.maintenance_broken=Технічне обслуговування потрібне +gregtech.top.maintenance.soft_mallet=Щось заклинило +gregtech.top.primitive_pump_production=Виробництво: +gregtech.top.filter.label=Фільтр: +gregtech.top.link_cover.color=Колір: +gregtech.top.ld_pipe_input=Вхід +option.gregtech.block_ore=Рудні блоки +option.gregtech.workable=Механізми +gregtech.waila.progress_tick=Прогрес: %d t / %d t +gregtech.machine.steam_bus.tooltip=Не працює з не паровими багатоблочними конструкціями +metaitem.shape.mold.name.tooltip=Форма для іменування предметів у формувальному пресі (перейменувати форму за допомогою ковадла) +metaitem.shape.mold.gear.small.name=Форма (Мала шестерня) +metaitem.shape.mold.rotor.tooltip=Форма для виготовлення роторів +metaitem.shape.extruder.rod.name=Форма екструдера (Cтержень) +metaitem.shape.extruder.ingot.tooltip=Форма екструдера для, зачекайте, хіба ми не можемо просто використовувати піч? +metaitem.shape.extruder.wire.tooltip=Форма екструдера для виготовлення дротів +metaitem.shape.extruder.pipe.tiny.tooltip=Форма екструдера для виготовлення крихітних труб +metaitem.shape.extruder.pipe.small.tooltip=Форма екструдера для виготовлення малих труб +metaitem.shape.extruder.pipe.normal.name=Форма екструдера (Труба) +metaitem.shape.extruder.pipe.large.tooltip=Форма екструдера для виготовлення великих труб +metaitem.shape.extruder.pipe.huge.name=Форма екструдера (Величезна труба) +metaitem.shape.extruder.sword.tooltip=Форма екструдера для виготовлення мечів +metaitem.shape.extruder.pickaxe.name=Форма екструдера (Головка кайла) +metaitem.shape.extruder.pickaxe.tooltip=Форма екструдера для виготовлення кайла +gregtech.multiblock.primitive_blast_furnace.bronze.description=Примітивна доменна піч (ПДП) це багатоблочна структура, що використовуєть для виготовлення сталі на початку гри. Хоча вона і не дуже швидка, вона забезпечить вам сталь для перших кроків. +gregtech.multiblock.coke_oven.description=Коксова піч - це багатоблочна конструкція, яка використовується для отриманя коксу та креозоту на початку гри. Вона не потребує палива і має внутрішній резервуар на 32 відра креозоту. Доступ до інвентарю можна отримати через люк коксової печі. +gregtech.multiblock.vacuum_freezer.description=Вакуумна морозильна камера - це багатоблочна структура, яка в більшості випадків використовується для охолоджування гарячих злитків до їхньоніх звичайних температур. Також може заморожувати інші речовини, до прикладу вода. +gregtech.multiblock.implosion_compressor.description=Імплохійний компресор - це багатоблочна структура яка використовує вибухівки щоб перетворити пил на відповідні дорогоцінні камені. +gregtech.multiblock.pyrolyse_oven.description=Піролізна піч - це багатоблочна конструкція, яка використовується для перетворення колод на деревне вугілля та креозот, або золу та тяжку нафту. +gregtech.multiblock.cracker.description=Крекінгова установка - це багатоблочна конструкція, яка використовується для перетворення легкого та важкаго палина на їхні потріскані варіанти. +gregtech.multiblock.large_combustion_engine.description=Великий двигун внутрішнього згоряння - це багатоблочна конструкція, яка діє як генератор внетрішнього згоряння для вироблення EV енергіє. +metaitem.shape.mold.anvil.name=Форма (Ковадло) +metaitem.shape.mold.anvil.tooltip=Форма для формування ковадла +metaitem.shape.extruder.rod.tooltip=Форма екструдера для виготовлення стержнів +metaitem.shape.extruder.bolt.tooltip=Форма екструдера для виготовлення болтів +metaitem.shape.extruder.ring.name=Форма екструдера (Кільце) +metaitem.shape.extruder.cell.tooltip=Форма екструдера для виготовлення капсул +metaitem.shape.extruder.ingot.name=Форма екструдера (злиток) +metaitem.shape.extruder.wire.name=Форма екструдера (Дріт) +metaitem.shape.extruder.casing.tooltip=Форма екструдера для виготовлення корпусів +metaitem.shape.extruder.sword.name=Форма екструдера (Лезо меча) +metaitem.shape.extruder.shovel.name=Форма екструдера (Головка лопати) +metaitem.shape.extruder.axe.name=Форма екструдера (Головка сокири) +metaitem.shape.extruder.axe.tooltip=Форма екструдера для виготовлення сокир +death.attack.file=%s був заокруглений до сметрі з допомогою %s +death.attack.drill_ev=%s був пробурений при напрузі 2048V з допомогою %s +death.attack.butchery_knife=%s був перетворений у фарш з допомогою %s +death.attack.drill_mv=%s був пробурений при напрузі 128V з допомогою %s +death.attack.wrench_lv=Труби %s були ослаблені з допомогою %s +gregtech.multiblock.large_turbine.description=Великі турбіни - це багатоблочна конструкція яка генерую електроенергію з пари, газів, і плазми шляхом обертання ротора турбіни. Вихід енергії залежить від ефективності ротора та поточної швидкості турбіни. У центрі конструкції використовуються корпуси коробки передач. +metaitem.shape.extruder.hammer.name=Форма екструдера (Молоткова головка) +metaitem.shape.extruder.hammer.tooltip=Форма екструдера для виготовлення молотків +metaitem.shape.extruder.file.tooltip=Форма екструдера для воготовлення напилка +metaitem.shape.extruder.file.name=Форма екструдера (Головка напилка) +metaitem.shape.extruder.gear.tooltip=Форма екструдера для виготовлення шестерень +metaitem.shape.extruder.bottle.name=Форма екструдера (Пляшка) +death.attack.scythe=Душу %s було викрадено з допомогою %s +gregtech.multiblock.extreme_combustion_engine.description=Екстремальний двигун внутрішнього згорання - це багатоблочна конструкція, яка діє як генератор згоряння для IV рівня напруги. +gregtech.multiblock.distillation_tower.description=Дистиляціна вежа - це багатоблочана конструкція, яка використовується для перегонки різних видів нафти та деяких побічних продуктів. Кожен шар починаючи з другого повинен мати рівно один вихідний люк. Нижній шар може виводити продукти і вводити рідини в будь-якому положенні. +gregtech.multiblock.electric_blast_furnace.description=Електрична доменна піч (ЕДП) - це багатоблочна конструкція, яка використовується для виплавки сплавів, готових металів та переробки сирих. Вона необхідна для отримання високоякісних сплавів і металів, таких як алюміній, нержавіюча сталь, титат і сплав наквади. +gregtech.multiblock.multi_furnace.description=Мультиплавильна піч - це багатоблочна конструкція, яка використовується для виплавлення великої кількості предметів. Різні рівні котушок забезпечують підвищення швидкості та енергоефективності. 32 - це базова кількість предметів, що виплавляються за операцію, яке можна збільшити, використовуючи котушки вищого рівня. +gregtech.multiblock.large_boiler.description=Великі котли - це багатоблочна структура, яка виробляє пар за допомогою енергії та води. Джерелом енергії є будь-яке тверде паливо з певним часом горіння або дизельне/напіврідке паливо. Може бути сповільнене заради зменшення кількості пари та потрібного палива. +gregtech.multiblock.fusion_reactor.luv.description=Термоядерний реактор модель 1 - це велика багатоблочна конструкція, яка використовується для злиття елементів у більш важкі. Може використовувати лише енергетичні люки типу LuV, ZPM, і UV. З кожним люком буфер енергії збільшується на 10 млн EU, і має максимум у 160 млн EU. +gregtech.multiblock.fusion_reactor.zpm.description=Термоядерний реактор модель 2 - це велика багатоблочна конструкція, яка використовується для злиття елементів у більш важкі. Може використовувати лише енергетичні люки типу ZPM і UV. З кожним люком буфер енергії збільшується на 20 млн EU, і має максимум у 320 млн EU. +gregtech.multiblock.large_chemical_reactor.description=Великий хімічний реактор виконує хімічні реакції зі 100%% енергоефективністю. Розгін збільшує швидкість і евергію в 4 рази. Багатоблочна конструкція потребує рівно 1 купронікелевий блок, який повинен бути розміщений поруч з копрусом ПТФЕ труби, розташованим в центрі. +metaitem.credit.platinum.tooltip=512 Кредитів +metaitem.credit.osmium.tooltip=4096 Кредити +metaitem.credit.naquadah.name=Наквадовий Кредит +metaitem.coin.gold.ancient.name=Старовинна золота монета +metaitem.coin.gold.ancient.tooltip=Знайдено в стародавніх руїнах +metaitem.power_unit.iv.name=Блок живлення (IV) +metaitem.shape.mold.casing.tooltip=Форма для виготовлення корпусів +metaitem.shape.mold.block.tooltip=Форма для виготовлення блоків +gregtech.multiblock.primitive_water_pump.description=Примітивна водяна помпа - це багатоблочна конструкція до парової ери, яка збирає води один раз на секунду, залежно в якому біома. Вона може використовувати помповий, ULV або LV вихідний люк, збільшуючи кількість води на рівень. Розраховується за формулою: коефіцієнь біома * множник люка +metaitem.credit.osmium.name=Осмійські Кредит +metaitem.credit.naquadah.tooltip=32768 Кредити +metaitem.credit.neutronium.name=Нейтронний кредит +metaitem.credit.neutronium.tooltip=262144 Кредити +metaitem.coin.chocolate.name=Шоколадна монетка +metaitem.coin.chocolate.tooltip=Загорнутий у золото +metaitem.shape.empty.tooltip=Сировина для виготовлення прес-форм та екструзійних форм +metaitem.power_unit.ev.name=Блок живлення (EV) +metaitem.shape.mold.credit.name=Форма (Монета) +metaitem.shape.mold.credit.tooltip=Безпечна форма для виготовлення монет (не загуби!) +metaitem.shape.mold.casing.name=Форма (Корпус) +metaitem.shape.mold.ingot.tooltip=Форма для виготовлення злитків +metaitem.shape.mold.nugget.tooltip=Форма для виготовлення самородків +gregtech.multiblock.primitive_water_pump.extra2=Множники люків:/n Люк насоса: 1x/n Вихідний люк ULV: 2x/n Вихідний люк LV: 4x/n/nПід час дощу в біомі насоса загальне виробництво води збільшується на 50%%. +gregtech.multiblock.processing_array.description=Оброблювальний масив об'єднує до 16 одноблочних машин в один мультиблок, що значно полегшує автоматизацію. +item.invalid.name=Некоректний предмет +fluid.empty=Порожньо +gregtech.tooltip.hold_shift=Утримуйте SHIFT, щоб дізнатися більше +gregtech.tooltip.hold_ctrl=Утримуйте CTRL, щоб дізнатися більше +gregtech.tooltip.tool_fluid_hold_shift=Утримуйте SHIFT, щоб відобразити інформацію про рідину та інструмент +metaitem.generic.fluid_container.tooltip=%,d/%,dЛ %s +metaitem.generic.electric_item.tooltip=%,d/%,d EU - Рівень %s +metaitem.electric.discharge_mode.enabled=§eУвімкнено режим розрядки +metaitem.dust.tooltip.purify=Киньте в Казан, щоб отримати чистий пил +metaitem.int_circuit.configuration=§aНалаштоване значення: §f%d§7 +metaitem.credit.copper.tooltip=0.125 Кредитів +metaitem.credit.silver.name=Срібний кредит +metaitem.credit.silver.tooltip=8 кредитів +metaitem.credit.gold.name=Золотий кредит +metaitem.credit.gold.tooltip=64 Кредитів +metaitem.credit.platinum.name=Платиновий кредит +metaitem.shape.extruder.rod_long.tooltip=Форма екструдера для виготовлення довгих стержнів +metaitem.shape.extruder.rod_long.name=Форма екструдера (Довгий стержень) +metaitem.spray.empty.name=Балончик (порожній) +metaitem.spray.empty.tooltip=Можна наповнювати спреями різних кольорів + +# Fluid Cells +metaitem.fluid_cell.empty=Порожньо +metaitem.fluid_cell.name=%s Капсула +metaitem.fluid_cell.universal.name=%s Універсальна капсула +metaitem.large_fluid_cell.steel.name=%s Сталева капсула +metaitem.fluid_cell.glass_vial.name=%s Пробірка +metaitem.large_fluid_cell.titanium.name=%s Титанова капсула +metaitem.spray.solvent.name=Балончик (розчинник) +metaitem.spray.can.dyes.orange.name=Балончик (помаранчевий) +metaitem.spray.can.dyes.purple.name=Балончик (фіолетовий) +metaitem.tool.matches.name=Сірник +metaitem.tool.lighter.platinum.name=Платинова запальничка +metaitem.battery.hull.hv.name=Великий корпус батареї +metaitem.battery.hull.ev.name=Малий корпус ванадієвої батареї +metaitem.battery.hull.zpm.name=Корпус середньої наквадівої батареї +metaitem.battery.hull.zpm.tooltip=Порожній §fZPM §7корпус батареї +metaitem.battery.hull.uv.name=Корпус великої наквадівої батареї +metaitem.battery.hull.uv.tooltip=Порожній §3UV §7корпус батареї +metaitem.battery.charge_time=§aЗберігає %,d%s електроенергії +metaitem.battery.charge_unit.minute=хв +metaitem.battery.charge_unit.hour=год +metaitem.battery.re.ulv.tantalum.name=Танталовий конденсатор +metaitem.battery.re.lv.cadmium.name=Маленька кадмієва батарея +metaitem.battery.re.lv.cadmium.tooltip=Багаторазова батарея +metaitem.battery.re.lv.lithium.name=Маленька літієва батарея +metaitem.battery.re.mv.cadmium.tooltip=Багаторазова батарея +metaitem.battery.re.mv.sodium.tooltip=Багаторазова батарея +metaitem.battery.re.hv.cadmium.name=Велика кадмієва батарея +metaitem.battery.re.hv.cadmium.tooltip=Багаторазова батарея +metaitem.battery.re.hv.lithium.name=Велика літієва батарея +metaitem.battery.re.hv.sodium.name=Велика натрієва батарея +metaitem.battery.ev.vanadium.name=Маленька ванадієва батарея +metaitem.battery.iv.vanadium.name=Середня ванадієва батарея +metaitem.battery.luv.vanadium.name=Велика ванадієва батарея +metaitem.battery.luv.vanadium.tooltip=Багаторазова батарея +metaitem.battery.uv.naquadria.name=Велика наквадрієва батарея +metaitem.energy_crystal.name=Енергетичний кристал +metaitem.energy.lapotronic_orb.tooltip=Багаторазова батарея +metaitem.energy.lapotronic_orb_cluster.name=Лапотронний кластер енергетичних куль +metaitem.energy.module.name=Енергетичний модуль +metaitem.energy.cluster.name=Енергетичний кластер +metaitem.max.battery.tooltip=Зарядіть це, щоб виграти Minecraft +metaitem.electric.motor.luv.name=Електродвигун LuV +metaitem.electric.motor.zpm.name=Електродвигун ZPM +metaitem.electric.motor.uev.name=Електродвигун UEV +metaitem.electric.motor.uxv.name=Електродвигун UXV +metaitem.electric.pump.ev.name=Електронасос EV +metaitem.electric.pump.iv.name=Електронасос IV +metaitem.electric.pump.uev.name=Електронасос UEV +metaitem.electric.pump.uxv.name=Електронасос UXV +metaitem.fluid.regulator.lv.name=Регулятор рідини LV +metaitem.fluid.regulator.mv.name=Регулятор рідини MV +metaitem.fluid.regulator.luv.name=Регулятор рідини LuV +metaitem.fluid.regulator.uv.name=Регулятор рідини UV +metaitem.conveyor.module.lv.name=Конвеєрний модуль LV +metaitem.conveyor.module.mv.name=Конвеєрний модуль MV +metaitem.conveyor.module.ev.name=Конвеєрний модуль EV +metaitem.conveyor.module.zpm.name=Конвеєрний модуль ZPM +metaitem.conveyor.module.uhv.name=Конвеєрний модуль UHV +metaitem.conveyor.module.uiv.name=Конвеєрний модуль UIV +metaitem.conveyor.module.uxv.name=Конвеєрний модуль UXV +metaitem.conveyor.module.opv.name=Конвеєрний модуль OpV +metaitem.electric.piston.lv.name=Електричний поршень LV +metaitem.electric.piston.mv.name=Електричний поршень MV +metaitem.electric.piston.ev.name=Електричний поршень EV +metaitem.electric.piston.iv.name=Електричний поршень IV +metaitem.electric.piston.luv.name=Електричний поршень LuV +metaitem.electric.piston.zpm.name=Електричний поршень ZPM +metaitem.electric.piston.uhv.name=Електричний поршень UHV +metaitem.electric.piston.uev.name=Електричний поршень UEV +metaitem.electric.piston.uiv.name=Електричний поршень UIV +metaitem.electric.piston.uxv.name=Електричний поршень UXV +metaitem.electric.piston.opv.name=Електричний поршень OpV +metaitem.robot.arm.mv.name=Роботизована рука MV +metaitem.robot.arm.hv.name=Роботизована рука HV +metaitem.robot.arm.iv.name=Роботизована рука IV +metaitem.robot.arm.luv.name=Роботизована рука LuV +metaitem.robot.arm.uv.name=Роботизована рука UV +metaitem.robot.arm.uhv.name=Роботизована рука UHV +metaitem.robot.arm.uiv.name=Роботизована рука UIV +metaitem.robot.arm.opv.name=Роботизована рука OpV +metaitem.field.generator.mv.name=Генератор поля MV +metaitem.field.generator.ev.name=Генератор поля EV +metaitem.field.generator.iv.name=Генератор поля IV +metaitem.field.generator.luv.name=Генератор поля LuV +metaitem.field.generator.zpm.name=Генератор поля ZPM +metaitem.field.generator.uhv.name=Генератор поля UHV +metaitem.field.generator.uev.name=Генератор поля UEV +metaitem.field.generator.uiv.name=Генератор поля UIV +metaitem.emitter.mv.name=Випромінювач MV +metaitem.emitter.ev.name=Випромінювач EV +metaitem.emitter.iv.name=Випромінювач IV +metaitem.emitter.luv.name=Випромінювач LuV +metaitem.emitter.zpm.name=Випромінювач ZPM +metaitem.emitter.uev.name=Випромінювач UEV +metaitem.emitter.uxv.name=Випромінювач UXV +metaitem.emitter.opv.name=Випромінювач OpV +metaitem.sensor.lv.name=Сенсор LV +metaitem.sensor.mv.name=Сенсор MV +metaitem.sensor.ev.name=Сенсор EV +metaitem.sensor.iv.name=Сенсор IV +metaitem.sensor.luv.name=Сенсор LuV +metaitem.sensor.zpm.name=Сенсор ZPM +metaitem.sensor.uv.name=Сенсор UV +metaitem.sensor.uhv.name=Сенсор UHV +metaitem.sensor.uev.name=Сенсор UEV +metaitem.sensor.uiv.name=Сенсор UIV +metaitem.sensor.opv.name=Сенсор OpV +metaitem.tool.datastick.name=Накопичувач даних +metaitem.tool.datastick.tooltip=Сховище для простих даних +metaitem.tool.dataorb.name=Сфера даних +metaitem.tool.datamodule.name=Модуль даних +metaitem.circuit.integrated.name=Запрограмована схема +metaitem.circuit.integrated.tooltip=ПКМ щоб відкрити графічний інтерфейс/n/nShift-ПКМ по машині/nзі схемою в руці/nщоб запрограмувати машину./n +metaitem.circuit.integrated.gui=Конфігурація схеми +item.glass.lens=Скляна лінза (Біла) +metaitem.glass_lens.orange.name=Скляна лінза (Помаранчева) +metaitem.glass_lens.magenta.name=Скляна лінза (Пурпурна) +metaitem.glass_lens.pink.name=Скляна лінза (Рожева) +metaitem.glass_lens.yellow.name=Скляна лінза (Жовта) +metaitem.glass_lens.light_gray.name=Скляна лінза (Світло-сіра) +metaitem.glass_lens.cyan.name=Скляна лінза (Блакитна) +metaitem.glass_lens.purple.name=Скляна лінза (Фіолетова) +metaitem.glass_lens.green.name=Скляна лінза (Зелена) +metaitem.glass_lens.red.name=Скляна лінза (Червона) +metaitem.glass_lens.black.name=Скляна лінза (Чорна) + +#CIRCUITS LOCALIZATION +metaitem.boule.silicon.name=Монокристалічний кремній +metaitem.boule.phosphorus.tooltip=Необроблена схема +metaitem.boule.naquadah.tooltip=Необроблена схема +metaitem.boule.neutronium.tooltip=Необроблена схема +metaitem.wafer.phosphorus.tooltip=Необроблена схема +metaitem.board.epoxy.tooltip=Покращена плата +metaitem.board.fiber_reinforced.tooltip=Екстремально гарна плата +metaitem.board.multilayer.fiber_reinforced.name=Багато рівнева посилена волокном друкована плата +metaitem.board.fiber_reinforced.name=Посилена волокном друкована плата +metaitem.board.multilayer.fiber_reinforced.tooltip=Відмінна плата +metaitem.board.wetware.name=Друкована плата зі системою життєзабезпечення +metaitem.board.wetware.tooltip=Плата, яка зберігає життя +metaitem.circuit_board.basic.name=Друкована плата +metaitem.circuit_board.basic.tooltip=Базова друкована плата +metaitem.circuit_board.good.name=Гарна друкована плата +metaitem.circuit_board.good.tooltip=Гарна друкована плата +metaitem.circuit_board.plastic.name=Пластикова друкована плата +metaitem.circuit_board.plastic.tooltip=Гарна друкована плата +metaitem.circuit_board.advanced.name=Покращена друкована плата +metaitem.circuit_board.advanced.tooltip=Покращена друкована плата +metaitem.circuit_board.extreme.name=Екстремально гарна друкована плата +metaitem.circuit_board.extreme.tooltip=Більш покращена друкована плата +metaitem.circuit_board.elite.tooltip=Відмінна друкована плата +metaitem.circuit.vacuum_tube.name=Вакумна лампа +metaitem.component.diode.name=Діод +metaitem.component.diode.tooltip=Базовий електричний компонент +metaitem.component.resistor.name=Резистор +metaitem.component.resistor.tooltip=Базовий електричний компонент +metaitem.component.transistor.name=Транзистор +metaitem.component.capacitor.name=Конденсатор +metaitem.component.glass.tube.name=Скляна трубка +metaitem.component.inductor.name=Індуктор +metaitem.component.inductor.tooltip=Мала котушка +metaitem.component.smd.diode.name=SMD Діод +metaitem.component.smd.capacitor.name=SMD Конденсатор +metaitem.component.smd.capacitor.tooltip=Електричний компонент +metaitem.component.smd.transistor.tooltip=Електричний компонент +metaitem.component.smd.resistor.name=SMD Резистор +metaitem.component.smd.resistor.tooltip=Електричний компонент +metaitem.component.smd.inductor.name=SMD Індуктор +metaitem.component.smd.inductor.tooltip=Електричний компонент +metaitem.component.advanced_smd.diode.name=Покращений SMD Діод +metaitem.component.advanced_smd.capacitor.name=Покращений SMD Конденсатор +metaitem.component.advanced_smd.capacitor.tooltip=Покращений електричний компонент +metaitem.component.advanced_smd.transistor.name=Покращений SMD Транзистор +metaitem.component.advanced_smd.resistor.name=Покращений SMD Резистор +metaitem.component.advanced_smd.resistor.tooltip=Покращений електричний компонент +metaitem.component.advanced_smd.inductor.name=Покращений SMD Індуктор +metaitem.component.advanced_smd.inductor.tooltip=Покращений електричний компонент +metaitem.wafer.advanced_system_on_chip.name=Пластина ASoC +metaitem.wafer.advanced_system_on_chip.tooltip=Необроблена покращена схема +metaitem.wafer.central_processing_unit.tooltip=Необроблений модуль обробки +metaitem.credit.cupronickel.name=Купронікелевий кредит +metaitem.credit.cupronickel.tooltip=1 Кредит +metaitem.electric.discharge_mode.tooltip=Використовуйте затиснувши кнопку Присісти для перемикання режиму розрядки +metaitem.crushed.tooltip.purify=Киньте в казан, щоб отримати очищену руду +metaitem.shape.extruder.rotor.name=Форма екструдера (Ротор) +metaitem.shape.extruder.rotor.tooltip=Форма екструдера для виготовлення роторів +metaitem.credit.copper.name=Мідний кредит +gregtech.multiblock.primitive_water_pump.extra1=Коефіцієнт біома:/n Океан, річка: 1000 л/с/n Болото: 800 л/с/n Джунглі: 350 л/с/n Засніжені: 300 л/с/n Рівнина, ліс: 250 л/с/n Тайга: 175 л/с/n Пляж: 170 Л/с/n Інше: 100 л/с +gregtech.multiblock.advanced_processing_array.description=Оброблювальний масив об'єднує до 64 одноблочних машин в один мультиблок, що значно полегшує автоматизацію. +gregtech.tooltip.fluid_pipe_hold_shift=Утримуйте SHIFT, щоб відобразити інформацію про рідину +metaitem.electric.discharge_mode.disabled=§eВимкнено режим розряду +metaitem.shape.extruder.bottle.tooltip=Форма екструдера для виготовлення пляшок +metaitem.shape.extruder.gear_small.tooltip=Форма екструдера для виготовлення малих шестерень +metaitem.shape.extruder.foil.name=Форма екструдера (Фольга) +metaitem.shape.extruder.gear_small.name=Форма екструдера (Мала шестерня) +metaitem.shape.extruder.foil.tooltip=Форма екструдера для виготовлення фольги з неметалів +metaitem.plant.ball.name=Кулька біомаси +metaitem.fluid_cell.universal.empty=Порожньо +metaitem.large_fluid_cell.aluminium.name=%s Алюмінієва капсула +metaitem.large_fluid_cell.stainless_steel.name=%s Капсула з нержавіючої сталі +metaitem.large_fluid_cell.tungstensteel.name=%s Вольфрамова капсула +metaitem.spray.can.dyes.white.name=Балончик (білий) +metaitem.spray.can.dyes.magenta.name=Балончик (пурпурний) +metaitem.spray.can.dyes.yellow.name=Балончик (жовтий) +metaitem.spray.can.dyes.lime.name=Балончик (лайм) +metaitem.spray.can.dyes.pink.name=Балончик (рожевий) +metaitem.spray.can.dyes.gray.name=Балончик (сірий) +metaitem.spray.can.dyes.silver.name=Балончик (світло-сірий) +metaitem.spray.can.dyes.cyan.name=Балончик (блакитний) +metaitem.spray.can.dyes.blue.name=Балончик (синій) +metaitem.spray.can.dyes.brown.name=Балончик (коричневий) +metaitem.spray.can.dyes.green.name=Балончик (зелений) +metaitem.spray.can.dyes.red.name=Балончик (червоний) +metaitem.spray.can.dyes.black.name=Балончик (чорний) +metaitem.tool.matchbox.name=Сірникова коробка +metaitem.tool.matchbox.tooltip=Це не автомобіль +metaitem.tool.lighter.platinum.tooltip=На ньому викарбувано відомого майстра жартів +metaitem.battery.hull.lv.tooltip=Порожній §7LV §7корпус батареї +metaitem.battery.hull.mv.tooltip=Порожній §bMV §7корпус батареї +metaitem.tool.lighter.invar.name=Запальничка + + +metaitem.battery.hull.lv.name=Малий корпус батареї +metaitem.battery.hull.mv.name=Середній корпус батареї +metaitem.battery.hull.hv.tooltip=Великий §6HV §7корпус батареї +metaitem.battery.hull.iv.name=Корпус середньої ванадієвої батареї +metaitem.battery.hull.iv.tooltip=Порожній §1IV §7корпус батареї +metaitem.battery.re.ulv.tantalum.tooltip=Багаторазова батарея +metaitem.battery.re.lv.sodium.tooltip=Багаторазова батарея +metaitem.battery.re.mv.cadmium.name=Середня кадмієва батарея +metaitem.battery.re.hv.lithium.tooltip=Багаторазова батарея +metaitem.battery.re.hv.sodium.tooltip=Багаторазова батарея +metaitem.battery.ev.vanadium.tooltip=Багаторазова батарея +metaitem.battery.iv.vanadium.tooltip=Багаторазова батарея +metaitem.battery.zpm.naquadria.name=Середня наквадрієва батарея +metaitem.battery.zpm.naquadria.tooltip=Багаторазова батарея +metaitem.battery.hull.ev.tooltip=Порожній §5EV §7корпус батареї +metaitem.battery.hull.luv.name=Великий ванадієвий корпус батареї +metaitem.battery.hull.luv.tooltip=Порожній §dLuV §7корпус батареї +metaitem.battery.charge_unit.second=сек +metaitem.battery.re.lv.lithium.tooltip=Багаторазова батарея +metaitem.battery.re.lv.sodium.name=Маленька натрієва батарея +metaitem.battery.re.mv.lithium.name=Середня літієва батарея +metaitem.battery.re.mv.lithium.tooltip=Багаторазова батарея +metaitem.battery.re.mv.sodium.name=Середня натрієва батарея +metaitem.battery.uv.naquadria.tooltip=Багаторазова батарея +metaitem.energy_crystal.tooltip=Багаторазова батарея +metaitem.lapotron_crystal.name=Лапотроний кристал +metaitem.lapotron_crystal.tooltip=Багаторазова батарея +metaitem.energy.lapotronic_orb_cluster.tooltip=Багаторазова батарея +metaitem.zpm.name=Модуль нульової точки +metaitem.energy.cluster.tooltip=Багаторазова батарея +metaitem.max.battery.name=Досконала батарея +metaitem.electric.motor.iv.name=Електродвигун IV +metaitem.energy.lapotronic_orb.name=Лапотронічна енергетична куля +metaitem.energy.module.tooltip=Багаторазова батарея +metaitem.fluid.regulator.tooltip=Обмежує §fРідини§7 до певної кількості, працює як §fПокращення§7. +metaitem.electric.pump.tooltip=Переводить §fРідини§7 з одинаковою швидкістю, працює як §fПокращення§7. +metaitem.electric.motor.lv.name=Електродвигун LV +metaitem.electric.motor.mv.name=Електродвигун MV +metaitem.electric.motor.hv.name=Електродвигун HV +metaitem.electric.motor.ev.name=Електродвигун EV +metaitem.electric.motor.uhv.name=Електродвигун UHV +metaitem.electric.motor.uiv.name=Електродвигун UIV +metaitem.electric.motor.opv.name=Електродвигун OpV +metaitem.electric.pump.lv.name=Електронасос LV +metaitem.electric.pump.hv.name=Електронасос HV +metaitem.electric.pump.uhv.name=Електронасос UHV +metaitem.fluid.regulator.hv.name=Регулятор рідини HV +metaitem.fluid.regulator.ev.name=Регулятор рідини EV +metaitem.conveyor.module.hv.name=Конвеєрний модуль HV +metaitem.conveyor.module.iv.name=Конвеєрний модуль IV +metaitem.conveyor.module.uev.name=Конвеєрний модуль UEV +metaitem.conveyor.module.tooltip=Передає §fПредмети§7 з одинаковою швидкістю, працює як §fПокращення§7. +metaitem.electric.piston.hv.name=Електричний поршень HV +metaitem.electric.piston.uv.name=Електричний поршень UV +metaitem.robot.arm.uxv.name=Роботизована рука UXV +metaitem.field.generator.lv.name=Генератор поля LV +metaitem.field.generator.uxv.name=Генератор поля UXV +metaitem.emitter.lv.name=Випромінювач LV +metaitem.electric.motor.uv.name=Електродвигун UV +metaitem.electric.pump.mv.name=Електронасос MV +metaitem.electric.pump.luv.name=Електронасос LuV +metaitem.electric.pump.zpm.name=Електронасос ZPM +metaitem.electric.pump.uv.name=Електронасос UV +metaitem.electric.pump.uiv.name=Електронасос UIV +metaitem.electric.pump.opv.name=Електронасос OpV +metaitem.fluid.regulator.iv.name=Регулятор рідини IV +metaitem.fluid.regulator.zpm.name=Регулятор рідини ZPM +metaitem.conveyor.module.luv.name=Конвеєрний модуль LuV +metaitem.conveyor.module.uv.name=Конвеєрний модуль UV +metaitem.robot.arm.lv.name=Роботизована рука LV +metaitem.robot.arm.ev.name=Роботизована рука EV +metaitem.robot.arm.zpm.name=Роботизована рука ZPM +metaitem.robot.arm.uev.name=Роботизована рука UEV +metaitem.robot.arm.tooltip=Обмежує §fПредмети§7 до певної кількості, працює як §fПокращення§7. +metaitem.field.generator.hv.name=Генератор поля HV +metaitem.field.generator.uv.name=Генератор поля UV +metaitem.field.generator.opv.name=Генератор поля OpV +metaitem.emitter.hv.name=Випромінювач HV +metaitem.emitter.uv.name=Випромінювач UV +metaitem.emitter.uiv.name=Випромінювач UIV +metaitem.tool.dataorb.tooltip=Сховище для складних даних +metaitem.tool.datamodule.tooltip=Сховище для неймовірно складних даних/n§cМоже бути прочитане лише банком даних +metaitem.emitter.uhv.name=Випромінювач UHV +metaitem.sensor.hv.name=Сенсор HV +metaitem.sensor.uxv.name=Сенсор UXV +metaitem.board.epoxy.name=Епоксидна друкована плата +metaitem.glass_lens.light_blue.name=Скляна лінза (Світло-блакитна) +metaitem.circuit.integrated.jei_description=JEI показує рецепти тільки для даної конфігурації.\n\nВи можете вибрати конфігурацію у графічному інтерфейсі схеми. +metaitem.spray.can.dyes.light_blue.name=Балончик (світло-синій) +metaitem.glass_lens.blue.name=Скляна лінза (Синя) +metaitem.boule.silicon.tooltip=Необроблена схема +metaitem.wafer.silicon.tooltip=Необроблена схема +metaitem.wafer.phosphorus.name=Пластина легована фосфором +metaitem.wafer.naquadah.name=Пластина легована наквадою +metaitem.boule.naquadah.name=Монокристалічний кремній легований наквадою +metaitem.board.plastic.name=Пластмасова друкована плата +metaitem.circuit_board.elite.name=Відмінна друкована плата +metaitem.circuit_board.wetware.tooltip=Плата, яка зберігає життя +metaitem.circuit.vacuum_tube.tooltip=Технічно це діод/n рівень §cULV +metaitem.component.transistor.tooltip=Базовий електричний компонент +metaitem.glass_lens.lime.name=Glass Lens (Лаймова) +metaitem.glass_lens.gray.name=Скляна лінза (Сіра) +metaitem.glass_lens.brown.name=Скляна лінза (Коричнева) +metaitem.boule.phosphorus.name=Монокристалічний кремній легований фосфором +metaitem.wafer.silicon.name=Кремнієва Пластина +metaitem.wafer.naquadah.tooltip=Необроблена схема +metaitem.wafer.neutronium.name=Пластина легована нейтронами +metaitem.boule.neutronium.name=Монокристалічний кремній легований нейтронами +metaitem.wafer.neutronium.tooltip=Необроблена схема +metaitem.board.coated.name=Друкована плата з покриттям +metaitem.board.coated.tooltip=Плата з покриттям +metaitem.board.phenolic.name=Фенольна друкована плата +metaitem.board.phenolic.tooltip=Гарна плата +metaitem.board.plastic.tooltip=Гарна плата +metaitem.component.capacitor.tooltip=Базовий електричний компонент +metaitem.component.smd.diode.tooltip=Електричний компонент +metaitem.component.smd.transistor.name=SMD Транзистор +metaitem.component.advanced_smd.diode.tooltip=Покращений електричний компонент +metaitem.component.advanced_smd.transistor.tooltip=Покращений електричний компонент +metaitem.wafer.highly_advanced_system_on_chip.tooltip=Необроблена високотехнологічна схема +metaitem.wafer.high_power_integrated_circuit.tooltip=Необроблена схема високої потужності +metaitem.wafer.central_processing_unit.name=Процесорна пластина +metaitem.petri_dish.name=Чашка Петрі +metaitem.duct_tape.name=Покращена армована клейка стрічка FAL-84 +metaitem.basic_tape.tooltip=Недостатньо міцна для вирішення механічних проблем +metaitem.gravistar.tooltip=Доскональна пекельна зірка +metaitem.carbon.mesh.name=Сітка з вуглецевого волокна +metaitem.carbon.plate.name=Вуглецева пластина +metaitem.minecart_wheels.steel.tooltip=Щоб все їхало за планом +metaitem.wafer.ultra_high_power_integrated_circuit.name=Пластина UHPIC +metaitem.wafer.ultra_high_power_integrated_circuit.tooltip=Необроблена схема надвисокої напруги +metaitem.wafer.nand_memory_chip.name=Пластина NAND +metaitem.wafer.nand_memory_chip.tooltip=Необроблений логічний вентиль +metaitem.wafer.ultra_low_power_integrated_circuit.name=Пластина ULPIC +metaitem.wafer.ultra_low_power_integrated_circuit.tooltip=Необроблена схема наднизької напруги +metaitem.wafer.low_power_integrated_circuit.name=Пластина LPIC +metaitem.wafer.low_power_integrated_circuit.tooltip=Необроблена схема низької напруги +metaitem.wafer.power_integrated_circuit.name=Пластина PIC +metaitem.wafer.power_integrated_circuit.tooltip=Необлена схема напруги +metaitem.wafer.nano_central_processing_unit.name=Пластина нанопроцесора +metaitem.wafer.nor_memory_chip.name=Пластина NOR +metaitem.wafer.nor_memory_chip.tooltip=Необроблений логічний вентиль +metaitem.wafer.random_access_memory.name=Пластина RAM +metaitem.wafer.random_access_memory.tooltip=Необроблена пам'ять +metaitem.wafer.system_on_chip.name=Пластина SoC +metaitem.wafer.simple_system_on_chip.name=Проста пластина SoC +metaitem.wafer.simple_system_on_chip.tooltip=Необроблена проста схема +metaitem.engraved.crystal_chip.name=Гравірований кришталевий чіп +metaitem.engraved.crystal_chip.tooltip=Потрібен для схем +metaitem.crystal.raw.name=Необроблений кришталевий чіп +metaitem.crystal.raw_chip.name=Частини необробленого криштального чіпа +metaitem.engraved.lapotron_chip.name=Гравірований лапотроний криштальний чіп +metaitem.crystal.central_processing_unit.name=Криштальний CPU +metaitem.crystal.central_processing_unit.tooltip=Криштальний модуль обробки +metaitem.crystal.system_on_chip.name=Криштальний SoC +metaitem.crystal.system_on_chip.tooltip=Криштальна система на чіпі +metaitem.plate.advanced_system_on_chip.name=ПСнЧ +metaitem.plate.highly_advanced_system_on_chip.name=ВТСнЧ +metaitem.plate.highly_advanced_system_on_chip.tooltip=Високотехнологічна система на чіпі +metaitem.plate.integrated_logic_circuit.name=Вбудована схема +metaitem.plate.integrated_logic_circuit.tooltip=Вбудована логічна схема +metaitem.plate.central_processing_unit.name=ЦП +metaitem.plate.central_processing_unit.tooltip=Центральний процесор +metaitem.plate.high_power_integrated_circuit.name=ВСВН +metaitem.plate.high_power_integrated_circuit.tooltip=Вбудована схема високої напруги +metaitem.plate.ultra_high_power_integrated_circuit.tooltip=Вбудована схема надвисокої напруги +metaitem.plate.ultra_high_power_integrated_circuit.name=ВСНВН +metaitem.plate.nand_memory_chip.name=NAND +metaitem.plate.nand_memory_chip.tooltip=Логічний вентиль NAND +metaitem.plate.nano_central_processing_unit.name=Нано ЦП +metaitem.plate.nano_central_processing_unit.tooltip=Нанопроцесор +metaitem.plate.nor_memory_chip.name=NOR +metaitem.plate.nor_memory_chip.tooltip=Логічний вентиль NOR +metaitem.circuit.good_electronic.name=Гарна електрична схема +metaitem.circuit.good_electronic.tooltip=Твоя друга схема/n§cРівень MV +metaitem.plate.ultra_low_power_integrated_circuit.tooltip=Вбудована схема наднизької напруги +metaitem.plate.low_power_integrated_circuit.name=ВСНН +metaitem.plate.ultra_low_power_integrated_circuit.name=ВСННН +metaitem.plate.low_power_integrated_circuit.tooltip=Вбудована схема низької напруги +metaitem.plate.power_integrated_circuit.name=ВСН +metaitem.plate.power_integrated_circuit.tooltip=Вбудована схема напруги +metaitem.plate.random_access_memory.name=RAM +metaitem.plate.random_access_memory.tooltip=Пам'ять з довільним доступом +metaitem.plate.system_on_chip.name=СнЧ +metaitem.plate.system_on_chip.tooltip=Система на чіпі +metaitem.plate.simple_system_on_chip.name=Проста СнЧ +metaitem.plate.simple_system_on_chip.tooltip=Проста система на чіпі + + +# T1: Electronic +metaitem.circuit.electronic.name=Проста електрична схема +metaitem.circuit.electronic.tooltip=Твоя перша схема/n§cРівень LV + +# T2: Integrated +metaitem.circuit.basic_integrated.name=Вбудована логічна схема +metaitem.circuit.basic_integrated.tooltip=Менша та більш потужна/n§6Рівень LV +metaitem.circuit.good_integrated.name=Гарна вбудована схема +metaitem.circuit.good_integrated.tooltip=Менша та більш потужна/n§6Рівень MV +metaitem.circuit.advanced_integrated.name=Покращена вбудована схема +metaitem.circuit.advanced_integrated.tooltip=Менша та більш потужна/n§6Рівень HV + +# Misc +metaitem.circuit.nand_chip.name=Чіп NAND +metaitem.circuit.nand_chip.tooltip=Передова проста схема/n§6Рівень ULV +metaitem.circuit.microprocessor.name=Мікропроцесор +metaitem.circuit.microprocessor.tooltip=Передова базова схема/n§eРівень LV + +# T3: Processor +metaitem.circuit.processor.name=Вбудований процесор +metaitem.circuit.processor.tooltip=Дивовижна швидкість обчислення!/n§eРівень MV +metaitem.circuit.assembly.name=Обчислювальний процесор +metaitem.circuit.assembly.tooltip=Дивовижна швидкість обчислення!/n§eРівень HV +metaitem.circuit.workstation.name=Суперкомп'ютер +metaitem.circuit.workstation.tooltip=Дивовижна швидкість обчислення!/n§eРівень EV +metaitem.circuit.mainframe.name=Основний каркас +metaitem.circuit.mainframe.tooltip=Дивовижна швидкість обчислення!/n§eРівень IV + +# T4: Nano +metaitem.circuit.nano_processor.name=Нанопроцесор +metaitem.circuit.nano_processor.tooltip=Менше, ніж будь-коли/n§bРівень HV +metaitem.circuit.nano_assembly.name=Обчислювальний нанопроцесор +metaitem.circuit.nano_assembly.tooltip=Менше, ніж будь-коли/n§bРівень EV +metaitem.circuit.nano_computer.name=Наносуперкомп'ютер +metaitem.circuit.nano_computer.tooltip=Менше, ніж будь-коли/n§bРівень IV +metaitem.circuit.nano_mainframe.name=Основний каркас нанопроцесора +metaitem.circuit.nano_mainframe.tooltip=Менше, ніж будь-коли/n§bРівень LuV + +# T5: Quantum +metaitem.circuit.quantum_processor.name=Квантовий процесор +metaitem.circuit.quantum_processor.tooltip=Квантові обчислення втілюються в життя!/n§aРівень EV +metaitem.circuit.quantum_assembly.name=Обчислювальний квантовий процесор +metaitem.circuit.quantum_assembly.tooltip=Квантові обчислення втілюються в життя!/n§aРівень IV +metaitem.circuit.quantum_computer.name=Квантовий суперкомп'ютер +metaitem.circuit.quantum_computer.tooltip=Квантові обчислення втілюються в життя!/n§aРівень LuV +metaitem.circuit.quantum_mainframe.name=Основний каркас квантового процесора +metaitem.circuit.quantum_mainframe.tooltip=Квантові обчислення втілюються в життя!/n§aРівень ZPM + +# T6: Crystal +metaitem.circuit.crystal_processor.name=Криштальний процесор +metaitem.circuit.crystal_processor.tooltip=Використання переваг гравіювання на кришталі/n§9Рівень IV +metaitem.circuit.crystal_assembly.name=Обчислювальний криштальний процесор +metaitem.circuit.crystal_assembly.tooltip=Використання переваг гравіювання на кришталі/n§9Рівень LuV +metaitem.circuit.crystal_computer.name=Криштальний суперкомп'ютер +metaitem.circuit.crystal_computer.tooltip=Використання переваг гравіювання на кришталі/n§9Рівень ZPM +metaitem.circuit.crystal_mainframe.name=Основний каркас криштального процесора +metaitem.circuit.crystal_mainframe.tooltip=Використання переваг гравіювання на кришталі/n§9Рівень UV + +# T7: Wetware +metaitem.circuit.wetware_processor.name=Органічний процесор +metaitem.circuit.wetware_processor.tooltip=У тебе таке відчуття, ніби воно спостерігає за тобою./n§4РівеньLuV +metaitem.circuit.wetware_assembly.name=Обчислювальний органічний процесор +metaitem.circuit.wetware_assembly.tooltip=Зможе запустити Minecraft/n§4Рівень ZPM +metaitem.circuit.wetware_computer.name=Органічний суперкомп'ютер +metaitem.circuit.wetware_mainframe.name=Основний каркас органічного процесора +metaitem.circuit.wetware_computer.tooltip=Ідеальне поєднання плоті та машини/n§4Рівень UV +metaitem.circuit.wetware_mainframe.tooltip=Потужне, але чи сможе воно запустити Crysis?/n§4Рівень UHV +metaitem.stem_cells.name=Cтовбурові клітини +metaitem.stem_cells.tooltip=Сирий інтелект +metaitem.processor.neuro.name=Нейроний модуль обробки +metaitem.processor.neuro.tooltip=Нейроний процесор +metaitem.petri_dish.tooltip=Для вирощування клітин +metaitem.bio_chaff.name=Біологічна маса +metaitem.carbon.fibers.name=Сире вуглецеве волокно +metaitem.neutron_reflector.name=Іридієвий нейтронний відбивач +metaitem.neutron_reflector.tooltip=Незламний +metaitem.duct_tape.tooltip=Якщо ви не можете виправити це за допомогою цього, використайте більше! +metaitem.basic_tape.name=Стрічка +metaitem.component.grinder.diamond.name=Алмазна шліфувальна головка +metaitem.component.grinder.tungsten.name=Вольфрамова шліфувальна головка +metaitem.minecart_wheels.iron.name=Залізні колеса вагонетки +metaitem.minecart_wheels.iron.tooltip=Щоб все їхало за планом +metaitem.minecart_wheels.steel.name=Стальні колеса вагонетки +metaitem.quantumeye.name=Квантове око +metaitem.quantumeye.tooltip=Вдосконалене око енду +metaitem.quantumstar.name=Квантова зірка +metaitem.quantumstar.tooltip=Вдосконалена пекельна зірка +metaitem.gravistar.name=Гравітаційна зірка +metaitem.item_filter.name=Фільтр предметів +metaitem.wafer.system_on_chip.tooltip=Необроблена базова схема +metaitem.wafer.nano_central_processing_unit.tooltip=Необроблема наносхема +metaitem.crystal.raw_chip.tooltip=Частини необробленого криштального процесора +metaitem.plate.advanced_system_on_chip.tooltip=Покращена система на чіпі +metaitem.crystal.raw.tooltip=Необроблений кришталевий процесор +metaitem.fluid_filter.name=Фільтр рідини +metaitem.ore_dictionary_filter.name=Фільтр руди +metaitem.fluid_filter.tooltip=Фільтрує §fРідини§7 працює як §fПокращення§7./nМожна виковистовувати для покращення §fЕлектронасоса§7 і §fРегулятора рідини§7. +metaitem.smart_item_filter.name=Розумний фільтр предметів +behaviour.filter_ui_manager=§fПКМ§7 для налаштувань, §fShift ПКМ§7 для очищення налаштувань +metaitem.cover.controller.name=Контролер машини +metaitem.cover.activity.detector.tooltip=Видає §fСтатус роботи§7 у вигляді сигналу Редстоуна, працює як §fПокращення§7. +metaitem.cover.fluid.detector.tooltip=Видає §fКількість рідини§7 у вигляді сигналу Редстоуна, працює як §fПокращення§7. +metaitem.cover.item.detector.tooltip=Видає §fКількість предметів§7 у вигляді сигналу Редстоуна, працює як §fПокращення§7. +metaitem.cover.activity.detector.name=Датчик активності +metaitem.cover.fluid.detector.name=Датчик рідини +metaitem.cover.fluid.detector.advanced.name=Покращений датчик рідини +metaitem.cover.item.detector.name=Датчик предметів +metaitem.cover.item.detector.advanced.name=Покращений датчик предметів +metaitem.cover.fluid.voiding.name=Видалятор рідини +metaitem.cover.fluid.voiding.tooltip=Видаляє §fРідини§7, працює як §fПокращення§7./nАктивується за допомогою §fМ'якої киянки§7 після розміщення. +metaitem.cover.fluid.voiding.advanced.name=Покращення видалятор рідини +metaitem.cover.item.voiding.name=Видалятор предметів +metaitem.cover.item.voiding.tooltip=Видаляє §fПредмети§7 працює як §fПокращення§7./nАктивується за допомогою §fМ'якої киянки§7 після розміщення. +metaitem.cover.item.voiding.advanced.name=Покращений видалятор предметів +metaitem.cover.storage.name=Сховище (Покращення) +metaitem.cover.energy.detector.advanced.name=Покращений датчик енергії +metaitem.cover.maintenance.detector.tooltip=Видає §fПотребу в технічного обслуговування§7 у вигляді сигналу Редстоуна, працює як §fПокращення§7. +metaitem.cover.facade.name=Фасад (%s) +metaitem.cover.screen.name=Комп'ютерний монітор +metaitem.cover.screen.tooltip=Показує §fДані§7, працює як §fПокращення§7. +metaitem.cover.crafting.name=Верстак (Покращення) +metaitem.cover.shutter.name=Затворний модуль (Покращення) +metaitem.cover.shutter.tooltip=§fБлокує передачу§7 через сторону на якій знаходиться, працює як §fПокращення§7. +metaitem.cover.solar.panel.ulv.name=Сонячна панель ультранизької напруги +metaitem.cover.solar.panel.mv.name=Сонячна панель середньої напруги (Покращення) +metaitem.cover.solar.panel.hv.name=Сонячна панель високої напруги (Покращення) +metaitem.cover.solar.panel.iv.name=Сонячна панель шаленої напруги (Покращення) +metaitem.cover.solar.panel.luv.name=Сонячна панель сміховинної напруги (Покращення) +metaitem.cover.solar.panel.uv.name=Сонячна панель кінцевої напруги (Покращення) +metaitem.cover.solar.panel.tooltip.1=Нехай Сонце буде з вами. +metaitem.cover.infinite_water.name=Нескінченне джерело води (Покращення) +metaitem.cover.infinite_water.tooltip.1=Наповнює контейнери §9Водою§7, працює як §fПокращення§7. +metaitem.cover.ender_fluid_link.name=Рідкий безтрубний зв'язок (Покращення) +metaitem.gelled_toluene.tooltip=Сира вибухівка +metaitem.bottle.purple.drink.name=Фіолетовий напій +metaitem.bottle.purple.drink.tooltip=Як щодо лимонаду? Або холодного чаю? А у мене є фіолетовий напій! +metaitem.dye.black.name=Чорний барвник +metaitem.dye.red.name=Червоний барвник +metaitem.dye.green.name=Зелений барвник +metaitem.dye.blue.name=Синій барвник +metaitem.dye.purple.name=Фіолетовий барвник +metaitem.dye.cyan.name=Блакитний барвник +metaitem.dye.silver.name=Світло-сірий барвник +metaitem.dye.gray.name=Сірий барвник +metaitem.dye.lime.name=Лаймовий барвник +metaitem.dye.magenta.name=Пурпурний барвник +metaitem.dye.orange.name=Помаранчевий барвник +metaitem.dye.white.name=Білий барвник +metaitem.tool_parts_box.name=Ящик для інструментів +metaitem.foam_sprayer.name=Розпилювач піни +metaitem.energium_dust.name=Енергітичний пил +metaitem.compressed.clay.name=Спресована глина +metaitem.compressed.fireclay.name=Спресована шамотна глина +metaitem.brick.fireclay.name=Цегла з шамотної глина +metaitem.brick.fireclay.tooltip=Термостійка +metaitem.brick.coke.name=Цегла для коксових печей +metaitem.wooden_form.empty.name=Порожня дерев'яна форма +item.gt.tool.replace_tool_head=Створіть нову головку інструменту, щоб замінити її +item.gt.tool.usable_as=Використовується як: §f%s +item.gt.tool.behavior.tree_felling=§4Лісоруб: §fРубка дерев +item.gt.tool.behavior.shield_disable=§cБрут: §fВідключає щити +item.gt.tool.behavior.ground_tilling=§eФермер: §fОбробляє землю +item.gt.tool.behavior.rail_rotation=§eЗалізничний інженер: §fОбертає рейки +item.gt.tool.behavior.block_rotation=§2Механік: §fОбертає блоки +gt.tool.class.sword=Меч +gt.tool.class.pickaxe=Кайло +gt.tool.class.shovel=Лопата +gt.tool.class.axe=Сокира +gt.tool.class.hoe=Мотика +gt.tool.class.saw=Пила +gt.tool.class.hammer=Молот +gt.tool.class.mallet=Киянка +gt.tool.class.wrench=Гайковий ключ +gt.tool.class.file=Напилок +gt.tool.class.crowbar=Лом +gt.tool.class.screwdriver=Викрутка +gt.tool.class.mortar=Ступка +gt.tool.class.scythe=Коса +gt.tool.class.shears=Ножиці +gt.tool.class.knife=Ніж +gt.tool.class.plunger=Вантуз +item.gt.tool.sword.name=Меч (%s) +item.gt.tool.pickaxe.name=Кайло (%s) +item.gt.tool.shovel.name=Лопата (%s) +item.gt.tool.axe.name=Сокира (%s) +item.gt.tool.hoe.name=Мотика (%s) +item.gt.tool.saw.name=Пила (%s) +item.gt.tool.hammer.name=Молот (%s) +item.gt.tool.mallet.name=М'яка киянка (%s) +item.gt.tool.mallet.tooltip=§8Зупиняє/запускає техніку +item.gt.tool.wrench.name=Гайковий ключ %s +item.gt.tool.file.name=Напилок (%s) +item.gt.tool.crowbar.name=Лом (%s) +item.gt.tool.crowbar.tooltip=§8Знімає покращення +item.gt.tool.screwdriver.name=Викрутка (%s) +item.gt.tool.screwdriver.tooltip=§8Налаштовує покращення та машини +item.gt.tool.mortar.name=Ступка (%s) +item.gt.tool.wire_cutter.name=Кусачки (%s) +item.gt.tool.butchery_knife.name=Тесак (%s) +item.gt.tool.butchery_knife.tooltip=§8Має низьку швидкість атаки +item.gt.tool.scythe.name=Коса (%s) +item.gt.tool.rolling_pin.name=Качалка (%s) +item.gt.tool.drill_lv.name=%s Бур (LV) +item.gt.tool.drill_hv.name=%s Бур (HV) +item.gt.tool.drill_ev.name=%s Бур (EV) +item.gt.tool.drill_iv.name=%s Бур (IV) +item.gt.tool.mining_hammer.name=%s Гірський молот +item.gt.tool.spade.tooltip=§8Видобуває велику площу за один раз (якщо тільки ви не присідаєте) +item.gt.tool.chainsaw_lv.name=%s Бензопила (LV) +item.gt.tool.chainsaw_mv.name=%s Бензопила (MV) +item.gt.tool.chainsaw_hv.name=%s Бензопила (HV) +item.gt.tool.wrench_lv.tooltip=§8Утримуйте ЛКМ, щоб демонтувати машини +item.gt.tool.wrench_iv.tooltip=§8Утримуйте ЛКМ, щоб демонтувати машини +item.gt.tool.buzzsaw.name=%s Циркулярна пила (LV) +item.gt.tool.screwdriver_lv.name=%s Викрутка (LV) +item.gt.tool.screwdriver_lv.tooltip=§8Налаштовує покращення та машини +item.gt.tool.plunger.name=%s Вантуз +item.gt.tool.plunger.tooltip=§8Видаляє рідини з машин +item.gt.tool.wire_cutter_lv.name=%s Кусачки (LV) +item.gt.tool.wire_cutter_hv.name=%s Кусачки (HV) +item.gt.tool.tooltip.general_uses=§bМіцність: %s +item.gt.tool.tooltip.attack_damage=§cШкода від атаки: %s +item.gt.tool.tooltip.attack_speed=§9Швидкість атаки: %s +item.gt.tool.tooltip.mining_speed=§dШвидкість видобутку: %s +item.gt.tool.tooltip.harvest_level_extra=§eРівень збору: %s §f(%s§f) +item.gt.tool.harvest_level.0=§8Дерево +item.gt.tool.harvest_level.2=§aЗалізо +item.gt.tool.harvest_level.3=§bАлмаз +item.gt.tool.harvest_level.4=§dУльтімет +item.gt.tool.harvest_level.5=§9Дюранієвий +item.gt.tool.harvest_level.6=§cНейтроній +item.gt.tool.tooltip.repair_info=Утримуйте клавішу SHIFT, щоб показати інформацію про ремонт +item.gt.tool.tooltip.repair_material=Ремонтується з допомогою: §a%s +item.gt.tool.aoe.rows=Ряди +item.gt.tool.aoe.columns=Колонки +item.gt.tool.aoe.layers=Шари +metaitem.turbine_rotor.name=%s Ротор турбіни +metaitem.turbine_rotor.tooltip=Ротори турбін для вашої електростанції +metaitem.clipboard.name=Блокнот +metaitem.clipboard.tooltip=Можна писати (без будь-якого інструменту для письма). Клацніть ПКМ на стіні, щоб розмістити, і клацніть Shift-ПКМ, щоб підібрати + + +metaitem.behavior.mode_switch.tooltip=SHIFT-ПКМ для змінення режиму +metaitem.behavior.mode_switch.mode_switched=§eРежим змінено на: %s +metaitem.behavior.mode_switch.current_mode=Режим: %s +metaitem.tool.tooltip.primary_material=§fМатеріал: §e%s +metaitem.tool.tooltip.durability=§fМіцність: §a%,d / %,d +metaitem.tool.tooltip.rotor.efficiency=Ефективність турбіни: §9%,d%% +metaitem.tool.tooltip.rotor.power=Потужність турбіни: §9%,d%% +metaitem.voltage_coil.ulv.name=Котушка (ULV) +metaitem.voltage_coil.ulv.tooltip=Примітивна котушка +metaitem.voltage_coil.lv.name=Котушка (LV) +metaitem.voltage_coil.lv.tooltip=Базова котушка +metaitem.voltage_coil.mv.name=Котушка середньої напруги +metaitem.voltage_coil.mv.tooltip=Гарна котушка +metaitem.voltage_coil.hv.name=Котушка високої напруги +metaitem.voltage_coil.hv.tooltip=Покращена котушка +metaitem.voltage_coil.ev.name=Котушка екстремальної напруги +metaitem.voltage_coil.ev.tooltip=Екстремально гарна котушка +metaitem.voltage_coil.iv.name=Котушка шаленої напруги +metaitem.voltage_coil.iv.tooltip=Відмінна котушка +metaitem.voltage_coil.luv.name=Котушка сміховинної напруги +metaitem.voltage_coil.luv.tooltip=Відмінна котушка V2 +metaitem.voltage_coil.zpm.name=Котушка (ZPM) +metaitem.voltage_coil.zpm.tooltip=Відмінна котушка V3 +metaitem.voltage_coil.uv.name=Котушка (UV) +metaitem.voltage_coil.uv.tooltip=Доскональна котушка +metaitem.voltage_coil.uhv.name=Котушка (UHV) +metaitem.voltage_coil.uhv.tooltip=Ідеальна котушка +metaitem.voltage_coil.uev.name=Котушка (UEV) +metaitem.voltage_coil.uev.tooltip=Нереальна котушка +metaitem.voltage_coil.uiv.name=Котушка (UIV) +metaitem.voltage_coil.uiv.tooltip=Бездоганна котушка V2 +metaitem.voltage_coil.uxv.name=Котушка (UXV) +metaitem.voltage_coil.uxv.tooltip=Бездоганна котушка V3 +metaitem.voltage_coil.opv.name=Котушка (OpV) +metaitem.voltage_coil.opv.tooltip=Бездоганна котушка V4 +metaitem.voltage_coil.max.name=Катушка (MAX) +metaitem.voltage_coil.max.tooltip=Максимальна котушка +metaitem.liquid_fuel_jetpack.name=Реактивний ранець на рідкому паливі +metaitem.liquid_fuel_jetpack.tooltip=Використовує паливо для тяги +metaitem.electric_jetpack.name=Реактивний ранець з електричним двигуном +metaitem.nightvision_goggles.name=Окуляри нічного бачення +metaitem.nms.leggings.name=NanoMuscle™ Штани +metaitem.nms.boots.name=NanoMuscle™ Чоботи +metaitem.nms.helmet.name=NanoMuscle™ Шолом +metaitem.nms.advanced_chestplate.name=Покращений NanoMuscle™ Нагрудник +metaitem.qts.chestplate.name=QuarkTech™ Нагрудник +metaitem.item_filter.tooltip=Фільтрує §fПредмети§7 працює як §fПокращення§7./nМожна виковистовувати для покращення §fКонвеєрного модуля§7 і §fРоботизованої руки§7. +metaitem.smart_item_filter.tooltip=Фільтрує §fПредмети§7 за допомогою §fРецептів машин§7 працює як §fПокращення§7./nМожна виковистовувати для покращення §fКонвеєрного модуля§7 і §fРоботизованої руки§7. +metaitem.qts.helmet.name=QuarkTech™ Шолом +metaitem.qts.advanced_chestplate.name=Покращений QuarkTech™ Нагрудник +metaitem.gravitation_engine.name=Модуль гравітаційного двигуна +metaitem.tool.multiblock_builder.name=Конструктор багатоблочних конструкцій +metaitem.tool.multiblock_builder.tooltip=Для налагодження та автоматичної збірки ваших багатоблочних конструкцій! +metaitem.ore_dictionary_filter.tooltip=Фільтрує §fПредмети§7 з допомогою §fСловника руд§7 працює як §fПокращення§7./nМожна виковистовувати для покращення §fКонвеєрного модуля§7 і §fРоботизованої руки§7. +metaarmor.nms.nightvision.enabled=NanoMuscle™ Костюм: Увімкнено нічне бачення +metaarmor.nms.nightvision.disabled=NanoMuscle™ Костюм: Вимкнено нічне бачення +metaitem.cover.controller.tooltip=§fВКЛ/ВИКЛ§7 машину працює як §fПокращення§7. +metaitem.cover.activity.detector_advanced.tooltip=Видає §fПрогрес роботи§7 у вигляді сигналу Редстоуна, працює як §fПокращення§7. +metaitem.cover.item.detector.advanced.tooltip=Видає §fСтатус зберігання предметів§7 у вигляді сигналу Редстоуна, працює як §fПокращення§7, з можливістю контролювати з допомогою §fRS-Latch§7. +metaitem.cover.energy.detector.advanced.tooltip=Дає §fRS-Latch§7 контроль за §fСтатусом енергії§7 за допомогою Редстоуну, працює як §fПокращення§7. +metaitem.cover.energy.detector.name=Датчик енергії +metaarmor.nms.nightvision.error=NanoMuscle™ Костюм: §cНедостатньо енергії! +metaarmor.qts.nightvision.enabled=QuarkTech™ Костюм: Увімкнено нічне бачення +metaitem.cover.fluid.detector.advanced.tooltip=Видає §fСтатус зберігання рідини§7 у вигляді сигналу Редстоуна, працює як §fПокращення§7, з можливістю контролювати з допомогою §fRS-Latch§7. +metaitem.cover.energy.detector.tooltip=Видає §fКількість енергії§7 у вигляді сигналу Редстоуна, працює як §fПокращення§7. +metaitem.cover.fluid.voiding.advanced.tooltip=Видаляє §fРідини§7, з контролем кількості, працює як §fПокращення§7./nАктивується за допомогою §fМ'якої киянки§7 після розміщення. +metaarmor.qts.nightvision.disabled=QuarkTech™ Костюм: Вимкнено нічне бачення +metaarmor.jetpack.hover.enable=Реактивний ранець: Увімкнено режим зависання +metaarmor.jetpack.hover.disable=Реактивний ранець: Вимкнено режим зависання +metaarmor.jetpack.emergency_hover_mode=Аварійний режим зависання увімкнено! +metaarmor.nms.share.enable=NanoMuscle™ Костюм: Зарядку ввімкнено +metaarmor.nms.share.disable=NanoMuscle™ Костюм: Зарядку вимкнено +metaarmor.nms.share.error=NanoMuscle™ Костюм: §cНе вистачає енергії для зарядки! +metaarmor.qts.share.enable=QuarkTech™ Костюм: Зарядку ввімкнено +metaarmor.qts.share.disable=QuarkTech™ Костюм: Зарядку вимкнено +metaarmor.qts.share.error=QuarkTech™ Костюм: §cНе вистачає енергії для зарядки! +metaarmor.message.nightvision.enabled=§bНічне бачення: §aУвімкнено +metaarmor.message.nightvision.disabled=§bНічне бачення: §cВимкнено +metaarmor.message.nightvision.error=§cНедостатньо енергії! +metaarmor.tooltip.stepassist=Забезпечує крокову допомогу +metaarmor.tooltip.speed=Збільшує швидкість бігу +metaarmor.tooltip.jump=Збільшує висоту та дистанцію стрибків +metaarmor.tooltip.falldamage=Обнуляє шкоду від падіння +metaarmor.tooltip.potions=Обнуляє шкідливі ефекти +metaarmor.tooltip.burning=Обнуляє горіння +metaarmor.tooltip.breath=Поповнює шкалу підводого дихання +metaarmor.tooltip.autoeat=Поповнює запаси їжі, використовуючи їжу з інвентарю +metaarmor.hud.status.enabled=§aУВІМК +metaarmor.hud.status.disabled=§cВИМК +metaarmor.hud.energy_lvl=Рівень енергії: %s +metaarmor.hud.fuel_lvl=Рівень палива: %s +metaarmor.hud.hover_mode=Режим зависання: %s +mataarmor.hud.supply_mode=Режим постачання: %s +metaarmor.energy_share.error=Енергопостачання: §cНе вистачає потужності для зарядки приладів! +metaarmor.energy_share.enable=Енергопостачання: Увімкнено заряджання приладів +metaarmor.energy_share.disable=Енергопостачання: Вимкнено зарядку пристроїв +metaarmor.energy_share.tooltip=Режим постачання: %s +metaarmor.energy_share.tooltip.guide=Щоб змінити режим, клацніть SHIFT-ПКМ, утримуючи предмет +metaitem.record.sus.name=Музичний диск +metaitem.record.sus.tooltip=§7Leonz - Among Us Drip +metaitem.nan.certificate.name=Сертифікат про те, що ви більше не новачок +metaitem.nan.certificate.tooltip=Виклик прийнято! +metaitem.fertilizer.name=Добриво +metaitem.blacklight.name=Чорне світло +metaitem.blacklight.tooltip=Довгохвильове §dУльтрафіолетове§7 джерело світла +gui.widget.incrementButton.default_tooltip=Утримуйте Shift, Ctrl або обидві клавіші, щоб змінити кількість +gui.widget.recipeProgressWidget.default_tooltip=Показати рецепти +gregtech.recipe_memory_widget.tooltip.1=§7Клікніть лівою кнопкою миші, щоб автоматично внести цей рецепт до сітки крафтингу +cover.filter.blacklist.disabled=Білий список +cover.filter.blacklist.enabled=Чорний список +cover.ore_dictionary_filter.title=Фільтр руди за словником +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 +cover.ore_dictionary_filter.test_slot.no_oredict.matches=§a(Немає словника руд) +cover.ore_dictionary_filter.test_slot.no_oredict.matches_not=§c(Немає словника руд) +cover.ore_dictionary_filter.status.err=§c%s помилка(и) +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.preview.next=... за яким слідує +cover.ore_dictionary_filter.preview.match='%s' +cover.ore_dictionary_filter.preview.match.not=не '%s' +cover.ore_dictionary_filter.preview.char=1 символ +cover.ore_dictionary_filter.preview.char.not=або більше ніж 1 символабо нічого +cover.ore_dictionary_filter.preview.chars=%s символів +cover.ore_dictionary_filter.preview.chars.not=або більше ніж або менше %s символів +cover.ore_dictionary_filter.preview.chars_or_more=%s чи більше символів +cover.ore_dictionary_filter.preview.chars_or_more.not=менше ніж %s символів +cover.ore_dictionary_filter.preview.group=не: +cover.ore_dictionary_filter.preview.or=один з... +cover.ore_dictionary_filter.preview.nor=будьщо, що не є одним із... +cover.ore_dictionary_filter.preview.or.entry= +cover.ore_dictionary_filter.preview.or.entry.start= +metaitem.cover.item.voiding.advanced.tooltip=Видаляє §fПредмети§7, з контролем кількості, працює як §fПокращення§7./nАктивується за допомогою §fМ'якої киянки§7 після розміщення. +metaitem.cover.storage.tooltip=Невеликий сховище для зберігання дрібниць +metaitem.cover.maintenance.detector.name=Датчик потреби технічного обслуговування +metaitem.cover.activity.detector_advanced.name=Покращений датчик активності +metaitem.cover.facade.tooltip=Декоративне оздоблення §fПокращення§7. +metaitem.cover.crafting.tooltip=§fПокращений верстак§7 на машині, працює як §fПокращення§7. +metaitem.cover.solar.panel.name=Сонячна панель (Покращення) +metaitem.cover.solar.panel.lv.name=Сонячна панель низької напруги (Покращення) +metaitem.cover.solar.panel.ev.name=Сонячна панель екстремальної напруги (Покращення) +metaitem.cover.solar.panel.zpm.name=Сонячна панель модуля нульової точки (Покращення) +metaitem.cover.solar.panel.tooltip.2=Виробляє §fЕнергію§7 з §eСонця§7, працює як §fПокращення§7. +metaitem.dye.pink.name=Рожевий барвник +metaitem.dye.yellow.name=Жовтий барвник +metaitem.dye.light_blue.name=Світло-синій барвник +metaitem.foam_sprayer.tooltip=Розпилює будівельну піну/nВикористовується на рамі для запінення з'єднаних рам/nПіна може бути кольоровою +item.gt.tool.behavior.grass_path=§eЛандшафтник: §fСтворює доріжки +item.gt.tool.behavior.plunger=§9Сантехнік: §fЗливає рідини +gt.tool.class.wirecutter=Кусачки +item.gt.tool.hammer.tooltip=§8Подрібнює блоки під час їх збирання +item.gt.tool.knife.name=Ніж (%s) +metaitem.cover.ender_fluid_link.tooltip=Передає §fРідини§7 за допомогою §fБезтрубового §dЕндер§f зв'яку§7, працює як §fПокращення§7. +metaitem.dye.brown.name=Коричневий барвник +metaitem.tool_parts_box.tooltip=Містить деякі частини інструментів/nПКМ для відкриття +metaitem.compressed.coke_clay.name=Спресована коксова глина +metaitem.wooden_form.brick.name=Дерев'яна форма для цегли +item.gt.tool.behavior.silk_ice=§bЛьодоруб: §fШовковий дотик для льоду +item.gt.tool.behavior.relocate_mining=§2Магніт: §fПритягує видобуті блоки +item.gt.tool.behavior.damage_boost=§4Посилення шкоди: §fДодаткова шкода проти %s +gt.tool.class.butchery_knife=Тесак +item.gt.tool.wrench.tooltip=§8Утримуйте ліву кнопку миші, щоб демонтувати машини +item.gt.tool.drill_mv.name=%s Бур (MV) +item.gt.tool.wire_cutter_iv.name=%s Кусачки (IV) + + +item.gt.tool.tooltip.crafting_uses=§aЗалишилося застосувань: %s +item.gt.tool.harvest_level.1=§7Камінь +item.gt.tool.mining_hammer.tooltip=§8Видобуває велику площу за один раз (якщо тільки ви не присідаєте) +item.gt.tool.wrench_lv.name= +item.gt.tool.wrench_hv.tooltip=§8Утримуйте ЛКМ, щоб демонтувати машини +item.gt.tool.buzzsaw.tooltip=§8Не підходить для добування блоків +item.gt.tool.tooltip.harvest_level=§eРівень збору: %s +metaitem.advanced_electric_jetpack.name=Покращений реактивний ранець +metaitem.nms.chestplate.name=NanoMuscle™ Нагрудник +metaitem.qts.leggings.name=QuarkTech™ Штани +metaarmor.qts.nightvision.error=QuarkTech™ Костюм: §cНедостатньо енергії! +gregtech.recipe_memory_widget.tooltip.2=§7Нажміть Shift, щоб заблокувати/розблокувати цей рецепт +metaitem.qts.boots.name=QuarkTech™ Чоботи +metaitem.tool.multiblock_builder.tooltip2=SHIFT-ПКМ по контролеру мультиблочної структури, щоб автоматично побудувати її diff --git a/src/main/resources/assets/gregtech/lang/zh_cn.lang b/src/main/resources/assets/gregtech/lang/zh_cn.lang index 88906474bcf..55dd3e25595 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,7 +104,22 @@ gregtech.top.ld_pipe_output=输出 gregtech.top.ld_pipe_input_endpoint=输入接口: gregtech.top.ld_pipe_output_endpoint=输出接口: -gregtech.waila.energy_stored=能量:%d EU / %d EU +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=能量:%s EU / %s EU gregtech.waila.progress_idle=闲置 gregtech.waila.progress_tick=进度:%d t / %d t gregtech.waila.progress_sec=进度:%d s / %d s @@ -112,7 +127,7 @@ gregtech.waila.progress_computation=计算进度:%s / %s gregtech.multiblock.title=多方块结构 gregtech.multiblock.primitive_blast_furnace.bronze.description=土高炉是(PBF)是个多方块结构。尽管它不是很快,却能在游戏前期为你的发展提供钢材。 -gregtech.multiblock.coke_oven.description=焦炉是个多方块结构,用于在早期生产焦炭和杂酚油。无需燃料即可工作,内部至多可容纳32桶杂酚油。其存储可通过焦炉仓进行访问。 +gregtech.multiblock.coke_oven.description=焦炉是一种多方块结构,用于在早期生产焦煤和杂酚油,无需燃料即可工作,内部至多可容纳 32 桶杂酚油。其存储可通过焦炉仓进行访问。 gregtech.multiblock.vacuum_freezer.description=真空冷冻机是个多方块结构,主要用于热锭冷却。此外,它还可以冻结水等其他物质。 gregtech.multiblock.implosion_compressor.description=聚爆压缩机是个多方块结构,能够借助炸药将宝石粉转化为相应的宝石。 gregtech.multiblock.pyrolyse_oven.description=热解炉是种用于将原木处理为木炭、杂酚油、灰烬或重油的多方块结构。 @@ -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=空 @@ -286,7 +301,7 @@ metaitem.fluid_cell.empty=空 metaitem.fluid_cell.name=%s单元 metaitem.fluid_cell.universal.empty=空 metaitem.fluid_cell.universal.name=%s通用单元 -metaitem.fluid_cell.glass_vial.name=%s玻璃单元 +metaitem.fluid_cell.glass_vial.name=%s玻璃试管 metaitem.large_fluid_cell.steel.name=%s钢单元 metaitem.large_fluid_cell.aluminium.name=%s铝单元 metaitem.large_fluid_cell.stainless_steel.name=%s不锈钢单元 @@ -531,7 +546,7 @@ metaitem.tool.datamodule.name=数据模块 metaitem.tool.datamodule.tooltip=超复杂数据存储/n§c只能用数据库读取 metaitem.circuit.integrated.name=编程电路 metaitem.circuit.integrated.tooltip=右击以打开配置界面/n/n手持并潜行右击带有编程电路槽位的机器可应用相应配置。/n -metaitem.circuit.integrated.gui=编程电路配置 +metaitem.circuit.integrated.gui=电路配置 metaitem.circuit.integrated.jei_description=JEI将仅显示匹配当前编程电路配置的配方。\n\n在编程电路配置界面中调整配置以查看对应配方。 item.glass.lens=玻璃透镜(白色) @@ -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机器。 @@ -852,7 +868,7 @@ metaitem.cover.item.voiding.advanced.tooltip=作§f覆盖板§7时允许按数 metaitem.cover.storage.name=存储覆盖板 metaitem.cover.storage.tooltip=给零碎的小玩意准备的小型存储空间 metaitem.cover.maintenance.detector.name=维护需求覆盖板 -metaitem.cover.maintenance.detector.tooltip=作§f覆盖板§7时在机器§f需要维护§7输出红石信号。 +metaitem.cover.maintenance.detector.tooltip=作§f覆盖板§7时在机器§f需要维护§7时发出红石信号。 metaitem.cover.facade.name=%s伪装板 metaitem.cover.facade.tooltip=可作为§f覆盖板§7加装装饰性套壳。 @@ -924,7 +940,7 @@ metaitem.wooden_form.brick.name=木制砖模具 item.gt.tool.replace_tool_head=在合成栏用新的工具头替换 item.gt.tool.usable_as=可用作:§f%s -item.gt.tool.behavior.silk_ice=§b切冰利刃:§f精准采集冰 +item.gt.tool.behavior.silk_ice=§b切冰利刃:§f精准采集冰块 item.gt.tool.behavior.torch_place=§e洞窟探客:§f右击可放置火把 item.gt.tool.behavior.tree_felling=§4伐木好手:§f一次性砍下整棵树木 item.gt.tool.behavior.shield_disable=§c野兽蛮攻:§f破除盾牌 @@ -1008,6 +1024,9 @@ item.gt.tool.screwdriver_lv.name=%s螺丝刀(LV) item.gt.tool.screwdriver_lv.tooltip=§8调整覆盖板和机器 item.gt.tool.plunger.name=%s搋子 item.gt.tool.plunger.tooltip=§8从机器中抽除流体 +item.gt.tool.wire_cutter_lv.name=%s剪线钳(LV) +item.gt.tool.wire_cutter_hv.name=%s剪线钳(HV) +item.gt.tool.wire_cutter_iv.name=%s剪线钳(IV) item.gt.tool.tooltip.crafting_uses=§a合成耐久度:%s @@ -1175,7 +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在表达式开头添加 §6$c§r 可严格区分大小写/n§b使用范例:/n§6dust*Gold | (plate* & !*Double*)/n匹配双层板以外的板与包括小撮、小堆在内的所有金粉 +cover.ore_dictionary_filter.info=§b接受复杂表达式\n§6a & b§r = 且\n§6a | b§r = 或\n§6a ^ b§r = 异或\n§6! abc§r = 非\n§6( abc )§r 表示组别\n§6*§r 表示通配(也即零或多个字符)\n§6?§r 表示任意一个字符\n§6()§r 匹配空条目(包括不带矿物词典的物品)\n§b使用范例:\n§6dust*Gold | (plate* & !*Double*)\n匹配双层板以外的板与包括小撮、小堆在内的所有金粉 +cover.ore_dictionary_filter.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 @@ -1186,6 +1207,10 @@ cover.ore_dictionary_filter.status.err_warn=§c%s个错误、%s个警告 cover.ore_dictionary_filter.status.warn=§7%s个警告 cover.ore_dictionary_filter.status.no_issues=§a无问题 cover.ore_dictionary_filter.status.explain=矿物过滤说明: +cover.ore_dictionary_filter.button.case_sensitive.disabled=忽略大小写 +cover.ore_dictionary_filter.button.case_sensitive.enabled=匹配大小写 +cover.ore_dictionary_filter.button.match_all.disabled=匹配物品的任一矿词条目 +cover.ore_dictionary_filter.button.match_all.enabled=匹配物品的所有矿词条目 cover.ore_dictionary_filter.preview.next=...接着是 cover.ore_dictionary_filter.preview.match='%s' @@ -1236,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=过滤两者 @@ -1243,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=进阶流体销毁设置 @@ -1266,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模式:禁用 @@ -1283,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=保持补给 @@ -1293,18 +1327,17 @@ 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 cover.fluid_regulator.keep_exact=保持补给:%s -cover.machine_controller.title=机器控制设定 -cover.machine_controller.normal=普通 -cover.machine_controller.inverted=反相 -cover.machine_controller.inverted.description=§e普通§r - 该模式下的覆盖板需要比设定强度小的红石信号来触发/n§e反相§r - 该模式下的覆盖板需要比设定强度大的红石信号来触发 -cover.machine_controller.redstone=最小红石信号强度:%,d cover.machine_controller.mode.machine=控制目标:机器 cover.machine_controller.mode.cover_up=控制目标:覆盖板(顶面) cover.machine_controller.mode.cover_down=控制目标:覆盖板(底面) @@ -1312,11 +1345,17 @@ cover.machine_controller.mode.cover_south=控制目标:覆盖板(南面) cover.machine_controller.mode.cover_north=控制目标:覆盖板(北面) cover.machine_controller.mode.cover_east=控制目标:覆盖板(东面) cover.machine_controller.mode.cover_west=控制目标:覆盖板(西面) +cover.machine_controller.this_cover=§c此覆盖板 +cover.machine_controller.cover_not_controllable=§c不可控制的覆盖板 +cover.machine_controller.machine_not_controllable=§c不可控制的机器 +cover.machine_controller.control=控制: +cover.machine_controller.enable_with_redstone=接收红石信号时开启 +cover.machine_controller.disable_with_redstone=接收红石信号时关闭 cover.ender_fluid_link.title=末影流体连接 cover.ender_fluid_link.iomode.enabled=已启用I/O 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此时关闭界面将导致丢失编辑内容! @@ -1356,9 +1395,9 @@ item.material.oreprefix.oreBasalt=玄武岩%s矿石 item.material.oreprefix.oreSand=沙子%s矿石 item.material.oreprefix.oreRedSand=红沙%s矿石 item.material.oreprefix.oreNetherrack=地狱岩%s矿石 -item.material.oreprefix.oreNether=下界%s矿石 +item.material.oreprefix.oreNether=地狱岩%s矿石 item.material.oreprefix.oreEndstone=末地石%s矿石 -item.material.oreprefix.oreEnd=末地%s矿石 +item.material.oreprefix.oreEnd=末地石%s矿石 item.material.oreprefix.ore=%s矿石 item.material.oreprefix.oreGranite=花岗岩%s矿石 item.material.oreprefix.oreDiorite=闪长岩%s矿石 @@ -1533,7 +1572,8 @@ gregtech.material.palladium=钯 gregtech.material.phosphorus=磷 gregtech.material.polonium=钋 gregtech.material.platinum=铂 -gregtech.material.plutonium=钚-239 +gregtech.material.plutonium=钚 +gregtech.material.plutonium_239=钚-239 gregtech.material.plutonium_241=钚-241 gregtech.material.potassium=钾 gregtech.material.praseodymium=镨 @@ -1568,8 +1608,9 @@ gregtech.material.tin=锡 gregtech.material.titanium=钛 gregtech.material.tritium=氚 gregtech.material.tungsten=钨 -gregtech.material.uranium=铀-238 +gregtech.material.uranium=铀 gregtech.material.uranium_235=铀-235 +gregtech.material.uranium_238=铀-238 gregtech.material.vanadium=钒 gregtech.material.xenon=氙 gregtech.material.ytterbium=镱 @@ -1645,7 +1686,7 @@ gregtech.material.rose_gold=玫瑰金 gregtech.material.black_bronze=黑青铜 gregtech.material.bismuth_bronze=铋青铜 gregtech.material.biotite=黑云母 -gregtech.material.powellite=钼钨钙矿 +gregtech.material.powellite=钼钙矿 gregtech.material.pyrite=黄铁矿 gregtech.material.pyrolusite=软锰矿 gregtech.material.pyrope=镁铝榴石 @@ -1789,6 +1830,14 @@ gregtech.material.enriched_naquadah_sulfate=硫酸富集硅岩 gregtech.material.naquadria_sulfate=硫酸超能硅岩 gregtech.material.pyrochlore=烧绿石 gregtech.material.rtm_alloy=钌钨钼合金 +gregtech.material.ilmenite_slag=钛铁矿渣 +gregtech.material.zircon=锆石 +gregtech.material.zirconia=氧化锆 +gregtech.material.zirconium_tetrachloride=四氯化锆 +gregtech.material.hafnia=二氧化铪 +gregtech.material.hafnium_tetrachloride=四氯化铪 +gregtech.material.zircaloy_4=锆-4合金 +gregtech.material.inconel_718=因科镍-718 # Organic Chemistry Materials @@ -2002,6 +2051,11 @@ gregtech.material.acidic_naquadria_solution=酸性超能硅岩溶液 gregtech.material.naquadria_waste=超能硅岩废液 gregtech.material.lapotron=兰波顿 gregtech.material.uu_matter=UU物质 +gregtech.material.bauxite_slurry=铝土浆液 +gregtech.material.cracked_bauxite_slurry=裂化铝土浆液 +gregtech.material.bauxite_sludge=铝土泥渣 +gregtech.material.decalcified_bauxite_sludge=脱钙铝土泥渣 +gregtech.material.bauxite_slag=铝土矿渣 # Second Degree Materials @@ -2343,15 +2397,26 @@ tile.treated_wood_fence.name=防腐木栅栏 tile.rubber_wood_fence_gate.name=橡胶木栅栏门 tile.treated_wood_fence_gate.name=防腐木栅栏门 +tile.gt_explosive.breaking_tooltip=破坏它会引爆火药,潜行挖掘以重新拾取 +tile.gt_explosive.lighting_tooltip=无法用红石信号引爆 + +tile.powderbarrel.name=火药桶 +tile.powderbarrel.drops_tooltip=爆炸范围略大于TNT,所有被摧毁的方块都会掉落 +entity.Powderbarrel.name=火药桶 + +tile.itnt.name=工业TNT +tile.itnt.drops_tooltip=爆炸范围比TNT大得多,所有被摧毁的方块都会掉落 +entity.ITNT.name=工业TNT + tile.brittle_charcoal.name=脆木炭块 tile.brittle_charcoal.tooltip.1=产自木炭堆点火器。 -tile.brittle_charcoal.tooltip.2=采掘可掉落木炭。 +tile.brittle_charcoal.tooltip.2=挖掘可掉落木炭。 tile.optical_pipe_normal.name=光缆 tile.optical_pipe_normal.tooltip1=传递§f算力§7或§f研究数据§7 tile.laser_pipe_normal.name=激光传导线缆 -tile.laser_pipe_normal.tooltip1=无线损地传递能量,只限直线摆放 +tile.laser_pipe_normal.tooltip1=§f无损§7传递能量,仅限直线摆放 metaitem.prospector.lv.name=电动勘探扫描仪(LV) metaitem.prospector.hv.name=电动勘探扫描仪(HV) @@ -2381,9 +2446,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 @@ -2493,7 +2558,7 @@ tile.warning_sign_1.high_pressure_hazard.name=高压力危害警示方块 # Decorative Metal Sheets tile.metal_sheet.white.name=白色金属板方块 -tile.metal_sheet.orange.name=橘色金属板方块 +tile.metal_sheet.orange.name=橙色金属板方块 tile.metal_sheet.magenta.name=品红色金属板方块 tile.metal_sheet.light_blue.name=淡蓝色金属板方块 tile.metal_sheet.yellow.name=黄色金属板方块 @@ -2510,7 +2575,7 @@ tile.metal_sheet.red.name=红色金属板方块 tile.metal_sheet.black.name=黑色金属板方块 tile.large_metal_sheet.white.name=白色粗纹金属板方块 -tile.large_metal_sheet.orange.name=橘色粗纹金属板方块 +tile.large_metal_sheet.orange.name=橙色粗纹金属板方块 tile.large_metal_sheet.magenta.name=品红色粗纹金属板方块 tile.large_metal_sheet.light_blue.name=淡蓝色粗纹金属板方块 tile.large_metal_sheet.yellow.name=黄色粗纹金属板方块 @@ -2527,7 +2592,7 @@ tile.large_metal_sheet.red.name=红色粗纹金属板方块 tile.large_metal_sheet.black.name=黑色粗纹金属板方块 tile.studs.white.name=白色橡胶混凝土 -tile.studs.orange.name=橘色橡胶混凝土 +tile.studs.orange.name=橙色橡胶混凝土 tile.studs.magenta.name=品红色橡胶混凝土 tile.studs.light_blue.name=淡蓝色橡胶混凝土 tile.studs.yellow.name=黄色橡胶混凝土 @@ -2738,7 +2803,7 @@ gregtech.machine.tank_valve.steel.name=钢制储罐阀门 gregtech.machine.tank.steel.name=钢制多方块储罐 gregtech.multiblock.tank.tooltip=通过控制器或储罐阀门进行吞吐。 -gregtech.tank_valve.tooltip=用以吞吐多方块储罐中的流体。正面向下时可自动输出。 +gregtech.tank_valve.tooltip=用于吞吐多方块储罐中的流体。正面向下时可自动输出。 gregtech.machine.clipboard.name=写字板 @@ -2908,9 +2973,9 @@ gregtech.machine.steam_hammer_bronze.tooltip=锤锻机器 gregtech.machine.steam_hammer_steel.name=高压蒸汽锻造锤 gregtech.machine.steam_hammer_steel.tooltip=锤锻机器 gregtech.machine.steam_furnace_bronze.name=蒸汽熔炉 -gregtech.machine.steam_furnace_bronze.tooltip=利用蒸汽来熔炼物品 +gregtech.machine.steam_furnace_bronze.tooltip=利用蒸汽冶炼物品 gregtech.machine.steam_furnace_steel.name=高压蒸汽熔炉 -gregtech.machine.steam_furnace_steel.tooltip=利用蒸汽来熔炼物品 +gregtech.machine.steam_furnace_steel.tooltip=利用蒸汽冶炼物品 gregtech.machine.steam_alloy_smelter_bronze.name=蒸汽合金炉 gregtech.machine.steam_alloy_smelter_bronze.tooltip=熔合冶炼炉 gregtech.machine.steam_alloy_smelter_steel.name=高压合金炉 @@ -2920,7 +2985,7 @@ gregtech.machine.steam_rock_breaker_bronze.tooltip=需紧贴侧面放置§b水§ gregtech.machine.steam_rock_breaker_steel.name=高压蒸汽碎岩机 gregtech.machine.steam_rock_breaker_steel.tooltip=需紧贴侧面放置§b水§7和§c熔岩 gregtech.machine.steam_miner.name=蒸汽采矿机 -gregtech.machine.steam_miner.tooltip=采掘机器下方的矿石! +gregtech.machine.steam_miner.tooltip=挖掘机器下方的矿石! # Generators gregtech.machine.combustion_generator.tooltip=需要可燃液体 @@ -2952,7 +3017,7 @@ gregtech.machine.block_breaker.lv.name=基础方块破坏器 gregtech.machine.block_breaker.mv.name=进阶方块破坏器 gregtech.machine.block_breaker.hv.name=进阶方块破坏器 II gregtech.machine.block_breaker.ev.name=进阶方块破坏器 III -gregtech.machine.block_breaker.tooltip=采掘面前的方块并收集掉落物 +gregtech.machine.block_breaker.tooltip=挖掘面前的方块并收集掉落物 gregtech.machine.block_breaker.speed_bonus=§e速度加成:§f%,d%% # Electric Furnace @@ -2989,9 +3054,9 @@ gregtech.machine.macerator.lv.tooltip=粉碎矿石 gregtech.machine.macerator.mv.name=进阶研磨机 gregtech.machine.macerator.mv.tooltip=粉碎矿石 gregtech.machine.macerator.hv.name=进阶研磨机 II -gregtech.machine.macerator.hv.tooltip=粉碎矿石,且能产出副产物 +gregtech.machine.macerator.hv.tooltip=粉碎矿石并获得副产物 gregtech.machine.macerator.ev.name=进阶研磨机 III -gregtech.machine.macerator.ev.tooltip=粉碎矿石,且能产出副产物 +gregtech.machine.macerator.ev.tooltip=粉碎矿石并获得副产物 gregtech.machine.macerator.iv.name=精英研磨机 gregtech.machine.macerator.iv.tooltip=全自动破壁机 9001 gregtech.machine.macerator.luv.name=精英研磨机 II @@ -3049,11 +3114,11 @@ gregtech.machine.arc_furnace.hv.tooltip=谁还要高炉啊? gregtech.machine.arc_furnace.ev.name=进阶电弧炉 III gregtech.machine.arc_furnace.ev.tooltip=谁还要高炉啊? gregtech.machine.arc_furnace.iv.name=精英电弧炉 -gregtech.machine.arc_furnace.iv.tooltip=解体加热器 +gregtech.machine.arc_furnace.iv.tooltip=放电加热器 gregtech.machine.arc_furnace.luv.name=精英电弧炉 II -gregtech.machine.arc_furnace.luv.tooltip=解体加热器 +gregtech.machine.arc_furnace.luv.tooltip=放电加热器 gregtech.machine.arc_furnace.zpm.name=精英电弧炉 III -gregtech.machine.arc_furnace.zpm.tooltip=解体加热器 +gregtech.machine.arc_furnace.zpm.tooltip=放电加热器 gregtech.machine.arc_furnace.uv.name=终极电弧炉 gregtech.machine.arc_furnace.uv.tooltip=短路加热器 gregtech.machine.arc_furnace.uhv.name=史诗电弧炉 @@ -3275,23 +3340,23 @@ gregtech.machine.chemical_reactor.hv.tooltip=使化学品相互反应 gregtech.machine.chemical_reactor.ev.name=进阶化学反应釜 III gregtech.machine.chemical_reactor.ev.tooltip=使化学品相互反应 gregtech.machine.chemical_reactor.iv.name=精英化学反应釜 -gregtech.machine.chemical_reactor.iv.tooltip=化学反应操作仪 +gregtech.machine.chemical_reactor.iv.tooltip=化学表演艺术家 gregtech.machine.chemical_reactor.luv.name=精英化学反应釜 II -gregtech.machine.chemical_reactor.luv.tooltip=化学反应操作仪 +gregtech.machine.chemical_reactor.luv.tooltip=化学表演艺术家 gregtech.machine.chemical_reactor.zpm.name=精英化学反应釜 III -gregtech.machine.chemical_reactor.zpm.tooltip=化学反应操作仪 +gregtech.machine.chemical_reactor.zpm.tooltip=化学表演艺术家 gregtech.machine.chemical_reactor.uv.name=终极化学反应釜 -gregtech.machine.chemical_reactor.uv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uv.tooltip=反应催化器 gregtech.machine.chemical_reactor.uhv.name=史诗化学反应釜 -gregtech.machine.chemical_reactor.uhv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uhv.tooltip=反应催化器 gregtech.machine.chemical_reactor.uev.name=史诗化学反应釜 II -gregtech.machine.chemical_reactor.uev.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uev.tooltip=反应催化器 gregtech.machine.chemical_reactor.uiv.name=史诗化学反应釜 III -gregtech.machine.chemical_reactor.uiv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uiv.tooltip=反应催化器 gregtech.machine.chemical_reactor.uxv.name=史诗化学反应釜 IV -gregtech.machine.chemical_reactor.uxv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.uxv.tooltip=反应催化器 gregtech.machine.chemical_reactor.opv.name=传奇化学反应釜 -gregtech.machine.chemical_reactor.opv.tooltip=化学反应催化者 +gregtech.machine.chemical_reactor.opv.tooltip=反应催化器 # Compressor gregtech.machine.compressor.lv.name=基础压缩机 @@ -3337,17 +3402,17 @@ gregtech.machine.cutter.luv.tooltip=物质切削器 gregtech.machine.cutter.zpm.name=精英切割机 III gregtech.machine.cutter.zpm.tooltip=物质切削器 gregtech.machine.cutter.uv.name=终极切割机 -gregtech.machine.cutter.uv.tooltip=物品对象分割者 +gregtech.machine.cutter.uv.tooltip=对象分割者 gregtech.machine.cutter.uhv.name=史诗切割机 -gregtech.machine.cutter.uhv.tooltip=物品对象分割者 +gregtech.machine.cutter.uhv.tooltip=对象分割者 gregtech.machine.cutter.uev.name=史诗切割机 II -gregtech.machine.cutter.uev.tooltip=物品对象分割者 +gregtech.machine.cutter.uev.tooltip=对象分割者 gregtech.machine.cutter.uiv.name=史诗切割机 III -gregtech.machine.cutter.uiv.tooltip=物品对象分割者 +gregtech.machine.cutter.uiv.tooltip=对象分割者 gregtech.machine.cutter.uxv.name=史诗切割机 IV -gregtech.machine.cutter.uxv.tooltip=物品对象分割者 +gregtech.machine.cutter.uxv.tooltip=对象分割者 gregtech.machine.cutter.opv.name=传奇切割机 -gregtech.machine.cutter.opv.tooltip=物品对象分割者 +gregtech.machine.cutter.opv.tooltip=对象分割者 # Distillery gregtech.machine.distillery.lv.name=基础蒸馏室 @@ -3365,17 +3430,17 @@ gregtech.machine.distillery.luv.tooltip=凝结物质分离器 gregtech.machine.distillery.zpm.name=精英蒸馏室 III gregtech.machine.distillery.zpm.tooltip=凝结物质分离器 gregtech.machine.distillery.uv.name=终极蒸馏室 -gregtech.machine.distillery.uv.tooltip=少数分流者 +gregtech.machine.distillery.uv.tooltip=馏分分离器 gregtech.machine.distillery.uhv.name=史诗蒸馏室 -gregtech.machine.distillery.uhv.tooltip=少数分流者 +gregtech.machine.distillery.uhv.tooltip=馏分分离器 gregtech.machine.distillery.uev.name=史诗蒸馏室 II -gregtech.machine.distillery.uev.tooltip=少数分流者 +gregtech.machine.distillery.uev.tooltip=馏分分离器 gregtech.machine.distillery.uiv.name=史诗蒸馏室 III -gregtech.machine.distillery.uiv.tooltip=少数分流者 +gregtech.machine.distillery.uiv.tooltip=馏分分离器 gregtech.machine.distillery.uxv.name=史诗蒸馏室 IV -gregtech.machine.distillery.uxv.tooltip=少数分流者 +gregtech.machine.distillery.uxv.tooltip=馏分分离器 gregtech.machine.distillery.opv.name=传奇蒸馏室 -gregtech.machine.distillery.opv.tooltip=少数分流者 +gregtech.machine.distillery.opv.tooltip=馏分分离器 # Electrolyzer gregtech.machine.electrolyzer.lv.name=基础电解机 @@ -3435,13 +3500,13 @@ gregtech.machine.electromagnetic_separator.opv.tooltip=电磁场驱离装置 # Extractor gregtech.machine.extractor.lv.name=基础提取机 -gregtech.machine.extractor.lv.tooltip=毁灭级榨干机 - D123 +gregtech.machine.extractor.lv.tooltip=毁灭级榨汁机 - D123 gregtech.machine.extractor.mv.name=进阶提取机 -gregtech.machine.extractor.mv.tooltip=毁灭级榨干机 - D123 +gregtech.machine.extractor.mv.tooltip=毁灭级榨汁机 - D123 gregtech.machine.extractor.hv.name=进阶提取机 II -gregtech.machine.extractor.hv.tooltip=毁灭级榨干机 - D123 +gregtech.machine.extractor.hv.tooltip=毁灭级榨汁机 - D123 gregtech.machine.extractor.ev.name=进阶提取机 III -gregtech.machine.extractor.ev.tooltip=毁灭级榨干机 - D123 +gregtech.machine.extractor.ev.tooltip=毁灭级榨汁机 - D123 gregtech.machine.extractor.iv.name=精英提取机 gregtech.machine.extractor.iv.tooltip=真空提炼机 gregtech.machine.extractor.luv.name=精英提取机 II @@ -3463,13 +3528,13 @@ gregtech.machine.extractor.opv.tooltip=液化吸取者 # Extruder gregtech.machine.extruder.lv.name=基础压模器 -gregtech.machine.extruder.lv.tooltip=通用的金属处理机器 +gregtech.machine.extruder.lv.tooltip=通用型金属加工器 gregtech.machine.extruder.mv.name=进阶压模器 -gregtech.machine.extruder.mv.tooltip=通用的金属处理机器 +gregtech.machine.extruder.mv.tooltip=通用型金属加工器 gregtech.machine.extruder.hv.name=进阶压模器 II -gregtech.machine.extruder.hv.tooltip=通用的金属处理机器 +gregtech.machine.extruder.hv.tooltip=通用型金属加工器 gregtech.machine.extruder.ev.name=进阶压模器 III -gregtech.machine.extruder.ev.tooltip=通用的金属处理机器 +gregtech.machine.extruder.ev.tooltip=通用型金属加工器 gregtech.machine.extruder.iv.name=精英压模器 gregtech.machine.extruder.iv.tooltip=材料压出器 gregtech.machine.extruder.luv.name=精英压模器 II @@ -3498,11 +3563,11 @@ gregtech.machine.fermenter.hv.tooltip=发酵流体 gregtech.machine.fermenter.ev.name=进阶发酵槽 III gregtech.machine.fermenter.ev.tooltip=发酵流体 gregtech.machine.fermenter.iv.name=精英发酵槽 -gregtech.machine.fermenter.iv.tooltip=发酵催促器 +gregtech.machine.fermenter.iv.tooltip=发酵加速器 gregtech.machine.fermenter.luv.name=精英发酵槽 II -gregtech.machine.fermenter.luv.tooltip=发酵催促器 +gregtech.machine.fermenter.luv.tooltip=发酵加速器 gregtech.machine.fermenter.zpm.name=精英发酵槽 III -gregtech.machine.fermenter.zpm.tooltip=发酵催促器 +gregtech.machine.fermenter.zpm.tooltip=发酵加速器 gregtech.machine.fermenter.uv.name=终极发酵槽 gregtech.machine.fermenter.uv.tooltip=呼吸控制器 gregtech.machine.fermenter.uhv.name=史诗发酵槽 @@ -3518,41 +3583,41 @@ gregtech.machine.fermenter.opv.tooltip=呼吸控制器 # Fluid Heater gregtech.machine.fluid_heater.lv.name=基础流体加热器 -gregtech.machine.fluid_heater.lv.tooltip=加热流体 +gregtech.machine.fluid_heater.lv.tooltip=加热你的流体 gregtech.machine.fluid_heater.mv.name=进阶流体加热器 -gregtech.machine.fluid_heater.mv.tooltip=加热流体 +gregtech.machine.fluid_heater.mv.tooltip=加热你的流体 gregtech.machine.fluid_heater.hv.name=进阶流体加热器 II -gregtech.machine.fluid_heater.hv.tooltip=加热流体 +gregtech.machine.fluid_heater.hv.tooltip=加热你的流体 gregtech.machine.fluid_heater.ev.name=进阶流体加热器 III -gregtech.machine.fluid_heater.ev.tooltip=加热流体 +gregtech.machine.fluid_heater.ev.tooltip=加热你的流体 gregtech.machine.fluid_heater.iv.name=精英流体加热器 -gregtech.machine.fluid_heater.iv.tooltip=热量注入器 +gregtech.machine.fluid_heater.iv.tooltip=热量灌注器 gregtech.machine.fluid_heater.luv.name=精英流体加热器 II -gregtech.machine.fluid_heater.luv.tooltip=热量注入器 +gregtech.machine.fluid_heater.luv.tooltip=热量灌注器 gregtech.machine.fluid_heater.zpm.name=精英流体加热器 III -gregtech.machine.fluid_heater.zpm.tooltip=热量注入器 +gregtech.machine.fluid_heater.zpm.tooltip=热量灌注器 gregtech.machine.fluid_heater.uv.name=终极流体加热器 -gregtech.machine.fluid_heater.uv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uv.tooltip=热量灌输器 gregtech.machine.fluid_heater.uhv.name=史诗流体加热器 -gregtech.machine.fluid_heater.uhv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uhv.tooltip=热量灌输器 gregtech.machine.fluid_heater.uev.name=史诗流体加热器 II -gregtech.machine.fluid_heater.uev.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uev.tooltip=热量灌输器 gregtech.machine.fluid_heater.uiv.name=史诗流体加热器 III -gregtech.machine.fluid_heater.uiv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uiv.tooltip=热量灌输器 gregtech.machine.fluid_heater.uxv.name=史诗流体加热器 IV -gregtech.machine.fluid_heater.uxv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.uxv.tooltip=热量灌输器 gregtech.machine.fluid_heater.opv.name=传奇流体加热器 -gregtech.machine.fluid_heater.opv.tooltip=热力灌注者 +gregtech.machine.fluid_heater.opv.tooltip=热量灌输器 # Fluid Solidifier gregtech.machine.fluid_solidifier.lv.name=基础流体固化器 -gregtech.machine.fluid_solidifier.lv.tooltip=冷却液体并定型为固体 +gregtech.machine.fluid_solidifier.lv.tooltip=冷却液体形成固体 gregtech.machine.fluid_solidifier.mv.name=进阶流体固化器 -gregtech.machine.fluid_solidifier.mv.tooltip=冷却液体并定型为固体 +gregtech.machine.fluid_solidifier.mv.tooltip=冷却液体形成固体 gregtech.machine.fluid_solidifier.hv.name=进阶流体固化器 II -gregtech.machine.fluid_solidifier.hv.tooltip=冷却液体并定型为固体 +gregtech.machine.fluid_solidifier.hv.tooltip=冷却液体形成固体 gregtech.machine.fluid_solidifier.ev.name=进阶流体固化器 III -gregtech.machine.fluid_solidifier.ev.tooltip=冷却液体并定型为固体 +gregtech.machine.fluid_solidifier.ev.tooltip=冷却液体形成固体 gregtech.machine.fluid_solidifier.iv.name=精英流体固化器 gregtech.machine.fluid_solidifier.iv.tooltip=并不是制冰机 gregtech.machine.fluid_solidifier.luv.name=精英流体固化器 II @@ -3582,11 +3647,11 @@ gregtech.machine.forge_hammer.hv.tooltip=停,抡锤时间到! gregtech.machine.forge_hammer.ev.name=进阶锻造锤 III gregtech.machine.forge_hammer.ev.tooltip=停,抡锤时间到! gregtech.machine.forge_hammer.iv.name=精英锻造锤 -gregtech.machine.forge_hammer.iv.tooltip=板材锻造机 +gregtech.machine.forge_hammer.iv.tooltip=锻板机 gregtech.machine.forge_hammer.luv.name=精英锻造锤 II -gregtech.machine.forge_hammer.luv.tooltip=板材锻造机 +gregtech.machine.forge_hammer.luv.tooltip=锻板机 gregtech.machine.forge_hammer.zpm.name=精英锻造锤 III -gregtech.machine.forge_hammer.zpm.tooltip=板材锻造机 +gregtech.machine.forge_hammer.zpm.tooltip=锻板机 gregtech.machine.forge_hammer.uv.name=终极锻造锤 gregtech.machine.forge_hammer.uv.tooltip=冲击调制器 gregtech.machine.forge_hammer.uhv.name=史诗锻造锤 @@ -3602,13 +3667,13 @@ gregtech.machine.forge_hammer.opv.tooltip=冲击调制器 # Forming Press gregtech.machine.forming_press.lv.name=基础冲压机床 -gregtech.machine.forming_press.lv.tooltip=将印象压印为实际的存在 +gregtech.machine.forming_press.lv.tooltip=图像拓印者 gregtech.machine.forming_press.mv.name=进阶冲压机床 -gregtech.machine.forming_press.mv.tooltip=印象具现者 +gregtech.machine.forming_press.mv.tooltip=图像拓印者 gregtech.machine.forming_press.hv.name=进阶冲压机床 II -gregtech.machine.forming_press.hv.tooltip=印象具现者 +gregtech.machine.forming_press.hv.tooltip=图像拓印者 gregtech.machine.forming_press.ev.name=进阶冲压机床 III -gregtech.machine.forming_press.ev.tooltip=印象具现者 +gregtech.machine.forming_press.ev.tooltip=图像拓印者 gregtech.machine.forming_press.iv.name=精英冲压机床 gregtech.machine.forming_press.iv.tooltip=对象层化机 gregtech.machine.forming_press.luv.name=精英冲压机床 II @@ -3742,13 +3807,13 @@ gregtech.machine.packer.opv.tooltip=亚马逊仓库 # Polarizer gregtech.machine.polarizer.lv.name=基础两极磁化机 -gregtech.machine.polarizer.lv.tooltip=使磁体两极化 +gregtech.machine.polarizer.lv.tooltip=将你的磁体极化 gregtech.machine.polarizer.mv.name=进阶两极磁化机 -gregtech.machine.polarizer.mv.tooltip=使磁体两极化 +gregtech.machine.polarizer.mv.tooltip=将你的磁体极化 gregtech.machine.polarizer.hv.name=进阶两极磁化机 II -gregtech.machine.polarizer.hv.tooltip=使磁体两极化 +gregtech.machine.polarizer.hv.tooltip=将你的磁体极化 gregtech.machine.polarizer.ev.name=进阶两极磁化机 III -gregtech.machine.polarizer.ev.tooltip=使磁体两极化 +gregtech.machine.polarizer.ev.tooltip=将你的磁体极化 gregtech.machine.polarizer.iv.name=精英两极磁化机 gregtech.machine.polarizer.iv.tooltip=磁性引入机 gregtech.machine.polarizer.luv.name=精英两极磁化机 II @@ -3778,11 +3843,11 @@ gregtech.machine.laser_engraver.hv.tooltip=请勿直视激光 gregtech.machine.laser_engraver.ev.name=进阶精密激光蚀刻机 III gregtech.machine.laser_engraver.ev.tooltip=请勿直视激光 gregtech.machine.laser_engraver.iv.name=精英精密激光蚀刻机 -gregtech.machine.laser_engraver.iv.tooltip=蕴含着两百零四万瓦的能量 +gregtech.machine.laser_engraver.iv.tooltip=功率高达两百零四万瓦 gregtech.machine.laser_engraver.luv.name=精英精密激光蚀刻机 II -gregtech.machine.laser_engraver.luv.tooltip=蕴含着两百零四万瓦的能量 +gregtech.machine.laser_engraver.luv.tooltip=功率高达八百一十六万瓦 gregtech.machine.laser_engraver.zpm.name=精英精密激光蚀刻机 III -gregtech.machine.laser_engraver.zpm.tooltip=蕴含着两百零四万瓦的能量 +gregtech.machine.laser_engraver.zpm.tooltip=功率高达三千两百六十四万瓦 gregtech.machine.laser_engraver.uv.name=终极精密激光蚀刻机 gregtech.machine.laser_engraver.uv.tooltip=高精度光子加农炮 gregtech.machine.laser_engraver.uhv.name=史诗激光蚀刻机 @@ -3882,13 +3947,13 @@ gregtech.machine.wiremill.opv.tooltip=导线易形者 # Circuit Assembler gregtech.machine.circuit_assembler.lv.name=基础电路组装机 -gregtech.machine.circuit_assembler.lv.tooltip=一拿一放,东拣西装。 +gregtech.machine.circuit_assembler.lv.tooltip=一拿一放,东拣西装 gregtech.machine.circuit_assembler.mv.name=进阶电路组装机 -gregtech.machine.circuit_assembler.mv.tooltip=一拿一放,东拣西装。 +gregtech.machine.circuit_assembler.mv.tooltip=一拿一放,东拣西装 gregtech.machine.circuit_assembler.hv.name=进阶电路组装机 II -gregtech.machine.circuit_assembler.hv.tooltip=一拿一放,东拣西装。 +gregtech.machine.circuit_assembler.hv.tooltip=一拿一放,东拣西装 gregtech.machine.circuit_assembler.ev.name=进阶电路组装机 III -gregtech.machine.circuit_assembler.ev.tooltip=一拿一放,东拣西装。 +gregtech.machine.circuit_assembler.ev.tooltip=一拿一放,东拣西装 gregtech.machine.circuit_assembler.iv.name=精英电路组装机 gregtech.machine.circuit_assembler.iv.tooltip=电子厂 gregtech.machine.circuit_assembler.luv.name=精英电路组装机 II @@ -3896,17 +3961,17 @@ gregtech.machine.circuit_assembler.luv.tooltip=电子厂 gregtech.machine.circuit_assembler.zpm.name=精英电路组装机 III gregtech.machine.circuit_assembler.zpm.tooltip=电子厂 gregtech.machine.circuit_assembler.uv.name=终极电路组装机 -gregtech.machine.circuit_assembler.uv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uv.tooltip=计算机工厂 gregtech.machine.circuit_assembler.uhv.name=史诗电路组装机 -gregtech.machine.circuit_assembler.uhv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uhv.tooltip=计算机工厂 gregtech.machine.circuit_assembler.uev.name=史诗电路组装机 II -gregtech.machine.circuit_assembler.uev.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uev.tooltip=计算机工厂 gregtech.machine.circuit_assembler.uiv.name=史诗电路组装机 III -gregtech.machine.circuit_assembler.uiv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uiv.tooltip=计算机工厂 gregtech.machine.circuit_assembler.uxv.name=史诗电路组装机 IV -gregtech.machine.circuit_assembler.uxv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.uxv.tooltip=计算机工厂 gregtech.machine.circuit_assembler.opv.name=传奇电路组装机 -gregtech.machine.circuit_assembler.opv.tooltip=计算工厂 +gregtech.machine.circuit_assembler.opv.tooltip=计算机工厂 # Mass Fabricator gregtech.machine.mass_fabricator.lv.name=基础质量发生器 @@ -3918,11 +3983,11 @@ gregtech.machine.mass_fabricator.hv.tooltip=UU物质 = “质量” * “发生 gregtech.machine.mass_fabricator.ev.name=进阶质量发生器 III gregtech.machine.mass_fabricator.ev.tooltip=UU物质 = “质量” * “发生”的平方 gregtech.machine.mass_fabricator.iv.name=精英质量发生器 -gregtech.machine.mass_fabricator.iv.tooltip=创世工坊 +gregtech.machine.mass_fabricator.iv.tooltip=创世纪工厂 gregtech.machine.mass_fabricator.luv.name=精英质量发生器 II -gregtech.machine.mass_fabricator.luv.tooltip=创世工坊 +gregtech.machine.mass_fabricator.luv.tooltip=创世纪工厂 gregtech.machine.mass_fabricator.zpm.name=精英质量发生器 III -gregtech.machine.mass_fabricator.zpm.tooltip=创世工坊 +gregtech.machine.mass_fabricator.zpm.tooltip=创世纪工厂 gregtech.machine.mass_fabricator.uv.name=终极质量发生器 gregtech.machine.mass_fabricator.uv.tooltip=存在之源 gregtech.machine.mass_fabricator.uhv.name=史诗质量发生器 @@ -3938,13 +4003,13 @@ gregtech.machine.mass_fabricator.opv.tooltip=存在之源 # Replicator gregtech.machine.replicator.lv.name=基础复制机 -gregtech.machine.replicator.lv.tooltip=生产出至纯的元素 +gregtech.machine.replicator.lv.tooltip=生产最纯净的元素 gregtech.machine.replicator.mv.name=进阶复制机 -gregtech.machine.replicator.mv.tooltip=生产出至纯的元素 +gregtech.machine.replicator.mv.tooltip=生产最纯净的元素 gregtech.machine.replicator.hv.name=进阶复制机 II -gregtech.machine.replicator.hv.tooltip=生产出至纯的元素 +gregtech.machine.replicator.hv.tooltip=生产最纯净的元素 gregtech.machine.replicator.ev.name=进阶复制机 III -gregtech.machine.replicator.ev.tooltip=生产出至纯的元素 +gregtech.machine.replicator.ev.tooltip=生产最纯净的元素 gregtech.machine.replicator.iv.name=精英复制机 gregtech.machine.replicator.iv.tooltip=物质粘贴机 gregtech.machine.replicator.luv.name=精英复制机 II @@ -4146,7 +4211,7 @@ gregtech.machine.transformer.adjustable.opv.name=过载压高能变压器(§9O gregtech.machine.diode.message=电流吞吐上限:%s gregtech.machine.diode.tooltip_tool_usage=手持软锤右击以调节电流。 gregtech.machine.diode.tooltip_general=使能量作单向传输并限制电流 -gregtech.machine.diode.tooltip_starts_at=默认为§f1A§7,使用软锤来轮换电流设定 +gregtech.machine.diode.tooltip_starts_at=默认允许§f1A§r电流通行,使用软锤切换。 gregtech.machine.diode.ulv.name=超低压二极管(§8ULV§r) gregtech.machine.diode.lv.name=低压二极管(§7LV§r) @@ -4302,7 +4367,7 @@ gregtech.machine.quantum_tank.uv.name=量子缸 IV gregtech.machine.quantum_tank.uhv.name=量子缸 V #Buffers -gregtech.machine.buffer.tooltip=能够存储物品与流体的小型缓存器 +gregtech.machine.buffer.tooltip=存储物品和流体的小小缓冲器 gregtech.machine.buffer.lv.name=基础缓存器 gregtech.machine.buffer.mv.name=进阶缓存器 gregtech.machine.buffer.hv.name=进阶缓存器 II @@ -4320,31 +4385,31 @@ tile.hermetic_casing.hermetic_casing_uhv.name=密封机械方块 IX #Gas Collectors gregtech.machine.gas_collector.lv.name=基础集气室 -gregtech.machine.gas_collector.lv.tooltip=收集不同维度的空气中种类各异的气体 +gregtech.machine.gas_collector.lv.tooltip=依照维度从空气中收集种类各异的气体 gregtech.machine.gas_collector.mv.name=进阶集气室 -gregtech.machine.gas_collector.mv.tooltip=收集不同维度的空气中种类各异的气体 +gregtech.machine.gas_collector.mv.tooltip=依照维度从空气中收集种类各异的气体 gregtech.machine.gas_collector.hv.name=进阶集气室 II -gregtech.machine.gas_collector.hv.tooltip=收集不同维度的空气中种类各异的气体 +gregtech.machine.gas_collector.hv.tooltip=依照维度从空气中收集种类各异的气体 gregtech.machine.gas_collector.ev.name=进阶集气室 III -gregtech.machine.gas_collector.ev.tooltip=收集不同维度的空气中种类各异的气体 +gregtech.machine.gas_collector.ev.tooltip=依照维度从空气中收集种类各异的气体 gregtech.machine.gas_collector.iv.name=精英集气室 -gregtech.machine.gas_collector.iv.tooltip=收集不同维度的大气中种类各异的气体 +gregtech.machine.gas_collector.iv.tooltip=依照维度从大气层中收集种类各异的气体 gregtech.machine.gas_collector.luv.name=精英集气室 II -gregtech.machine.gas_collector.luv.tooltip=收集不同维度的大气中种类各异的气体 +gregtech.machine.gas_collector.luv.tooltip=依照维度从大气层中收集种类各异的气体 gregtech.machine.gas_collector.zpm.name=精英集气室 III -gregtech.machine.gas_collector.zpm.tooltip=收集不同维度的大气中种类各异的气体 +gregtech.machine.gas_collector.zpm.tooltip=依照维度从大气层中收集种类各异的气体 gregtech.machine.gas_collector.uv.name=终极集气室 -gregtech.machine.gas_collector.uv.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uv.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.uhv.name=史诗集气室 -gregtech.machine.gas_collector.uhv.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uhv.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.uev.name=史诗集气室 II -gregtech.machine.gas_collector.uev.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uev.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.uiv.name=史诗集气室 III -gregtech.machine.gas_collector.uiv.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uiv.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.uxv.name=史诗集气室 IV -gregtech.machine.gas_collector.uxv.tooltip=从太阳系中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.uxv.tooltip=依照维度从太阳系中收集种类各异的气体 gregtech.machine.gas_collector.opv.name=传说集气室 -gregtech.machine.gas_collector.opv.tooltip=从宇宙中依照不同的维度收集种类各异的气体 +gregtech.machine.gas_collector.opv.tooltip=依照维度从宇宙中收集种类各异的气体 #Rock Breakers gregtech.machine.rock_breaker.lv.name=基础碎岩机 @@ -4362,17 +4427,17 @@ gregtech.machine.rock_breaker.luv.tooltip=岩浆冷却固化器 R-9200 gregtech.machine.rock_breaker.zpm.name=精英碎岩机 III gregtech.machine.rock_breaker.zpm.tooltip=岩浆冷却固化器 R-10200 gregtech.machine.rock_breaker.uv.name=终极碎岩机 -gregtech.machine.rock_breaker.uv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uv.tooltip=火山成型室 gregtech.machine.rock_breaker.uhv.name=史诗碎岩机 -gregtech.machine.rock_breaker.uhv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uhv.tooltip=火山成型室 gregtech.machine.rock_breaker.uev.name=史诗碎岩机 II -gregtech.machine.rock_breaker.uev.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uev.tooltip=火山成型室 gregtech.machine.rock_breaker.uiv.name=史诗碎岩机 III -gregtech.machine.rock_breaker.uiv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uiv.tooltip=火山成型室 gregtech.machine.rock_breaker.uxv.name=史诗碎岩机 IV -gregtech.machine.rock_breaker.uxv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.uxv.tooltip=火山成型室 gregtech.machine.rock_breaker.opv.name=传奇碎岩机 -gregtech.machine.rock_breaker.opv.tooltip=火山成型仓 +gregtech.machine.rock_breaker.opv.tooltip=火山成型室 #Fisher gregtech.machine.fisher.lv.name=基础捕鱼机 @@ -4709,7 +4774,7 @@ gregtech.machine.large_chemical_reactor.name=大型化学反应釜 gregtech.machine.large_combustion_engine.name=大型内燃引擎 gregtech.machine.extreme_combustion_engine.name=极限内燃引擎 gregtech.machine.large_combustion_engine.tooltip.boost_regular=提供§f20 L/s§7的氧气,并消耗§f双倍§7燃料以产生高达§f%s§7 EU/t的功率。 -gregtech.machine.large_combustion_engine.tooltip.boost_extreme=提供§f80 L/s§7的液氧,并消耗§f双倍§7燃料以产生高达§f%s§7 EU/t的功率。 +gregtech.machine.large_combustion_engine.tooltip.boost_extreme=提供§f80L/s§7的液态氧,并消耗§f双倍§7燃料以产生高达§f%s§7EU/t的功率。 gregtech.machine.large_turbine.steam.name=大型蒸汽涡轮 gregtech.machine.large_turbine.gas.name=大型燃气涡轮 @@ -4733,14 +4798,14 @@ gregtech.machine.fusion_reactor.overclocking=超频将使能耗翻倍,处理 gregtech.machine.miner.lv.name=基础采矿机 gregtech.machine.miner.mv.name=进阶采矿机 gregtech.machine.miner.hv.name=进阶采矿机 II -gregtech.machine.miner.tooltip=只采掘机器下方的矿石!工作范围默认为§f%sx%s§7。 +gregtech.machine.miner.tooltip=只挖掘机器下方的矿石!工作范围默认为§f%sx%s§7。 gregtech.machine.miner.per_block=§7每个方块需要§f%d§7秒。 gregtech.machine.large_miner.ev.name=基础采矿场 gregtech.machine.large_miner.iv.name=进阶采矿场 gregtech.machine.large_miner.luv.name=进阶采矿场 II gregtech.machine.miner.multi.modes=具有精准采集模式与区块对齐模式。 -gregtech.machine.miner.multi.production=粉碎矿石的产出量为§f研磨机§7的§f3倍§7。 +gregtech.machine.miner.multi.production=它能产出§f三倍§7于§f研磨机§7的粉碎矿石。 gregtech.machine.miner.fluid_usage=每tick消耗§f%,d L§7的§f%s§7,超频时翻倍。 gregtech.machine.miner.multi.description=一台工作范围极广的多方块采矿机,能够提供巨量矿石。 gregtech.machine.miner.multi.needsfluid=钻井液不足! @@ -4759,7 +4824,7 @@ gregtech.machine.miner.chunkradius=区块半径:%d gregtech.machine.fluid_drilling_rig.mv.name=基础流体钻机 gregtech.machine.fluid_drilling_rig.hv.name=进阶流体钻机 gregtech.machine.fluid_drilling_rig.ev.name=进阶流体钻机 II -gregtech.machine.fluid_drilling_rig.description=钻取基岩之下的涓涓流体。 +gregtech.machine.fluid_drilling_rig.description=钻取基岩之下的漫漫流体。 gregtech.machine.fluid_drilling_rig.production=§e产量倍数:§f%dx,超频时为%fx gregtech.machine.fluid_drilling_rig.depletion=§b损耗率:§f%s%% gregtech.machine.fluid_drilling_rig.shows_depletion=显示流体矿脉信息 @@ -4781,6 +4846,7 @@ gregtech.multiblock.cleanroom.clean_status=状态:%s gregtech.multiblock.cleanroom.clean_state=洁净(%s%%) gregtech.multiblock.cleanroom.dirty_state=污染(%s%%) gregtech.multiblock.cleanroom.warning_contaminated=被污染! +gregtech.multiblock.cleanroom.low_tier=能源仓等级过低,最低等级为%s! gregtech.machine.charcoal_pile.name=木炭堆点火器 gregtech.machine.charcoal_pile.tooltip.1=§c点火后§7将原木烧制成§a木炭§7。 @@ -4804,14 +4870,14 @@ gregtech.machine.power_substation.tooltip3=最多容许§f%d层电容§7。 gregtech.machine.power_substation.tooltip4=每§f24小时§7损失相当于总容量的§f1%%§7的能量。 gregtech.machine.power_substation.tooltip5=每个电容的损失上限为§f%,d EU/t§7。 gregtech.machine.power_substation.tooltip6=可以使用 -gregtech.machine.power_substation.tooltip6.5= 激光仓§7。 +gregtech.machine.power_substation.tooltip6.5=激光仓§7。 gregtech.multiblock.power_substation.description=蓄能变电站是一个用于储存大量能量的多方块结构,它最多可以容纳18层电容,每层都必须填充完整,这意味着你可以用空电容来填充空间。 gregtech.machine.active_transformer.name=有源变压器 gregtech.machine.active_transformer.tooltip1=变形金刚:伪装的激光 gregtech.machine.active_transformer.tooltip2=可以将任意数量的能量§f输入§7整合为任意数量的能量§f输出§7。 gregtech.machine.active_transformer.tooltip3=当你使用§d激光§7进行能量传输时,拥有惊人的传输距离。 -gregtech.machine.active_transformer.tooltip3.5= +gregtech.machine.active_transformer.tooltip3.5= gregtech.multiblock.active_transformer.description=有源变压器是个多方块变压器,它可以接受任意数量,任意能量等级的能源仓输入,并以任意数量,任意能量等级的动力仓输出。有源变压器允许使用激光仓进行能量传输,这种长距离能量传输没有任何线损,但激光传导线缆必须位于一条直线上,否则不能传递能量。 gregtech.machine.active_transformer.routing=路由模式 @@ -4933,7 +4999,6 @@ gregtech.machine.item_bus.export.uhv.name=§4UHV§r输出总线 gregtech.bus.collapse_true=已启用物品堆叠自动合并 gregtech.bus.collapse_false=已禁用物品堆叠自动合并 -gregtech.bus.collapse.error=总线位于已成型的多方块结构后方可进行该操作 gregtech.machine.fluid_hatch.import.tooltip=为多方块结构输入流体 @@ -5071,8 +5136,8 @@ gregtech.machine.substation_hatch.output_64a.zpm.name=64安§cZPM§r变电动力 gregtech.machine.substation_hatch.output_64a.uv.name=64安§3UV§r变电动力仓 gregtech.machine.substation_hatch.output_64a.uhv.name=64安§4UHV§r变电动力仓 -gregtech.machine.rotor_holder.tooltip1=为多方块结构的转子 -gregtech.machine.rotor_holder.tooltip2=提供支撑,固定转子使其不能飞走 +gregtech.machine.rotor_holder.tooltip1=为多方块结构固定转子, +gregtech.machine.rotor_holder.tooltip2=使其不能飞走 gregtech.machine.rotor_holder.hv.name=§6HV§r转子支架 gregtech.machine.rotor_holder.ev.name=§5EV§r转子支架 @@ -5082,24 +5147,24 @@ 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_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_tool_slot.tooltip=所需工具处于物品栏时空手点击该槽位来维护 gregtech.machine.maintenance_hatch_tape_slot.tooltip=放入胶带以防止发生故障 gregtech.maintenance.configurable_duration=处理耗时:%fx gregtech.maintenance.configurable_duration.unchanged_description=配方以正常速度运行。更改配置以更新。 gregtech.maintenance.configurable_duration.changed_description=配方处理速度现为正常速度(不计超频)的%f倍。 -gregtech.maintenance.configurable_time=故障几率:%fx -gregtech.maintenance.configurable_time.unchanged_description=故障的发生几率为正常值。更改配置以更新。 -gregtech.maintenance.configurable_time.changed_description=故障的发生几率现为正常值的%f倍。 +gregtech.maintenance.configurable_time=故障概率:%fx +gregtech.maintenance.configurable_time.unchanged_description=故障的发生概率为正常值。更改配置以更新。 +gregtech.maintenance.configurable_time.changed_description=故障的发生概率现为正常值的%f倍。 gregtech.maintenance.configurable.tooltip_basic=以更频繁的维护需求为代价,加快机器的处理速度 gregtech.maintenance.configurable.tooltip_more_info=按住SHIFT进行特殊交互 @@ -5125,7 +5190,7 @@ gregtech.machine.muffler_hatch.uxv.name=§eUXV§r消声仓 gregtech.machine.muffler_hatch.opv.name=§9OpV§r消声仓 gregtech.machine.muffler_hatch.max.name=§c§lMAX§r消声仓 -gregtech.muffler.recovery_tooltip=§b收集几率:§f%d%% +gregtech.muffler.recovery_tooltip=§b收集概率:§f%d%% gregtech.machine.pump_hatch.name=水泵输出仓 gregtech.machine.pump_hatch.tooltip=原始水泵专用流体输出口 @@ -5237,17 +5302,34 @@ gregtech.machine.laser_hatch.target.tooltip1=远距离接收能量 gregtech.machine.laser_hatch.tooltip2=§c激光传导线缆必须直线摆放!§7 gregtech.machine.fluid_tank.max_multiblock=多方块结构最大尺寸:%,dx%,dx%,d -gregtech.machine.fluid_tank.fluid=含有%s mB%s - -gregtech.machine.me_export_fluid_hatch.name=ME输出仓 +gregtech.machine.fluid_tank.fluid=含有%s L%s + +# ME Parts +gregtech.machine.me_import_item_bus.name=ME输入总线 +gregtech.machine.me.item_import.tooltip=从ME网络提取指定物品 +gregtech.machine.me_stocking_item_bus.name=ME库存输入总线 +gregtech.machine.me.stocking_item.tooltip=直接从ME网络抽取物品 +gregtech.machine.me.stocking_item.tooltip.2=ME自动拉取模式将自动标记ME网络中的前16种物品,每5秒更新一次。 +gregtech.machine.me_import_item_hatch.configs.tooltip=可标记16种物品 +gregtech.machine.me_import_fluid_hatch.name=ME输入仓 +gregtech.machine.me.fluid_import.tooltip=从ME网络提取指定流体 +gregtech.machine.me_stocking_fluid_hatch.name=ME库存输入仓 +gregtech.machine.me.stocking_fluid.tooltip=直接从ME网络抽取流体 +gregtech.machine.me.stocking_fluid.tooltip.2=ME自动拉取模式将自动标记ME网络中的前16种流体,每5秒更新一次。 +gregtech.machine.me_import_fluid_hatch.configs.tooltip=可标记16种流体 gregtech.machine.me_export_item_bus.name=ME输出总线 -gregtech.machine.me_import_fluid_hatch.name=ME库存输入仓 -gregtech.machine.me_import_item_bus.name=ME库存输入总线 -gregtech.machine.me.fluid_export.tooltip=将流体直接存储到ME网络中。 -gregtech.machine.me.item_export.tooltip=将物品直接存储到ME网络中。 -gregtech.machine.me.fluid_import.tooltip=自动从ME网络获取流体。 -gregtech.machine.me.item_import.tooltip=自动从ME网络获取物品。 -gregtech.machine.me.export.tooltip=在连接到ME网络之前,它具有无限容量。 +gregtech.machine.me.item_export.tooltip=将物品直接存储到ME网络中 +gregtech.machine.me.item_export.tooltip.2=可以缓存无限数量的物品 +gregtech.machine.me_export_fluid_hatch.name=ME输出仓 +gregtech.machine.me.fluid_export.tooltip=将流体直接存储到ME网络中 +gregtech.machine.me.fluid_export.tooltip.2=可以缓存无限数量的流体 +gregtech.machine.me.stocking_auto_pull_enabled=ME自动拉取已启用 +gregtech.machine.me.stocking_auto_pull_disabled=ME自动拉取已禁用 +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) @@ -5270,7 +5352,7 @@ gregtech.universal.tooltip.item_stored=§d内含物品:§f%2$,d + %3$,d 个%1$ gregtech.universal.tooltip.item_transfer_rate=§b传输速率:§f%,d件物品/s gregtech.universal.tooltip.item_transfer_rate_stacks=§b传输速率:§f%,d组物品/s gregtech.universal.tooltip.fluid_storage_capacity=§9流体容量:§f%,d L -gregtech.universal.tooltip.fluid_storage_capacity_mult=§9流体容量:共§f%d§7个流体槽,每个§f%dL§7 +gregtech.universal.tooltip.fluid_storage_capacity_mult=§9流体容量:§7共§f%d§7个流体槽,每个§f%dL§7 gregtech.universal.tooltip.fluid_stored=§d内含流体:§f%2$,d L %1$s gregtech.universal.tooltip.fluid_transfer_rate=§b传输速率:§f%,d L/t gregtech.universal.tooltip.parallel=§d最大并行:§f%d @@ -5307,6 +5389,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=无菌超净间 @@ -5364,11 +5447,16 @@ gregtech.gui.overclock.off=X gregtech.gui.sort=分类 gregtech.gui.fluid_auto_output.tooltip.enabled=流体自动输出已启用 gregtech.gui.fluid_auto_output.tooltip.disabled=流体自动输出已禁用 +gregtech.gui.item_auto_input.tooltip.enabled=物品自动输入已启用 +gregtech.gui.item_auto_input.tooltip.disabled=物品自动输入已禁用 gregtech.gui.item_auto_output.tooltip.enabled=物品自动输出已启用 gregtech.gui.item_auto_output.tooltip.disabled=物品自动输出已禁用 +gregtech.gui.item_auto_collapse.tooltip.enabled=物品堆叠自动合并已启用 +gregtech.gui.item_auto_collapse.tooltip.disabled=物品堆叠自动合并已禁用 gregtech.gui.charger_slot.tooltip=§f充电槽§r/n§7从%s电池中取电§7/n§7也可为%s工具或电池充电 -gregtech.gui.configurator_slot.tooltip=§f编程电路槽§r/n§a配置值:§f%d§7/n/n§7左击/右击/滚轮可浏览循环列表/n§7Shift+右键单击以清除 +gregtech.gui.configurator_slot.tooltip=§f编程电路槽§r\n§a配置值:§f%d§7\n\n§7左击/右击/滚轮可循环浏览列表\n§7Shift+左键单击以打开选择GUI\n§7Shift+右键单击以清除 gregtech.gui.configurator_slot.no_value=空 +gregtech.gui.configurator_slot.unavailable.tooltip=编程电路槽位无法使用 gregtech.gui.fluid_lock.tooltip.enabled=流体锁定已启用 gregtech.gui.fluid_lock.tooltip.disabled=流体锁定已禁用 gregtech.gui.fluid_voiding.tooltip.enabled=过量流体销毁已启用 @@ -5385,8 +5473,12 @@ gregtech.gui.me_network.offline=网络状态:§4离线§r gregtech.gui.waiting_list=发送队列: gregtech.gui.config_slot=§f配置槽位§r gregtech.gui.config_slot.set=§7点击§b设置/选择§7配置槽位。§r +gregtech.gui.config_slot.set_only=§7点击§b设置§7配置槽位。§r gregtech.gui.config_slot.scroll=§7使用滚轮§a切换§7配置数。§r gregtech.gui.config_slot.remove=§7右击§4清除§7配置槽位。§r +gregtech.gui.config_slot.auto_pull_managed=§4禁用:§7由ME自动拉取管理 +gregtech.gui.me_bus.extra_slot=额外槽位/n§7在这里放置配方的额外物品,例如模具或透镜 +gregtech.gui.me_bus.auto_pull_button=单击以切换ME自动拉取模式 gregtech.gui.alarm.radius=半径: @@ -5414,14 +5506,14 @@ fluid.spawnlocation.name=流体矿脉信息 gregtech.jei.fluid.vein_weight=矿脉权重:%d gregtech.jei.fluid.min_yield=最小产量:%d gregtech.jei.fluid.max_yield=最大产量:%d -gregtech.jei.fluid.depletion_chance=消耗几率:%d%% +gregtech.jei.fluid.depletion_chance=消耗概率:%d%% gregtech.jei.fluid.depletion_amount=消耗量:%d gregtech.jei.fluid.depleted_rate=殆尽后产量:%d gregtech.jei.fluid.dimension=维度: gregtech.jei.fluid.weight_hover=流体矿脉的生成权重。鼠标悬于图标可查看该流体在特定生物群系中特殊的生成权重 gregtech.jei.fluid.min_hover=流体矿脉所能具有的的最小产量 gregtech.jei.fluid.max_hover=流体矿脉所能具有的的最大产量 -gregtech.jei.fluid.dep_chance_hover=开采流体矿脉时消耗的几率 +gregtech.jei.fluid.dep_chance_hover=开采流体矿脉时消耗的概率 gregtech.jei.fluid.dep_amount_hover=消耗后消耗的量 gregtech.jei.fluid.dep_yield_hover=流体矿脉殆尽后能开采的最大流体量 @@ -5555,7 +5647,7 @@ gregtech.multiblock.pattern.error.batteries=§c必须至少有一个不是空电 gregtech.multiblock.pattern.error.filters=§c必须使用同种过滤器§r gregtech.multiblock.pattern.clear_amount_1=§6前方必须有1x1x1大小的空间§r gregtech.multiblock.pattern.clear_amount_3=§6前方必须有3x3x1大小的空间§r -gregtech.multiblock.pattern.single=§6仅可使用该种方块§r +gregtech.multiblock.pattern.single=§6仅可使用该种方块类型§r gregtech.multiblock.pattern.location_end=§c最末端§r gregtech.multiblock.pattern.replaceable_air=可为空气 @@ -5579,7 +5671,7 @@ gregtech.multiblock.large_combustion_engine.supply_liquid_oxygen_to_boost=提供 gregtech.multiblock.large_combustion_engine.obstructed=引擎进气口受阻! gregtech.multiblock.large_combustion_engine.obstructed.desc=引擎进气口前方必须有一格空气。 -gregtech.multiblock.turbine.fuel_amount=燃料量:%s mB(%s) +gregtech.multiblock.turbine.fuel_amount=燃料量:%s L(%s) gregtech.multiblock.turbine.fuel_needed=消耗量:%s / %s ticks gregtech.multiblock.turbine.rotor_speed=转子转速:%s gregtech.multiblock.turbine.rotor_rpm_unit_name=RPM @@ -5640,8 +5732,10 @@ gregtech.multiblock.computation.not_enough_computation=机器需要更多算力 gregtech.multiblock.power_substation.stored=存储:%s gregtech.multiblock.power_substation.capacity=容量:%s gregtech.multiblock.power_substation.passive_drain=被动损失:%s -gregtech.multiblock.power_substation.average_io=平均输入/输出:%s -gregtech.multiblock.power_substation.average_io_hover=蓄能变电站内部的平均能量变化 +gregtech.multiblock.power_substation.average_in=平均EU输入:%s +gregtech.multiblock.power_substation.average_out=平均EU输出:%s +gregtech.multiblock.power_substation.average_in_hover=蓄能变电站内部的平均功率输入 +gregtech.multiblock.power_substation.average_out_hover=蓄能变电站内部的平均功率输出,包括被动损耗和输出 gregtech.multiblock.power_substation.time_to_fill=预计充满时间:%s gregtech.multiblock.power_substation.time_to_drain=预计耗空时间:%s gregtech.multiblock.power_substation.time_seconds=%s秒 @@ -5667,14 +5761,14 @@ gregtech.multiblock.hpca.warning_multiple_bridges=- 多个桥接组件(没有 gregtech.multiblock.hpca.warning_no_computation=- 没有计算组件 gregtech.multiblock.hpca.warning_low_cooling=- 冷却不足 gregtech.multiblock.hpca.info_max_computation=最大算力:%s -gregtech.multiblock.hpca.info_max_cooling_demand=冷却液需求:%s -gregtech.multiblock.hpca.info_max_cooling_available=冷却液可用:%s -gregtech.multiblock.hpca.info_max_coolant_required=冷却液还需:%s +gregtech.multiblock.hpca.info_max_cooling_demand=冷却需求:%s +gregtech.multiblock.hpca.info_max_cooling_available=冷却可用:%s +gregtech.multiblock.hpca.info_max_coolant_required=冷却液需求:%s L/t gregtech.multiblock.hpca.info_coolant_name=多氯联苯冷却液 gregtech.multiblock.hpca.info_bridging_enabled=桥接已启动 gregtech.multiblock.hpca.info_bridging_disabled=桥接已关闭 -gregtech.command.usage=用法:/gregtech +gregtech.command.usage=用法:/gregtech gregtech.command.worldgen.usage=用法:/gregtech worldgen gregtech.command.worldgen.reload.usage=用法:/gregtech worldgen reload gregtech.command.worldgen.reload.success=已从配置文件中重载世界生成设定。 @@ -5701,6 +5795,12 @@ gregtech.command.copy.copied_and_click=已复制至剪贴板。点击以再次 gregtech.command.copy.click_to_copy=点击以复制 gregtech.command.copy.copied_start=已复制[ gregtech.command.copy.copied_end=]至剪贴板 +gregtech.command.datafix.usage=用法:/gregtech datafix +gregtech.command.datafix.bqu.usage=用法:/gregtech datafix [confirm] +gregtech.command.datafix.bqu.backup=备份你的存档和BQu配置文件,然后使用“confirm”参数重新运行 +gregtech.command.datafix.bqu.start=开始迁移BQu任务数据库… +gregtech.command.datafix.bqu.complete=BQu任务数据库迁移完成 +gregtech.command.datafix.bqu.failed=BQu任务数据库迁移失败。恢复你的备份! gregtech.chat.cape=§5恭喜你:你刚刚解锁了一件新披风!查看终端应用程序“披风选择器”来使用它。§r @@ -5907,7 +6007,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=升级后方可解锁该模式 @@ -5972,31 +6072,31 @@ gregtech.key.armor_charging=启用/禁用盔甲向物品栏充能 gregtech.key.tool_aoe_change=切换工具范围性效用模式 gregtech.subtitle.tick.forge_hammer=锻造锤:DUANG -gregtech.subtitle.tick.macerator=研磨机:运行中 +gregtech.subtitle.tick.macerator=研磨机:破碎 gregtech.subtitle.tick.chemical_reactor=化学反应釜:运行中 gregtech.subtitle.tick.assembler=组装机:运行中 -gregtech.subtitle.tick.centrifuge=离心机:运行中 -gregtech.subtitle.tick.compressor=压缩机:运行中 -gregtech.subtitle.tick.electrolyzer=电解机:电流滋滋响 -gregtech.subtitle.tick.mixer=搅拌机:运行中 +gregtech.subtitle.tick.centrifuge=离心机:旋转 +gregtech.subtitle.tick.compressor=压缩机:挤压 +gregtech.subtitle.tick.electrolyzer=电解机:爆出火花 +gregtech.subtitle.tick.mixer=搅拌机:搅动 gregtech.subtitle.tick.replicator=复制机:运行中 -gregtech.subtitle.tick.arc=电弧炉:运行中 +gregtech.subtitle.tick.arc=电弧炉:嗡—— gregtech.subtitle.tick.boiler=锅炉:液体沸腾 gregtech.subtitle.tick.furnace=电炉:冶炼 -gregtech.subtitle.tick.cooling=热锭:冷却 -gregtech.subtitle.tick.fire=火:燃烧 -gregtech.subtitle.tick.bath=化学浸洗机:运行中 +gregtech.subtitle.tick.cooling=真空冷冻机:运行中 +gregtech.subtitle.tick.fire=火:爆裂 +gregtech.subtitle.tick.bath=化学浸洗机:嘶嘶 gregtech.subtitle.tick.motor=马达:转啊转 gregtech.subtitle.tick.cut=切割机:运行中 -gregtech.subtitle.tick.turbine=涡轮:转子旋转 +gregtech.subtitle.tick.turbine=涡轮:呼啸 gregtech.subtitle.tick.combustion=燃烧发电机:燃料燃烧 gregtech.subtitle.tick.miner=采矿机:开采 -gregtech.subtitle.tick.computation=计算机:处理 -gregtech.subtitle.use.wrench=扳手:拧动 +gregtech.subtitle.tick.computation=计算机:哔哔 +gregtech.subtitle.use.wrench=扳手:嘎啦 gregtech.subtitle.use.soft_hammer=软锤:轻敲 gregtech.subtitle.use.drill=电钻:嗡嗡 -gregtech.subtitle.use.plunger=搋子:流体被清理 -gregtech.subtitle.use.file=锉:摩擦 +gregtech.subtitle.use.plunger=搋子:清理流体 +gregtech.subtitle.use.file=锉:磨削 gregtech.subtitle.use.saw=锯:切割 gregtech.subtitle.use.screwdriver=螺丝刀:拧螺丝 gregtech.subtitle.use.chainsaw=链锯:拉动油门 @@ -6210,3 +6310,8 @@ gregtech.scanner.forestry.larvae=§o幼体(已扫描) gregtech.scanner.forestry.serum=§o血清(已扫描) gregtech.scanner.forestry.caterpillar=§o幼虫(已扫描) gregtech.scanner.forestry.pollen=§o花粉(已扫描) + +# Mutation +gregtech.mutation.block_of=%s块 + +record.sus=Leonz - Among Us Drip diff --git a/src/main/resources/assets/gregtech/models/item/material_sets/dull/tool_head_wirecutter.json b/src/main/resources/assets/gregtech/models/item/material_sets/dull/tool_head_wirecutter.json new file mode 100644 index 00000000000..92690c87e45 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/material_sets/dull/tool_head_wirecutter.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/material_sets/dull/tool_head_wire_cutter" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_hv.json b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_hv.json new file mode 100644 index 00000000000..60a5a9255c1 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_hv.json @@ -0,0 +1,7 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "gregtech:items/tools/handle_electric_wire_cutter_hv", + "layer1": "gregtech:items/tools/wire_cutter_electric" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_iv.json b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_iv.json new file mode 100644 index 00000000000..6a7f378d8a9 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_iv.json @@ -0,0 +1,7 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "gregtech:items/tools/handle_electric_wire_cutter_iv", + "layer1": "gregtech:items/tools/wire_cutter_electric" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_lv.json b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_lv.json new file mode 100644 index 00000000000..406df61785c --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/tools/wire_cutter_lv.json @@ -0,0 +1,7 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "gregtech:items/tools/handle_electric_wire_cutter_lv", + "layer1": "gregtech:items/tools/wire_cutter_electric" + } +} diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/activity_detector.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/activity_detector.json deleted file mode 100644 index 6e5523990e7..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/activity_detector.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Activity Detector", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:302" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/advanced_activity_detector.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/advanced_activity_detector.json deleted file mode 100644 index d6e5d2faf81..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/advanced_activity_detector.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Advanced Activity Detector", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:303" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/computer_monitor.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/computer_monitor.json deleted file mode 100644 index 9557d8c2c78..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/computer_monitor.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Computer Monitorc", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:307" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/conveyor.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/conveyor.json deleted file mode 100644 index 11e8a651db3..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/conveyor.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Conveyor Cover", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:157" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/crafting_table.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/crafting_table.json deleted file mode 100644 index c6fd856c2d0..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/crafting_table.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Crafting Table Cover", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:308" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/digital_interface_cover.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/digital_interface_cover.json deleted file mode 100644 index 3e9b91d7b99..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/digital_interface_cover.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "metaitem": "cover.digital", - "section": "Covers", - "title": "Digital Interface Cover", - "stream": [ - { - "type": "textbox", - "isCenter": false, - "content": [ - "§cDigital Interface Cover §ris a new cover, hereinafter referred to as the §lDIC§r.\n" - ] - }, - { - "type": "slots", - "item_list": [ - { - "id": "gregtech:meta_item_1", - "damage": 312, - "count": 1 - }, - { - "id": "gregtech:meta_item_1", - "damage": 313, - "count": 1 - } - ] - }, - { - "type": "textbox", - "content": [ - "§lContents:" - ] - }, - { - "type": "textbox", - "link": "introduction", - "content": [ - "1. §9Introduction" - ] - }, - { - "type": "textbox", - "link": "fluid", - "content": [ - "2. §9Fluid Mode" - ] - }, - { - "type": "textbox", - "link": "item", - "content": [ - "3. §r§9Item Mode" - ] - }, - { - "type": "textbox", - "link": "energy", - "content": [ - "4. §9Energy Mode" - ] - }, - { - "type": "textbox", - "link": "machine", - "content": [ - "5. §9Machine Mode" - ] - }, - { - "type": "textbox", - "link": "proxy", - "content": [ - "6. §9Proxy Mode" - ] - }, - { - "type": "textbox", - "link": "wireless", - "content": [ - "7. §9Wireless Cover" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "introduction", - "content": [ - "§lIntroduction:" - ] - }, - { - "type": "textbox", - "content": [ - "You can place it at any side of machines, including the front side. It will automatically detect the machine and display the information of the machine.\n\nUsing the Screwdriver right click the §4DIC§r to open GUI.\n\nThere are five modes supported: §lFluid, Item, Energy, Machine, and Proxy§r.\n\nIn addition to the GUI, you can interact with DIC directly by hand.Try exploring on your own." - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "fluid", - "content": [ - "§lFluid Mode:" - ] - }, - { - "type": "textbox", - "content": [ - "monitor and interact(fill or drain) with fluids." - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/107397364-8d212680-6b39-11eb-9152-b91f8f559ed6.png", - "width": 190, - "height": 100 - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "item", - "content": [ - "§lItem Mode:" - ] - }, - { - "type": "textbox", - "content": [ - "monitor and interact(fill or extract) with items." - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/107397608-c8235a00-6b39-11eb-95ad-77e4e5bc5d8b.png", - "width": 190, - "height": 100 - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "energy", - "content": [ - "§lEnergy Mode:" - ] - }, - { - "type": "textbox", - "content": [ - "monitor the Energy usage. (monitoring energy stored, input and output per second)." - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/107397946-1a647b00-6b3a-11eb-8680-52d13dd56e59.png", - "width": 190, - "height": 110 - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "machine", - "content": [ - "§lMachine Mode:" - ] - }, - { - "type": "textbox", - "content": [ - "monitor and interact (stop or active) with workable machines. (low power, is working, working progress, isActive)." - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/107398096-42ec7500-6b3a-11eb-8c26-b708ae183c3d.png", - "width": 190, - "height": 100 - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "proxy", - "content": [ - "§lProxy Mode:" - ] - }, - { - "type": "textbox", - "content": [ - "should be used with the §1§lCentral Monitor§r." - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/107856228-c1f6eb80-6e61-11eb-8098-454ea7133ca1.png", - "width": 190, - "height": 100 - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "wireless", - "content": [ - "§lWireless:" - ] - }, - { - "type": "textbox", - "content": [ - "The wireless cover only has §4proxy Mode§r, allowing the §1§lCentral Monitor§r to access the cover remotely. Bind it remotely by right-clicking on a Central Monitor, and clear the binding by shift-right-clicking on Air." - ] - } - ], - "fixed": [] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/ender_fluid_link.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/ender_fluid_link.json deleted file mode 100644 index d88198015f9..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/ender_fluid_link.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Ender Fluid Link Cover", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:311" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/energy_detector.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/energy_detector.json deleted file mode 100644 index 8d5fc2e475b..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/energy_detector.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Energy Detector", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:306" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/fluid_detector.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/fluid_detector.json deleted file mode 100644 index 9562d8b3b92..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/fluid_detector.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Fluid Detector", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:304" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/fluid_filter.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/fluid_filter.json deleted file mode 100644 index 6c60268ca91..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/fluid_filter.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Fluid Filter", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:290" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/fluid_regulator.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/fluid_regulator.json deleted file mode 100644 index 163bed84c5a..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/fluid_regulator.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Fluid Regulator Cover", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:247" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/infinite_water.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/infinite_water.json deleted file mode 100644 index c7c7301571b..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/infinite_water.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Infinite Water Cover", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:310" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/item_detector.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/item_detector.json deleted file mode 100644 index 71ec3aa4ed6..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/item_detector.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Item Detector", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:305" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/item_filter.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/item_filter.json deleted file mode 100644 index 52d6678b331..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/item_filter.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Item Filter", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:291" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/machine_controller.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/machine_controller.json deleted file mode 100644 index a930161ac5c..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/machine_controller.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Machine Controller", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:301" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/ore_dictionary_filter.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/ore_dictionary_filter.json deleted file mode 100644 index d08d8d18401..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/ore_dictionary_filter.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Ore Dictionary Filter", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:292" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/pump.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/pump.json deleted file mode 100644 index c5f615d74cb..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/pump.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Pump Cover", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:142" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/robot_arm.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/robot_arm.json deleted file mode 100644 index 28294c1190e..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/robot_arm.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Robot Arm Cover", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:187" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/shutter_module.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/shutter_module.json deleted file mode 100644 index db8644be3b4..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/shutter_module.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Shutter Module", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:309" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/smart_item_filter.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/smart_item_filter.json deleted file mode 100644 index b8c617b0b67..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/covers/smart_item_filter.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Covers", - "title": "Smart Item Filter", - "stream": [], - "fixed": [], - "item": "gregtech:meta_item_1:293" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/axe.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/axe.json deleted file mode 100644 index 30e9c44f99a..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/axe.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Tools", - "title": "Axe", - "stream": [], - "fixed": [], - "item": "gregtech:meta_tool:3" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/buzzsaw.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/buzzsaw.json deleted file mode 100644 index 747a0c678e5..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/buzzsaw.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Tools", - "title": "Buzzsaw", - "stream": [], - "fixed": [], - "item": "gregtech:meta_tool:32" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/drill.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/drill.json deleted file mode 100644 index a8cdb41186e..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/drill.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Tools", - "title": "Drill", - "stream": [], - "fixed": [], - "item": "gregtech:meta_tool:20" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/file.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/file.json deleted file mode 100644 index e37a5a6437d..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/file.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Tools", - "title": "File", - "stream": [ - { - "type": "textbox", - "content": [ - "The §6File§r is a tool that is only used for crafting recipes. No special uses unfortunately.\n\nLike most Gregtech tools, it can be repaired in an anvil." - ] - } - ], - "fixed": [], - "item": "gregtech:meta_tool:9" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/hammer.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/hammer.json deleted file mode 100644 index 466e74ee9b5..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/hammer.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Tools", - "title": "Hammer", - "stream": [ - { - "type": "textbox", - "content": [ - "The §6Hammer§r is a tool mainly used in crafting recipes.\n\nHowever, it has one special use outside of crafting recipes. When Right Clicked on a machine, it will mute the sounds of the machine running. Simply Right Click again to unmute.\n\nLike most Gregtech tools, it can be repaired in an anvil." - ] - } - ], - "fixed": [], - "item": "gregtech:meta_tool:6" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/mining_hammer.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/mining_hammer.json deleted file mode 100644 index c83b8f534a8..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/mining_hammer.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Tools", - "title": "Mining Hammer", - "stream": [ - { - "type": "textbox", - "content": [ - "The §6Mining Hammer§r is an Early Game alternative to the §6Drill§r, which does not require a source of power. It mines in a simple 3x3 area, and will mine in a 1x1 area when sneaking. Make sure to make some before going mining.\n\nLike most Gregtech tools, it can be repaired in an anvil." - ] - } - ], - "fixed": [], - "item": "gregtech:meta_tool:19" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/saw.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/saw.json deleted file mode 100644 index 0be14973fff..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/saw.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Tools", - "title": "Saw", - "stream": [ - { - "type": "textbox", - "content": [ - "The §6Saw§r is a Gregtech tool that is mainly using in crafting recipes, but has some special uses outside of crafting recipes.\n\nFirstly, it will harvest §1Ice§r and §1Packed Ice§r as if it had Silk Touch, dropping the actual items.\n\nSecondly, it will act like Shears when harvesting §1Leaves§r and §1Vines§r, meaning that the actual blocks will be dropped." - ] - } - ], - "fixed": [], - "item": "gregtech:meta_tool:5" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/screwdriver.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/screwdriver.json deleted file mode 100644 index f0b0125daca..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/screwdriver.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Tools", - "title": "Screwdriver", - "stream": [], - "fixed": [], - "item": "gregtech:meta_tool:11" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/sense.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/sense.json deleted file mode 100644 index a291d156b8c..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/sense.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Tools", - "title": "Sense", - "stream": [], - "fixed": [], - "item": "gregtech:meta_tool:17" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/wrench.json b/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/wrench.json deleted file mode 100644 index 99a163904d9..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/en_us/tools/wrench.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "section": "Tools", - "title": "Wrench", - "stream": [ - { - "type": "textbox", - "isCenter": false, - "content": [ - "The §6Wrench§r is one of the main tools in §1Gregtech§r and has several important uses.\n\nFirst, the Wrench can be the designated tool for breaking machines (Config option, default false). If a Wrench is not used to break the machine, it will break slower.\n\nSecondly, the Wrench can be used to set the output side for machines and multiblock components. Using the §4Machine Grid§r or just clicking on the desired face, Right Clicking with a Wrench will set the output face.\n\nRelated to the above, the Wrench can be used to set the Front Face of machines. Sneaking while Right Clicking (either directly on a face of the machine or using the machine grid) will change the front face of a machine, if it can be changed.\n\nIn addition to manipulating machines, wrenches are used for manipulating pipes. When Right Clicking on a pipe with a wrench, it will enable or disable the pipe connections to the corresponding face. When Sneaking while Right Clicking, pipes will have their travel routes blocked instead (Fluid Pipes only).\n\nLike most Gregtech tools, it can be repaired in an anvil." - ] - } - ], - "fixed": [], - "item": "gregtech:meta_tool:8" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/zh_cn/covers/digital_interface_cover.json b/src/main/resources/assets/gregtech/terminal/guide/items/zh_cn/covers/digital_interface_cover.json deleted file mode 100644 index 59fd56d2cad..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/zh_cn/covers/digital_interface_cover.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "metaitem": "cover.digital", - "section": "覆盖版", - "title": "数字化接口覆盖版", - "stream": [ - { - "type": "textbox", - "isCenter": false, - "content": [ - "§c数字化接口覆盖版 §r是一个新覆盖版, 一下简称 §lDIC§r.\n" - ] - }, - { - "type": "slots", - "item_list": [ - { - "id": "gregtech:meta_item_1", - "damage": 312, - "count": 1 - }, - { - "id": "gregtech:meta_item_1", - "damage": 313, - "count": 1 - } - ] - }, - { - "type": "textbox", - "content": [ - "§l目录:" - ] - }, - { - "type": "textbox", - "link": "introduction", - "content": [ - "1. §9介绍" - ] - }, - { - "type": "textbox", - "link": "fluid", - "content": [ - "2. §9流体模式" - ] - }, - { - "type": "textbox", - "link": "item", - "content": [ - "3. §r§9物品模式" - ] - }, - { - "type": "textbox", - "link": "energy", - "content": [ - "4. §9能源模式" - ] - }, - { - "type": "textbox", - "link": "machine", - "content": [ - "5. §9机器模式" - ] - }, - { - "type": "textbox", - "link": "proxy", - "content": [ - "6. §9代理模式" - ] - }, - { - "type": "textbox", - "link": "wireless", - "content": [ - "7. §9无线覆盖板" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "introduction", - "content": [ - "§l介绍:" - ] - }, - { - "type": "textbox", - "content": [ - "你可以将DIC放在任机器何面(包括正面)。它会自动检测机器并可视化信息。\n\n用扳手右键§4DIC§r 可以打开GUI。\n\n有五种模式: §l流体, 物品, 能源, 机器, 以及代理§r.\n\n此外,你也能直接用手和覆盖版进行交互。尝试着自己探索吧!" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "fluid", - "content": [ - "§l流体模式:" - ] - }, - { - "type": "textbox", - "content": [ - "监控并交互(填充或抽取)流体." - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/107397364-8d212680-6b39-11eb-9152-b91f8f559ed6.png", - "width": 190, - "height": 100 - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "item", - "content": [ - "§l物品模式:" - ] - }, - { - "type": "textbox", - "content": [ - "监控并交互(提取或存放)物品。" - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/107397608-c8235a00-6b39-11eb-95ad-77e4e5bc5d8b.png", - "width": 190, - "height": 100 - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "energy", - "content": [ - "§l能源模式:" - ] - }, - { - "type": "textbox", - "content": [ - "监控能源情况。 (监控能源储量,输入/输出的每秒流量)" - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/107397946-1a647b00-6b3a-11eb-8680-52d13dd56e59.png", - "width": 190, - "height": 110 - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "machine", - "content": [ - "§l机器模式:" - ] - }, - { - "type": "textbox", - "content": [ - "监控并交互(暂停或启动)机器(是否低电量,是否工作,当前配方进度,是否启动)。" - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/107398096-42ec7500-6b3a-11eb-8c26-b708ae183c3d.png", - "width": 190, - "height": 100 - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "proxy", - "content": [ - "§l代理模式:" - ] - }, - { - "type": "textbox", - "content": [ - "应该配合§1§l中央监控器§r使用。" - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/107856228-c1f6eb80-6e61-11eb-8098-454ea7133ca1.png", - "width": 190, - "height": 100 - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "wireless", - "content": [ - "§l无线覆盖版:" - ] - }, - { - "type": "textbox", - "content": [ - "无线覆盖版只有 §4代理模式§r, 允许§1§l中央监控器§r 远程访问改覆盖版. 通过右键点击中央监控器来绑定,通过对空气shfit右键点击来取消绑定。" - ] - } - ], - "fixed": [] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/items/zh_cn/tools/wrench.json b/src/main/resources/assets/gregtech/terminal/guide/items/zh_cn/tools/wrench.json deleted file mode 100644 index 1a48f7fc6c3..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/items/zh_cn/tools/wrench.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "metaitem": "tool.wrench", - "section": "工具", - "title": "Wrench", - "stream": [ - { - "type": "textbox", - "isCenter": false, - "content": [ - "扳扳这,扳扳那" - ] - }, - { - "type": "textbox", - "isCenter": true, - "fontSize": 5, - "content": [ - "§nMinecraft Formatting", - "§r§00 §11 §22 §33", - "§44 §55 §66 §77", - "§88 §99 §aa §bb", - "§cc §dd §ee §ff", - "§r§0k §kMinecraft", - "§rl §lMinecraft", - "§rm §mMinecraft", - "§rn §nMinecraft", - "§ro §oMinecraft", - "§rr §rMinecraft" - ] - } - ], - "fixed": [] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/machines/en_us/steam/steam_boiler_coal_bronze.json b/src/main/resources/assets/gregtech/terminal/guide/machines/en_us/steam/steam_boiler_coal_bronze.json deleted file mode 100644 index ea0ae9bbbdf..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/machines/en_us/steam/steam_boiler_coal_bronze.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "machine": "steam_boiler_coal_bronze", - "section": "Steam", - "title": "Small Steam Coal Boiler", - "stream": [ - { - "type": "textbox", - "isCenter": false, - "content": [ - "Wrench this, wrench that" - ] - }, - { - "type": "textbox", - "isCenter": true, - "fontSize": 5, - "content": [ - "§nMinecraft Formatting", - "§r§00 §11 §22 §33", - "§44 §55 §66 §77", - "§88 §99 §aa §bb", - "§cc §dd §ee §ff", - "§r§0k §kMinecraft", - "§rl §lMinecraft", - "§rm §mMinecraft", - "§rn §nMinecraft", - "§ro §oMinecraft", - "§rr §rMinecraft" - ] - } - ], - "fixed": [] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/advanced_fluid_drilling_plant.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/advanced_fluid_drilling_plant.json deleted file mode 100644 index 20f7045ceac..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/advanced_fluid_drilling_plant.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Electric", - "title": "Advanced Fluid Drilling Plant", - "stream": [ - { - "type": "textbox", - "content": [ - "§oExtreme is very apprioriate this time around, and you will see why.§r\n\nAt the cost of 4x the drilling Power, the §3Advanced Fluid Drilling Rig§r will be gaining §616x the output§r in Fluid.\nThe depletion of veins is also halved. This means you will get a total of §632x§r as much Oil (or whatever fluid) from a bedrock fluid vein until depletion!\n\nEven when depleted, you can still use this and be very power positive.\n\nOne single §3Advanced Fluid Drilling Rig§r should be enough to supply Power for a base up to §dLuV§r Age and possibly beyond!\n\nAs a brief §9reminder§r:\n§9-§r §aLight Oil§r can be used for §dLPG§r and §dMethane§r, to run in §3Large Gas Turbines§r.\n§9-§r §aOil§r can be used for §dDiesel§r and §dCetane-Boosted Diesel§r, to run in §3Large Combustion Engines§r.\n§9-§r §aHeavy Oil§r can be used for §dNitrobenzene§r, to run in §3Large Gas Turbines§r." - ] - } - ], - "fixed": [], - "metatileentity": "fluid_drilling_rig.hv" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/advanced_processing_array.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/advanced_processing_array.json deleted file mode 100644 index 2ffe5eb1b67..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/advanced_processing_array.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Electric", - "title": "Advanced Processing Array", - "stream": [], - "fixed": [], - "metatileentity": "advanced_processing_array" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/assembly_line.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/assembly_line.json deleted file mode 100644 index 379c8bca589..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/assembly_line.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Electric", - "title": "Assembly Line", - "stream": [ - { - "type": "textbox", - "content": [ - "§oNo. The Assembly Line is not just a big Assembler, it\u0027s a lot more than that!\nYou can also call it the Assline. Do not feel guilty.§r\n\nMaking §dLuV§r Components will require more work.\nThe §3Assembly Line§r is an entry point towards late game.\n\nThis Multiblock has a §cvariable size§r. Each §3ULV Input Bus§r accepts a different stack of items.\nYou will want to build this with a size of §d10§r to get started, or of a size of §d14§r to accept all possible recipes.\n\nRecipes require §aFluids§r, so it is a good idea to keep the §3Input Hatches§r permanently filled with §dSoldering Alloy§r, §dLubricant§r and §dStyrene-Butadienne Rubber§r.\n\nMy recommendation of Assembly Line §4automation§r goes as follows:\nHave your Interface face an §3Item P2P§r. Set two output P2Ps, into the first §3Input Bus§r, and into §3Item Pipes§r. Make your Item Pipes connect to all Input Buses including the first.\nDo not forget §dBlocking Mode§r, and you have got yourself an easy automation! This will also work flawlessly once we inevitably add ordered item inputs.\n\n\n§bLots of Lore:§r GT5\u0027s Assembly Line is a massive project to work towards, even more so than here. You are required to scan items to put their construction data into a Data Stick. That Data Stick is then required to fit into a Data Hatch which has limited slots on the Assembly Line.\n\nThe recipe could only be viewed by printing a book with the Data Stick! It was then made to display in NEI once you acquire the item.\nTecTech made a nice machine which acts as a recipe viewer for the Data Stick (this mod is so great...).\n\nFurthermore, Item and Fluid inputs are required to be ordered the same way as the recipe indicates it. This makes automation of the Assembly Line a nice challenge which can be solved using other mods, redstone, GT item pipes... you pick it.\n\nWe are planning to port some of the GT5 features, as the Assembly Line §lshould be a challenge§r for the player." - ] - } - ], - "fixed": [], - "metatileentity": "assembly_line" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/basic_fluid_drilling_rig.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/basic_fluid_drilling_rig.json deleted file mode 100644 index e504de906ab..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/basic_fluid_drilling_rig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Electric", - "title": "Basic Fluid Drilling Rig", - "stream": [ - { - "type": "textbox", - "content": [ - "§oFinally, Fluid Drilling Rigs in GTCEu!§r\n\nIt is quite an investment to get to run a §3Fluid Drilling Rig§r, but it is by far the most prominent §6source of Oil§r.\nIt pumps fluids from underneath Bedrock. Note that the fluids aren\u0027t actually there, instead they are simulated.\n\nFluid veins are stored within regions of §48x8 chunks§r. Each vein has a different fluid, but they are mostly types Oil.\nYou are not able to do prospection for fluid veins §oyet§r, this will come in the §6HV§r Age.\n\nEach vein generates with a different base yield. This is typically between §d150L§r to §d300L per second§r.\n\nWhen drained, fluid veins will slowly deplete. This will cause the fluid yield to decrease over time, until it reaches its depletion yield. At that point you should move the Rig to somewhere else.\nA §3Basic Fluid Drilling Rig§r will last for 100,000 operations (with 1 second per operation) until depletion. This is enough for §6well over 10,000§r buckets of Oil. Higher tier Rigs will massively increase the yield, while also decreasing the depletion rate.\n\n\nWhat you can find in the §2Overworld§r:\n§9Oil:§r richer in §aLight Fuel§r, the most appreciated variant.\n§9Light Oil:§r richer in §aRefinery Gas§r, usable for power.\n§9Heavy Oil:§r richer in §aHeavy Fuel§r, which has uses that are more niche.\n§9Raw Oil:§r essentially a less dense version of §aOil§r, the least appreciated.\n§9Natural Gas:§r grants §aRefinery Gas§r with no distillation required.\n§9Salt Water:§r grants §aSodium§r and §aChlorine§r, useful later.\n\n§rWhat you can find in the §cNether§r:\n§9Natural Gas:§r grants §aRefinery Gas§r but with higher yield than the Overworld vein.\n§9Lava:§r you know what this is.\n\n\nFor starters you may have to tap randomly until you find something you like. Whatever you pump can be used to refuel your Fluid Rig." - ] - } - ], - "fixed": [], - "metatileentity": "fluid_drilling_rig.mv" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/basic_ore_drilling_plant.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/basic_ore_drilling_plant.json deleted file mode 100644 index 200af4c7c9f..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/basic_ore_drilling_plant.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Electric", - "title": "Basic Ore Drilling Plant", - "stream": [ - { - "type": "textbox", - "content": [ - "A completely §doptional§r Multiblock.\n\nThe §3Larger Miner§r is ridiculously good to collect ores from veins!\n\nOres are mined as if they were §amacerated§r, but they yield §6three times§r as many §dCrushed ores§r.\n\nYou will need §aDrilling Fluid§r automation to run this.\n\nYou might also want to use a §3Quantum Tunnel§r from AE2 and §3GTEU P2P Tunnels§r to transfer the items and to power it up.\n\n\n§bLore:§r There were some interesting side effects from porting this over from Gregicality, as the multiblock originated from GregTech 5... It\u0027s not perfect, as there isn\u0027t really any advantage on upgrading this miner to the advanced versions. We were thinking of rebalancing the energy costs and yield per tier, so there may be rework for this miner at some point!" - ] - } - ], - "fixed": [], - "metatileentity": "large_miner.ev" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/central_monitor.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/central_monitor.json deleted file mode 100644 index 1c130bac657..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/central_monitor.json +++ /dev/null @@ -1,183 +0,0 @@ -{ - "metatileentity": "central_monitor", - "section": "Electric", - "title": "Central Monitor", - "stream": [ - { - "type": "slots", - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1029, - "count": 1 - }, - { - "id": "gregtech:machine", - "damage": 1667, - "count": 1 - } - ] - }, - { - "type": "textbox", - "content": [ - "§lContents:" - ] - }, - { - "type": "textbox", - "link": "introduction", - "content": [ - "1. §9Introduction" - ] - }, - { - "type": "textbox", - "link": "fluid", - "content": [ - "2. §9How to build it" - ] - }, - { - "type": "textbox", - "link": "item", - "content": [ - "3. §r§9How to use it" - ] - }, - { - "type": "textbox", - "link": "energy", - "content": [ - "4. §9Plugins" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/107856228-c1f6eb80-6e61-11eb-8098-454ea7133ca1.png", - "width": 190, - "height": 100 - }, - { - "type": "textbox", - "ref": "introduction", - "content": [ - "§lIntroduction" - ] - }, - { - "type": "textbox", - "content": [ - "§c§lCentral Monitor§r is a multi machine for monitor (visualization and interaction).\n\nIt can monitor the storage and status of machines, including all §9Digital Interface Cover§r§9\u0027s §rfeatures, and extends the capabilities of machines to the screen.\n\nIn addition, there are many plugins that support more advanced features." - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "fluid", - "content": [ - "§lHow to build it?" - ] - }, - { - "type": "textbox", - "content": [ - "In order to build it, you need a §c§lCentral Monitor§r, several §c§lMonitor Screen§r, several §c§lSteel Metal Casing§r, and at least one §c§lEnergy Input Hatch§r.\n\nYou can build the screen from 3×2 to 14×9 (width × height). The default build height is 3, and you can adjust the screen height in the GUI before the structure formed.\n\n§lEnergy Cost:§r 50 EU/s for each screen." - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "item", - "content": [ - "§lHow to use it?" - ] - }, - { - "type": "textbox", - "content": [ - "1. The back of §c§lCentral Monitor §rcan be connected to cables or wires, which can be connected to the energy net to monitor all the machines being proxied (A §9Digital Interface Cover§r set with proxy mode is placed at the connecting side between the machine and the wire. ). Besides, a §9Wireless Cover §rthat is boung to the central monitor can also be used, avoiding using cables.\n\n2. Right click the §c§lCentral Monitor §ror screwdriver right click the §c§lMonitor§r to open the GUI for settings." - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "energy", - "content": [ - "§lPlugins" - ] - }, - { - "type": "textbox", - "content": [ - "Put the plugin into the plugin slot for use. For specific features, please refer to their guide pages. The following are the supported plugins.\n\n§4§lNote§r§4: §rsome plugins need to work with the proxy mode in the §c§lCentral Monitor§r, and the proxy mode is only used for plugins." - ] - }, - { - "type": "card", - "fill": -3745585, - "width": 170, - "height": 60, - "isShadow": true - }, - { - "type": "textbox", - "content": [ - "\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - } - ], - "fixed": [ - { - "type": "slots", - "x": 48, - "y": 930, - "width": 100, - "height": 18, - "item_list": [ - { - "id": "gregtech:meta_item_1", - "damage": 780, - "count": 1 - }, - { - "id": "gregtech:meta_item_1", - "damage": 781, - "count": 1 - }, - { - "id": "gregtech:meta_item_1", - "damage": 782, - "count": 1 - }, - { - "id": "gregtech:meta_item_1", - "damage": 783, - "count": 1 - } - ] - } - ] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/distillation_tower.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/distillation_tower.json deleted file mode 100644 index cea752f1798..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/distillation_tower.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "section": "Electric", - "title": "Distillation Tower", - "stream": [ - { - "type": "textbox", - "content": [ - "The §6Distillation Tower§r is the Variable Layer Multiblock form of the Single Block Distilleries. While the Distillery can only have one output from an input fluid, the Distillation Tower can get all possible outputs from the input fluid.\n\nHowever, the Distillation Tower has a few additional limitations. Most importantly, The number of fluids that the Distillation Tower can output is equal to the number of layers of the of the Multiblock. Additionally, the Distillation Tower cannot be formed with Multifluid output hatches, and the fluid input hatch must be located on the bottom layer of the structure." - ] - }, - { - "type": "slots", - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1005, - "count": 1 - } - ] - } - ], - "fixed": [ - { - "type": "card", - "x": 10, - "y": 234, - "width": 177, - "height": 90, - "fill": -3745585, - "isShadow": true - }, - { - "type": "slots", - "x": 3, - "y": 269, - "width": 52, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1181, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": -1, - "y": 242, - "width": 61, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1196, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": -5, - "y": 296, - "width": 67, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1166, - "count": 1 - } - ] - }, - { - "type": "textbox", - "x": 50, - "y": 241, - "width": 100, - "height": 20, - "content": [ - "Fluid Output Hatch. Exactly 1 per layer" - ] - }, - { - "type": "textbox", - "x": 49, - "y": 267, - "width": 100, - "height": 20, - "content": [ - "Fluid Input Hatch. Exactly 1" - ] - }, - { - "type": "textbox", - "x": 46, - "y": 294, - "width": 100, - "height": 20, - "content": [ - "Item Output bus. Optionally 1" - ] - } - ], - "metatileentity": "distillation_tower" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/electric_blast_furnace.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/electric_blast_furnace.json deleted file mode 100644 index 483e092d20c..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/electric_blast_furnace.json +++ /dev/null @@ -1,243 +0,0 @@ -{ - "section": "Electric", - "title": "Electric Blast Furnace", - "stream": [ - { - "type": "textbox", - "isCenter": false, - "content": [ - "The §6Electric Blast Furnace§r is one of the main Multiblock Structures in Gregtech, and the main goal of earlygame progression." - ] - }, - { - "type": "slots", - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1001, - "count": 1 - } - ] - }, - { - "type": "textbox", - "content": [ - "Like all Gregtech Multiblocks, this structure is modular, and can be made up of many different combinations of Multiblock Parts." - ] - }, - { - "type": "card", - "fill": -3745585, - "width": 180, - "height": 190, - "isShadow": true - }, - { - "type": "textbox", - "content": [ - "The §6Electric Blast Furnace§r can form with any combination of blocks above. For example, if the desired recipe does not deal with fluids, neither of the fluid related hatches are required.\n\nOverclocking the Blast Furnace is as simple as ensuring the the Multiblock has 2 Energy Inputs, so 4 Amps of energy can be received, which will ensure that the mutliblock runs at the tier above the energy inputs.\n\nFor the Blast Furnace specifically, the Muffler Hatch needs to be placed at the center of the top layer, and must face upwards." - ] - }, - { - "type": "textbox", - "content": [ - "The §3Electric Blast Furnace§r, §3Pyrolyse Oven, §3Multi Smelter§r, and §3Cracking Unit§r all require heating Coils. But what are the advantages of using higher tier coils?\n\nThe latter three are quite straightforward. Higher tier coils reduce the §eprocessing time§r of the Pyrolyse Oven, reduce the §9energy usage§r of the Cracking Unit, and increase the §anumber of parallel smelts§r and reduce the §9energy usage§r of the Multi Smelter.\n\nFor the EBF, things get slightly more complicated. The EBF smelts items at a certain §dtemperature§r. This is mainly determined by the tier of heating coil used - §r§6Cupronickel§r is §d1800K§r, §bKanthal§r is §d2700K§r, etc. Additionally, starting from §6HV§r, each tier of energy adds §d100K§r to the temperature.\n\nEach EBF recipe has a certain base temperature, for example, §bAluminium§r is smelted at §d1700K§r. If the EBF temperature is not high enough, the recipe can\u0027t be done. If the EBF temperature is high enough, 2 different bonuses are applied:\n§9-§r For every §d900K§r above the recipe temperature, the amount of energy required is multiplied by §a0.95x§r, which stacks.\n§9-§r For every §d1800K§r above the recipe temperature, one additional overclock will be §6100% efficient§r; in other words, it will §5quadruple the speed§r, instead of doubling it." - ] - } - ], - "fixed": [ - { - "type": "slots", - "x": 12, - "y": 159, - "width": 35, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1001, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": 11, - "y": 182, - "width": 36, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1151, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": 12, - "y": 206, - "width": 34, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1166, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": 13, - "y": 228, - "width": 32, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1181, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": 13, - "y": 251, - "width": 32, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1196, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": 10, - "y": 273, - "width": 38, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1654, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": 10, - "y": 296, - "width": 38, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1657, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": 9, - "y": 319, - "width": 40, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1211, - "count": 1 - } - ] - }, - { - "type": "textbox", - "x": 52, - "y": 159, - "width": 100, - "height": 20, - "content": [ - "The Controller block" - ] - }, - { - "type": "textbox", - "x": 52, - "y": 182, - "width": 100, - "height": 20, - "content": [ - "Item Input. Minimum 1" - ] - }, - { - "type": "textbox", - "x": 51, - "y": 206, - "width": 108, - "height": 10, - "content": [ - "Item Output. Minimum 1" - ] - }, - { - "type": "textbox", - "x": 51, - "y": 230, - "width": 125, - "height": 10, - "content": [ - "Fluid Input. No Minimum" - ] - }, - { - "type": "textbox", - "x": 49, - "y": 251, - "width": 131, - "height": 10, - "content": [ - "Fluid Output. No Minimum" - ] - }, - { - "type": "textbox", - "x": 48, - "y": 271, - "width": 135, - "height": 20, - "content": [ - "Maintence Hatch. Required based on Config. Exactly 1" - ] - }, - { - "type": "textbox", - "x": 48, - "y": 295, - "width": 100, - "height": 20, - "content": [ - "Muffler Hatch. Exactly 1" - ] - }, - { - "type": "textbox", - "x": 47, - "y": 318, - "width": 100, - "height": 20, - "content": [ - "Energy Input. Minimum 1" - ] - } - ], - "metatileentity": "electric_blast_furnace" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/fusion_reactor_1.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/fusion_reactor_1.json deleted file mode 100644 index 049f379b986..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/fusion_reactor_1.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Electric", - "title": "Fusion Reactor MK 1", - "stream": [], - "fixed": [], - "metatileentity": "fusion_reactor.luv" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/fusion_reactor_2.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/fusion_reactor_2.json deleted file mode 100644 index fbd7234eb99..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/fusion_reactor_2.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Electric", - "title": "Fusion Reactor MK 2", - "stream": [], - "fixed": [], - "metatileentity": "fusion_reactor.zpm" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/fusion_reactor_3.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/fusion_reactor_3.json deleted file mode 100644 index 6f896cd695f..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/fusion_reactor_3.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Electric", - "title": "Fusion Reactor MK 3", - "stream": [], - "fixed": [], - "metatileentity": "fusion_reactor.uv" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/implosion_compressor.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/implosion_compressor.json deleted file mode 100644 index bb6d263b219..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/implosion_compressor.json +++ /dev/null @@ -1,136 +0,0 @@ -{ - "section": "Electric", - "title": "Implosion Compressor", - "stream": [ - { - "type": "textbox", - "content": [ - "The §6Implosion Compressor§r is a Multiblock that turns gem dusts back into gems, as well as processes a few other recipes." - ] - }, - { - "type": "slots", - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1003, - "count": 1 - } - ] - }, - { - "type": "textbox", - "content": [ - "Recipes in the Implosion Compressor use varying explosives with different efficiencies, so make sure to check recipes in JEI." - ] - } - ], - "fixed": [ - { - "type": "card", - "x": 11, - "y": 138, - "width": 179, - "height": 112, - "fill": -3745585, - "isShadow": true - }, - { - "type": "slots", - "x": 6, - "y": 147, - "width": 63, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1151, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": 6, - "y": 174, - "width": 63, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1166, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": 7, - "y": 203, - "width": 63, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1657, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": 9, - "y": 229, - "width": 58, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1654, - "count": 1 - } - ] - }, - { - "type": "textbox", - "x": 56, - "y": 146, - "width": 100, - "height": 20, - "content": [ - "Item Input Bus. Minimum 1" - ] - }, - { - "type": "textbox", - "x": 52, - "y": 172, - "width": 100, - "height": 20, - "content": [ - "Item Output Bus. Minimum 1" - ] - }, - { - "type": "textbox", - "x": 53, - "y": 203, - "width": 100, - "height": 20, - "content": [ - "Muffler Hatch. Exactly 1" - ] - }, - { - "type": "textbox", - "x": 55, - "y": 227, - "width": 100, - "height": 20, - "content": [ - "Maintenance Hatch. Exactly 1" - ] - } - ], - "metatileentity": "implosion_compressor" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/large_chemical_reactor.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/large_chemical_reactor.json deleted file mode 100644 index 257f082cb09..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/large_chemical_reactor.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Electric", - "title": "Large Chemical Reactor", - "stream": [ - { - "type": "textbox", - "content": [ - "The §3Large Chemical Reactor (LCR)§r is a multiblock §3Chemical Reactor§r with more input/output slots, which can handle more recipes thanks to Teflon.\n\nThe §3LCR§r can perform some exclusive reactions which allow you to combine multiple normal §3Chemical Reactor§r steps into a §6single step§r. Examples below:\n§9-§r §aNitrogen Dioxide§r (for Nitric Acid and Dinitrogen Tetroxide)\n§9-§r §aSulfuric Acid§r\n§9-§r §aPhenol§r\n§9-§r §aEpichlorohydrin§r (you need it for Epoxy§r!)\n§9-§r §aEpoxy§r\n\n\nThere are also §3LCR§r exclusive recipes. For example §aRadon§r requires it.\n\nAll §dOverclocks§r in the §3LCR§r are §6100% efficient§r; each overclock will §5quadruple the speed§r, as opposed to doubling it.\n\n\n§9Tip:§r Given the amount of LCRs you may end up using, I would recommend using the §dwallsharing§r to its full potential.\nYou may share one 2A (standard) §3Energy Hatch§r with 2 LCRs.\nYou may share §3Input/Output Hatches§r, but be careful to not make them run the wrong recipes.\nKeep in mind Maintenance is not sharable." - ] - } - ], - "fixed": [], - "metatileentity": "large_chemical_reactor" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/multi_smelter.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/multi_smelter.json deleted file mode 100644 index f2e74134c6e..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/multi_smelter.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Electric", - "title": "Multi Smelter", - "stream": [ - { - "type": "textbox", - "content": [ - "§oThe §3§oMulti Smelter§r§o might be the §6§omost powerful Furnace§r§o in modded Minecraft.§r\n\nAt its lowest power (Cupronickel coils and LV Voltage), it smelts 32 items in just 12 seconds - equivalent to §926.7 Furnaces§r, or 3.3 Steam Ovens!\n\nNot to mention, standard §aoverclocks§r are in effect.\nAnd more importantly higher tier §3Coils§r increase the amount of items it can smelt in §dparallel§r! Higher tier §3Coils§r also provide better energy and duration discounts for recipes." - ] - } - ], - "fixed": [], - "metatileentity": "multi_furnace" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/oil_cracking_unit.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/oil_cracking_unit.json deleted file mode 100644 index 0526093adf4..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/oil_cracking_unit.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Electric", - "title": "Oil Cracking Unit", - "stream": [ - { - "type": "textbox", - "content": [ - "§oLet\u0027s get cracking, shall we?§r\n\nThe §3Oil Cracking Unit§r is a multiblock meant to make cracked fluids. It has all the recipes of §3Chemical Reactor§r Cracking, but it is §6lossless§r.\n\nThis multiblock is §doptional§r, but it saves a lot of Fuel in the long term!\n\nHigher Coil tiers provide small energy discount, not too important." - ] - } - ], - "fixed": [], - "metatileentity": "cracker" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/processing_array.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/processing_array.json deleted file mode 100644 index 2ab24c291d6..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/processing_array.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Electric", - "title": "Processing Array", - "stream": [ - { - "type": "textbox", - "content": [ - "§oThe Processing Array does nothing... except that it does a lot!§r\n\nThe §3Processing Array§r is a power §6automation tool§r.\nIt combines several single block machines into one single multiblock.\nPlace up to §d16§r Machines into the §3Machine Access Interface§r.\n\nThe §3PA§r will now §asimulate§r all the machines you put inside, as if they were running at the same time.\nThis means recipes can now be performed up to §d16§r at a time, this is called §4parallel§r.\n\nPower cost is based on the current recipe being run, times the number of §4parallel§r being performed.\nAs an §9example§r, §316 LV Distilleries§r will require an §3HV Energy Hatch§r in order to run effectively.\n\n\n§cWhere or why is the Processing Array useful?§r\n§9-§r §4Parallelization is superior§r to oveclocking. Use it for passive setups such as Ore Processing or Oil Distilling.\n§9-§r §6Distinct buses§r: a §3PA§r can accept up to 10 §3Input Buses§r. Use it for your pattern automation with §3Extruder§r, §3Engraver§r, and many other.\n\n\n§9Note:§r With §2Gregicality Multiblocks§r installed, the §3PA§r can be mostly replaced with all the specialized Multiblocks instead. That\u0027s for you if you hate 3x3 blue cubes, or if you hate crafting numerous low tier machines.\n\n\n§bLore:§r In GregTech 5, the Data Orb was used to Matter Replicator to store data of the material you wanted to replicate. There is no replication here, the Orb is just a crafting component." - ] - } - ], - "fixed": [], - "metatileentity": "processing_array" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/pyrolyse_oven.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/pyrolyse_oven.json deleted file mode 100644 index bb143f76d3c..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/pyrolyse_oven.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Electric", - "title": "Pyrolyse Oven", - "stream": [ - { - "type": "textbox", - "content": [ - "§oThe Pyrolyse Oven processes organic products by thermal decomposition in an inert environment.§r\n\nThe §3Pyrolyse Oven§r is an electric equivalent of the §3Coke Oven§r. It can produce §9Coal Coke§r and §9Charcoal§r with a §9Creosote§r byproduct just as before, but also has additional §6Organic Byproducts§r. The most beneficial of these being §aWood Tar§r.\nAnother product is §aBiomass§r, which is more pertinent for progression §oright now§r.\n\nThose byproducts can be Distilled for an array of organic resources, with different byproducts giving different ratios of different chemicals.\nYou will need to read the §9Distillation§r Quest to hopefully understand the full scale..\n\nThere are recipes that can accept §bNitrogen§r to double the speed.\n\nThe §3Cupronickel Coils§r are more than enough to get started, but you will want to upgrade eventually. This is because the §3Cupronickel Coils§r actually have a processing speed malus, making all recipes slower. This malus turns into a processing speed bonus as the coil tier used increases.\n\n\n§9§lNote:§r§l The Plant path is one path towards §9§lEthylene§r§l. The other path involves Oil.§r\nThe Pyrolyse Oven remains §doptional§r. But it is great to have either for Power, or for the various Byproducts.\n\n\n§bLore:§r In GT5u, the structure for the Pyrolyse Oven is a giant box with only 9 coils inside. Players usually spend several minutes debugging what is wrong due to the lack of JEI preview." - ] - } - ], - "fixed": [], - "metatileentity": "pyrolyse_oven" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/vacuum_freezer.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/vacuum_freezer.json deleted file mode 100644 index 01c1f2dc76f..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/electric/vacuum_freezer.json +++ /dev/null @@ -1,136 +0,0 @@ -{ - "section": "Electric", - "title": "Vacuum Freezer", - "stream": [ - { - "type": "textbox", - "content": [ - "The §6Vacuum Freezer§r is one of the more important Multiblocks, as it allows you to get actual ingots from super heated Blast Furnace outputs." - ] - }, - { - "type": "slots", - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1002, - "count": 1 - } - ] - }, - { - "type": "textbox", - "content": [ - "Any ingots made in the §6Electric Blast Furnace§r that have a blast temperature of greater than §91750§r K will not generate regular ingots, but instead will generate Hot Ingots. These Ingots will damage the player when held, and are required to be cooled down in the Vacuum Freezer." - ] - } - ], - "fixed": [ - { - "type": "card", - "x": 6, - "y": 189, - "width": 178, - "height": 105, - "fill": -3745585, - "isShadow": true - }, - { - "type": "slots", - "x": 7, - "y": 198, - "width": 56, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1151, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": 14, - "y": 224, - "width": 43, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1166, - "count": 1 - } - ] - }, - { - "type": "textbox", - "x": 54, - "y": 199, - "width": 100, - "height": 20, - "content": [ - "Item Input bus. Maximum 1" - ] - }, - { - "type": "textbox", - "x": 53, - "y": 223, - "width": 100, - "height": 20, - "content": [ - "Item Output Bus. Maximum 1" - ] - }, - { - "type": "slots", - "x": 8, - "y": 249, - "width": 55, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1181, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": 1, - "y": 274, - "width": 68, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1196, - "count": 1 - } - ] - }, - { - "type": "textbox", - "x": 52, - "y": 248, - "width": 100, - "height": 20, - "content": [ - "Fluid Input Hatch. Optionally 1" - ] - }, - { - "type": "textbox", - "x": 51, - "y": 273, - "width": 100, - "height": 20, - "content": [ - "Fluid Output Hatch. Optionally 1" - ] - } - ], - "metatileentity": "vacuum_freezer" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/extreme_combustion_engine.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/extreme_combustion_engine.json deleted file mode 100644 index b61c47fa6a7..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/extreme_combustion_engine.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Generator", - "title": "Extreme Combustion Engine", - "stream": [ - { - "type": "textbox", - "content": [ - "§oThe Ultimate Combustion fuel Generator!§r\n\nTo run the §3Extreme Combustion Engine§r, you will most likely want to boost it (§oelse why would you bother...§r).\nYou will want a §34A IV Dynamo Hatch§r as the output, and one §3Vacuum Freezer§r for §aLiquid Oxygen§r.\n\nYou can now harness the equivalent of 1 §dLuV§r Amp, while burning fuel at §6200% efficiency§r!\n\nDon\u0027t forge to keep it supplied with a small amount of §aLubricant§r.\n\nThe §3ECE§r is also void-free, unlike Large Turbines. Any energy that cannot be output will momentarily pause the multiblock.\n\n\n§bLore:§r The ECE comes from GT:NH. However... the story is not so great. The stats on the tooltip looked similar to this one, so far so good.\nHowever if you made calculations, you ended up realizing you needed to run around 16 whole HV Vacuum Freezers to keep up with Liquid Oxygen...\nThe one and only fuel it would accept is High Octane Gasoline, which was stated to be burned at 300% efficiency when boosted, but it was a lie! The efficiency remained 100%!\nThe GT:NH team recently decided to rework the ECE among other power options, phew!" - ] - } - ], - "fixed": [], - "metatileentity": "extreme_combustion_engine" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/large_bronze_boiler.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/large_bronze_boiler.json deleted file mode 100644 index ee94e350d65..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/large_bronze_boiler.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Generator", - "title": "Large Bronze Boiler", - "stream": [ - { - "type": "textbox", - "content": [ - "This is an §6optional§r power generating multiblock, depending on which power options you chose.\n\n\nThe §3Large Boilers§r ultimately are §othe§r option for large scale Steam production. They will run off solid and liquid fuels.\n§cImportant:§r This Boiler can also §cexplode§r similarly to the regular Boilers!\n§cWater supply is crucial§r. But simply upgrading the §3Output Hatch§r on your §3Primitive Pump§r should be enough.\n\n\nOnce fully heated up, the §3LBB§r produces 800 Steam per tick, which is §d400EU/t§r after conversion, or 12.5 Basic Steam Turbines! This (relatively!) immense power comes at the cost of §la lot§r of burnable fuel.\n§5§lBut§r the GUI can let you §9throttle§r the Boiler, down to 25% power for 200 Steam per tick. That is §d100EU/t§r, or slightly above 3 Basic Steam Turbines." - ] - } - ], - "fixed": [], - "metatileentity": "large_boiler.bronze" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/large_combustion_engine.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/large_combustion_engine.json deleted file mode 100644 index 1bea232463c..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/large_combustion_engine.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Generator", - "title": "Large Combustion Engine", - "stream": [ - { - "type": "textbox", - "content": [ - "The §3Large Combustion Engine§r is a multiblock able to burn §dCombustion Fuels§r for even more Power Generation!\n\nIt\u0027s default production outputs 2048 EU/t, which is simply the same as 4 §3Turbo Combustion Generators§r.\n\nWhere it shines is the ability to §6boost§r it with §aOxygen§r.\nThis will double the fuel consumption, but §9triple the power generation§r for 6144 EU/t!\nThis results in §6150% Fuel efficiency§r.\n\nIt also requires a small amount of §aLubricant§r, nothing too crazy.\n\nThe §3LCE§r is also void-free, unlike Large Turbines. Any energy that cannot be output will momentarily pause the multiblock.\n\n\n§9Note:§r To harness the 6144 EU/t Power output, you will need a §34A EV Dynamo Hatch§r, or an §3IV Dynamo Hatch§r." - ] - } - ], - "fixed": [], - "metatileentity": "large_combustion_engine" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/large_gas_turbine.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/large_gas_turbine.json deleted file mode 100644 index f9cca9cd4c9..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/large_gas_turbine.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Generator", - "title": "Large Gas Turbine", - "stream": [ - { - "type": "textbox", - "content": [ - "The §3Large Gas Turbine§r may not be so impressive in the §5EV§r Age, but it has the ability to scale really well, to §9better production§r than the base 4096 EU/t, and §9greater efficiency§r.\n\nEach Large Turbine will require a §aTurbine Rotor§r and a §3Rotor Holder§r. More on the Turbine mechanics in the §lnext§r Quest.\n\n§9Note:§r To harness the Power output when using a Rotor having more than 100% Power stats, you will need a §34A EV Dynamo Hatch§r or an §3IV Dynamo Hatch§r.\nTurbines §cvoid§r energy that they can not output." - ] - } - ], - "fixed": [], - "metatileentity": "large_turbine.gas" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/large_plasma_turbine.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/large_plasma_turbine.json deleted file mode 100644 index 7ae7b70399d..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/large_plasma_turbine.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "section": "Generator", - "title": "Large Plasma Turbine", - "stream": [], - "fixed": [], - "metatileentity": "large_turbine.plasma" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/large_steam_turbine.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/large_steam_turbine.json deleted file mode 100644 index c4b7cb22ea6..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/large_steam_turbine.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Generator", - "title": "Large Steam Turbine", - "stream": [ - { - "type": "textbox", - "content": [ - "§oIf you\u0027re still running off Steam, here is a solution for you!§r\n\nThe §3Large Steam Turbine§r is a multiblock Steam Turbine for §6HV§r power. It is a quite expensive multiblock to generate 1024 EU/t, but it also the ability to scale to §9higher Power Production and higher Effiency§r.\n\nThe Turbine will output §dDistilled Water§r given an §3Output Hatch§r, so you can loop it back to your §3Large Boilers§r.\nNot completely recommend, as your Boilers will end up exploding if the system fails...\n\nEach Large Turbine will require a §aTurbine Rotor§r and a §3Rotor Holder§r. More on the Turbine mechanics in the §lnext§r Quest.\n\n§9Note:§r Turbines §cvoid§r energy that they can not output. If you plan on using this with HV power, use a Rotor with close to 100% Power stat." - ] - } - ], - "fixed": [], - "metatileentity": "large_turbine.steam" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/large_steel_boiler.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/large_steel_boiler.json deleted file mode 100644 index 59da1510221..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/generator/large_steel_boiler.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Generator", - "title": "Large Steel Boiler", - "stream": [ - { - "type": "textbox", - "content": [ - "If you\u0027re still running off the §3Large Bronze Boiler§r, you may want to upgrade to the §3Large Steel Boiler§r.\n\nIt is slightly more efficient than the §3LBB§r, and produces §d900 EU/t worth of Steam§r." - ] - } - ], - "fixed": [], - "metatileentity": "large_boiler.steel" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/hatches/advanced_maintenance.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/hatches/advanced_maintenance.json deleted file mode 100644 index cc2a252d8d8..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/hatches/advanced_maintenance.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Hatches", - "title": "Advanced Maintenance", - "stream": [ - { - "type": "textbox", - "content": [ - "You now have access to two §3new Maintenance Hatches§r. Both start with §6no Maintenance required§r.\n\nThe §3Automatic Maintenance Hatch§r is pretty simple, it eliminates the need for Maintenance, §6forever§r.\n\nThe §3Configurable Maintenance Hatch§r is more interesting. You can configure it to cut off §a10% duration§r on recipes, at the cost of making Maintenance happen three times as fast. That is §d16 real hours§r of activity.\n§9Reminder:§r You can put Tape in the maintenance Hatch to automatically fix problems.\n\n\n§bLore:§r The Automatic Maintenance Hatch texture and mechanic comes from TecTech, an addon mod originally made for GregTech: New Horizons. I will be honest with you: that mod is excessively cool!\nMore TecTech references coming up, if you stick with us with the late game!" - ] - } - ], - "fixed": [], - "metatileentity": "maintenance_hatch_full_auto" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/hatches/energy_hatch.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/hatches/energy_hatch.json deleted file mode 100644 index 49c10bc70bd..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/hatches/energy_hatch.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Hatches", - "title": "Energy Hatch", - "stream": [ - { - "type": "textbox", - "content": [ - "§oTo power Multiblocks with energy, you need Energy Hatches.§r\n\nMultiblocks do not look at Voltage of recipes, instead they simply check if they have the Power requirement.\nFor example, The EBF needs at least §4120EU/t§r power input to run its recipes. It is achieved with §3two LV Energy Hatches§r. Each one takes 2 Amps of LV, so that\u0027s 4 Amps of LV for 128EU/t maximum power.\n\n\n§9Note:§r Be wary of Cable §closses§r bringing the actual power input below the recipe requirement! I §lhighly§r recommend placing your §3Battery Buffer§r next to the §3Energy Hatches§r for the minimum cable length." - ] - } - ], - "fixed": [], - "metatileentity": "energy_hatch.input.lv" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/hatches/maintenance_hatch.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/hatches/maintenance_hatch.json deleted file mode 100644 index a6db7c6fb68..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/hatches/maintenance_hatch.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Hatches", - "title": "Maintenance Hatch", - "stream": [ - { - "type": "textbox", - "content": [ - "§oI know what you\u0027re thinking! Don\u0027t think! I mean... Maintenance in GregTech is not as bad as you think, and looking at multiblocks with this hatch makes me feel happy.§r\n\nMost Multiblocks require a §3Maintenance Hatch§r. You will need to do Maintenance for the Multiblock to begin operating.\nThis is done by having a §9Wrench§r, a §9Screwdriver§r, a §9Soft Mallet§r, a §9Hammer§r, a §9Wire Cutter§r, and a §9Crowbar§r in your inventory, opening the Maintenance Hatch and §4clicking the center spot once§r. §cNo need to move tools individually§r.\nAlternatively you can fix problems by placing a §9Tape§r in the Maintenance Hatch, but I would love to tell you that\u0027s unethical.\n\nMaintenance problems may occur after §d48 real hours of activity§r. Needless to say they are very rare. Each problem increases the recipe durations by 10%. Fixing the problems is done the same way as above.\n\n\nAt §6HV§r age, you will unlock other Maintenance Hatches that do not enforce fixing the problems manually.\n\n\n§bLore:§r Maintenance dates back to GregTech 3 for Minecraft 1.5.2. That\u0027s a long time ago!\nMaintenance problems increased power usage instead of duration. And that caused all sorts of \"happy\" issues. Ah, fun times!" - ] - } - ], - "fixed": [], - "metatileentity": "maintenance_hatch" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/hatches/muffler_hatch.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/hatches/muffler_hatch.json deleted file mode 100644 index e11eef2deb6..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/hatches/muffler_hatch.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Hatches", - "title": "Muffler Hatch", - "stream": [ - { - "type": "textbox", - "content": [ - "The §3Electric Blast Furnace§r requires a §3Muffler Hatch§r to run. This hatch must be §cunobstructed§r so it can output its beautiful smoke particles.\n\nWhen a recipe is performed, there is a small chance for the §3Muffler Hatch§r to give bonus items, typically tiny Dusts of Ash.\n\n§9Note:§r Do not try to automate the extraction of items from the §3Muffler Hatch§r, it is not intended. It voids excess when full, so do not worry about it stopping machines from running.\n\n\n§bLore:§r In GregTech 5, polluting multiblocks had Muffler Hatches. The higher tier the hatch, the lower the Pollution.\nPollution had interesting effects such as turning grass and dirt into sand.\nMuffler Hatches in GTCEu are more about the look (can you deny that the particles look good!?) and small rewards, rather than punishing game mechanics." - ] - } - ], - "fixed": [], - "metatileentity": "muffler_hatch.lv" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/hatches/multiblock_input_output.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/hatches/multiblock_input_output.json deleted file mode 100644 index 3a6532b2d87..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/hatches/multiblock_input_output.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "section": "Hatches", - "title": "Multiblock Input/Output", - "stream": [ - { - "type": "textbox", - "content": [ - "§3Busses§r are needed to for Multiblocks in order to insert recipe inputs and retrieve recipe outputs.\nHigher tier §3Busses§r have more slots for items\n\nFor fluids, you will need §3Hatches§r.\n\nFor fluids, there are also special §3Multi-Fluid Hatches§r, which can handle multiple fluids at the same time. These come in 4x and 9x versions." - ] - } - ], - "fixed": [], - "metatileentity": "item_bus.import.lv" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/coke_oven.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/coke_oven.json deleted file mode 100644 index 2b300585370..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/coke_oven.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "section": "Primitive", - "title": "Coke Oven", - "stream": [ - { - "type": "textbox", - "content": [ - "The §6Coke Oven§r is most likely one of the first Multiblocks that you will make. It is the source of early game §1Charcoal§r, a nice fuel for making §1Steel§r initially." - ] - }, - { - "type": "slots", - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1017, - "count": 1 - } - ] - }, - { - "type": "textbox", - "content": [ - "Unlike other Multiblocks,this structure has a limited number of multiblock parts that can be added." - ] - } - ], - "fixed": [ - { - "type": "card", - "x": 6, - "y": 137, - "width": 182, - "height": 61, - "fill": -3745585, - "isShadow": true - }, - { - "type": "slots", - "x": 3, - "y": 140, - "width": 52, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1017, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": -3, - "y": 163, - "width": 65, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1018, - "count": 1 - } - ] - }, - { - "type": "textbox", - "x": 46, - "y": 160, - "width": 100, - "height": 20, - "content": [ - "The Coke Oven Hatch. Maximum: 5" - ] - }, - { - "type": "textbox", - "x": 47, - "y": 139, - "width": 100, - "height": 20, - "content": [ - "The Controller Block" - ] - } - ], - "metatileentity": "coke_oven" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/multiblock_steel_tank.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/multiblock_steel_tank.json deleted file mode 100644 index b9b4d9b8bc6..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/multiblock_steel_tank.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "section": "Primitive", - "title": "Steel Multiblock Tank", - "stream": [ - { - "type": "textbox", - "content": [ - "The §6Steel Multiblock Tank§r is another early game multiblock for storing fluids. However, unlike the Wooden version, this structure can store gases and hot fluids." - ] - }, - { - "type": "slots", - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1599, - "count": 1 - } - ] - }, - { - "type": "textbox", - "content": [ - "Similar to the Wooden version, this structure has specific Multiblock Parts used for automating fluid input and output into the structure." - ] - } - ], - "fixed": [ - { - "type": "slots", - "x": 2, - "y": 149, - "width": 52, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1598, - "count": 1 - } - ] - }, - { - "type": "card", - "x": 8, - "y": 146, - "width": 178, - "height": 32, - "fill": -3745585, - "isShadow": true - }, - { - "type": "textbox", - "x": 47, - "y": 149, - "width": 137, - "height": 20, - "content": [ - "Tank Valve for automating structure. Maximum: 2" - ] - } - ], - "metatileentity": "tank.steel" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/multiblock_wooden_tank.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/multiblock_wooden_tank.json deleted file mode 100644 index 4fb6f84f526..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/multiblock_wooden_tank.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "section": "Primitive", - "title": "Wooden Multiblock Tank", - "stream": [ - { - "type": "textbox", - "content": [ - "The §6Wooden Multiblock Tank§r is an early game solution for storing liquids. Unfortunately, it cannot store much, as it does not handle gases or hot liquids." - ] - }, - { - "type": "slots", - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1597, - "count": 1 - } - ] - }, - { - "type": "textbox", - "content": [ - "This Multiblock has one possible Multiblock Part, which is used for automatically filling and extracting fluids from the structure." - ] - } - ], - "fixed": [ - { - "type": "slots", - "x": -12, - "y": 176, - "width": 59, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1596, - "count": 1 - } - ] - }, - { - "type": "card", - "x": 7, - "y": 170, - "width": 178, - "height": 35, - "fill": -3745585, - "isShadow": true - }, - { - "type": "textbox", - "x": 35, - "y": 176, - "width": 137, - "height": 20, - "content": [ - "Tank Valve for automating structure. Maximum: 2" - ] - } - ], - "metatileentity": "tank.wood" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/primitive_blast_furnace.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/primitive_blast_furnace.json deleted file mode 100644 index 34c471d6958..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/primitive_blast_furnace.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "section": "Primitive", - "title": "Primitive Blast Furnace", - "stream": [ - { - "type": "textbox", - "content": [ - "The §6Primitive Blast Furnace§r is the main multiblock of the Steam Age. It is used for making the first §1Steel§r, which is the main gateway to the §2LV§r age." - ] - }, - { - "type": "slots", - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1000, - "count": 1 - } - ] - }, - { - "type": "textbox", - "content": [ - "Unlike other §3Gregtech§r Multiblocks, there are no multiblock parts that can be used in this structure. It is only composed of the controller and the Primitive Bricks." - ] - } - ], - "fixed": [], - "metatileentity": "primitive_blast_furnace.bronze" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/primitive_water_pump.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/primitive_water_pump.json deleted file mode 100644 index 59377b8d57f..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/primitive_water_pump.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "section": "Primitive", - "title": "Primitive Water Pump", - "stream": [ - { - "type": "textbox", - "content": [ - "The §6Primitive Water Pump§r is a Multiblock used for gathering water in the early game. The amount of water gathered depends on the biome that the Multiblock is constructed in. Detailed information on the rates in available on the §3JEI§r information page for the Multiblock." - ] - }, - { - "type": "slots", - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1648, - "count": 1 - } - ] - }, - { - "type": "textbox", - "content": [ - "The §6Primitive Water Pump§r has only one possible Multiblock part, though it is limited in what tier the part can be." - ] - } - ], - "fixed": [ - { - "type": "slots", - "x": -23, - "y": 189, - "width": 100, - "height": 18, - "item_list": [] - }, - { - "type": "slots", - "x": 61, - "y": 182, - "width": 67, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1649, - "count": 1 - }, - { - "id": "gregtech:machine", - "damage": 1195, - "count": 1 - }, - { - "id": "gregtech:machine", - "damage": 1196, - "count": 1 - } - ] - }, - { - "type": "card", - "x": 9, - "y": 174, - "width": 180, - "height": 76, - "fill": -3745585, - "isShadow": true - }, - { - "type": "textbox", - "x": 13, - "y": 203, - "width": 168, - "height": 40, - "content": [ - "The §6Primitive Water Pump§r is limited to §rthe specific output hatch, §ra §2ULV§r output hatch, or a §2LV§r output hatch" - ] - } - ], - "metatileentity": "primitive_water_pump" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/steam_grinder.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/steam_grinder.json deleted file mode 100644 index 4a3ad379efd..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/steam_grinder.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "section": "Primitive", - "title": "Steam Grinder", - "stream": [ - { - "type": "textbox", - "content": [ - "The §6Steam Grinder§r is an early game multiblock for performing macerator recipes. It can perform up to §58§r recipes in parallel, and has duration of §51.5§r times the normal macerator recipe duration.\n\nHowever, only the first output from the recipe will be output. This means that no byproducts will be recieved from any ores grinded down." - ] - }, - { - "type": "slots", - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1025, - "count": 1 - } - ] - }, - { - "type": "textbox", - "content": [ - "Unlike other Multiblocks, this structure has specialized hatches for handling steam that must be used." - ] - } - ], - "fixed": [ - { - "type": "card", - "x": 4, - "y": 217, - "width": 182, - "height": 81, - "fill": -3745585, - "isShadow": true - }, - { - "type": "slots", - "x": 11, - "y": 224, - "width": 50, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1651, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": 5, - "y": 247, - "width": 62, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1652, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": 10, - "y": 272, - "width": 52, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1653, - "count": 1 - } - ] - }, - { - "type": "textbox", - "x": 53, - "y": 224, - "width": 117, - "height": 20, - "content": [ - "Specialized Output bus for Steam Multiblocks" - ] - }, - { - "type": "textbox", - "x": 53, - "y": 250, - "width": 120, - "height": 20, - "content": [ - "Specialized Input bus for Steam Multiblocks" - ] - }, - { - "type": "textbox", - "x": 53, - "y": 273, - "width": 120, - "height": 20, - "content": [ - "Specialized Input Hatch for Steam Multiblocks" - ] - } - ], - "metatileentity": "steam_grinder" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/steam_oven.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/steam_oven.json deleted file mode 100644 index b45a1bf6604..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/en_us/primitive/steam_oven.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "section": "Primitive", - "title": "Steam Oven", - "stream": [ - { - "type": "textbox", - "content": [ - "The §6Steam Oven§r is an early game multiblock for performing furnace recipes. It can perform up to §58§r recipes in parallel, and has duration of §51.5§r times the normal furnace recipe duration.\n\nThis should not really matter, but only the first output from the recipe will be obtained. Although if someone is adding a weird furnace recipe, that is their fault." - ] - }, - { - "type": "slots", - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1024, - "count": 1 - } - ] - }, - { - "type": "textbox", - "content": [ - "Unlike other Multiblocks, this structure has specialized hatches for handling steam that must be used." - ] - } - ], - "fixed": [ - { - "type": "card", - "x": 4, - "y": 217, - "width": 182, - "height": 81, - "fill": -3745585, - "isShadow": true - }, - { - "type": "slots", - "x": 11, - "y": 224, - "width": 50, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1651, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": 5, - "y": 247, - "width": 62, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1652, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": 10, - "y": 272, - "width": 52, - "height": 18, - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1653, - "count": 1 - } - ] - }, - { - "type": "textbox", - "x": 53, - "y": 224, - "width": 117, - "height": 20, - "content": [ - "Specialized Output bus for Steam Multiblocks" - ] - }, - { - "type": "textbox", - "x": 53, - "y": 250, - "width": 120, - "height": 20, - "content": [ - "Specialized Input bus for Steam Multiblocks" - ] - }, - { - "type": "textbox", - "x": 53, - "y": 273, - "width": 120, - "height": 20, - "content": [ - "Specialized Input Hatch for Steam Multiblocks" - ] - } - ], - "metatileentity": "steam_oven" -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/zh_cn/electric/central_monitor.json b/src/main/resources/assets/gregtech/terminal/guide/multiblocks/zh_cn/electric/central_monitor.json deleted file mode 100644 index 4de1eb5024f..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/multiblocks/zh_cn/electric/central_monitor.json +++ /dev/null @@ -1,183 +0,0 @@ -{ - "section": "电力", - "title": "中央监控器", - "stream": [ - { - "type": "slots", - "item_list": [ - { - "id": "gregtech:machine", - "damage": 1028, - "count": 1 - }, - { - "id": "gregtech:machine", - "damage": 1667, - "count": 1 - } - ] - }, - { - "type": "textbox", - "content": [ - "§l目录:" - ] - }, - { - "type": "textbox", - "link": "introduction", - "content": [ - "1. §9介绍" - ] - }, - { - "type": "textbox", - "link": "fluid", - "content": [ - "2. §9如何构建它" - ] - }, - { - "type": "textbox", - "link": "item", - "content": [ - "3. §r§9如何使用它" - ] - }, - { - "type": "textbox", - "link": "energy", - "content": [ - "4. §9插件" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/107856228-c1f6eb80-6e61-11eb-8098-454ea7133ca1.png", - "width": 190, - "height": 100 - }, - { - "type": "textbox", - "ref": "introduction", - "content": [ - "§l介绍" - ] - }, - { - "type": "textbox", - "content": [ - "§c§l中央监控仪§r是一个用来监控(可视化和交互)的多方块.\n\n它可以监控并交互机器的存储及运行状态,它包含§9数字化接口覆盖版§r§9§r的所有功能,并将机器的其他接口扩展到屏幕上。\n\n此外,还有许多插件支持更多高级功能。" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "fluid", - "content": [ - "§l怎么构建它?" - ] - }, - { - "type": "textbox", - "content": [ - "为了构建它,你需要一个§c§l中央监控器§r,一些§c§l监控屏幕§r,一些§c§l不锈钢机械方块§r,个至少一个§c§l能源输入仓§r.\n\n屏幕尺寸从3×2到14×9(宽 × 高)不等。默认高度是3,但是你可以在结构成型前在GUI中设置高度。\n\n§l能源消耗:§r每个屏幕50 EU/s。" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "item", - "content": [ - "§l如何使用它?" - ] - }, - { - "type": "textbox", - "content": [ - "1. §c§l中央监控器的§r的背后可以连接线缆,线缆所处的电网中可以监控所有被代理的机器(§9数字化接口覆盖版§r设置为代理模式,并放置在线和机器的接口处。) 此外,绑定了中央控制器的§9无线覆盖版§r同样可以使用,避免使用线缆。\n\n2. 右击§c§l中央监控器§r或者扳手右击§c§l监控屏幕§r可以打开GUI进行设置。" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "energy", - "content": [ - "§l插件" - ] - }, - { - "type": "textbox", - "content": [ - "将插件放入插件槽中使用。有关具体功能,请参阅其指南页。以下是支持的插件。\n\n§4§l注意§r§4: §r在§c§l中央监控器§r中,有些插件需要使用代理模式工作,而代理模式仅用于插件。" - ] - }, - { - "type": "card", - "fill": -3745585, - "width": 170, - "height": 60, - "isShadow": true - }, - { - "type": "textbox", - "content": [ - "\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - } - ], - "fixed": [ - { - "type": "slots", - "x": 48, - "y": 730, - "width": 100, - "height": 18, - "item_list": [ - { - "id": "gregtech:meta_item_1", - "damage": 780, - "count": 1 - }, - { - "id": "gregtech:meta_item_1", - "damage": 781, - "count": 1 - }, - { - "id": "gregtech:meta_item_1", - "damage": 782, - "count": 1 - }, - { - "id": "gregtech:meta_item_1", - "damage": 783, - "count": 1 - } - ] - } - ], - "metatileentity": "central_monitor" -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/material/01_definition.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/material/01_definition.json deleted file mode 100644 index b319e88fe15..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/material/01_definition.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "section": "CraftTweaker/Material", - "title": "Material Definition", - "stream": [ - { - "type": "textbox", - "fontSize": 11, - "fontColor": -65536, - "content": [ - "§lFirstly, you should know what is the Material." - ] - }, - { - "type": "textbox", - "content": [ - "Material is the basis of CEu. It defines to a substance and its properties. It usually takes the form of an §lelement§r or a §lchemical§r, but it can also take the form of something weird like the §lEnder Eye§r." - ] - }, - { - "type": "textbox", - "fontSize": 11, - "fontColor": -16776961, - "content": [ - "§lSecondly, it defines which properties?" - ] - }, - { - "type": "textbox", - "content": [ - "The §lmaterial§r specifies whether it has a §lfluid§r state, §lplasma§r state, §ldust§r state, etc. When it has a specific state, the CEu will register the corresponding item or fluid automatically." - ] - }, - { - "type": "textbox", - "fontSize": 11, - "fontColor": -16731136, - "content": [ - "§lThirdly, What else does it define?" - ] - }, - { - "type": "textbox", - "content": [ - "You can actually define its colors, flag, iconSet, cableProperties, Element, formula, components and so on. Don\u0027t worry, they are not complicated, will be introduced in other pages." - ] - } - ], - "fixed": [] -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/material/02_element.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/material/02_element.json deleted file mode 100644 index 22f3b6a04af..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/material/02_element.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "section": "CraftTweaker/Material", - "title": "Element", - "stream": [ - { - "type": "textbox", - "fontSize": 9, - "content": [ - "The §lElement§r use to specify a material as an elemental and affects its chemical fomular. CEu basically has the periodic table, so you probably won\u0027t need it. \n\n§lContents:" - ] - }, - { - "type": "textbox", - "link": "element", - "content": [ - "1. §9Element" - ] - }, - { - "type": "textbox", - "link": "ct", - "content": [ - "2. §9CT" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "element", - "content": [ - "§c§lElement:§r\n §l○ §nprotons§r – Amount of Protons\n §l○ §nneutrons§r – Amount of Neutrons (I could have made mistakes with the Neutron amount calculation, please tell me if I did something wrong)\n §l○ §nhalfLifeSeconds§r – Amount of Half Life this Material has in Seconds. -1 for stable Materials\n §l○ §ndecayTo§r – String representing the Elements it decays to. Separated by an \u0027\u0026\u0027 Character\n §l○ §nname§r – Name of the Element\n §l○ §nsymbol§r – Symbol of the Element" - ] - }, - { - "type": "textbox", - "content": [ - "§lExisting elements:" - ] - }, - { - "type": "textbox", - "stroke": 1623820032, - "stroke_width": 3, - "fill": 1623820032, - "content": [ - " §l○ §c§lH§r: 1, 0, -1, null, \"Hydrogen\", \"H\", false\n §l○ §c§lD§r: 1, 1, -1, \"H\", \"Deuterium\", \"D\", true\n §l○ §c§lT§r: 1, 2, -1, \"D\", \"Tritium\", \"T\", true\n §l○ §c§lHe§r: 2, 2, -1, null, \"Helium\", \"He\", false\n §l○ §c§lHe3§r: 2, 1, -1, \"H\u0026D\", \"Helium-3\", \"He-3\", true\n §l○ §c§lLi§r: 3, 4, -1, null, \"Lithium\", \"Li\", false\n §l○ §c§lBe§r: 4, 5, -1, null, \"Beryllium\", \"Be\", false\n §l○ §c§lB§r: 5, 5, -1, null, \"Boron\", \"B\", false\n §l○ §c§lC§r: 6, 6, -1, null, \"Carbon\", \"C\", false\n §l○ §c§lN§r: 7, 7, -1, null, \"Nitrogen\", \"N\", false\n §l○ §c§lO§r: 8, 8, -1, null, \"Oxygen\", \"O\", false\n §l○ §c§lF§r: 9, 9, -1, null, \"Fluorine\", \"F\", false\n §l○ §c§lNe§r: 10, 10, -1, null, \"Neon\", \"Ne\", false\n §l○ §c§lNa§r: 11, 11, -1, null, \"Sodium\", \"Na\", false\n §l○ §c§lMg§r: 12, 12, -1, null, \"Magnesium\", \"Mg\", false\n §l○ §c§lAl§r: 13, 13, -1, null, \"Aluminium\", \"Al\", false\n §l○ §c§lSi§r: 14, 14, -1, null, \"Silicon\", \"Si\", false\n §l○ §c§lP§r: 15, 15, -1, null, \"Phosphorus\", \"P\", false\n §l○ §c§lS§r: 16, 16, -1, null, \"Sulfur\", \"S\", false\n §l○ §c§lCl§r: 17, 18, -1, null, \"Chlorine\", \"Cl\", false\n §l○ §c§lAr§r: 18, 22, -1, null, \"Argon\", \"Ar\", false\n §l○ §c§lK§r: 19, 20, -1, null, \"Potassium\", \"K\", false\n §l○ §c§lCa§r: 20, 20, -1, null, \"Calcium\", \"Ca\", false\n §l○ §c§lSc§r: 21, 24, -1, null, \"Scandium\", \"Sc\", false\n §l○ §c§lTi§r: 22, 26, -1, null, \"Titanium\", \"Ti\", false\n §l○ §c§lV§r: 23, 28, -1, null, \"Vanadium\", \"V\", false\n §l○ §c§lCr§r: 24, 28, -1, null, \"Chrome\", \"Cr\", false\n §l○ §c§lMn§r: 25, 30, -1, null, \"Manganese\", \"Mn\", false\n §l○ §c§lFe§r: 26, 30, -1, null, \"Iron\", \"Fe\", false\n §l○ §c§lCo§r: 27, 32, -1, null, \"Cobalt\", \"Co\", false\n §l○ §c§lNi§r: 28, 30, -1, null, \"Nickel\", \"Ni\", false\n §l○ §c§lCu§r: 29, 34, -1, null, \"Copper\", \"Cu\", false\n §l○ §c§lZn§r: 30, 35, -1, null, \"Zinc\", \"Zn\", false\n §l○ §c§lGa§r: 31, 39, -1, null, \"Gallium\", \"Ga\", false\n §l○ §c§lGe§r: 32, 40, -1, null, \"Germanium\", \"Ge\", false\n §l○ §c§lAs§r: 33, 42, -1, null, \"Arsenic\", \"As\", false\n §l○ §c§lSe§r: 34, 45, -1, null, \"Selenium\", \"Se\", false\n §l○ §c§lBr§r: 35, 45, -1, null, \"Bromine\", \"Br\", false\n §l○ §c§lKr§r: 36, 48, -1, null, \"Krypton\", \"Kr\", false\n §l○ §c§lRb§r: 37, 48, -1, null, \"Rubidium\", \"Rb\", false\n §l○ §c§lSr§r: 38, 49, -1, null, \"Strontium\", \"Sr\", false\n §l○ §c§lY§r: 39, 50, -1, null, \"Yttrium\", \"Y\", false\n §l○ §c§lZr§r: 40, 51, -1, null, \"Zirconium\", \"Zr\", false\n §l○ §c§lNb§r: 41, 53, -1, null, \"Niobium\", \"Nb\", false\n §l○ §c§lMo§r: 42, 53, -1, null, \"Molybdenum\", \"Mo\", false\n §l○ §c§lTc§r: 43, 55, -1, null, \"Technetium\", \"Tc\", false\n §l○ §c§lRu§r: 44, 57, -1, null, \"Ruthenium\", \"Ru\", false\n §l○ §c§lRh§r: 45, 58, -1, null, \"Rhodium\", \"Rh\", false\n §l○ §c§lPd§r: 46, 60, -1, null, \"Palladium\", \"Pd\", false\n §l○ §c§lAg§r: 47, 60, -1, null, \"Silver\", \"Ag\", false\n §l○ §c§lCd§r: 48, 64, -1, null, \"Cadmium\", \"Cd\", false\n §l○ §c§lIn§r: 49, 65, -1, null, \"Indium\", \"In\", false\n §l○ §c§lSn§r: 50, 68, -1, null, \"Tin\", \"Sn\", false\n §l○ §c§lSb§r: 51, 70, -1, null, \"Antimony\", \"Sb\", false\n §l○ §c§lTe§r: 52, 75, -1, null, \"Tellurium\", \"Te\", false\n §l○ §c§lI§r: 53, 74, -1, null, \"Iodine\", \"I\", false\n §l○ §c§lXe§r: 54, 77, -1, null, \"Xenon\", \"Xe\", false\n §l○ §c§lCs§r: 55, 77, -1, null, \"Caesium\", \"Cs\", false\n §l○ §c§lBa§r: 56, 81, -1, null, \"Barium\", \"Ba\", false\n §l○ §c§lLa§r: 57, 81, -1, null, \"Lanthanum\", \"La\", false\n §l○ §c§lCe§r: 58, 82, -1, null, \"Cerium\", \"Ce\", false\n §l○ §c§lPr§r: 59, 81, -1, null, \"Praseodymium\", \"Pr\", false\n §l○ §c§lNd§r: 60, 84, -1, null, \"Neodymium\", \"Nd\", false\n §l○ §c§lPm§r: 61, 83, -1, null, \"Promethium\", \"Pm\", false\n §l○ §c§lSm§r: 62, 88, -1, null, \"Samarium\", \"Sm\", false\n §l○ §c§lEu§r: 63, 88, -1, null, \"Europium\", \"Eu\", false\n §l○ §c§lGd§r: 64, 93, -1, null, \"Gadolinium\", \"Gd\", false\n §l○ §c§lTb§r: 65, 93, -1, null, \"Terbium\", \"Tb\", false\n §l○ §c§lDy§r: 66, 96, -1, null, \"Dysprosium\", \"Dy\", false\n §l○ §c§lHo§r: 67, 97, -1, null, \"Holmium\", \"Ho\", false\n §l○ §c§lEr§r: 68, 99, -1, null, \"Erbium\", \"Er\", false\n §l○ §c§lTm§r: 69, 99, -1, null, \"Thulium\", \"Tm\", false\n §l○ §c§lYb§r: 70, 103, -1, null, \"Ytterbium\", \"Yb\", false\n §l○ §c§lLu§r: 71, 103, -1, null, \"Lutetium\", \"Lu\", false\n §l○ §c§lHf§r: 72, 106, -1, null, \"Hafnium\", \"Hf\", false\n §l○ §c§lTa§r: 73, 107, -1, null, \"Tantalum\", \"Ta\", false\n §l○ §c§lW§r: 74, 109, -1, null, \"Tungsten\", \"W\", false\n §l○ §c§lRe§r: 75, 111, -1, null, \"Rhenium\", \"Re\", false\n §l○ §c§lOs§r: 76, 114, -1, null, \"Osmium\", \"Os\", false\n §l○ §c§lIr§r: 77, 115, -1, null, \"Iridium\", \"Ir\", false\n §l○ §c§lPt§r: 78, 117, -1, null, \"Platinum\", \"Pt\", false\n §l○ §c§lAu§r: 79, 117, -1, null, \"Gold\", \"Au\", false\n §l○ §c§lHg§r: 80, 120, -1, null, \"Mercury\", \"Hg\", false\n §l○ §c§lTl§r: 81, 123, -1, null, \"Thallium\", \"Tl\", false\n §l○ §c§lPb§r: 82, 125, -1, null, \"Lead\", \"Pb\", false\n §l○ §c§lBi§r: 83, 125, -1, null, \"Bismuth\", \"Bi\", false\n §l○ §c§lPo§r: 84, 124, -1, null, \"Polonium\", \"Po\", false\n §l○ §c§lAt§r: 85, 124, -1, null, \"Astatine\", \"At\", false\n §l○ §c§lRn§r: 86, 134, -1, null, \"Radon\", \"Rn\", false\n §l○ §c§lFr§r: 87, 134, -1, null, \"Francium\", \"Fr\", false\n §l○ §c§lRa§r: 88, 136, -1, null, \"Radium\", \"Ra\", false\n §l○ §c§lAc§r: 89, 136, -1, null, \"Actinium\", \"Ac\", false\n §l○ §c§lTh§r: 90, 140, -1, null, \"Thorium\", \"Th\", false\n §l○ §c§lPa§r: 91, 138, -1, null, \"Protactinium\", \"Pa\", false\n §l○ §c§lU§r: 92, 146, -1, null, \"Uranium\", \"U\", false\n §l○ §c§lU238§r: 92, 146, -1, null, \"Uranium-238\", \"U-238\", false\n §l○ §c§lU235§r: 92, 143, -1, null, \"Uranium-235\", \"U-235\", true\n §l○ §c§lNp§r: 93, 144, -1, null, \"Neptunium\", \"Np\", false\n §l○ §c§lPu§r: 94, 152, -1, null, \"Plutonium\", \"Pu\", false\n §l○ §c§lPu239§r: 94, 145, -1, null, \"Plutonium-239\", \"Pu-239\", false\n §l○ §c§lPu241§r: 94, 149, -1, null, \"Plutonium-241\", \"Pu-241\", true\n §l○ §c§lAm§r: 95, 150, -1, null, \"Americium\", \"Am\", false\n §l○ §c§lCm§r: 96, 153, -1, null, \"Curium\", \"Cm\", false\n §l○ §c§lBk§r: 97, 152, -1, null, \"Berkelium\", \"Bk\", false\n §l○ §c§lCf§r: 98, 153, -1, null, \"Californium\", \"Cf\", false\n §l○ §c§lEs§r: 99, 153, -1, null, \"Einsteinium\", \"Es\", false\n §l○ §c§lFm§r: 100, 157, -1, null, \"Fermium\", \"Fm\", false\n §l○ §c§lMd§r: 101, 157, -1, null, \"Mendelevium\", \"Md\", false\n §l○ §c§lNo§r: 102, 157, -1, null, \"Nobelium\", \"No\", false\n §l○ §c§lLr§r: 103, 159, -1, null, \"Lawrencium\", \"Lr\", false\n §l○ §c§lRf§r: 104, 161, -1, null, \"Rutherfordium\", \"Rf\", false\n §l○ §c§lDb§r: 105, 163, -1, null, \"Dubnium\", \"Db\", false\n §l○ §c§lSg§r: 106, 165, -1, null, \"Seaborgium\", \"Sg\", false\n §l○ §c§lBh§r: 107, 163, -1, null, \"Bohrium\", \"Bh\", false\n §l○ §c§lHs§r: 108, 169, -1, null, \"Hassium\", \"Hs\", false\n §l○ §c§lMt§r: 109, 167, -1, null, \"Meitnerium\", \"Mt\", false\n §l○ §c§lDs§r: 110, 171, -1, null, \"Darmstadtium\", \"Ds\", false\n §l○ §c§lRg§r: 111, 169, -1, null, \"Roentgenium\", \"Rg\", false\n §l○ §c§lCn§r: 112, 173, -1, null, \"Copernicium\", \"Cn\", false\n §l○ §c§lNh§r: 113, 171, -1, null, \"Nihonium\", \"Nh\", false\n §l○ §c§lFl§r: 114, 175, -1, null, \"Flerovium\", \"Fl\", false\n §l○ §c§lMc§r: 115, 173, -1, null, \"Moscovium\", \"Mc\", false\n §l○ §c§lLv§r: 116, 177, -1, null, \"Livermorium\", \"Lv\", false\n §l○ §c§lTs§r: 117, 177, -1, null, \"Tennessine\", \"Ts\", false\n §l○ §c§lOg§r: 118, 176, -1, null, \"Oganesson\", \"Og\", false\n §l○ §c§lTr§r: 119, 178, -1, null, \"Tritanium\", \"Tr\", false\n §l○ §c§lDr§r: 120, 180, -1, null, \"Duranium\", \"Dr\", false\n §l○ §c§lKe§r: 125, 198, -1, null, \"Trinium\", \"Ke\", false\n §l○ §c§lNq§r: 174, 352, 140, null, \"Naquadah\", \"Nq\", true\n §l○ §c§lNq1§r: 174, 354, 140, null, \"NaquadahEnriched\", \"Nq+\", true\n §l○ §c§lNq2§r: 174, 348, 140, null, \"Naquadria\", \"*Nq*\", true\n §l○ §c§lNt§r: 0, 1000, -1, null, \"Neutronium\", \"Nt\", false\n §l○ §c§lAd§r: 750, 1000, -1, null, \"Adamantium\", \"Ad\", false\n §l○ §c§lVb§r: 850, 900, -1, null, \"Vibranium\", \"Vb\", false\n §l○ §c§lTn§r: 550, 670, -1, null, \"Taranium\", \"Tn\", false" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "ct", - "content": [ - "§lElements.add§r: §o§nElements.add(long protons, long neutrons, long halfLifeSeconds, String decayTo, String name, String symbol, boolean isIsotope)§r \nAdd a new element.\n\n§lElements.get§r: §o§nElements.get(String name)§r \nGet the element by name." - ] - }, - { - "type": "textbox", - "stroke": 687800320, - "stroke_width": 3, - "fill": 687800320, - "content": [ - "§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0MaterialBuilder§r§5;§r§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0Material§r§5;§r§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0Elements§r§5;§r§5\n§r§5\n§r§9var§r§5 §r§0Au§r§5 §r§5\u003d§r§5 §r§0Elements§r§5.§r§0get§r§5(§r§0Au§r§5)§r§5;§r§5 §r§8// get an existing element.§r§5\n§r§9var§r§5 §r§0name§r§5 §r§5\u003d§r§5 §r§0Au§r§5.§r§0name§r§5;§r§5 §r§8// \"Gold\"§r§5\n§r§9var§r§5 §r§0symbol§r§5 §r§5\u003d§r§5 §r§0Au§r§5.§r§0symbol§r§5;§r§5 §r§8// \"Au\"§r§5\n§r§9var§r§5 §r§0protons§r§5 §r§5\u003d§r§5 §r§0Au§r§5.§r§0protons§r§5 §r§8// 79§r§5\n§r§9var§r§5 §r§0neutrons§r§5 §r§5\u003d§r§5 §r§0Au§r§5.§r§0neutrons§r§8// 117§r§5\n§r§9var§r§5 §r§0mass§r§5 §r§5\u003d§r§5 §r§0Au§r§5.§r§0mass§r§5 §r§8// 196§r§5\n§r§5\n§r§9var§r§5 §r§0CEu§r§5 §r§5\u003d§r§5 §r§0Elements§r§5.§r§0add§r§5(§r§c999§r§5,§r§5 §r§c999§r§5,§r§5 §r§5-§r§c1§r§5,§r§5 §r§cnull§r§5,§r§5 §r§2\"GTCEu\"§r§5,§r§5 §r§2\"CEu\"§r§5,§r§5 §r§cfalse§r§5)§r§5;§r§5 §r§8// create a new element.§r§5\n§r§5\n§r§9var§r§5 §r§0myMaterial§r§5 §r§5\u003d§r§5 §r§0MaterialBuilder§r§5(§r§2\"my_material\"§r§5)§r§5.§r§0element§r§5(§r§2\"CEu\"§r§5)§r§5.§r§0build§r§5(§r§5)§r§5;§r§5 §r§8// register my element.§r§5\n§r" - ] - } - ], - "fixed": [] -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/material/03_flag.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/material/03_flag.json deleted file mode 100644 index e739ce18cc5..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/material/03_flag.json +++ /dev/null @@ -1,148 +0,0 @@ -{ - "section": "CraftTweaker/Material", - "title": "MaterialFlag", - "stream": [ - { - "type": "textbox", - "fontSize": 9, - "content": [ - "The §lMaterialFlag§r refers to some additional features it has.\n\nAvailable MaterialFlag are: " - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "element", - "content": [ - "§r§4§ogeneric:" - ] - }, - { - "type": "textbox", - "content": [ - " §l○ §n\"no_unification\"§r: Add to material to disable it\u0027s unification fully todo implement.\n §l○ §n\"decomposition_requires_hydrogen\"§r: Decomposition recipe requires hydrogen as additional input. Amount is equal to input amount.\n §l○ §n\"decomposition_by_electrolyzing\"§r: Enables electrolyzer decomposition recipe generation.\n §l○ §n\"decomposition_by_centrifuging\"§r: Enables centrifuge decomposition recipe generatio.\n §l○ §n\"disable_decomposition\"§r: Disables decomposition recipe generation for this material and all materials that has it as component.\n §l○ §n\"explosive\"§r: Add to material if it is some kind of explosive.\n §l○ §n\"flammable\"§r: Add to material if it is some kind of flammable." - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "ct", - "content": [ - "§4§oGenerate a plate for this material If it\u0027s dust material, dust compressor recipe into plate will be generated If it\u0027s metal material, bending machine recipes will be generated If block is found, cutting machine recipe will be also generated:" - ] - }, - { - "type": "textbox", - "content": [ - "§n\"generate_plate\"§r, §n\"generate_rod\"§r, §n\"generate_frame\"§r, §n\"generate_gear\"§r, §n\"generate_long_rod\"§r" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "content": [ - "§4§oThis will prevent material from creating Shapeless recipes for dust to block and vice versa Also preventing extruding and alloy smelting recipes via SHAPE_EXTRUDING/MOLD_BLOCK:" - ] - }, - { - "type": "textbox", - "content": [ - "§n\"exclude_block_crafting_recipes\"§r, §n\"exclude_plate_compressor_recipe\"§r" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "content": [ - "§4§oThis will prevent material from creating Shapeless recipes for dust to block and vice versa:" - ] - }, - { - "type": "textbox", - "content": [ - "§n\"exclude_block_crafting_by_hand_recipes\"§r, §n\"mortar_grindable\"§r" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "content": [ - "§4§oAdd to material if it cannot be worked by any other means, than smashing or smelting. This is used for coated Materials:" - ] - }, - { - "type": "textbox", - "content": [ - "§n\"no_working\"§r, §n\"no_smashing\"§r, §n\"no_smelting\"§r" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "content": [ - "§4§oAdd this to your Material if you want to have its Ore Calcite heated in a Blast Furnace for more output. Already listed are: Iron, Pyrite, PigIron, WroughtIron:" - ] - }, - { - "type": "textbox", - "content": [ - "§n\"blast_furnace_calcite_double\"§r, §n\"blast_furnace_calcite_triple\"§r, §n\"generate_foil\"§r, §n\"generate_bolt_screw\"§r, §n\"generate_ring\"§r, §n\"generate_spring\"§r, §n\"generate_spring_small\"§r, §n\"generate_small_gear\"§r, §n\"generate_fine_wire\"§r, §n\"generate_rotor\"§r, §n\"generate_dense\"§r, §n\"generate_round\"§r" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "content": [ - "§4§oIf this material can be crystallized:" - ] - }, - { - "type": "textbox", - "content": [ - "§n\"crystallizable\"§r, §n\"generate_lens\"§r, §n\"high_sifter_output\"§r" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - } - ], - "fixed": [] -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/material/04_icon_set.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/material/04_icon_set.json deleted file mode 100644 index f0749c2b2a5..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/material/04_icon_set.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "section": "CraftTweaker/Material", - "title": "MaterialIconSet", - "stream": [ - { - "type": "textbox", - "fontSize": 9, - "content": [ - "The §lMaterialIconSet§r will determine the appearance of the material." - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "element", - "content": [ - "§rAvailable MaterialIconSet are:" - ] - }, - { - "type": "textbox", - "content": [ - "§l\"NONE\", \"METALLIC\", \"DULL\", \"MAGNETIC\", \"QUARTZ\", \"DIAMOND\", \"EMERALD\", \"SHINY\", \"ROUGH\", \"FINE\", \"SAND\", \"FLINT\", \"RUBY\", \"LAPIS\", \"FLUID\", \"GAS\", \"LIGNITE\", \"OPAL\", \"GLASS\", \"WOOD\", \"GEM_HORIZONTAL\", \"GEM_VERTICAL\", \"PAPER\", \"NETHERSTAR\", \"BRIGHT\"§r." - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "ct", - "content": [ - "For example, the following figure shows the appearance of ores with different Materialiconsets." - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/143435701-058dcfea-ea35-4976-a7ba-7901fa791e36.png", - "width": 190, - "height": 100 - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - } - ], - "fixed": [] -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/material/05_create.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/material/05_create.json deleted file mode 100644 index feaa04ef1f8..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/material/05_create.json +++ /dev/null @@ -1,257 +0,0 @@ -{ - "section": "CraftTweaker/Material", - "title": "Create a Material", - "stream": [ - { - "type": "textbox", - "fontSize": 9, - "content": [ - "You can help create a Material by the §lMaterialBuilder§r.\n\n§lContents:" - ] - }, - { - "type": "textbox", - "link": "bui", - "content": [ - "1. §9MaterialBuilder" - ] - }, - { - "type": "textbox", - "link": "pro", - "content": [ - "2. §9Material Properties" - ] - }, - { - "type": "textbox", - "link": "ico", - "content": [ - "3. §9Material IconSet" - ] - }, - { - "type": "textbox", - "link": "com", - "content": [ - "4. §9Material Component" - ] - }, - { - "type": "textbox", - "link": "fla", - "content": [ - "5. §9Material Flag" - ] - }, - { - "type": "textbox", - "link": "ele", - "content": [ - "6§r. §9Material Element" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "content": [ - "§lMaterialBuilder" - ], - "ref": "bui" - }, - { - "type": "textbox", - "ref": "element", - "content": [ - "§o§nMaterialBuilder(String materialName)§r" - ] - }, - { - "type": "textbox", - "stroke": 687800320, - "stroke_width": 3, - "fill": 687800320, - "content": [ - "§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0MaterialBuilder§r§5;§r§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0Material§r§5;§r§5\n§r§5\n§r§9var§r§5 §r§0myMaterial§r§5 §r§5\u003d§r§5 §r§0MaterialBuilder§r§5(§r§2\"my_material\"§r§5)§r§5.§r§0build§r§5(§r§5)§r§5;§r§5\n" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "pro", - "content": [ - "§lMaterial Properties" - ] - }, - { - "type": "textbox", - "content": [ - "§lcolor§r: §o§ncolor(int color)§r\nSet the Color of this Material. Defaults to 0xFFFFFF unless §ncolorAverage()§r.\n\n§lcolorAverage§r: §o§ncolorAverage(int color)§r\nColor will be a weighted average of the components of the Material.\n\n§lFluid§r: §o§nfluid(@Optional String type, @Optional boolean hasBlock)§r\nAdd a FluidProperty to this Material.\n §l○§r type – The Material.FluidType of this Material, either \"fluid\" or \"gas\".\n §l○§r hasBlock – If true, create a Fluid Block for this Material.\n\n§lplasma§r: §o§nplasma()§r \nAdd a PlasmaProperty to this Material.\n §l○§r type – The Material.FluidType of this Material, either \"fluid\" or \"gas\".\n §l○§r hasBlock – If true, create a Fluid Block for this Material.\n\n§ldust§r: §o§ndust(@Optional int harvestLevel, @Optional int burnTime)§r \nAdd a DustProperty to this Material.\n §l○§r harvestLevel – The Harvest Level of this block for Mining. If this Material also has a ToolProperty, this value will also be used to determine the tool\u0027s Mining Level.\n §l○§r burnTime – The Burn Time (in ticks) of this Material as a Furnace Fuel.\n\n§lingot§r: §o§ningot(@Optional int harvestLevel, @Optional int burnTime)§r \nAdd an IngotProperty to this Material.\n §l○§r harvestLevel – The Harvest Level of this block for Mining. If this Material also has a ToolProperty, this value will also be used to determine the tool\u0027s Mining level. If this Material already had a Harvest Level defined, it will be overridden.\n §l○§r burnTime – The Burn Time (in ticks) of this Material as a Furnace Fuel. If this Material already had a Burn Time defined, it will be overridden.\n\n§lgem§r: §o§ngem(@Optional int harvestLevel, @Optional int burnTime)§r \nAdd a GemProperty to this Material.\n §l○§r harvestLevel – The Harvest Level of this block for Mining. If this Material also has a ToolProperty, this value will also be used to determine the tool\u0027s Mining level. If this Material already had a Harvest Level defined, it will be overridden.\n §l○§r burnTime – The Burn Time (in ticks) of this Material as a Furnace Fuel. If this Material already had a Burn Time defined, it will be overridden.\n\n§ltoolStats§r: §o§ntoolStats(float speed, float damage, int durability, int enchantability)§r \nSet the stat for tools which are made from this Material.\n §l○§r speed – Speed.\n §l○§r damage – Attack damage.\n §l○§r durability – Durability of tools.\n §l○§r enchantability – Enchantability of tools.\n\n§lblastTemp§r: §o§nblastTemp(int temp)§r \nBlast Furnace Temperature of this Material. If below 1000K, Primitive Blast Furnace recipes will be also added. If above 1750K, a Hot Ingot and its Vacuum Freezer recipe will be also added.\n\nIf a Material with this Property has a Fluid, its temperature will be set to this if it is the default Fluid temperature.\n §l○§r temp – Temperature.\n\n§lore§r: §o§nore(@Optional int oreMultiplier, @Optional int byproductMultiplier, @Optional boolean emissive)§r \nAdd ore blocks of this Material.\n §l○§r oreMultiplier – Crushed Ore output amount multiplier during Maceration. Default: 1 (no multiplier).\n §l○§r byproductMultiplier – Byproducts output amount multiplier during Maceration. Default: 1 (no multiplier).\n §l○§r emissive – Should ore block use the emissive texture. Default: false.\n\nEmissive ore as follow:" - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/143446969-80de6354-ad12-4170-81f5-071d6c0bb7cd.png", - "width": 190, - "height": 110 - }, - { - "type": "textbox", - "content": [ - "§lwashedIn§r: §o§nwashedIn(String materialName, @Optional int washedAmount)§r \n\n§lwashedIn§r: §o§nwashedIn(Material material, @Optional int washedAmount)§r \nSet washing product of this Material (must has the ore property).\n §l○§r material – material.\n §l○§r washedAmount – amount.\n\n§lseparatedInto§r: §o§nseparatedInto(String... materialNames)§r \n\n§lseparatedInto§r: §o§nseparatedInto(Material... materials)§r \nSet separated products of this Material (must has the ore property).\n §l○§r materials – separated materials.\n\n§laddOreByproducts§r: §o§naddOreByproducts(String... materialNames)§r \n\n§laddOreByproducts§r: §o§naddOreByproducts(Material... materials)§r \nSet ore byproducts of this Material (must has the ore property).\n §l○§r materials – separated materials.\n\n§loreSmeltInto§r: §o§noreSmeltInto(String materialName)§r \n\n§loreSmeltInto§r: §o§noreSmeltInto(Material material)§r \nSet smelt product of this Material (must has the ore property).\n §l○§r material – material.\n\n§lpolarizesInto§r: §o§npolarizesInto(String materialName)§r \n\n§lpolarizesInto§r: §o§npolarizesInto(Material material)§r \nSet polarizes product of this Material (must has the ore property).\n §l○§r material – material.\n\n§larcSmeltInto§r: §o§narcSmeltInto(String materialName)§r \n\n§larcSmeltInto§r: §o§narcSmeltInto(Material material)§r \nSet arcSmelt product of this Material (must has the ore property).\n §l○§r material – material.\n\n§lmacerateInto§r: §o§nmacerateInto(String materialName)§r \n\n§lmacerateInto§r: §o§nmacerateInto(Material material)§r \nSet macerate product of this Material (must has the ore property).\n §l○§r material – material.\n\n§lingotSmeltInto§r: §o§ningotSmeltInto(String materialName)§r \n\n§lingotSmeltInto§r: §o§ningotSmeltInto(Material material)§r \nSet ingotSmelt product of this Material (must has the ore property).\n §l○§r material – material.\n\n§lfluidTemp§r: §o§nfluidTemp(int temp)§r \nSet the temperature of the fluid of this Material (must has the fluid property).\n §l○§r temp – temperature.\n\n§lcableProperties§r: §o§ncableProperties(long voltage, int amperage, int loss, @Optional boolean isSuperCon)§r \nAdd a cables and wires of this Material.\n §l○§r voltage – voltage.\n §l○§r amperage – amperage.\n §l○§r loss – loss.\n §l○§r isSuperCon – isSuperCon.\n\n§lfluidPipeProperties§r: §o§nfluidPipeProperties(int maxTemp, int throughput, boolean gasProof)§r \nAdd fluid pipes of this Material.\n §l○§r maxTemp – max acceptable temperature.\n §l○§r throughput – §l//TODO§r.\n §l○§r gasProof – §l//TODO§r.\n\n§litemPipeProperties§r: §o§nitemPipeProperties(int priority, float stacksPerSec)§r \nAdd item pipes of this Material.\n §l○§r priority – Items will try to take the path with the lowest priority.\n §l○§r stacksPerSec – rate in stacks per sec.\n\n§laddDefaultEnchant§r: §o§naddDefaultEnchant(IEnchantment enchantment)§r \nAdd Default Enchant of this Material.\n §l○§r enchantment – enchantment." - ] - }, - { - "type": "textbox", - "stroke": 687800320, - "stroke_width": 3, - "fill": 687800320, - "content": [ - "§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0MaterialBuilder§r§5;§r§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0Material§r§5;§r§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0MaterialRegistry§r§5;§r§5\n§r§5\n§r§9var§r§5 §r§0gold§r§5 §r§5\u003d§r§5 §r§0MaterialRegistry§r§5(§r§2\"gold\"§r§5)§r§5\n§r§9var§r§5 §r§0copper§r§5 §r§5\u003d§r§5 §r§0MaterialRegistry§r§5(§r§2\"copper\"§r§5)§r§5\n§r§5\n§r§9var§r§5 §r§0myMaterial§r§5 §r§5\u003d§r§5 §r§0MaterialBuilder§r§5(§r§2\"my_material\"§r§5)§r§5 §r§8// name§r§5\n§r§5 §r§5 §r§5 §r§5 §r§5.§r§0color§r§5(§r§5-§r§c1§r§5)§r§5 §r§8// white§r§5\n§r§5 §r§5 §r§5 §r§5 §r§5.§r§0fluid§r§5(§r§2\"gas\"§r§5,§r§5 §r§cfalse§r§5)§r§5 §r§8// gas without block§r§5\n§r§5 §r§5 §r§5 §r§5 §r§5.§r§0dust§r§5(§r§5)§r§5 §r§8// has dust§r§5\n§r§5 §r§5 §r§5 §r§5 §r§5.§r§0ingot§r§5(§r§5)§r§5 §r§8// has ingot§r§5\n§r§5 §r§5 §r§5 §r§5 §r§5.§r§0toolStats§r§5(§r§c10§r§5,§r§5 §r§c3§r§5,§r§5 §r§c256§r§5,§r§5 §r§c21§r§5)§r§5 §r§8// tool stats§r§5\n§r§5 §r§5 §r§5 §r§5 §r§5.§r§0blastTemp§r§5(§r§c1000§r§5)§r§5 §r§8// EBF temperature§r§5\n§r§5 §r§5 §r§5 §r§5 §r§5.§r§0ore§r§5(§r§5)§r§5 §r§8// has ore blocks§r§5\n§r§5 §r§5 §r§5 §r§5 §r§5.§r§0addOreByproducts§r§5(§r§0gold§r§5,§r§5 §r§0copper§r§5)§r§5 §r§8// add byproducts§r§5\n§r§5 §r§5 §r§5 §r§5 §r§5.§r§0cableProperties§r§5(§r§c0§r§5,§r§5 §r§c2§r§5,§r§5 §r§c0§r§5,§r§5 §r§ctrue§r§5)§r§5 §r§8// add cables§r§5\n§r§5 §r§5 §r§5 §r§5 §r§5.§r§0build§r§5(§r§5)§r§5;§r§5\n" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "ico", - "content": [ - "§lMaterial IconSet" - ] - }, - { - "type": "textbox", - "content": [ - "§liconSet§r: §o§niconSet(String iconSet)§r \nSet the MaterialIconSet of this Material. Defaults vary depending on if the Material has a: \n §l○§r §nGemProperty§r, it will default to §l\"GEM_VERTICAL\"§r\n §l○§r §nIngotProperty§r or §nDustProperty§r, it will default to §l\"DULL\"§r\n §l○§r §nFluidProperty§r, it will default to either §l\"FLUID\"§r or §l\"GAS\"§r, depending on the FluidType\n §l○§r §nPlasmaProperty§r, it will default to §l\"FLUID\"§r\n\nDefault will be determined by first-found Property in this order, unless specified." - ] - }, - { - "type": "textbox", - "stroke": 687800320, - "stroke_width": 3, - "fill": 687800320, - "content": [ - "§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0MaterialBuilder§r§5;§r§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0Material§r§5;§r§5\n§r§5\n§r§9var§r§5 §r§0myMaterial§r§5 §r§5\u003d§r§5 §r§0MaterialBuilder§r§5(§r§2\"my_material\"§r§5)§r§5.§r§0iconSet§r§5(§r§2\"QUARTZ\"§r§5)§r§5.§r§0build§r§5(§r§5)§r§5;§r§5\n§r" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "com", - "content": [ - "§lComponent" - ] - }, - { - "type": "textbox", - "content": [ - "The §lComponent§r refers to compositions of the material. \nFor example, the compositions of the §lSugar§r are §n2*Carbon§r, §n5*Water§r, and §n25*Oxygen§r. That would affect its chemical formula:" - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/143438573-cd2e9078-744d-4861-a00c-1e9fc5ccd32a.png", - "width": 110, - "height": 50 - }, - { - "type": "textbox", - "content": [ - "§lcomponents§r: §o§ncomponents(MaterialStack[] components)§r \nSet the compositions of the material.\n §l○§r components - compositions." - ] - }, - { - "type": "textbox", - "stroke": 687800320, - "stroke_width": 3, - "fill": 687800320, - "content": [ - "§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0MaterialBuilder§r§5;§r§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0Material§r§5;§r§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0MaterialStack§r§5;§r§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0MaterialRegistry§r§5;§r§5\n§r§5\n§r§9var§r§5 §r§0carbonMaterial§r§5 §r§5\u003d§r§5 §r§0MaterialRegistry§r§5.§r§0get§r§5(§r§2\"carbon\"§r§5)§r§5;§r§5\n§r§9var§r§5 §r§0oxygenMaterial§r§5 §r§5\u003d§r§5 §r§0MaterialRegistry§r§5.§r§0get§r§5(§r§2\"oxygen\"§r§5)§r§5;§r§5\n§r§5\n§r§0val§r§5 §r§0compositions§r§5 §r§0as§r§5 §r§0MaterialStack§r§5[§r§5]§r§5 §r§5\u003d§r§5 §r§5[§r§5\n§r§5 §r§5 §r§5 §r§5 §r§5 §r§5 §r§5 §r§5 §r§0carbonMaterial§r§5 §r§5*§r§5 §r§c2§r§5,§r§5\n§r§5 §r§5 §r§5 §r§5 §r§5 §r§5 §r§5 §r§5 §r§0oxygenMaterial§r§5 §r§5*§r§5 §r§c3§r§5,§r§5\n§r§5 §r§5 §r§5 §r§5 §r§5]§r§5;§r§5\n§r§5\n§r§9var§r§5 §r§0myMaterial§r§5 §r§5\u003d§r§5 §r§0MaterialBuilder§r§5(§r§2\"my_material\"§r§5)§r§5.§r§0components§r§5(§r§0compositions§r§5)§r§5.§r§0build§r§5(§r§5)§r§5;§r§5\n§r" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "fla", - "content": [ - "§lMaterial Flag" - ] - }, - { - "type": "textbox", - "content": [ - "§lflags§r: §o§nflags(String... names)§r \nAdd MaterialFlags to this Material.\n §l○§r names - names of specific MaterialFlags." - ] - }, - { - "type": "textbox", - "stroke": 687800320, - "stroke_width": 3, - "fill": 687800320, - "content": [ - "§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0MaterialBuilder§r§5;§r§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0Material§r§5;§r§5\n§r§5\n§r§9var§r§5 §r§0myMaterial§r§5 §r§5\u003d§r§5 §r§0MaterialBuilder§r§5(§r§2\"my_material\"§r§5)§r§5.§r§0flags§r§5(§r§2\"generate_rod\"§r§5,§r§5 §r§2\"generate_foil\"§r§5)§r§5.§r§0build§r§5(§r§5)§r§5;§r§5\n§r" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "ele", - "content": [ - "§lElement" - ] - }, - { - "type": "textbox", - "content": [ - "§lelement§r: §o§nelement(String elementName)§r \nSet the element of this Material.\n §l○§r elementName - names of the element." - ] - }, - { - "type": "textbox", - "stroke": 687800320, - "stroke_width": 3, - "fill": 687800320, - "content": [ - "§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0MaterialBuilder§r§5;§r§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0Material§r§5;§r§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0Elements§r§5;§r§5\n§r§5\n§r§9var§r§5 §r§0CEu§r§5 §r§5\u003d§r§5 §r§0Elements§r§5.§r§0add§r§5(§r§c999§r§5,§r§5 §r§c999§r§5,§r§5 §r§5-§r§c1§r§5,§r§5 §r§cnull§r§5,§r§5 §r§2\"GTCEu\"§r§5,§r§5 §r§2\"CEu\"§r§5,§r§5 §r§cfalse§r§5)§r§5;§r§5 §r§8// create a new element.§r§5\n§r§5\n§r§9var§r§5 §r§0myMaterial§r§5 §r§5\u003d§r§5 §r§0MaterialBuilder§r§5(§r§2\"my_material\"§r§5)§r§5.§r§0element§r§5(§r§2\"CEu\"§r§5)§r§5.§r§0build§r§5(§r§5)§r§5;§r§5 §r§8// register my element.§r§5\n§r" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - } - ], - "fixed": [] -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/material/06_modify.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/material/06_modify.json deleted file mode 100644 index f9e1deeaf23..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/material/06_modify.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "section": "CraftTweaker/Material", - "title": "Modify Existing Materials", - "stream": [ - { - "type": "textbox", - "fontSize": 9, - "content": [ - "You can get Materials by the §lMaterialRegistry§r." - ] - }, - { - "type": "textbox", - "link": "element", - "content": [ - "1. §9Getters" - ] - }, - { - "type": "textbox", - "link": "ct", - "content": [ - "2. §9Setters" - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "element", - "content": [ - "§c§lGetters:" - ] - }, - { - "type": "textbox", - "content": [ - " §l○§r §o§nMaterialRegistry.get(String materialName)§r get §nMaterial§r by name.\n\n §l○§r §o§nMaterialRegistry.getAllMaterials()§r get §nMaterial§r List.\n\n §l○§r §o§ngetChemicalFormula()§r get default formula.\n\n §l○§r §o§nmaterialRGB§r get default materialRGB.\n\n §l○§r §o§nradioactive§r get default radioactive.\n\n §l○§r §o§nprotons§r get default protons.\n\n §l○§r §o§nneutrons§r get default neutrons.\n\n §l○§r §o§nmass§r get default mass.\n\n §l○§r §o§naverageProtons§r get default averageProtons.\n\n §l○§r §o§naverageNeutrons§r get default averageNeutrons.\n\n §l○§r §o§naverageMass§r get default averageMass.\n\n §l○§r §o§nblastTemperature§r get default blastTemperature.\n\n §l○§r §o§ncamelCaseName§r get default camelCaseName.\n\n §l○§r §o§nunlocalizedName§r get default unlocalizedName.\n\n §l○§r §o§nlocalizedName§r get default localizedName.\n\n §l○§r §o§nname§r get default name." - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "ref": "ct", - "content": [ - "§c§lSetters:" - ] - }, - { - "type": "textbox", - "content": [ - " §l○§r §o§nsetFormula(String formula, @Optional boolean withFormatting)§r Set the formula of this Material.\n\n §l○§r §o§naddFlags(String... names)§r Add additional flags to this Material.\n\n §l○§r §o§nsetMaterialRGB(int materialRGB)§r Set the color of this Material.\n\n §l○§r §o§nsetFormula(String formula, @Optional boolean withFormatting)§r Set the formula of this Material." - ] - }, - { - "type": "textbox", - "content": [ - "\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d" - ] - }, - { - "type": "textbox", - "stroke": 687800320, - "stroke_width": 3, - "fill": 687800320, - "content": [ - "§5\n§r§8#loader gregtech§r§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0MaterialRegistry§r§5;§r§5\n§r§9import§r§5 §r§0mods§r§5.§r§0gregtech§r§5.§r§0material§r§5.§r§0Material§r§5;§r§5\n§r§5\n§r§9var§r§5 §r§0gold§r§5 §r§5\u003d§r§5 §r§0MaterialRegistry§r§5.§r§0get§r§5(§r§2\"gold\"§r§5)§r§5;§r§5\n§r§9var§r§5 §r§0name§r§5 §r§5\u003d§r§5 §r§0gold§r§5.§r§0name§r§5;§r§5 §r§8// \"gold\"§r§5\n§r§9var§r§5 §r§0color§r§5 §r§5\u003d§r§5 §r§0gold§r§5.§r§0materialRGB§r§5;§r§5 §r§8// 0xFFE650§r§5\n§r§0gold§r§5.§r§0setFormula§r§5(§r§2\"AggA\"§r§5)§r§5;§r§5 §r§8// set formula§r§5\n§r§9var§r§5 §r§0formula§r§5 §r§5\u003d§r§5 §r§0gold§r§5.§r§0getChemicalFormula§r§5(§r§5)§r§5;§r§5 §r§8// \"AggA\"§r§5\n§r§0gold§r§5.§r§0addFlag§r§5(§r§2\"generate_long_rod\"§r§5,§r§5 §r§2\"generate_gear\"§r§5)§r§5;§r§5 §r§8// add gold long rod, add gold gear§r§5\n§r" - ] - } - ], - "fixed": [] -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/terminal/ct_terminal_01.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/terminal/ct_terminal_01.json deleted file mode 100644 index b1cdd3a9570..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/crafttweaker/terminal/ct_terminal_01.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "section": "CraftTweaker/Terminal", - "title": "CraftTweaker of Terminal", - "stream": [ - { - "type": "textbox", - "content": [ - "Content:" - ] - }, - { - "type": "textbox", - "content": [ - "§1§lURL:§r§n https://github.com/Gregicality/GregTech/wiki/CraftTweaker-of-Terminal" - ] - }, - { - "type": "textbox", - "ref": "api", - "isShadow": false, - "content": [ - "§4§lAPI:" - ] - }, - { - "type": "textbox", - "fontSize": 9, - "content": [ - "1. §1registerDevice(deviceItemStack, deviceName)§0:\nRegister the custon device.\n\n2. §1createAppRegistryBuilder(appName):\n§0Create the registryBuilder according to the app name (found in the store app).\n\n3. §1isDefaultApp(default):\n§0Make it as a default app.\n\n4. §1battery(euTier, cost):\n§0Set battery requirements for all tier.\n\n5. §1battery(appTier, euTier, cost):\n§0Set battery requirements for the specific tier.\n\n6. §1device(deviceName...):\n§0Set device requirements for all tier. (available by default: \"scanner\", \"wireless\", \"camera\", \"solar_lv\").\n\n7. §1device(appTier, device...):\n§0Set device requirements for the specific tier.\n\n8. §1upgrade(upgradeItemStack...):\n§0Set upgrade requirements for all tier.\n\n9. §1upgrade(appTier, upgradeItemStack...):\n§0Set upgrade requirements for the specific tier.\n\n10. §1build():\n§0finish and register." - ] - }, - { - "type": "textbox", - "ref": "demo", - "space": 1, - "content": [ - "\n§4§lZS Demo:" - ] - }, - { - "type": "textbox", - "fill": -912478525, - "fontSize": 9, - "content": [ - "import mods.gregtech.TerminalRegistry;\n\nTerminalRegistry.registerDevice(\u003core:ingotIron\u003e.firstItem, \"ingot_iron\");\n\nTerminalRegistry.createAppRegistryBuilder(\"ore_prospector\")\n .isDefaultApp(true)\n .battery(1, 500)\n .battery(3, 3, 1000)\n .device(\"camera\", \"wireless\")\n .device(4, \"ingot_iron\")\n .upgrade(\u003cminecraft:apple\u003e * 9)\n .upgrade(2, \u003cminecraft:apple\u003e * 9, \u003cminecraft:grass\u003e * 12)\n .build();" - ] - }, - { - "type": "textbox", - "fontSize": 9, - "content": [ - "§4§lResult:\n§rCustom Device" - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/140280593-37922838-4a20-4e1b-9be9-73935c4c8c13.png", - "width": 190, - "height": 120 - }, - { - "type": "textbox", - "content": [ - "Register Battery, Device, and Upgrade" - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/140280587-84dc8f67-6dde-472f-9ed8-6a4c5e71abc4.png", - "width": 190, - "height": 120 - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/140280590-d4700a88-5780-4e0f-95f8-130e82f4634a.png", - "width": 190, - "height": 120 - } - ], - "fixed": [ - { - "type": "textbox", - "x": 49, - "y": 40, - "width": 16, - "height": 10, - "link": "api", - "content": [ - "§9§napi" - ] - }, - { - "type": "textbox", - "x": 67, - "y": 40, - "width": 25, - "height": 10, - "link": "demo", - "content": [ - "§9§ndemo" - ] - } - ] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/guide_widget_api/api_0_guidepage.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/guide_widget_api/api_0_guidepage.json deleted file mode 100644 index 8fe3a94e403..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/guide_widget_api/api_0_guidepage.json +++ /dev/null @@ -1,148 +0,0 @@ -{ - "section": "Guide Widget Api", - "title": "Guide Page", - "stream": [ - { - "type": "textbox", - "content": [ - "In this page we'll learn how to write a guide page.", - "-------------------------------", - "Let's take a look at an example config file for a guide page.", - "§lJSON§r:", - "{", - " \"section\": \"section name here\",", - " \"title\": \"title here\",", - " \"stream\": [", - " {", - " \"type\": \"textbox\",", - " \"content\": [\"TextBox widget\"]", - " }", - " ],", - " \"fixed\": [", - " {", - " \"x\": 50,", - " \"y\": 100,", - " \"width\": 150,", - " \"height\": 40,", - " \"type\": 0,", - " \"content\": [\"TextBox widget\"]", - " }", - " ]", - "}", - "-------------------------------", - "§lContents§r" - ] - }, - { - "type": "textbox", - "link": "section", - "content": [ - " 1.§nsection§r" - ] - }, - { - "type": "textbox", - "link": "title", - "content": [ - " 2.§ntitle§r" - ] - }, - { - "type": "textbox", - "link": "stream", - "content": [ - " 3.§nstream§r" - ] - }, - { - "type": "textbox", - "link": "fixed", - "content": [ - " 4.§nfixed§r" - ] - }, - { - "type": "textbox", - "ref": "section", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §nsection§r (§4required§r)", - "§ltype§r: String", - "§lillustrate§r: Specifies which section of the application the page belongs to.", - "The application automatically merges pages of the same section name and builds a directory tree." - ] - }, - { - "type": "textbox", - "ref": "title", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §ntitle§r (§4required§r)", - "§ltype§r: String", - "§lillustrate§r: The page title." - ] - }, - { - "type": "textbox", - "ref": "stream", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §nstream§r (§4required§r)", - "§ltype§r: Array", - "§lillustrate§r: Widgets in streaming layout. You don't need to care the position and size of widgets in stream, all typography will be done automatically." - ] - }, - { - "type": "textbox", - "ref": "fixed", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §nfixed§r (§4required§r)", - "§ltype§r: Array", - "§lillustrate§r: Widgets in fixed layout. You need to specify the position and size of each widget." - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§lDemo§r: fixed and stream" - ] - }, - { - "type": "textbox", - "isCenter": true, - "hover_text": ["stream widget"], - "content": [ - "§nMinecraft Formatting", - "§r§00 §11 §22 §33", - "§44 §55 §66 §77", - "§88 §99 §aa §bb", - "§cc §dd §ee §ff", - "§r§0k §kMinecraft", - "§rl §lMinecraft", - "§rm §mMinecraft", - "§rn §nMinecraft", - "§ro §oMinecraft", - "§rr §rMinecraft" - ] - } - ], - "fixed": [ - { - "type": "image", - "x": 30, - "y": 800, - "stroke": 4278190335, - "hover_text": ["fixed widget", "\"x\": 30","\"y\": 800","\"width\": 100","\"width\": 100"], - "form": "item", - "source": "minecraft:ender_pearl", - "width": 100, - "height": 100 - } - ] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/guide_widget_api/api_1_widget.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/guide_widget_api/api_1_widget.json deleted file mode 100644 index 7d8d23bea8c..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/guide_widget_api/api_1_widget.json +++ /dev/null @@ -1,304 +0,0 @@ -{ - "section": "Guide Widget Api", - "title": "Guide Widget", - "stream": [ - { - "type": "textbox", - "content": [ - "In this page we'll learn what is §4§lGuide Widget§r, and its public attributes.", - "Widgets are rendered in the Guide Page, which is the basis for your custom pages. §nTextbox§r, §nImage§r, etc", - "To use it, just add the related JSON code under the §l\"fixed\"§r or §l\"stream\"§r.", - "There are some attributes effects (styles) that are valid for all widgets", - "-------------------------------", - "§lJSON§r:", - "{", - " \"type\": \"type here\",", - " \"x\": 50,", - " \"y\": 100,", - " \"width\": 150,", - " \"height\": 40,", - " \"ref\": \"ref\",", - " \"stroke\": 0,", - " \"stroke_width\": 1,", - " \"fill\": 0,", - " \"link\": \"ref\"", - " \"hover_text\": [\"text here\"]", - "}", - "-------------------------------", - "§lContents§r" - ] - }, - { - "type": "textbox", - "link": "type", - "content": [ - " 1.§ntype§r" - ] - }, - { - "type": "textbox", - "link": "xywh", - "content": [ - " 2.§nx, y, width, height§r" - ] - }, - { - "type": "textbox", - "link": "ref", - "content": [ - " 3.§nref§r" - ] - }, - { - "type": "textbox", - "link": "fill", - "content": [ - " 4.§nfill§r" - ] - }, - { - "type": "textbox", - "link": "stroke", - "content": [ - " 5.§nstroke§r" - ] - }, - { - "type": "textbox", - "link": "stroke_width", - "content": [ - " 6.§nstroke_width§r" - ] - }, - { - "type": "textbox", - "link": "link", - "content": [ - " 7.§nlink§r" - ] - }, - { - "type": "textbox", - "link": "hover", - "content": [ - " 8.§nhover_text§r" - ] - }, - { - "type": "textbox", - "ref": "type", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §ntype§r (§4required§r)", - "§ltype§r: String", - "§lillustrate§r: This is the unique id of the widget. See the API documentation for each widget." - ] - }, - { - "type": "textbox", - "ref": "xywh", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §nx, y, width, height§r (§4optional§r)", - "§ltype§r: Integer", - "§lillustrate§r: The position and size of the widget. In a stream layout, you usually don't need to set it (the image widget needs to set width and height). Under fixed layout you must set these four attributes." - ] - }, - { - "type": "textbox", - "ref": "ref", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §nref§r (§4optional§r)", - "§ltype§r: String", - "§ldefault§r: null", - "§lillustrate§r: This is a tag of this widget. The ref should be unique on the same page." - ] - }, - { - "type": "textbox", - "ref": "fill", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §nfill§r (§6optional§r)", - "§ltype§r: Number", - "§ldefault§r: 0", - "§lillustrate§r: The background color." - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§lDemo§r: 4278190335 (0xFF0000FF)" - ] - }, - { - "type": "textbox", - "isCenter": true, - "fill": 4278190335, - "content": [ - "§nMinecraft Formatting", - "§r§00 §11 §22 §33", - "§44 §55 §66 §77", - "§88 §99 §aa §bb", - "§cc §dd §ee §ff", - "§r§0k §kMinecraft", - "§rl §lMinecraft", - "§rm §mMinecraft", - "§rn §nMinecraft", - "§ro §oMinecraft", - "§rr §rMinecraft" - ] - }, - { - "type": "textbox", - "ref": "stroke", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §nstroke§r (§6optional§r)", - "§ltype§r: Number", - "§ldefault§r: 0", - "§lillustrate§r: The border color." - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§lDemo§r: 4278190335 (0xFF0000FF)" - ] - }, - { - "type": "image", - "form": "item", - "source": "minecraft:ender_pearl", - "stroke": 4278190335, - "width": 50, - "height": 50 - }, - { - "type": "textbox", - "ref": "stroke_width", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §nstroke_width§r (§6optional§r)", - "§ltype§r: Number", - "§ldefault§r: 1", - "§lillustrate§r: The border width." - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§lDemo§r: 5" - ] - }, - { - "type": "image", - "form": "item", - "source": "minecraft:ender_pearl", - "stroke": 4278190335, - "stroke_width": 5, - "width": 50, - "height": 50 - }, - { - "type": "textbox", - "ref": "link", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §nlink§r (§6optional§r)", - "§ltype§r: String", - "§ldefault§r: null", - "§lillustrate§r: Click to jump to the specified location. Need to be used with ref, target is ref." - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§lDemo§r: \"P2\"" - ] - }, - { - "type": "textbox", - "isCenter": true, - "fill": 4286430975, - "hover_text": ["\"ref\": \"P1\""], - "ref": "P1", - "link": "P2", - "content": ["Click Me!"] - }, - { - "type": "textbox", - "content": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§lDemo§r: \"P1\"" - ] - }, - { - "type": "textbox", - "isCenter": true, - "fill": 4286430975, - "hover_text": ["\"ref\": \"P2\""], - "ref": "P2", - "link": "P1", - "content": ["Click Me!"] - }, - { - "type": "textbox", - "ref": "hover", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §nhover_text§r (§6optional§r)", - "§ltype§r: Array", - "§ldefault§r: null", - "§lillustrate§r: Displays text when the mouse is over the widget." - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§lDemo§r: [\"THIS IS\",\"GT ICON\"]" - ] - }, - { - "type": "image", - "hover_text": ["THIS IS","GT ICON"], - "form": "resource", - "source": "gregtech:textures/gui/icon/gregtech_logo.png", - "width": 100, - "height": 100 - } - ], - "fixed": [] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/guide_widget_api/api_2_textbox.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/guide_widget_api/api_2_textbox.json deleted file mode 100644 index f67b885350a..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/guide_widget_api/api_2_textbox.json +++ /dev/null @@ -1,256 +0,0 @@ -{ - "section": "Guide Widget Api", - "title": "1. TextBox Widget", - "stream": [ - { - "type": "textbox", - "content": [ - "In this page we'll learn how to use the powerful §4§lTextBox§r, which is the most commonly used. So you should read the API documentation carefully.", - "-------------------------------", - "§lWidget Type§r: §ntextbox§r", - "-------------------------------", - "§lJSON§r:", - "{", - " \"type\": \"textbox\",", - " \"space\": 1,", - " \"fontSize\": 9,", - " \"fontColor\": 4278190080,", - " \"isCenter\": false,", - " \"isShadow\": false,", - " \"content\": [\"content here!\"]", - "}", - "-------------------------------", - "§lContents§r" - ] - }, - { - "type": "textbox", - "link": "content", - "content": [ - " 1.§ncontent§r" - ] - }, - { - "type": "textbox", - "link": "space", - "content": [ - " 2.§nspace§r" - ] - }, - { - "type": "textbox", - "link": "fontSize", - "content": [ - " 3.§nfontSize§r" - ] - }, - { - "type": "textbox", - "link": "fontColor", - "content": [ - " 4.§nfontColor§r" - ] - }, - { - "type": "textbox", - "link": "isCenter", - "content": [ - " 5.§nisCenter§r" - ] - }, - { - "type": "textbox", - "link": "isShadow", - "content": [ - " 6.§nisShadow§r" - ] - }, - { - "type": "textbox", - "ref": "content", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §ncontent§r (§4required§r)", - "§ltype§r: Array", - "§lillustrate§r: Text contents, each item will be a newline.Text that is too long will auto wrap itself. (Supporting Minecraft Formatting Code)" - ] - }, - { - "type": "textbox", - "isCenter": true, - "stroke": 4294901760, - "content": [ - "§lDemo§r: [...]", - "§nMinecraft Formatting", - "§r§00 §11 §22 §33", - "§44 §55 §66 §77", - "§88 §99 §aa §bb", - "§cc §dd §ee §ff", - "§r§0k §kMinecraft", - "§rl §lMinecraft", - "§rm §mMinecraft", - "§rn §nMinecraft", - "§ro §oMinecraft", - "§rr §rMinecraft" - ] - }, - { - "type": "textbox", - "ref": "space", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §nspace§r (§6optional§r)", - "§ltype§r: Number", - "§ldefault§r: 1", - "§lillustrate§r: The spacing between lines of text." - ] - }, - { - "type": "textbox", - "isCenter": true, - "stroke": 4294901760, - "space": 5, - "content": [ - "§lDemo§r: 5", - "§nMinecraft Formatting", - "§r§00 §11 §22 §33", - "§44 §55 §66 §77", - "§88 §99 §aa §bb", - "§cc §dd §ee §ff", - "§r§0k §kMinecraft", - "§rl §lMinecraft", - "§rm §mMinecraft", - "§rn §nMinecraft", - "§ro §oMinecraft", - "§rr §rMinecraft" - ] - },{ - "type": "textbox", - "ref": "fontSize", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §nfontSize§r (§6optional§r)", - "§ltype§r: Number", - "§ldefault§r: 9", - "§lillustrate§r: The font size. (Actually it's the height of the font)" - ] - }, - { - "type": "textbox", - "isCenter": true, - "stroke": 4294901760, - "fontSize": 5, - "content": [ - "§lDemo§r: 5", - "§nMinecraft Formatting", - "§r§00 §11 §22 §33", - "§44 §55 §66 §77", - "§88 §99 §aa §bb", - "§cc §dd §ee §ff", - "§r§0k §kMinecraft", - "§rl §lMinecraft", - "§rm §mMinecraft", - "§rn §nMinecraft", - "§ro §oMinecraft", - "§rr §rMinecraft" - ] - },{ - "type": "textbox", - "ref": "fontColor", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §nfontColor§r (§6optional§r)", - "§ltype§r: Number", - "§ldefault§r: 4278190080", - "§lillustrate§r: The default color of the content. You can also set the colors with special symbols (provided by Minecraft).But maybe you need it sometimes." - ] - }, - { - "type": "textbox", - "isCenter": true, - "stroke": 4294901760, - "fontColor": 5, - "content": [ - "§lDemo§r: 4294901760 (0xFFFF0000)", - "§nMinecraft Formatting", - "§r§00 §11 §22 §33", - "§44 §55 §66 §77", - "§88 §99 §aa §bb", - "§cc §dd §ee §ff", - "§r§0k §kMinecraft", - "§rl §lMinecraft", - "§rm §mMinecraft", - "§rn §nMinecraft", - "§ro §oMinecraft", - "§rr §rMinecraft" - ] - }, - { - "type": "textbox", - "ref": "isCenter", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §nisCenter§r (§6optional§r)", - "§ltype§r: Boolean", - "§ldefault§r: false", - "§lillustrate§r: Text-align center." - ] - }, - { - "type": "textbox", - "isCenter": false, - "stroke": 4294901760, - "content": [ - "§lDemo§r: false", - "§nMinecraft Formatting", - "§r§00 §11 §22 §33", - "§44 §55 §66 §77", - "§88 §99 §aa §bb", - "§cc §dd §ee §ff", - "§r§0k §kMinecraft", - "§rl §lMinecraft", - "§rm §mMinecraft", - "§rn §nMinecraft", - "§ro §oMinecraft", - "§rr §rMinecraft" - ] - },{ - "type": "textbox", - "ref": "isShadow", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §nisShadow§r (§6optional§r)", - "§ltype§r: Boolean", - "§ldefault§r: false", - "§lillustrate§r: Render shadow." - ] - }, - { - "type": "textbox", - "isCenter": true, - "stroke": 4294901760, - "isShadow": true, - "content": [ - "§lDemo§r: true", - "§nMinecraft Formatting", - "§r§00 §11 §22 §33", - "§44 §55 §66 §77", - "§88 §99 §aa §bb", - "§cc §dd §ee §ff", - "§r§0k §kMinecraft", - "§rl §lMinecraft", - "§rm §mMinecraft", - "§rn §nMinecraft", - "§ro §oMinecraft", - "§rr §rMinecraft" - ] - } - ], - "fixed": [] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/guide_widget_api/api_3_image.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/guide_widget_api/api_3_image.json deleted file mode 100644 index 39f6d14f5ad..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/guide_widget_api/api_3_image.json +++ /dev/null @@ -1,207 +0,0 @@ -{ - "section": "Guide Widget Api", - "title": "2. Image Widget", - "stream": [ - { - "type": "textbox", - "content": [ - "In this page we'll learn how to add an §4§lImage§r. There are three different forms of image supported here: §4Url§r, §4Item§r, and §4ResourceLocation§r. Don't worry, it's easy", - "-------------------------------", - "§lWidget Type§r: §nimage§r", - "-------------------------------", - "§lJSON§r:", - "{", - " \"type\": \"image\",", - " \"form\": \"Item\",", - " \"source\": \"minecraft:ender_pearl\",", - " \"width\": 100,", - " \"height\": 100", - "}", - "-------------------------------", - "§lContents§r" - ] - }, - { - "type": "textbox", - "link": "form", - "content": [ - " 1.§nform§r" - ] - }, - { - "type": "textbox", - "link": "source", - "content": [ - " 2.§nsource§r" - ] - }, - { - "type": "textbox", - "link": "wh", - "content": [ - " 3.§nwidth, height§r" - ] - }, - { - "type": "textbox", - "ref": "form", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §nform§r (§4required§r)", - "§ltype§r: String", - "§lillustrate§r: It can only be set one of §4Url§r, §4Item§r, or §4ResourceLocation§r.", - " \"url\" -- image url.", - " \"item\" -- The registered name of the Item in game.", - " \"resource\" -- The resource location." - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§lDemo§r: \"url\"" - ] - }, - { - "type": "image", - "hover_text": ["https://z3.ax1x.com/2021/07/29/Wb4Djs.gif"], - "form": "url", - "source": "https://z3.ax1x.com/2021/07/29/Wb4Djs.gif", - "stroke": 4278190080, - "stroke_width": 2, - "width": 100, - "height": 100 - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§lDemo§r: \"item\"" - ] - }, - { - "type": "image", - "hover_text": ["minecraft:ender_pearl"], - "form": "item", - "source": "minecraft:ender_pearl", - "width": 100, - "height": 100 - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§lDemo§r: \"resource\"" - ] - }, - { - "type": "image", - "hover_text": ["gregtech:textures/gui/icon/multiblock_category.png"], - "form": "resource", - "source": "gregtech:textures/gui/icon/multiblock_category.png", - "width": 100, - "height": 100 - }, - { - "type": "textbox", - "ref": "source", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §nsource§r (§4required§r)", - "§ltype§r: String", - "§lillustrate§r: The source of the picture. The three images above correspond to the following sources:" - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§lDemo§r: \"https://z3.ax1x.com/2021/07/29/Wb4Djs.gif\"" - ] - }, - { - "type": "image", - "hover_text": ["https://z3.ax1x.com/2021/07/29/Wb4Djs.gif"], - "form": "url", - "source": "https://z3.ax1x.com/2021/07/29/Wb4Djs.gif", - "stroke": 4278190080, - "stroke_width": 2, - "width": 100, - "height": 100 - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§lDemo§r: \"minecraft:ender_pearl\"" - ] - }, - { - "type": "image", - "hover_text": ["minecraft:ender_pearl"], - "form": "item", - "source": "minecraft:ender_pearl", - "width": 100, - "height": 100 - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§lDemo§r: \"gregtech:textures/gui/icon/multiblock_category.png\"" - ] - }, - { - "type": "image", - "hover_text": ["gregtech:textures/gui/icon/multiblock_category.png"], - "form": "resource", - "source": "gregtech:textures/gui/icon/multiblock_category.png", - "width": 100, - "height": 100 - }, - { - "type": "textbox", - "ref": "wh", - "content": [ - "-------------------------------", - "", - "§lAttr§r: §nwidth, height§r (§4required§r)", - "§ltype§r: Integer", - "§lillustrate§r: The Size of the picture." - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§lDemo§r: \"50, 50\"" - ] - }, - { - "type": "image", - "hover_text": ["minecraft:ender_pearl"], - "form": "item", - "source": "minecraft:ender_pearl", - "width": 50, - "height": 50 - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§lDemo§r: \"100, 50\"" - ] - }, - { - "type": "image", - "hover_text": ["minecraft:ender_pearl"], - "form": "item", - "source": "minecraft:ender_pearl", - "width": 100, - "height": 50 - } - ], - "fixed": [] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/important_concepts/machine_grid.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/important_concepts/machine_grid.json deleted file mode 100644 index 31aafa46b30..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/important_concepts/machine_grid.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "section": "Important Concepts", - "title": "Machine Grid", - "stream": [], - "fixed": [] -} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/multiblocks/forming_multiblocks.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/multiblocks/forming_multiblocks.json deleted file mode 100644 index e98245d48a4..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/multiblocks/forming_multiblocks.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "section": "Multiblocks", - "title": "Forming Multiblocks", - "stream": [ - { - "type": "textbox", - "content": [ - "§oThis is a Guide to help you form Multiblocks and troubleshoot issues.§r\n\nThere are two really important factors to know when building Multiblocks.\n\n§lCheck the JEI preview:§r This one was probably obvious, but there\u0027s more than just a picture of how the Multiblock looks like! Use your mouse to §drotate§r the preview, §9hover over the parts§r to gain additional informations. The JEI page also contains the amount of blocks to build it. You can also §dright-click§r a block in the preview to get a display of all available blocks in that placement.\n\n\n§lThe JEI preview is a suggestion:§r There is no unique way to form the Multiblock. Most of the time, you have complete freedom for the §9tier of Buses/Hatches§r. And you also have the §dfreedom of placement§r.\n\nTaking the EBF as example, any tier of Energy/Bus/Hatch can be used, and they can be placed anywhere replacing a casing. Fluid Hatches are also optional, though you probably want them to handle recipes with fluid.\n\nAdditionally, you can §dsneak right-click§r the multiblock controller for an §6in-world preview§r, or use the §4Terminal§r\u0027s Multiblock Helper." - ] - } - ], - "fixed": [] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/multiblocks/large_turbine_mechanics.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/multiblocks/large_turbine_mechanics.json deleted file mode 100644 index a96702086bc..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/multiblocks/large_turbine_mechanics.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "section": "Multiblocks", - "title": "Large Turbine Mechanics", - "stream": [ - { - "type": "textbox", - "content": [ - "§oThe Large Turbines are the most complex Multiblock Generators there exists in GTCEu in the present day.§r\n\nLet\u0027s start with the §4drawbacks§r of §3Large Turbines§r:\n§9-§r They work off §cInertia§r, which requires continuous running to achieve maximum Power.\n§9-§r Any excess unconsumed Energy produced will be §cvoided§r. So ideally you want to use large Energy buffers, and possibly control your Turbines with a redstone RS latch type of deal.\n§9-§r They require a §aRotor§r which loses durability over time and eventually §cbreak§r.\n§9-§r A little bit of Math is required to get the expected results.\n\n\nNow, with the §6upsides§r:\n§9-§r They can scale §9Power§r production substancially higher than the base output thanks to tiered §3Rotor Holders§r.\n§9-§r The §aRotor§r can give a huge boost to §dFuel efficiency§r, and §9Power§r production.\n§9-§r Self satisfaction for setting them up properly (yay!).\n\n\n§3Rotor Holders§r above the tier of the §3Large Turbine§r will §6double§r the production for every tier, multiplicatively.\n§3Rotor Holders§r above the tier of the §3Large Turbine§r will increase the efficiency by 10% for every tier, additively.\n\n§aRotors§r have a §9Power§r, §dEfficiency§r and §4Durability§r that are based on tool stats.\n§9Power§r multiplies the production of the §3Turbine§r. This stacks multiplicatively with the §3Rotor Holder§r.\n§dEfficiency§r reduces the fuel consumption. This stacks multiplicatively with the §3Rotor Holder§r.\n§4Durability§r is the lifetime of the §aRotor§r in seconds, when the §3Turbine§r is active.\n\n\n§2§lIn summary:§r\n\nThe §9Power§r output affects both the fuel consumption and the EU/t generation. It is calculated with the following formula:\n§cproduction \u003d baseEUt §l*§r rotorPower §l*§r 2^(rotorHolderTier - turbineTier)§r\n\nThe §dEfficiency§r reduces the fuel consumption, but does not alter the EU/t generation. It is calculated with the following formula:\n§cefficiency \u003d rotorEfficiency §l*§r (1 + 0.1 §l*§r (rotorHolderTier - turbineTier))§r\n\n\n§2§lSome examples:§r\n\nLarge Steam Turbine, with Ultimet Rotor and EV Rotor Holder:\nProduction \u003d 1024 §l*§r 1.60 §l*§r 2 \u003d 3276 EU/t\nEfficiency \u003d 1.30 §l*§r 1.10 \u003d 143%\n(Steam consumption \u003d 4582 L/t, this is above a Titanium Boiler, or a TungstenSteel Boiler with §m70% throttle)\n\nLarge Gas Turbine, with Chrome Rotor and EV Rotor Holder:\nProduction \u003d 4096 §l*§r 1.70 §l*§r 1 \u003d 5325 EU/t\nEfficiency \u003d 1.55 §l*§r 1.00 \u003d 155%\n(The same fuel consumption would produce 3435 EU/t using 6.7 Turbo Gas Turbines)\n\nLarge Plasma Turbine, with HSS-S Rotor and ZPM Rotor Holder:\nProduction \u003d 16834 §l*§r 2.50 §l*§r 4 \u003d 168340 EU/t\nEfficiency \u003d 1.80 §l*§r 1.20 \u003d 216%\n(This is more than a ZPM Amp!)" - ] - } - ], - "fixed": [] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/multiblocks/multibock_troubleshooting.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/multiblocks/multibock_troubleshooting.json deleted file mode 100644 index 096c157438a..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/multiblocks/multibock_troubleshooting.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "section": "Multiblocks", - "title": "Multiblock Troubleshooting", - "stream": [ - { - "type": "textbox", - "content": [ - "If a multiblock is formed, but you are having troubles figuring out why it does not run:\n§9-§r Check if the Multiblock is properly plugged in (we all make these mistakes!).\n\n§9-§r Do the initial Maintenance fix.\n\n§9-§r Verify the recipe usage, the max EU/t has to be greater than that of the recipe.\n\n§9- §rCheck the special requirements the recipe may have (JEI always has some kind of indication for it).\n\n§9-§r Make sure the recipe is properly input, this is less obvious than in a regular machine because you have to juggle between Input Bus and Input Hatch.\n\n§9-§r Make sure there is space for output. Maybe the multiblock formed but you forgot a Hatch. The other biggest offender is the Output Hatches being too low tier and having too little capacity!" - ] - } - ], - "fixed": [] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/resource_pack/emissive_texture.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/resource_pack/emissive_texture.json deleted file mode 100644 index 752ae4248f0..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/resource_pack/emissive_texture.json +++ /dev/null @@ -1,135 +0,0 @@ -{ - "section": "Resource Pack", - "title": "Custom Emissive Texture", - "stream": [ - { - "type": "textbox", - "content": [ - "Developers and resource pack authors can easily have emissive textures and set the bloom effect.\n\n§lContents:" - ] - }, - { - "type": "textbox", - "link": "emissive", - "content": [ - "1. §1Emissive Texture" - ] - }, - { - "type": "textbox", - "link": "bloom", - "content": [ - "2.§1 Bloom" - ] - }, - { - "type": "textbox", - "link": "demo", - "content": [ - "3. §1Demo" - ] - }, - { - "type": "textbox", - "ref": "emissive", - "content": [ - "§lEmissive Texture" - ] - }, - { - "type": "textbox", - "content": [ - "* For model-based blocks: Similar to §4CTM§r, you only need to set mcmeta file for the texture that you want to have the emissive effect." - ] - }, - { - "type": "card", - "fill": -3745585, - "width": 190, - "height": 100, - "isShadow": true - }, - { - "type": "textbox", - "content": [ - "§2light §rhere represents the default level of light it emit (from 0~15). Besides, you can also set sky and block separately as what CTM does." - ] - }, - { - "type": "textbox", - "content": [ - "* For CEu machines: They mostly are overlay textures under the assets/textures/blocks/machines and assets/textures/overlay/machines. You no need to set the mcmeta file for them. Just add a new texture file for the emissive part named \"XXX_emissive.png\"." - ] - }, - { - "type": "textbox", - "content": [ - "§lBloom" - ], - "ref": "bloom" - }, - { - "type": "textbox", - "content": [ - "* For CEu machines: You don\u0027t need to modify anything; all emissive textures have the bloom effect by default.\n\n* For model-based blocks: You just need to add an extra line to the mcmeta file. (§2\"layer\"§r: \"BLOOM\")" - ] - }, - { - "type": "card", - "fill": -3745585, - "width": 190, - "height": 110, - "isShadow": true - }, - { - "type": "textbox", - "ref": "demo", - "content": [ - "§lDemo" - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/138578815-d2d4e357-8080-4d57-b8ac-61235eac8c2a.png", - "width": 190, - "height": 130 - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/138578838-b9e6a16d-e348-4fea-8ab4-8a940e1ecd0f.png", - "width": 190, - "height": 100 - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/138578853-9a2497f4-e1f5-45e9-ab64-26b5eb859139.png", - "width": 190, - "height": 110 - } - ], - "fixed": [ - { - "type": "textbox", - "x": 8, - "y": 206, - "width": 181, - "height": 90, - "content": [ - "{\n §2\"ctm\"§r: {\n §2\"ctm_version\"§r: 1,\n §2\"gregtech:§r true,\n §2\"extra\"§r: {\n §2\"light\"§r: 15\n }\n }\n}" - ] - }, - { - "type": "textbox", - "x": 8, - "y": 550, - "width": 181, - "height": 100, - "content": [ - "{\n §2\"ctm\"§r: {\n §2\"ctm_version\"§r: 1,\n §2\"layer\"§r: \"BLOOM\",\n §2\"gregtech\"§r true,\n §2\"extra\"§r: {\n §2\"light\"§r: 15\n }\n }\n}" - ] - } - ] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/terminal/terminal_hardware.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/terminal/terminal_hardware.json deleted file mode 100644 index 3a9c51f4a73..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/en_us/terminal/terminal_hardware.json +++ /dev/null @@ -1,223 +0,0 @@ -{ - "section": "Terminal", - "title": "Hardware", - "stream": [ - { - "type": "textbox", - "content": [ - "Current supported §4§lhardware§r:" - ] - }, - { - "type": "textbox", - "link": "battery", - "content": [ - " 1.§nBattery" - ] - }, - { - "type": "textbox", - "link": "device", - "content": [ - " 2.§nDevice" - ] - }, - { - "type": "textbox", - "isCenter": true, - "isShadow": false, - "content": [ - "§lBattery" - ], - "ref": "battery" - }, - { - "type": "card", - "fill": -2172721, - "width": 170, - "height": 90, - "isShadow": true - }, - { - "type": "textbox", - "ref": "device", - "isCenter": true, - "content": [ - "\n\n§lDevice" - ] - }, - { - "type": "card", - "fill": -2172721, - "width": 170, - "height": 133, - "isShadow": true - } - ], - "fixed": [ - { - "type": "textbox", - "x": 18, - "y": 92, - "width": 160, - "height": 30, - "content": [ - "All §4§lresuable§r batteries can be used as the §lBattery Hardware" - ] - }, - { - "type": "textbox", - "x": 53, - "y": 229, - "width": 102, - "height": 10, - "content": [ - "Wireless transmitter" - ] - }, - { - "type": "slots", - "x": 47, - "y": 136, - "width": 100, - "height": 18, - "item_list": [ - { - "id": "gregtech:meta_item_1", - "damage": 732, - "count": 1 - }, - { - "id": "gregtech:meta_item_1", - "damage": 733, - "count": 1 - }, - { - "id": "gregtech:meta_item_1", - "damage": 742, - "count": 1 - }, - { - "id": "gregtech:meta_item_1", - "damage": 748, - "count": 1 - }, - { - "id": "gregtech:meta_item_1", - "damage": 753, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": -16, - "y": 224, - "width": 100, - "height": 18, - "item_list": [ - { - "id": "gregtech:meta_item_1", - "damage": 503, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": -16, - "y": 250, - "width": 100, - "height": 18, - "item_list": [ - { - "id": "gregtech:meta_item_1", - "damage": 466, - "count": 1 - } - ] - }, - { - "type": "textbox", - "x": 52, - "y": 253, - "width": 100, - "height": 10, - "content": [ - "Prospector" - ] - }, - { - "type": "textbox", - "x": 52, - "y": 279, - "width": 100, - "height": 10, - "content": [ - "Solar" - ] - }, - { - "type": "slots", - "x": 10, - "y": 325, - "width": 48, - "height": 18, - "item_list": [ - { - "id": "gregtech:meta_item_1", - "damage": 467, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": 12, - "y": 275, - "width": 45, - "height": 18, - "item_list": [ - { - "id": "gregtech:meta_item_1", - "damage": 333, - "count": 1 - } - ] - }, - { - "type": "slots", - "x": 22, - "y": 302, - "width": 25, - "height": 18, - "item_list": [ - { - "id": "gregtech:meta_item_1", - "damage": 504, - "count": 1 - } - ] - }, - { - "type": "textbox", - "x": 52, - "y": 306, - "width": 100, - "height": 10, - "content": [ - "Camera" - ] - }, - { - "type": "textbox", - "x": 51, - "y": 325, - "width": 100, - "height": 20, - "content": [ - "Advanced Prospector" - ] - } - ] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/crafttweaker/terminal/ct_terminal_01.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/crafttweaker/terminal/ct_terminal_01.json deleted file mode 100644 index d787b384e06..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/crafttweaker/terminal/ct_terminal_01.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "section": "CraftTweaker/终端", - "title": "终端的CT教程", - "stream": [ - { - "type": "textbox", - "content": [ - "目录:" - ] - }, - { - "type": "textbox", - "content": [ - "§1§lURL:§r§n https://github.com/Gregicality/GregTech/wiki/CraftTweaker-of-Terminal" - ] - }, - { - "type": "textbox", - "ref": "api", - "isShadow": false, - "content": [ - "§4§lAPI:" - ] - }, - { - "type": "textbox", - "fontSize": 9, - "content": [ - "1. §1registerDevice(deviceItemStack, deviceName)§0:\n注册自定义设备。\n\n2. §1createAppRegistryBuilder(appName):\n§0根据应用名称(可从商店获取)获得构造器。\n\n3. §1isDefaultApp(default):\n§0设置为默认应用。\n\n4. §1battery(euTier, cost):\n§0为所有层级设置相同的电池要求。\n\n5. §1battery(appTier, euTier, cost):\n§0为特定等级设置电池要求。\n\n6. §1device(deviceName...):\n§0为所有等级设置设备要求。 (默认可用设备: \"scanner\", \"wireless\", \"camera\", \"solar_lv\").\n\n7. §1device(appTier, device...):\n§0为特定等级设置设备要求。\n\n8. §1upgrade(upgradeItemStack...):\n§0设置所有等级的升级要求。\n\n9. §1upgrade(appTier, upgradeItemStack...):\n§0设置特定等级的升级和要求。\n\n10. §1build():\n§0完成并注册。" - ] - }, - { - "type": "textbox", - "ref": "demo", - "space": 1, - "content": [ - "\n§4§lZS Demo:" - ] - }, - { - "type": "textbox", - "fill": -912478525, - "fontSize": 9, - "content": [ - "import mods.gregtech.TerminalRegistry;\n\nTerminalRegistry.registerDevice(\u003core:ingotIron\u003e.firstItem, \"ingot_iron\");\n\nTerminalRegistry.createAppRegistryBuilder(\"ore_prospector\")\n .isDefaultApp(true)\n .battery(1, 500)\n .battery(3, 3, 1000)\n .device(\"camera\", \"wireless\")\n .device(4, \"ingot_iron\")\n .upgrade(\u003cminecraft:apple\u003e * 9)\n .upgrade(2, \u003cminecraft:apple\u003e * 9, \u003cminecraft:grass\u003e * 12)\n .build();" - ] - }, - { - "type": "textbox", - "fontSize": 9, - "content": [ - "§4§l结果:\n§r自定义设备" - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/140280593-37922838-4a20-4e1b-9be9-73935c4c8c13.png", - "width": 190, - "height": 120 - }, - { - "type": "textbox", - "content": [ - "注册电池、设备、升级" - ] - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/140280587-84dc8f67-6dde-472f-9ed8-6a4c5e71abc4.png", - "width": 190, - "height": 120 - }, - { - "type": "image", - "form": "url", - "source": "https://user-images.githubusercontent.com/18493855/140280590-d4700a88-5780-4e0f-95f8-130e82f4634a.png", - "width": 190, - "height": 120 - } - ], - "fixed": [ - { - "type": "textbox", - "x": 27, - "y": 24, - "width": 16, - "height": 10, - "link": "api", - "content": [ - "§9§napi" - ] - }, - { - "type": "textbox", - "x": 41, - "y": 24, - "width": 25, - "height": 10, - "link": "demo", - "content": [ - "§9§ndemo" - ] - } - ] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/guide_widget_api/api_0_guidepage.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/guide_widget_api/api_0_guidepage.json deleted file mode 100644 index c501c92ca8c..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/guide_widget_api/api_0_guidepage.json +++ /dev/null @@ -1,148 +0,0 @@ -{ - "section": "指南页控件API", - "title": "指南页", - "stream": [ - { - "type": "textbox", - "content": [ - "这一页我们将学习如何编写指南页。", - "-------------------------------", - "先看一看一个简单里指南页示例。", - "§lJSON§r:", - "{", - " \"section\": \"section name here\",", - " \"title\": \"title here\",", - " \"stream\": [", - " {", - " \"type\": \"textbox\",", - " \"content\": [\"TextBox widget\"]", - " }", - " ],", - " \"fixed\": [", - " {", - " \"x\": 50,", - " \"y\": 100,", - " \"width\": 150,", - " \"height\": 40,", - " \"type\": 0,", - " \"content\": [\"TextBox widget\"]", - " }", - " ]", - "}", - "-------------------------------", - "§l目录§r" - ] - }, - { - "type": "textbox", - "link": "section", - "content": [ - " 1.§nsection§r" - ] - }, - { - "type": "textbox", - "link": "title", - "content": [ - " 2.§ntitle§r" - ] - }, - { - "type": "textbox", - "link": "stream", - "content": [ - " 3.§nstream§r" - ] - }, - { - "type": "textbox", - "link": "fixed", - "content": [ - " 4.§nfixed§r" - ] - }, - { - "type": "textbox", - "ref": "section", - "content": [ - "-------------------------------", - "", - "§l属性§r: §nsection§r (§4必须§r)", - "§l类型§r: String", - "§l说明§r: 指定页面属于哪个章节。", - "指南App会自动合并具有相同节名的页面并构建目录树。" - ] - }, - { - "type": "textbox", - "ref": "title", - "content": [ - "-------------------------------", - "", - "§l属性§r: §ntitle§r (§4必须§r)", - "§l类型§r: String", - "§l说明§r: 页标题。" - ] - }, - { - "type": "textbox", - "ref": "stream", - "content": [ - "-------------------------------", - "", - "§l属性§r: §nstream§r (§4必须§r)", - "§l类型§r: Array", - "§l说明§r: 属于流布局的控件。 你不需要关心控件在流中的位置和大小,所有的排版都会自动完成。" - ] - }, - { - "type": "textbox", - "ref": "fixed", - "content": [ - "-------------------------------", - "", - "§l属性§r: §nfixed§r (§4必须§r)", - "§l类型§r: Array", - "§l说明§r: 属于固定布局的控件。 您需要指定每个控件的位置和大小。" - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§l示例§r: 固定布局和流布局" - ] - }, - { - "type": "textbox", - "isCenter": true, - "hover_text": ["流布局"], - "content": [ - "§nMinecraft Formatting", - "§r§00 §11 §22 §33", - "§44 §55 §66 §77", - "§88 §99 §aa §bb", - "§cc §dd §ee §ff", - "§r§0k §kMinecraft", - "§rl §lMinecraft", - "§rm §mMinecraft", - "§rn §nMinecraft", - "§ro §oMinecraft", - "§rr §rMinecraft" - ] - } - ], - "fixed": [ - { - "type": "image", - "x": 30, - "y": 800, - "stroke": 4278190335, - "hover_text": ["固定布局", "\"x\": 30","\"y\": 800","\"width\": 100","\"width\": 100"], - "form": "item", - "source": "minecraft:ender_pearl", - "width": 100, - "height": 100 - } - ] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/guide_widget_api/api_1_widget.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/guide_widget_api/api_1_widget.json deleted file mode 100644 index a1575f6685e..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/guide_widget_api/api_1_widget.json +++ /dev/null @@ -1,304 +0,0 @@ -{ - "section": "指南页控件API", - "title": "控件", - "stream": [ - { - "type": "textbox", - "content": [ - "这里我们将学习什么是 §4§l控件§r, 以及它的公共属性。", - "控件被渲染在指南页中,是一切的基础。 §n文本控件§r, §n图片控件§r, 等等", - "要使用控件,只需要将对应的控件配置写在 §l\"fixed\"§r 或者 §l\"stream\"§r下即可。", - "有一些公共属性、效果(样式)对所有控件都有效。", - "-------------------------------", - "§lJSON§r:", - "{", - " \"type\": \"type here\",", - " \"x\": 50,", - " \"y\": 100,", - " \"width\": 150,", - " \"height\": 40,", - " \"ref\": \"ref\",", - " \"stroke\": 0,", - " \"stroke_width\": 1,", - " \"fill\": 0,", - " \"link\": \"ref\"", - " \"hover_text\": [\"text here\"]", - "}", - "-------------------------------", - "§l目录§r" - ] - }, - { - "type": "textbox", - "link": "type", - "content": [ - " 1.§ntype§r" - ] - }, - { - "type": "textbox", - "link": "xywh", - "content": [ - " 2.§nx, y, width, height§r" - ] - }, - { - "type": "textbox", - "link": "ref", - "content": [ - " 3.§nref§r" - ] - }, - { - "type": "textbox", - "link": "fill", - "content": [ - " 4.§nfill§r" - ] - }, - { - "type": "textbox", - "link": "stroke", - "content": [ - " 5.§nstroke§r" - ] - }, - { - "type": "textbox", - "link": "stroke_width", - "content": [ - " 6.§nstroke_width§r" - ] - }, - { - "type": "textbox", - "link": "link", - "content": [ - " 7.§nlink§r" - ] - }, - { - "type": "textbox", - "link": "hover", - "content": [ - " 8.§nhover_text§r" - ] - }, - { - "type": "textbox", - "ref": "type", - "content": [ - "-------------------------------", - "", - "§l属性§r: §ntype§r (§4必须§r)", - "§l类型§r: String", - "§l说明§r: 控件类型的唯一标识。通过api文档可以查看控件对应的控件类型标识。" - ] - }, - { - "type": "textbox", - "ref": "xywh", - "content": [ - "-------------------------------", - "", - "§l属性§r: §nx, y, width, height§r (§4可选§r)", - "§l类型§r: Integer", - "§l说明§r: 控件的位置和大小。 在流布局中,通常不需要设置它(图片控件需要设置宽度和高度)。 在固定布局下,你必须设置这四个属性。" - ] - }, - { - "type": "textbox", - "ref": "ref", - "content": [ - "-------------------------------", - "", - "§l属性§r: §nref§r (§4可选§r)", - "§l类型§r: String", - "§l缺省值§r: null", - "§l说明§r: 这是这个控件的一个引用标记。 同一页中的引用标记应该是唯一的。" - ] - }, - { - "type": "textbox", - "ref": "fill", - "content": [ - "-------------------------------", - "", - "§l属性§r: §nfill§r (§6可选§r)", - "§l类型§r: Number", - "§l缺省值§r: 0", - "§l说明§r: 背景颜色。" - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§l示例§r: 4278190335 (0xFF0000FF)" - ] - }, - { - "type": "textbox", - "isCenter": true, - "fill": 4278190335, - "content": [ - "§nMinecraft Formatting", - "§r§00 §11 §22 §33", - "§44 §55 §66 §77", - "§88 §99 §aa §bb", - "§cc §dd §ee §ff", - "§r§0k §kMinecraft", - "§rl §lMinecraft", - "§rm §mMinecraft", - "§rn §nMinecraft", - "§ro §oMinecraft", - "§rr §rMinecraft" - ] - }, - { - "type": "textbox", - "ref": "stroke", - "content": [ - "-------------------------------", - "", - "§l属性§r: §nstroke§r (§6可选§r)", - "§l类型§r: Number", - "§l缺省值§r: 0", - "§l说明§r: 边框颜色" - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§l示例§r: 4278190335 (0xFF0000FF)" - ] - }, - { - "type": "image", - "form": "item", - "source": "minecraft:ender_pearl", - "stroke": 4278190335, - "width": 50, - "height": 50 - }, - { - "type": "textbox", - "ref": "stroke_width", - "content": [ - "-------------------------------", - "", - "§l属性§r: §nstroke_width§r (§6可选§r)", - "§l类型§r: Number", - "§l缺省值§r: 1", - "§l说明§r: 边框宽度。" - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§l示例§r: 5" - ] - }, - { - "type": "image", - "form": "item", - "source": "minecraft:ender_pearl", - "stroke": 4278190335, - "stroke_width": 5, - "width": 50, - "height": 50 - }, - { - "type": "textbox", - "ref": "link", - "content": [ - "-------------------------------", - "", - "§l属性§r: §nlink§r (§6可选§r)", - "§l类型§r: String", - "§l缺省值§r: null", - "§l说明§r: 单击可跳转到指定引用的位置。需要与引用标记一起使用,目标是ref。" - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§l示例§r: \"P2\"" - ] - }, - { - "type": "textbox", - "isCenter": true, - "fill": 4286430975, - "hover_text": ["\"ref\": \"P1\""], - "ref": "P1", - "link": "P2", - "content": ["点我!"] - }, - { - "type": "textbox", - "content": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§l示例§r: \"P1\"" - ] - }, - { - "type": "textbox", - "isCenter": true, - "fill": 4286430975, - "hover_text": ["\"ref\": \"P2\""], - "ref": "P2", - "link": "P1", - "content": ["点我!"] - }, - { - "type": "textbox", - "ref": "hover", - "content": [ - "-------------------------------", - "", - "§l属性§r: §nhover_text§r (§6可选§r)", - "§l类型§r: Array", - "§l缺省值§r: null", - "§l说明§r: 鼠标悬停时的展示文本。" - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§l示例§r: [\"这是\",\"GT图标\"]" - ] - }, - { - "type": "image", - "hover_text": ["这是","GT图标"], - "form": "resource", - "source": "gregtech:textures/gui/icon/gregtech_logo.png", - "width": 100, - "height": 100 - } - ], - "fixed": [] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/guide_widget_api/api_2_textbox.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/guide_widget_api/api_2_textbox.json deleted file mode 100644 index 83c645bd0c2..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/guide_widget_api/api_2_textbox.json +++ /dev/null @@ -1,256 +0,0 @@ -{ - "section": "指南页控件API", - "title": "1. 文本控件", - "stream": [ - { - "type": "textbox", - "content": [ - "我们将学习指南中最常用的控件 §4§l文本控件§r。 因此,您应该仔细阅读API文档。", - "-------------------------------", - "§l控件类型标识§r: §ntextbox§r", - "-------------------------------", - "§lJSON§r:", - "{", - " \"type\": \"textbox\",", - " \"space\": 1,", - " \"fontSize\": 9,", - " \"fontColor\": 4278190080,", - " \"isCenter\": false,", - " \"isShadow\": false,", - " \"content\": [\"content here!\"]", - "}", - "-------------------------------", - "§l目录§r" - ] - }, - { - "type": "textbox", - "link": "content", - "content": [ - " 1.§ncontent§r" - ] - }, - { - "type": "textbox", - "link": "space", - "content": [ - " 2.§nspace§r" - ] - }, - { - "type": "textbox", - "link": "fontSize", - "content": [ - " 3.§nfontSize§r" - ] - }, - { - "type": "textbox", - "link": "fontColor", - "content": [ - " 4.§nfontColor§r" - ] - }, - { - "type": "textbox", - "link": "isCenter", - "content": [ - " 5.§nisCenter§r" - ] - }, - { - "type": "textbox", - "link": "isShadow", - "content": [ - " 6.§nisShadow§r" - ] - }, - { - "type": "textbox", - "ref": "content", - "content": [ - "-------------------------------", - "", - "§l属性§r: §ncontent§r (§4必须§r)", - "§l类型§r: Array", - "§l说明§r: 文本内容数组,每一项都会换行。 文本太长会自动换行。 (支持Minecraft格式代码) " - ] - }, - { - "type": "textbox", - "isCenter": true, - "stroke": 4294901760, - "content": [ - "§l示例§r: [...]", - "§nMinecraft Formatting", - "§r§00 §11 §22 §33", - "§44 §55 §66 §77", - "§88 §99 §aa §bb", - "§cc §dd §ee §ff", - "§r§0k §kMinecraft", - "§rl §lMinecraft", - "§rm §mMinecraft", - "§rn §nMinecraft", - "§ro §oMinecraft", - "§rr §rMinecraft" - ] - }, - { - "type": "textbox", - "ref": "space", - "content": [ - "-------------------------------", - "", - "§l属性§r: §nspace§r (§6可选§r)", - "§l类型§r: Number", - "§l缺省值§r: 1", - "§l说明§r: 文本行之间的间隔。" - ] - }, - { - "type": "textbox", - "isCenter": true, - "stroke": 4294901760, - "space": 5, - "content": [ - "§l示例§r: 5", - "§nMinecraft Formatting", - "§r§00 §11 §22 §33", - "§44 §55 §66 §77", - "§88 §99 §aa §bb", - "§cc §dd §ee §ff", - "§r§0k §kMinecraft", - "§rl §lMinecraft", - "§rm §mMinecraft", - "§rn §nMinecraft", - "§ro §oMinecraft", - "§rr §rMinecraft" - ] - },{ - "type": "textbox", - "ref": "fontSize", - "content": [ - "-------------------------------", - "", - "§l属性§r: §nfontSize§r (§6可选§r)", - "§l类型§r: Number", - "§l缺省值§r: 9", - "§l说明§r: 字体大小。(实际上是字体的高度)" - ] - }, - { - "type": "textbox", - "isCenter": true, - "stroke": 4294901760, - "fontSize": 5, - "content": [ - "§l示例§r: 5", - "§nMinecraft Formatting", - "§r§00 §11 §22 §33", - "§44 §55 §66 §77", - "§88 §99 §aa §bb", - "§cc §dd §ee §ff", - "§r§0k §kMinecraft", - "§rl §lMinecraft", - "§rm §mMinecraft", - "§rn §nMinecraft", - "§ro §oMinecraft", - "§rr §rMinecraft" - ] - },{ - "type": "textbox", - "ref": "fontColor", - "content": [ - "-------------------------------", - "", - "§l属性§r: §nfontColor§r (§6可选§r)", - "§l类型§r: Number", - "§l缺省值§r: 4278190080", - "§l说明§r: 文本的默认颜色。你也可以用特殊的符号设置颜色(Minecraft提供的)。但也许有时候你需要它。" - ] - }, - { - "type": "textbox", - "isCenter": true, - "stroke": 4294901760, - "fontColor": 5, - "content": [ - "§l示例§r: 4294901760 (0xFFFF0000)", - "§nMinecraft Formatting", - "§r§00 §11 §22 §33", - "§44 §55 §66 §77", - "§88 §99 §aa §bb", - "§cc §dd §ee §ff", - "§r§0k §kMinecraft", - "§rl §lMinecraft", - "§rm §mMinecraft", - "§rn §nMinecraft", - "§ro §oMinecraft", - "§rr §rMinecraft" - ] - }, - { - "type": "textbox", - "ref": "isCenter", - "content": [ - "-------------------------------", - "", - "§l属性§r: §nisCenter§r (§6可选§r)", - "§l类型§r: Boolean", - "§l缺省值§r: false", - "§l说明§r: 文本水平居中。" - ] - }, - { - "type": "textbox", - "isCenter": false, - "stroke": 4294901760, - "content": [ - "§l示例§r: false", - "§nMinecraft Formatting", - "§r§00 §11 §22 §33", - "§44 §55 §66 §77", - "§88 §99 §aa §bb", - "§cc §dd §ee §ff", - "§r§0k §kMinecraft", - "§rl §lMinecraft", - "§rm §mMinecraft", - "§rn §nMinecraft", - "§ro §oMinecraft", - "§rr §rMinecraft" - ] - },{ - "type": "textbox", - "ref": "isShadow", - "content": [ - "-------------------------------", - "", - "§l属性§r: §nisShadow§r (§6可选§r)", - "§l类型§r: Boolean", - "§l缺省值§r: false", - "§l说明§r: 渲染文本阴影。" - ] - }, - { - "type": "textbox", - "isCenter": true, - "stroke": 4294901760, - "isShadow": true, - "content": [ - "§l示例§r: true", - "§nMinecraft Formatting", - "§r§00 §11 §22 §33", - "§44 §55 §66 §77", - "§88 §99 §aa §bb", - "§cc §dd §ee §ff", - "§r§0k §kMinecraft", - "§rl §lMinecraft", - "§rm §mMinecraft", - "§rn §nMinecraft", - "§ro §oMinecraft", - "§rr §rMinecraft" - ] - } - ], - "fixed": [] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/guide_widget_api/api_3_image.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/guide_widget_api/api_3_image.json deleted file mode 100644 index 9098438adb2..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/guide_widget_api/api_3_image.json +++ /dev/null @@ -1,207 +0,0 @@ -{ - "section": "指南页控件API", - "title": "2. 图片控件", - "stream": [ - { - "type": "textbox", - "content": [ - "我们将学习实用的§4§l图片控件§r。这里支持三种不同形式的图像:§4Url§r, §4Item§r, and §4ResourceLocation§r。别担心,一切都很容易。", - "-------------------------------", - "§l控件类型标识§r: §nimage§r", - "-------------------------------", - "§lJSON§r:", - "{", - " \"type\": \"image\",", - " \"form\": \"Item\",", - " \"source\": \"minecraft:ender_pearl\",", - " \"width\": 100,", - " \"height\": 100", - "}", - "-------------------------------", - "§l目录§r" - ] - }, - { - "type": "textbox", - "link": "form", - "content": [ - " 1.§nform§r" - ] - }, - { - "type": "textbox", - "link": "source", - "content": [ - " 2.§nsource§r" - ] - }, - { - "type": "textbox", - "link": "wh", - "content": [ - " 3.§nwidth, height§r" - ] - }, - { - "type": "textbox", - "ref": "form", - "content": [ - "-------------------------------", - "", - "§l属性§r: §nform§r (§4必须§r)", - "§l类型§r: String", - "§l说明§r: 它只能是 §4Url§r, §4Item§r, 或 §4ResourceLocation§r中的一个。", - " \"url\" -- image url.", - " \"item\" -- The registered name of the Item in game.", - " \"resource\" -- The resource location." - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§l示例§r: \"url\"" - ] - }, - { - "type": "image", - "hover_text": ["https://z3.ax1x.com/2021/07/29/Wb4Djs.gif"], - "form": "url", - "source": "https://z3.ax1x.com/2021/07/29/Wb4Djs.gif", - "stroke": 4278190080, - "stroke_width": 2, - "width": 100, - "height": 100 - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§l示例§r: \"item\"" - ] - }, - { - "type": "image", - "hover_text": ["minecraft:ender_pearl"], - "form": "item", - "source": "minecraft:ender_pearl", - "width": 100, - "height": 100 - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§l示例§r: \"resource\"" - ] - }, - { - "type": "image", - "hover_text": ["gregtech:textures/gui/icon/coke_oven.png"], - "form": "resource", - "source": "gregtech:textures/gui/icon/coke_oven.png", - "width": 100, - "height": 100 - }, - { - "type": "textbox", - "ref": "source", - "content": [ - "-------------------------------", - "", - "§l属性§r: §nsource§r (§4必须§r)", - "§l类型§r: String", - "§l说明§r: The source of the picture. The three images above correspond to the following sources:" - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§l示例§r: \"https://z3.ax1x.com/2021/07/29/Wb4Djs.gif\"" - ] - }, - { - "type": "image", - "hover_text": ["https://z3.ax1x.com/2021/07/29/Wb4Djs.gif"], - "form": "url", - "source": "https://z3.ax1x.com/2021/07/29/Wb4Djs.gif", - "stroke": 4278190080, - "stroke_width": 2, - "width": 100, - "height": 100 - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§l示例§r: \"minecraft:ender_pearl\"" - ] - }, - { - "type": "image", - "hover_text": ["minecraft:ender_pearl"], - "form": "item", - "source": "minecraft:ender_pearl", - "width": 100, - "height": 100 - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§l示例§r: \"gregtech:textures/gui/icon/coke_oven.png\"" - ] - }, - { - "type": "image", - "hover_text": ["gregtech:textures/gui/icon/coke_oven.png"], - "form": "resource", - "source": "gregtech:textures/gui/icon/coke_oven.png", - "width": 100, - "height": 100 - }, - { - "type": "textbox", - "ref": "wh", - "content": [ - "-------------------------------", - "", - "§l属性§r: §nwidth, height§r (§4必须§r)", - "§l类型§r: Integer", - "§l说明§r: 图片尺寸。" - ] - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§l示例§r: \"50, 50\"" - ] - }, - { - "type": "image", - "hover_text": ["minecraft:ender_pearl"], - "form": "item", - "source": "minecraft:ender_pearl", - "width": 50, - "height": 50 - }, - { - "type": "textbox", - "isCenter": true, - "content": [ - "§l示例§r: \"100, 50\"" - ] - }, - { - "type": "image", - "hover_text": ["minecraft:ender_pearl"], - "form": "item", - "source": "minecraft:ender_pearl", - "width": 100, - "height": 50 - } - ], - "fixed": [] -} diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/resource_pack/emissive_texture.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/resource_pack/emissive_texture.json deleted file mode 100644 index dfef1a0bd48..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/resource_pack/emissive_texture.json +++ /dev/null @@ -1 +0,0 @@ -{"section":"资源包","title":"自定义发光材质","stream":[{"type":"textbox","content":["开发人员和资源包作者可以很容易地有发光材质和设置泛光效果。\n\n§l目录:"]},{"type":"textbox","link":"emissive","content":["1. §1发光材质"]},{"type":"textbox","link":"bloom","content":["2.§1 泛光"]},{"type":"textbox","link":"demo","content":["3. §1示例"]},{"type":"textbox","ref":"emissive","content":["§l发光材质"]},{"type":"textbox","content":["* 对于常规模型: 与§4CTM§r相似,你只需要为你想要有发射效果的材质配置mcmeta文件即可。"]},{"type":"card","fill":-3745585,"width":190,"height":100,"isShadow":true},{"type":"textbox","content":["这里的§2light §r表示它发出的默认光级别(从0~15)。另外,你也可以像CTM一样把sky和block分开设置。"]},{"type":"textbox","content":["* 对于CEu机器: 他们材质大多数在 assets/textures/blocks/machines 和 assets/textures/overlay/machines下。 你不需要为他们设置mcmeta文件。只需为发光部分添加一个名为 \"XXX_emissive.png\"的材质即可。"]},{"type":"textbox","content":["§l泛光"],"ref":"bloom"},{"type":"textbox","content":["* 对于CEu机器: 你不需要修改任何东西,所有发光的材质都自带泛光。\n\n* 对于基本模型: 你只需要在mcmeta文件中添加额外的一行。 (§2\"layer\"§r: \"BLOOM\")"]},{"type":"card","fill":-3745585,"width":190,"height":110,"isShadow":true},{"type":"textbox","ref":"demo","content":["§l示例"]},{"type":"image","form":"url","source":"https://user-images.githubusercontent.com/18493855/138578815-d2d4e357-8080-4d57-b8ac-61235eac8c2a.png","width":190,"height":130},{"type":"image","form":"url","source":"https://user-images.githubusercontent.com/18493855/138578838-b9e6a16d-e348-4fea-8ab4-8a940e1ecd0f.png","width":190,"height":100},{"type":"image","form":"url","source":"https://user-images.githubusercontent.com/18493855/138578853-9a2497f4-e1f5-45e9-ab64-26b5eb859139.png","width":190,"height":110}],"fixed":[{"type":"textbox","x":8,"y":171,"width":181,"height":90,"content":["{\n §2\"ctm\"§r: {\n §2\"ctm_version\"§r: 1,\n §2\"gregtech:§r true,\n §2\"extra\"§r: {\n §2\"light\"§r: 15\n }\n }\n}"]},{"type":"textbox","x":7,"y":466,"width":181,"height":100,"content":["{\n §2\"ctm\"§r: {\n §2\"ctm_version\"§r: 1,\n §2\"layer\"§r: \"BLOOM\",\n §2\"gregtech\"§r true,\n §2\"extra\"§r: {\n §2\"light\"§r: 15\n }\n }\n}"]}]} diff --git a/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/terminal/terminal_hardware.json b/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/terminal/terminal_hardware.json deleted file mode 100644 index ebfa5647886..00000000000 --- a/src/main/resources/assets/gregtech/terminal/guide/tutorials/zh_cn/terminal/terminal_hardware.json +++ /dev/null @@ -1 +0,0 @@ -{"section":"终端","title":"Hardware","stream":[{"type":"textbox","content":["Current supported §4§lhardware§r:"]},{"type":"textbox","link":"battery","content":[" 1.§nBattery"]},{"type":"textbox","link":"device","content":[" 2.§nDevice"]},{"type":"textbox","isCenter":true,"isShadow":false,"content":["§lBattery"],"ref":"battery"},{"type":"card","fill":-2172721,"width":170,"height":90,"isShadow":true},{"type":"textbox","ref":"device","isCenter":true,"content":["\n\n§lDevice"]},{"type":"card","fill":-2172721,"width":170,"height":113,"isShadow":true}],"fixed":[{"type":"textbox","x":18,"y":92,"width":160,"height":30,"content":["All §4§lresuable§r batteries could be used as the §lBattery Hardware"]},{"type":"textbox","x":53,"y":229,"width":102,"height":10,"content":["Wireless transmitter"]},{"type":"slots","x":47,"y":136,"width":100,"height":18,"item_list":[{"id":"gregtech:meta_item_1","damage":732,"count":1},{"id":"gregtech:meta_item_1","damage":733,"count":1},{"id":"gregtech:meta_item_1","damage":742,"count":1},{"id":"gregtech:meta_item_1","damage":748,"count":1},{"id":"gregtech:meta_item_1","damage":753,"count":1}]},{"type":"slots","x":-16,"y":224,"width":100,"height":18,"item_list":[{"id":"gregtech:meta_item_1","damage":468,"count":1}]},{"type":"slots","x":-16,"y":250,"width":100,"height":18,"item_list":[{"id":"gregtech:meta_item_1","damage":465,"count":1}]},{"type":"textbox","x":52,"y":253,"width":100,"height":10,"content":["Scanner"]},{"type":"textbox","x":52,"y":279,"width":100,"height":10,"content":["Solar"]},{"type":"slots","x":12,"y":275,"width":45,"height":18,"item_list":[{"id":"gregtech:meta_item_1","damage":333,"count":1}]},{"type":"slots","x":22,"y":302,"width":25,"height":18,"item_list":[{"id":"gregtech:meta_item_1","damage":469,"count":1}]},{"type":"textbox","x":52,"y":306,"width":100,"height":10,"content":["Camera"]}]} diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_active.png b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_active.png new file mode 100644 index 00000000000..bcaa1934780 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_active.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_active.png.mcmeta new file mode 100644 index 00000000000..60af678259b --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_active.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation":{ + "frametime":4 + } +} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_active_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_active_emissive.png new file mode 100644 index 00000000000..f3d2b53db29 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_active_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_active_emissive.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_active_emissive.png.mcmeta new file mode 100644 index 00000000000..f70648e7b1b --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_active_emissive.png.mcmeta @@ -0,0 +1,14 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "CTM", + "layer": "BLOOM", + "gregtech": true, + "textures": [ + "gregtech:blocks/casings/quantum/controller_active_emissive" + ] + }, + "animation":{ + "frametime":4 + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_front_active.png b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_front_active.png new file mode 100644 index 00000000000..6c93d14ea6b Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_front_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_front_active_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_front_active_emissive.png new file mode 100644 index 00000000000..10af88febdf Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_front_active_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_front_active_emissive.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_front_active_emissive.png.mcmeta new file mode 100644 index 00000000000..4e8c6493e99 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_front_active_emissive.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation": { + "frametime": 8 + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_front_inactive.png b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_front_inactive.png new file mode 100644 index 00000000000..6c93d14ea6b Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_front_inactive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_inactive.png b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_inactive.png new file mode 100644 index 00000000000..2c3e0d025d4 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/controller_inactive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/extender.png b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/extender.png new file mode 100644 index 00000000000..b79e381d3ef Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/extender.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/extender_active.png b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/extender_active.png new file mode 100644 index 00000000000..e77eec21401 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/extender_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/extender_active_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/extender_active_emissive.png new file mode 100644 index 00000000000..3e2be0d612a Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/extender_active_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/extender_active_emissive.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/extender_active_emissive.png.mcmeta new file mode 100644 index 00000000000..66b15be410d --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/extender_active_emissive.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation":{ + "frametime":4 + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/proxy_active.png b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/proxy_active.png new file mode 100644 index 00000000000..3e37ee5702a Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/proxy_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/proxy_active_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/proxy_active_emissive.png new file mode 100644 index 00000000000..bd4e03ab408 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/proxy_active_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/proxy_active_emissive.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/proxy_active_emissive.png.mcmeta new file mode 100644 index 00000000000..ea715020dc5 --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/proxy_active_emissive.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation":{ + "frametime":4 + } +} diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/proxy_inactive.png b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/proxy_inactive.png new file mode 100644 index 00000000000..3e37ee5702a Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/proxy_inactive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/quantum_casing.png b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/quantum_casing.png new file mode 100644 index 00000000000..e3e9eda45ec Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/quantum_casing.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/quantum_indicator_connected.png b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/quantum_indicator_connected.png new file mode 100644 index 00000000000..979458b11ad Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/quantum_indicator_connected.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/quantum_indicator_connected_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/quantum_indicator_connected_emissive.png new file mode 100644 index 00000000000..e6ce137eee4 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/quantum_indicator_connected_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/quantum_indicator_disconnected.png b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/quantum_indicator_disconnected.png new file mode 100644 index 00000000000..d703813cf92 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/quantum_indicator_disconnected.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/quantum_indicator_powered.png b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/quantum_indicator_powered.png new file mode 100644 index 00000000000..767c0e84670 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/quantum_indicator_powered.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/quantum_indicator_powered_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/quantum_indicator_powered_emissive.png new file mode 100644 index 00000000000..2083500cae4 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/casings/quantum/quantum_indicator_powered_emissive.png differ 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/misc/itnt.png b/src/main/resources/assets/gregtech/textures/blocks/misc/itnt.png new file mode 100644 index 00000000000..a167e1676b7 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/misc/itnt.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/misc/powderbarrel.png b/src/main/resources/assets/gregtech/textures/blocks/misc/powderbarrel.png new file mode 100644 index 00000000000..b5624295e93 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/misc/powderbarrel.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/multiblock/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/blocks/overlay/appeng/me_input_bus.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus.png index 76486f57cdd..dd3d1f12037 100644 Binary files a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus.png and b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus_active.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus_active.png new file mode 100644 index 00000000000..c9bb59b3b46 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_bus_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch.png index f19def26e30..a2644c44b46 100644 Binary files a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch.png and b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch_active.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch_active.png new file mode 100644 index 00000000000..fd4570e0f9f Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_input_hatch_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_bus.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_bus.png index 96ac2920c71..8914379ca05 100644 Binary files a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_bus.png and b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_bus.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_bus_active.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_bus_active.png new file mode 100644 index 00000000000..39de0bb51bf Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_bus_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch.png index 313e4fdbeb6..e13a7f0fb7c 100644 Binary files a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch.png and b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch_active.png b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch_active.png new file mode 100644 index 00000000000..de4b2100518 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/overlay/appeng/me_output_hatch_active.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/base/slot_dark.png b/src/main/resources/assets/gregtech/textures/gui/base/slot_dark.png new file mode 100644 index 00000000000..90a91082dc3 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/base/slot_dark.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/overlay/conveyor_mode_overlay.png b/src/main/resources/assets/gregtech/textures/gui/overlay/conveyor_mode_overlay.png new file mode 100644 index 00000000000..0c2a1ac6212 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/overlay/conveyor_mode_overlay.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/overlay/filter_mode_overlay.png b/src/main/resources/assets/gregtech/textures/gui/overlay/filter_mode_overlay.png new file mode 100644 index 00000000000..0f9c95e8b68 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/overlay/filter_mode_overlay.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/overlay/filter_settings_overlay.png b/src/main/resources/assets/gregtech/textures/gui/overlay/filter_settings_overlay.png new file mode 100644 index 00000000000..31b8cdb6ce8 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/overlay/filter_settings_overlay.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/overlay/fluid_transfer_mode_overlay.png b/src/main/resources/assets/gregtech/textures/gui/overlay/fluid_transfer_mode_overlay.png new file mode 100644 index 00000000000..6fe690f9fbb Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/overlay/fluid_transfer_mode_overlay.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/overlay/manual_io_overlay_in.png b/src/main/resources/assets/gregtech/textures/gui/overlay/manual_io_overlay_in.png new file mode 100644 index 00000000000..a8f8bef7a54 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/overlay/manual_io_overlay_in.png differ 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/assets/gregtech/textures/gui/overlay/menu_overlay.png b/src/main/resources/assets/gregtech/textures/gui/overlay/menu_overlay.png new file mode 100644 index 00000000000..dc166fac7e4 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/overlay/menu_overlay.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/overlay/transfer_mode_overlay.png b/src/main/resources/assets/gregtech/textures/gui/overlay/transfer_mode_overlay.png new file mode 100644 index 00000000000..9364d84544d Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/overlay/transfer_mode_overlay.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/overlay/voiding_mode_overlay.png b/src/main/resources/assets/gregtech/textures/gui/overlay/voiding_mode_overlay.png new file mode 100644 index 00000000000..d948e2c551c Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/overlay/voiding_mode_overlay.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/terminal/console/icon.png b/src/main/resources/assets/gregtech/textures/gui/terminal/console/icon.png deleted file mode 100644 index 1aa90b06a4b..00000000000 Binary files a/src/main/resources/assets/gregtech/textures/gui/terminal/console/icon.png and /dev/null differ diff --git a/src/main/resources/assets/gregtech/textures/gui/terminal/fluid_prospector/icon.png b/src/main/resources/assets/gregtech/textures/gui/terminal/fluid_prospector/icon.png deleted file mode 100644 index c9ef5ce0d7a..00000000000 Binary files a/src/main/resources/assets/gregtech/textures/gui/terminal/fluid_prospector/icon.png and /dev/null differ diff --git a/src/main/resources/assets/gregtech/textures/gui/terminal/frame_side_down.png b/src/main/resources/assets/gregtech/textures/gui/terminal/frame_side_down.png deleted file mode 100644 index 67e56db7dc7..00000000000 Binary files a/src/main/resources/assets/gregtech/textures/gui/terminal/frame_side_down.png and /dev/null differ diff --git a/src/main/resources/assets/gregtech/textures/gui/terminal/frame_side_up.png b/src/main/resources/assets/gregtech/textures/gui/terminal/frame_side_up.png deleted file mode 100644 index 9e7a2e0ff8d..00000000000 Binary files a/src/main/resources/assets/gregtech/textures/gui/terminal/frame_side_up.png and /dev/null differ diff --git a/src/main/resources/assets/gregtech/textures/gui/terminal/guide_editor/icon.png b/src/main/resources/assets/gregtech/textures/gui/terminal/guide_editor/icon.png deleted file mode 100644 index d9f2047fd1a..00000000000 Binary files a/src/main/resources/assets/gregtech/textures/gui/terminal/guide_editor/icon.png and /dev/null differ diff --git a/src/main/resources/assets/gregtech/textures/gui/terminal/hardware_manager/circuit.png b/src/main/resources/assets/gregtech/textures/gui/terminal/hardware_manager/circuit.png deleted file mode 100644 index 1d9e6095cab..00000000000 Binary files a/src/main/resources/assets/gregtech/textures/gui/terminal/hardware_manager/circuit.png and /dev/null differ diff --git a/src/main/resources/assets/gregtech/textures/gui/terminal/multiblock_ar/icon.png b/src/main/resources/assets/gregtech/textures/gui/terminal/multiblock_ar/icon.png deleted file mode 100644 index 82a592d8ac6..00000000000 Binary files a/src/main/resources/assets/gregtech/textures/gui/terminal/multiblock_ar/icon.png and /dev/null differ diff --git a/src/main/resources/assets/gregtech/textures/gui/terminal/multiblock_ar/profile.png b/src/main/resources/assets/gregtech/textures/gui/terminal/multiblock_ar/profile.png deleted file mode 100644 index d7ad55895cb..00000000000 Binary files a/src/main/resources/assets/gregtech/textures/gui/terminal/multiblock_ar/profile.png and /dev/null differ diff --git a/src/main/resources/assets/gregtech/textures/gui/terminal/ore_prospector/icon.png b/src/main/resources/assets/gregtech/textures/gui/terminal/ore_prospector/icon.png deleted file mode 100644 index 9aa927b81f8..00000000000 Binary files a/src/main/resources/assets/gregtech/textures/gui/terminal/ore_prospector/icon.png and /dev/null differ diff --git a/src/main/resources/assets/gregtech/textures/gui/terminal/terminal_dialog.png b/src/main/resources/assets/gregtech/textures/gui/terminal/terminal_dialog.png deleted file mode 100644 index d18efc6cbc1..00000000000 Binary files a/src/main/resources/assets/gregtech/textures/gui/terminal/terminal_dialog.png and /dev/null differ diff --git a/src/main/resources/assets/gregtech/textures/gui/terminal/terminal_frame.png b/src/main/resources/assets/gregtech/textures/gui/terminal/terminal_frame.png deleted file mode 100644 index b557aef1cc1..00000000000 Binary files a/src/main/resources/assets/gregtech/textures/gui/terminal/terminal_frame.png and /dev/null differ diff --git a/src/main/resources/assets/gregtech/textures/gui/terminal/terminal_home.png b/src/main/resources/assets/gregtech/textures/gui/terminal/terminal_home.png deleted file mode 100644 index 4d7bac24410..00000000000 Binary files a/src/main/resources/assets/gregtech/textures/gui/terminal/terminal_home.png and /dev/null differ diff --git a/src/main/resources/assets/gregtech/textures/gui/terminal/vtank_viewer/icon.png b/src/main/resources/assets/gregtech/textures/gui/terminal/vtank_viewer/icon.png deleted file mode 100644 index d287058807f..00000000000 Binary files a/src/main/resources/assets/gregtech/textures/gui/terminal/vtank_viewer/icon.png and /dev/null differ diff --git a/src/main/resources/assets/gregtech/textures/gui/terminal/world_prospector/icon.png b/src/main/resources/assets/gregtech/textures/gui/terminal/world_prospector/icon.png deleted file mode 100644 index 32acbcd65c2..00000000000 Binary files a/src/main/resources/assets/gregtech/textures/gui/terminal/world_prospector/icon.png and /dev/null differ diff --git a/src/main/resources/assets/gregtech/textures/gui/terminal/world_prospector/profile.png b/src/main/resources/assets/gregtech/textures/gui/terminal/world_prospector/profile.png deleted file mode 100644 index 1575c67f60b..00000000000 Binary files a/src/main/resources/assets/gregtech/textures/gui/terminal/world_prospector/profile.png and /dev/null differ diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/arrow_double.png b/src/main/resources/assets/gregtech/textures/gui/widget/arrow_double.png new file mode 100644 index 00000000000..5613c4a3785 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/widget/arrow_double.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/button_cross.png b/src/main/resources/assets/gregtech/textures/gui/widget/button_cross.png new file mode 100644 index 00000000000..863553adbdc Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/widget/button_cross.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/button_distribution_mode.png b/src/main/resources/assets/gregtech/textures/gui/widget/button_distribution_mode.png index 86f6a27bd53..9dbdac4862f 100644 Binary files a/src/main/resources/assets/gregtech/textures/gui/widget/button_distribution_mode.png and b/src/main/resources/assets/gregtech/textures/gui/widget/button_distribution_mode.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/button_me_auto_pull.png b/src/main/resources/assets/gregtech/textures/gui/widget/button_me_auto_pull.png new file mode 100644 index 00000000000..16ada2daad4 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/widget/button_me_auto_pull.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/button_no_distinct_buses.png b/src/main/resources/assets/gregtech/textures/gui/widget/button_no_distinct_buses.png index 351ac8bbf00..fd5cb681e07 100644 Binary files a/src/main/resources/assets/gregtech/textures/gui/widget/button_no_distinct_buses.png and b/src/main/resources/assets/gregtech/textures/gui/widget/button_no_distinct_buses.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/button_redstone_off.png b/src/main/resources/assets/gregtech/textures/gui/widget/button_redstone_off.png new file mode 100644 index 00000000000..e51d4534755 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/widget/button_redstone_off.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/button_redstone_on.png b/src/main/resources/assets/gregtech/textures/gui/widget/button_redstone_on.png new file mode 100644 index 00000000000..44d6e446b72 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/widget/button_redstone_on.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/voltage_coil.ev.png b/src/main/resources/assets/gregtech/textures/items/metaitems/voltage_coil.ev.png index 2b48fc9d20e..3912a508409 100644 Binary files a/src/main/resources/assets/gregtech/textures/items/metaitems/voltage_coil.ev.png and b/src/main/resources/assets/gregtech/textures/items/metaitems/voltage_coil.ev.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_hv.png b/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_hv.png new file mode 100644 index 00000000000..b54d8d136c2 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_hv.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_iv.png b/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_iv.png new file mode 100644 index 00000000000..303fea217f6 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_iv.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_lv.png b/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_lv.png new file mode 100644 index 00000000000..c45bffa4360 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/tools/handle_electric_wire_cutter_lv.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/tools/wire_cutter_electric.png b/src/main/resources/assets/gregtech/textures/items/tools/wire_cutter_electric.png new file mode 100644 index 00000000000..602eea83d49 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/tools/wire_cutter_electric.png differ diff --git a/src/main/resources/assets/gregtech/worldgen/vein/end/naquadah_vein.json b/src/main/resources/assets/gregtech/worldgen/vein/end/naquadah_vein.json index d223a5e7651..a8c23d9f419 100644 --- a/src/main/resources/assets/gregtech/worldgen/vein/end/naquadah_vein.json +++ b/src/main/resources/assets/gregtech/worldgen/vein/end/naquadah_vein.json @@ -31,7 +31,7 @@ "between": "ore:naquadah" }, { - "sporadic": "ore:plutonium" + "sporadic": "ore:zircon" } ] } diff --git a/src/main/resources/gregtech_at.cfg b/src/main/resources/gregtech_at.cfg index 343dd1b65f5..76892c9fc05 100644 --- a/src/main/resources/gregtech_at.cfg +++ b/src/main/resources/gregtech_at.cfg @@ -81,3 +81,6 @@ protected net.minecraft.entity.item.EntityBoat field_184473_aH # lastYd # EntityItem public net.minecraft.entity.item.EntityItem field_145804_b # pickupDelay + +# Explosion +public net.minecraft.world.Explosion field_77283_e # exploder 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..50eeb75fb65 --- /dev/null +++ b/src/main/resources/mixins.gregtech.minecraft.json @@ -0,0 +1,29 @@ +{ + "package": "gregtech.mixins.minecraft", + "refmap": "mixins.gregtech.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "injectors": { + "maxShiftBy": 10 + }, + "mixins": [ + "BlockConcretePowderMixin", + "BlockRenderLayerMixin", + "DamageSourceMixin", + "EnchantmentCanApplyMixin", + "MinecraftMixin" + ], + "client": [ + "BlockMixin", + "EntityRendererMixin", + "LayerArmorBaseMixin", + "LayerCustomHeadMixin", + "RecipeRepairItemMixin", + "RegionRenderCacheBuilderMixin", + "RenderChunkMixin", + "RenderGlobalMixin", + "RenderItemMixin" + ], + "server": [] +} diff --git a/src/main/resources/mixins.gregtech.nothirium.json b/src/main/resources/mixins.gregtech.nothirium.json new file mode 100644 index 00000000000..c3ffca3074e --- /dev/null +++ b/src/main/resources/mixins.gregtech.nothirium.json @@ -0,0 +1,12 @@ +{ + "package": "gregtech.mixins.nothirium", + "refmap": "mixins.gregtech.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "ChunkRenderPassMixin" + ], + "client": [], + "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..5949918f337 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(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(30L)); + // 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 @@ -73,7 +158,7 @@ protected long getEnergyCapacity() { } @Override - protected boolean drawEnergy(int recipeEUt, boolean simulate) { + protected boolean drawEnergy(long recipeEUt, boolean simulate) { return true; } @@ -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); } diff --git a/src/test/java/gregtech/api/capability/impl/MultiblockRecipeLogicTest.java b/src/test/java/gregtech/api/capability/impl/MultiblockRecipeLogicTest.java index b8624475633..47c4287aef1 100644 --- a/src/test/java/gregtech/api/capability/impl/MultiblockRecipeLogicTest.java +++ b/src/test/java/gregtech/api/capability/impl/MultiblockRecipeLogicTest.java @@ -194,7 +194,7 @@ protected long getEnergyCapacity() { } @Override - protected boolean drawEnergy(int recipeEUt, boolean simulate) { + protected boolean drawEnergy(long recipeEUt, boolean simulate) { return true; } @@ -441,7 +441,7 @@ protected long getEnergyCapacity() { } @Override - protected boolean drawEnergy(int recipeEUt, boolean simulate) { + protected boolean drawEnergy(long recipeEUt, boolean simulate) { return true; } @@ -668,7 +668,7 @@ protected long getEnergyCapacity() { } @Override - protected boolean drawEnergy(int recipeEUt, boolean simulate) { + protected boolean drawEnergy(long recipeEUt, boolean simulate) { return true; } diff --git a/src/test/java/gregtech/api/recipes/logic/IParallelableRecipeLogicTest.java b/src/test/java/gregtech/api/recipes/logic/IParallelableRecipeLogicTest.java index 5d1105e8a5b..882d9287e6a 100644 --- a/src/test/java/gregtech/api/recipes/logic/IParallelableRecipeLogicTest.java +++ b/src/test/java/gregtech/api/recipes/logic/IParallelableRecipeLogicTest.java @@ -12,6 +12,7 @@ import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; +import gregtech.api.recipes.RecipeMapBuilder; import gregtech.api.recipes.builders.BlastRecipeBuilder; import gregtech.api.unification.material.Materials; import gregtech.api.util.GTUtility; @@ -24,6 +25,7 @@ import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockPart; import net.minecraft.init.Blocks; +import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; @@ -38,8 +40,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.CoreMatchers.*; public class IParallelableRecipeLogicTest { @@ -237,7 +238,7 @@ public void findMultipliedRecipe_AtMaxParallelsTest() { MatcherAssert.assertThat(parallelRecipe.getParallel(), is(4)); // Check that the EUt of the recipe was multiplied correctly - MatcherAssert.assertThat(parallelRecipe.getEUt(), is(120)); + MatcherAssert.assertThat(parallelRecipe.getEUt(), is(120L)); // Check if the recipe duration was not modified MatcherAssert.assertThat(parallelRecipe.getDuration(), is(100)); @@ -290,7 +291,7 @@ public void findMultipliedRecipe_LessThanMaxParallelsTest() { MatcherAssert.assertThat(parallelRecipe.getParallel(), is(2)); // Check that the EUt of the recipe was multiplied correctly - MatcherAssert.assertThat(parallelRecipe.getEUt(), is(60)); + MatcherAssert.assertThat(parallelRecipe.getEUt(), is(60L)); // Check if the recipe duration was not modified MatcherAssert.assertThat(parallelRecipe.getDuration(), is(100)); @@ -346,7 +347,7 @@ public void findMultipliedRecipe_FluidOnlyMaxParallelTest() { MatcherAssert.assertThat(parallelRecipe.getParallel(), is(4)); // Check that the EUt of the recipe was multiplied correctly - MatcherAssert.assertThat(parallelRecipe.getEUt(), is(1920)); + MatcherAssert.assertThat(parallelRecipe.getEUt(), is(1920L)); // Check if the recipe duration was not modified MatcherAssert.assertThat(parallelRecipe.getDuration(), is(10)); @@ -399,7 +400,7 @@ public void findMultipliedRecipe_FluidOnlyLessThanMaxParallelTest() { MatcherAssert.assertThat(parallelRecipe.getParallel(), is(2)); // Check that the EUt of the recipe was multiplied correctly - MatcherAssert.assertThat(parallelRecipe.getEUt(), is(960)); + MatcherAssert.assertThat(parallelRecipe.getEUt(), is(960L)); // Check if the recipe duration was not modified MatcherAssert.assertThat(parallelRecipe.getDuration(), is(10)); @@ -446,7 +447,7 @@ public void findAppendedParallelItemRecipe_AtMaxParallelsTest() { MatcherAssert.assertThat(parallelRecipe.getParallel(), is(4)); // Check that the EUt of the recipe was not modified - MatcherAssert.assertThat(parallelRecipe.getEUt(), is(30)); + MatcherAssert.assertThat(parallelRecipe.getEUt(), is(30L)); // Check if the recipe duration was multiplied correctly MatcherAssert.assertThat(parallelRecipe.getDuration(), is(400)); @@ -493,7 +494,7 @@ public void findAppendedParallelItemRecipe_LessThanMaxParallelsTest() { MatcherAssert.assertThat(parallelRecipe.getParallel(), is(2)); // Check that the EUt of the recipe was not modified - MatcherAssert.assertThat(parallelRecipe.getEUt(), is(30)); + MatcherAssert.assertThat(parallelRecipe.getEUt(), is(30L)); // Check if the recipe duration was multiplied correctly MatcherAssert.assertThat(parallelRecipe.getDuration(), is(200)); @@ -525,7 +526,7 @@ protected long getEnergyCapacity() { } @Override - protected boolean drawEnergy(int recipeEUt, boolean simulate) { + protected boolean drawEnergy(long recipeEUt, boolean simulate) { return true; } @@ -568,7 +569,7 @@ public MetaTileEntity getMetaTileEntity() { exportFluidBus.getExportFluids(), 128, parallelLimit); // Check that the EUt of the recipe was multiplied correctly - MatcherAssert.assertThat(outputRecipe.getEUt(), is(120)); + MatcherAssert.assertThat(outputRecipe.getEUt(), is(120L)); // Check if the recipe duration was not modified MatcherAssert.assertThat(outputRecipe.getDuration(), is(100)); @@ -600,7 +601,7 @@ protected long getEnergyCapacity() { } @Override - protected boolean drawEnergy(int recipeEUt, boolean simulate) { + protected boolean drawEnergy(long recipeEUt, boolean simulate) { return true; } @@ -665,7 +666,7 @@ protected long getEnergyCapacity() { } @Override - protected boolean drawEnergy(int recipeEUt, boolean simulate) { + protected boolean drawEnergy(long recipeEUt, boolean simulate) { return true; } @@ -713,6 +714,44 @@ public MetaTileEntity getMetaTileEntity() { MatcherAssert.assertThat(outputRecipe, nullValue()); } + @Test + public void findParallelRecipe_SmallMaxStackSize() { + MetaTileEntityElectricBlastFurnace EBF = initEBF(521); + + int parallelLimit = 4; + + // Create a recipe Map to be used for testing + RecipeMap map = new RecipeMapBuilder<>("electric_blast_furnace", new BlastRecipeBuilder()) + .itemInputs(3).itemOutputs(2).fluidInputs(1).fluidOutputs(1).build(); + + // Create a simple recipe to be used for testing + // Use an output item with small max stack size + Recipe recipe = map.recipeBuilder() + .inputs(new ItemStack(Blocks.COBBLESTONE)) + .outputs(new ItemStack(Items.ELYTRA)) + .blastFurnaceTemp(1000) + .EUt(30).duration(100) + .build().getResult(); + + IParallelableRecipeLogic logic = new ParallelableTestLogic(EBF, map, ParallelLogicType.MULTIPLY); + + // Populate the Input Bus + importItemBus.getImportItems().insertItem(0, new ItemStack(Blocks.COBBLESTONE, 16), false); + + // Saturate the export bus, except for one slot + exportItemBus.getExportItems().insertItem(0, new ItemStack(Blocks.BONE_BLOCK, 16), false); + exportItemBus.getExportItems().insertItem(1, new ItemStack(Blocks.BONE_BLOCK, 16), false); + exportItemBus.getExportItems().insertItem(2, new ItemStack(Blocks.BONE_BLOCK, 16), false); + + RecipeBuilder parallelRecipe = logic.findMultipliedParallelRecipe(map, recipe, + importItemBus.getImportItems(), importFluidBus.getImportFluids(), + exportItemBus.getExportItems(), exportFluidBus.getExportFluids(), parallelLimit, Integer.MAX_VALUE, + EBF); + + MatcherAssert.assertThat(parallelRecipe, notNullValue()); + MatcherAssert.assertThat(parallelRecipe.getParallel(), is(1)); + } + @Test public void applyParallelBonus_Test() { MetaTileEntityElectricBlastFurnace EBF = initEBF(518); @@ -732,7 +771,7 @@ protected long getEnergyCapacity() { } @Override - protected boolean drawEnergy(int recipeEUt, boolean simulate) { + protected boolean drawEnergy(long recipeEUt, boolean simulate) { return true; } @@ -775,7 +814,7 @@ public MetaTileEntity getMetaTileEntity() { exportFluidBus.getExportFluids(), 128, parallelLimit); // Check that the EUt of the recipe was not modified - MatcherAssert.assertThat(outputRecipe.getEUt(), is(1)); + MatcherAssert.assertThat(outputRecipe.getEUt(), is(1L)); // Check if the recipe duration was multiplied correctly MatcherAssert.assertThat(outputRecipe.getDuration(), is(50)); diff --git a/src/test/java/gregtech/api/recipes/logic/OverclockingTest.java b/src/test/java/gregtech/api/recipes/logic/OverclockingTest.java index d503cff24ea..3b0fd575daf 100644 --- a/src/test/java/gregtech/api/recipes/logic/OverclockingTest.java +++ b/src/test/java/gregtech/api/recipes/logic/OverclockingTest.java @@ -1,226 +1,561 @@ package gregtech.api.recipes.logic; +import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; import static gregtech.api.GTValues.*; +import static gregtech.api.recipes.logic.OverclockingLogic.*; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.lessThanOrEqualTo; -public class OverclockingTest { +class OverclockingTest { @Test - public void testULV() { + void testULV() { final int recipeDuration = 32768; final int recipeTier = ULV; - final int recipeVoltage = (int) V[recipeTier]; + final long recipeVoltage = V[recipeTier]; // ULV recipe, LV machine int machineTier = LV; - int[] oc = testOC(recipeDuration, recipeTier, recipeVoltage, machineTier, (int) V[machineTier]); + OCResult oc = testOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); // 0 overclocks - assertThat(oc[0], is(recipeVoltage)); - assertThat(oc[1], is(recipeDuration)); + assertThat(oc.eut(), is(recipeVoltage)); + assertThat(oc.duration(), is(recipeDuration)); // ULV recipe, MV machine machineTier = MV; - oc = testOC(recipeDuration, recipeTier, recipeVoltage, machineTier, (int) V[machineTier]); + oc = testOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); // 1 overclock - assertThat(oc[0], is(recipeVoltage * 4)); - assertThat(oc[1], is(recipeDuration / 2)); + assertThat(oc.eut(), is(recipeVoltage * 4)); + assertThat(oc.duration(), is(recipeDuration / 2)); // ULV recipe, HV machine machineTier = HV; - oc = testOC(recipeDuration, recipeTier, recipeVoltage, machineTier, (int) V[machineTier]); + oc = testOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); // 2 overclocks - assertThat(oc[0], is(recipeVoltage * ((int) Math.pow(4, 2)))); - assertThat(oc[1], is(recipeDuration / ((int) Math.pow(2, 2)))); + assertThat(oc.eut(), is(recipeVoltage * 4 * 4)); + assertThat(oc.duration(), is(recipeDuration / (2 * 2))); } @Test - public void testULV2() { + void testULV2() { final int recipeDuration = 32768; final int recipeTier = ULV; - final int recipeVoltage = (int) V[recipeTier] * 2; + final long recipeVoltage = V[recipeTier] * 2; // ULV recipe, LV machine int machineTier = LV; - int[] oc = testOC(recipeDuration, recipeTier, recipeVoltage, machineTier, (int) V[machineTier]); + OCResult oc = testOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); // 0 overclocks - assertThat(oc[0], is(recipeVoltage)); - assertThat(oc[1], is(recipeDuration)); + assertThat(oc.eut(), is(recipeVoltage)); + assertThat(oc.duration(), is(recipeDuration)); // ULV recipe, MV machine machineTier = MV; - oc = testOC(recipeDuration, recipeTier, recipeVoltage, machineTier, (int) V[machineTier]); + oc = testOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); // 1 overclock - assertThat(oc[0], is(recipeVoltage * 4)); - assertThat(oc[1], is(recipeDuration / 2)); + assertThat(oc.eut(), is(recipeVoltage * 4)); + assertThat(oc.duration(), is(recipeDuration / 2)); // ULV recipe, HV machine machineTier = HV; - oc = testOC(recipeDuration, recipeTier, recipeVoltage, machineTier, (int) V[machineTier]); + oc = testOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); // 2 overclocks - assertThat(oc[0], is(recipeVoltage * ((int) Math.pow(4, 2)))); - assertThat(oc[1], is(recipeDuration / ((int) Math.pow(2, 2)))); + assertThat(oc.eut(), is(recipeVoltage * 4 * 4)); + assertThat(oc.duration(), is(recipeDuration / (2 * 2))); } @Test - public void testLV() { + void testLV() { final int recipeDuration = 32768; final int recipeTier = LV; - final int recipeVoltage = (int) V[recipeTier]; + final long recipeVoltage = V[recipeTier]; // LV recipe, LV machine int machineTier = LV; - int[] oc = testOC(recipeDuration, recipeTier, recipeVoltage, machineTier, (int) V[machineTier]); + OCResult oc = testOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); - assertThat(oc[0], is(recipeVoltage)); - assertThat(oc[1], is(recipeDuration)); + assertThat(oc.eut(), is(recipeVoltage)); + assertThat(oc.duration(), is(recipeDuration)); // LV recipe, MV machine machineTier = MV; - oc = testOC(recipeDuration, recipeTier, recipeVoltage, machineTier, (int) V[machineTier]); + oc = testOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); - assertThat(oc[0], is(recipeVoltage * 4)); - assertThat(oc[1], is(recipeDuration / 2)); + assertThat(oc.eut(), is(recipeVoltage * 4)); + assertThat(oc.duration(), is(recipeDuration / 2)); // LV recipe, HV machine machineTier = HV; - oc = testOC(recipeDuration, recipeTier, recipeVoltage, machineTier, (int) V[machineTier]); + oc = testOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); - assertThat(oc[0], is(recipeVoltage * ((int) Math.pow(4, 2)))); - assertThat(oc[1], is(recipeDuration / ((int) Math.pow(2, 2)))); + assertThat(oc.eut(), is(recipeVoltage * 4 * 4)); + assertThat(oc.duration(), is(recipeDuration / (2 * 2))); } @Test - public void testHeatingCoilsDiffTemp() { + void testSubTickParallel() { + final int recipeDuration = 2; + final int recipeTier = LV; + final long recipeVoltage = V[recipeTier]; + + // LV recipe, LV machine + int machineTier = LV; + + OCResult oc = testSubTickParallelOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); + + assertThat(oc.eut(), is(recipeVoltage)); + assertThat(oc.duration(), is(recipeDuration)); + assertThat(oc.parallel(), lessThanOrEqualTo(1)); + + // LV recipe, MV machine + machineTier = MV; + + oc = testSubTickParallelOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); + + assertThat(oc.eut(), is(recipeVoltage * 4)); + assertThat(oc.duration(), is(recipeDuration / 2)); + assertThat(oc.parallel(), lessThanOrEqualTo(1)); + + // LV recipe, HV machine + machineTier = HV; + + oc = testSubTickParallelOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); + + assertThat(oc.eut(), is(recipeVoltage * 4)); + assertThat(oc.duration(), is(1)); + assertThat(oc.parallel(), is(2)); + assertThat(oc.parallelEUt(), is(recipeVoltage * 4 * 4)); + + // LV recipe, EV machine + machineTier = EV; + + oc = testSubTickParallelOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); + + assertThat(oc.eut(), is(recipeVoltage * 4)); + assertThat(oc.duration(), is(1)); + assertThat(oc.parallel(), is(2 * 2)); + assertThat(oc.parallelEUt(), is(recipeVoltage * 4 * 4 * 4)); + } + + @Test + void testSubTickParallelPerfect() { + final int recipeDuration = 3; + final int recipeTier = LV; + final long recipeVoltage = V[recipeTier]; + + // LV recipe, LV machine + int machineTier = LV; + + OCResult oc = testSubTickParallelPerfectOC(recipeDuration, recipeTier, recipeVoltage, machineTier, + V[machineTier]); + + assertThat(oc.eut(), is(recipeVoltage)); + assertThat(oc.duration(), is(recipeDuration)); + assertThat(oc.parallel(), lessThanOrEqualTo(1)); + + // LV recipe, MV machine + machineTier = MV; + + oc = testSubTickParallelPerfectOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); + + assertThat(oc.eut(), is(recipeVoltage)); + assertThat(oc.duration(), is(recipeDuration)); + assertThat(oc.parallel(), is(4)); + assertThat(oc.parallelEUt(), is(recipeVoltage * 4)); + + // LV recipe, HV machine + machineTier = HV; + + oc = testSubTickParallelPerfectOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); + + assertThat(oc.eut(), is(recipeVoltage)); + assertThat(oc.duration(), is(recipeDuration)); + assertThat(oc.parallel(), is(4 * 4)); + assertThat(oc.parallelEUt(), is(recipeVoltage * 4 * 4)); + + // LV recipe, HV machine + machineTier = EV; + + oc = testSubTickParallelPerfectOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); + + assertThat(oc.eut(), is(recipeVoltage)); + assertThat(oc.duration(), is(recipeDuration)); + assertThat(oc.parallel(), is(4 * 4 * 4)); + assertThat(oc.parallelEUt(), is(recipeVoltage * 4 * 4 * 4)); + } + + @Test + void testSubTickNonParallel() { + final int recipeDuration = 2; + final int recipeTier = LV; + final long recipeVoltage = V[recipeTier]; + + // LV recipe, LV machine + int machineTier = LV; + + OCResult oc = testSubTickNonParallelOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); + + assertThat(oc.eut(), is(recipeVoltage)); + assertThat(oc.duration(), is(recipeDuration)); + assertThat(oc.parallel(), is(0)); + + // LV recipe, MV machine + machineTier = MV; + + oc = testSubTickNonParallelOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); + + assertThat(oc.eut(), is(recipeVoltage * 4)); + assertThat(oc.duration(), is(recipeDuration / 2)); + assertThat(oc.parallel(), is(0)); + + // LV recipe, HV machine + machineTier = HV; + + oc = testSubTickNonParallelOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); + + assertThat(oc.eut(), is(recipeVoltage * 4 / 2)); + assertThat(oc.duration(), is(recipeDuration / 2)); + assertThat(oc.parallel(), is(0)); + + // LV recipe, EV machine + machineTier = EV; + + oc = testSubTickNonParallelOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); + + assertThat(oc.eut(), is(recipeVoltage)); + assertThat(oc.duration(), is(recipeDuration / 2)); + assertThat(oc.parallel(), is(0)); + } + + @Test + void testHeatingCoilsOC() { final int recipeDuration = 32768; final int recipeTier = LV; - final int recipeVoltage = (int) V[recipeTier]; + final long recipeVoltage = V[recipeTier]; // LV recipe, HV machine final int machineTier = HV; // 1800K recipe, 1800K machine - int[] oc = testHeatingOC(recipeDuration, recipeTier, recipeVoltage, machineTier, (int) V[machineTier], 1800, + OCResult oc = testHeatingOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier], 1800, 1800); // 0 EU discounts, 2 overclocks - assertThat(oc[0], is(recipeVoltage * ((int) Math.pow(4, 2)))); - assertThat(oc[1], is(recipeDuration / ((int) Math.pow(2, 2)))); + assertThat(oc.eut(), is(recipeVoltage * 4 * 4)); + assertThat(oc.duration(), is(recipeDuration / (2 * 2))); // 1800K recipe, 2700K machine - oc = testHeatingOC(recipeDuration, recipeTier, recipeVoltage, machineTier, (int) V[machineTier], 1800, 2700); + oc = testHeatingOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier], 1800, 2700); // 1 EU discount, 2 overclocks - assertThat(oc[0], is(((int) (recipeVoltage * 0.95)) * ((int) Math.pow(4, 2)))); - assertThat(oc[1], is(recipeDuration / ((int) Math.pow(2, 2)))); + assertThat(oc.eut(), is((long) ((recipeVoltage * 0.95)) * 4 * 4)); + assertThat(oc.duration(), is(recipeDuration / (2 * 2))); // 1800K recipe, 3600K machine - oc = testHeatingOC(recipeDuration, recipeTier, recipeVoltage, machineTier, (int) V[machineTier], 1800, 3600); + oc = testHeatingOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier], 1800, 3600); // 2 EU discounts, 1 perfect overclock, 1 regular overclock - assertThat(oc[0], is(((int) (recipeVoltage * Math.pow(0.95, 2))) * ((int) Math.pow(4, 2)))); - assertThat(oc[1], is(recipeDuration / 2 / 4)); + assertThat(oc.eut(), is((long) ((recipeVoltage * Math.pow(0.95, 2))) * 4 * 4)); + assertThat(oc.duration(), is(recipeDuration / 2 / 4)); } @Test - public void testFusionReactor() { + void testHeatingCoilsSubtickOC() { + final int recipeDuration = 4; + final int recipeTier = LV; + final long recipeVoltage = V[recipeTier]; + + // LV recipe, HV machine + int machineTier = HV; + + // 1800K recipe, 1800K machine + OCResult oc = testHeatingSubtickOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier], 1800, + 1800); + + // 0 EU discounts, 2 overclocks + assertThat(oc.eut(), is(recipeVoltage * 4 * 4)); + assertThat(oc.duration(), is(recipeDuration / (2 * 2))); + + // 1800K recipe, 2700K machine + oc = testHeatingSubtickOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier], 1800, 2700); + + // 1 EU discount, 2 overclocks + assertThat(oc.eut(), is((long) ((recipeVoltage * 0.95)) * 4 * 4)); + assertThat(oc.duration(), is(recipeDuration / (2 * 2))); + + // 1800K recipe, 3600K machine + oc = testHeatingSubtickOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier], 1800, 3600); + + // 2 EU discounts, 1 perfect overclock, 1 regular subtick overclock + assertThat(oc.eut(), is((long) ((recipeVoltage * Math.pow(0.95, 2))) * 4)); + assertThat(oc.duration(), is(1)); + assertThat(oc.parallel(), is(2)); + assertThat(oc.parallelEUt(), is((long) ((recipeVoltage * Math.pow(0.95, 2))) * 4 * 4)); + + // 1800K recipe, 5400K machine + oc = testHeatingSubtickOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier], 1800, 5400); + + // 4 EU discounts, 1 perfect overclock, 1 perfect subtick overclock + assertThat(oc.eut(), is((long) ((recipeVoltage * Math.pow(0.95, 4))) * 4)); + assertThat(oc.duration(), is(1)); + assertThat(oc.parallel(), is(4)); + assertThat(oc.parallelEUt(), is((long) ((recipeVoltage * Math.pow(0.95, 4))) * 4 * 4)); + + // LV recipe, EV machine + machineTier = EV; + + // 1800K recipe, 1800K machine + oc = testHeatingSubtickOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier], 1800, + 1800); + + // 0 EU discounts, 2 overclocks, 1 regular subtick overclock + assertThat(oc.eut(), is(recipeVoltage * 4 * 4)); + assertThat(oc.duration(), is(recipeDuration / (2 * 2))); + assertThat(oc.parallel(), is(2)); + assertThat(oc.parallelEUt(), is(recipeVoltage * 4 * 4 * 4)); + + // 1800K recipe, 2700K machine + oc = testHeatingSubtickOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier], 1800, 2700); + + // 1 EU discount, 2 overclocks, 1 regular subtick overclock + assertThat(oc.eut(), is((long) ((recipeVoltage * 0.95)) * 4 * 4)); + assertThat(oc.duration(), is(recipeDuration / (2 * 2))); + assertThat(oc.parallel(), is(2)); + assertThat(oc.parallelEUt(), is((long) ((recipeVoltage * 0.95)) * 4 * 4 * 4)); + + // 1800K recipe, 3600K machine + oc = testHeatingSubtickOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier], 1800, 3600); + + // 2 EU discounts, 1 perfect overclock, 2 regular subtick overclock + assertThat(oc.eut(), is((long) ((recipeVoltage * Math.pow(0.95, 2))) * 4)); + assertThat(oc.duration(), is(1)); + assertThat(oc.parallel(), is(2 * 2)); + assertThat(oc.parallelEUt(), is((long) ((recipeVoltage * Math.pow(0.95, 2))) * 4 * 4 * 4)); + + // 1800K recipe, 5400K machine + oc = testHeatingSubtickOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier], 1800, 5400); + + // 4 EU discounts, 1 perfect overclock, 1 perfect subtick overclock, 1 regular subtick overclock + assertThat(oc.eut(), is((long) ((recipeVoltage * Math.pow(0.95, 4))) * 4)); + assertThat(oc.duration(), is(1)); + assertThat(oc.parallel(), is(4 * 2)); + assertThat(oc.parallelEUt(), is((long) ((recipeVoltage * Math.pow(0.95, 4))) * 4 * 4 * 4)); + } + + @Test + void testFusionReactor() { final int recipeDuration = 32768; final int recipeTier = LuV; - final int recipeVoltage = (int) V[recipeTier]; + final long recipeVoltage = V[recipeTier]; // LuV recipe, LuV machine int machineTier = LuV; - int[] oc = testFusionOC(recipeDuration, recipeTier, recipeVoltage, machineTier, (int) V[machineTier]); + OCResult oc = testFusionOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); - assertThat(oc[0], is(recipeVoltage)); - assertThat(oc[1], is(recipeDuration)); + assertThat(oc.eut(), is(recipeVoltage)); + assertThat(oc.duration(), is(recipeDuration)); // LuV recipe, ZPM machine machineTier = ZPM; - oc = testFusionOC(recipeDuration, recipeTier, recipeVoltage, machineTier, (int) V[machineTier]); + oc = testFusionOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); - assertThat(oc[0], is(recipeVoltage * 2)); - assertThat(oc[1], is(recipeDuration / 2)); + assertThat(oc.eut(), is(recipeVoltage * 2)); + assertThat(oc.duration(), is(recipeDuration / 2)); // LuV recipe, UV machine machineTier = UV; - oc = testFusionOC(recipeDuration, recipeTier, recipeVoltage, machineTier, (int) V[machineTier]); + oc = testFusionOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); + + assertThat(oc.eut(), is(recipeVoltage * (2 * 2))); + assertThat(oc.duration(), is(recipeDuration / (2 * 2))); + + // LuV recipe, UHV machine + machineTier = UHV; + + oc = testFusionOC(recipeDuration, recipeTier, recipeVoltage, machineTier, V[machineTier]); + + assertThat(oc.eut(), is(recipeVoltage * (2 * 2 * 2))); + assertThat(oc.duration(), is(recipeDuration / (2 * 2 * 2))); + } + + private static @NotNull OCResult testOC(int recipeDuration, int recipeTier, long recipeVoltage, int machineTier, + long maxVoltage) { + int ocAmount = machineTier - recipeTier; + if (recipeTier == ULV) ocAmount--; // no ULV overclocking + + OCResult ocResult = new OCResult(); + + // cannot overclock, so return the starting values + if (ocAmount <= 0) { + ocResult.init(recipeVoltage, recipeDuration); + return ocResult; + } + + OCParams ocParams = new OCParams(); + ocParams.initialize(recipeVoltage, recipeDuration, ocAmount); + + OverclockingLogic.standardOC(ocParams, ocResult, maxVoltage, STD_DURATION_FACTOR, STD_VOLTAGE_FACTOR); + + return ocResult; + } + + private static @NotNull OCResult testSubTickParallelOC(int recipeDuration, int recipeTier, long recipeVoltage, + int machineTier, + long maxVoltage) { + int ocAmount = machineTier - recipeTier; + if (recipeTier == ULV) ocAmount--; // no ULV overclocking + + OCResult ocResult = new OCResult(); + + // cannot overclock, so return the starting values + if (ocAmount <= 0) { + ocResult.init(recipeVoltage, recipeDuration); + return ocResult; + } + + OCParams ocParams = new OCParams(); + ocParams.initialize(recipeVoltage, recipeDuration, ocAmount); + + OverclockingLogic.subTickParallelOC(ocParams, ocResult, maxVoltage, STD_DURATION_FACTOR, STD_VOLTAGE_FACTOR); + + return ocResult; + } - assertThat(oc[0], is(recipeVoltage * ((int) Math.pow(2, 2)))); - assertThat(oc[1], is(recipeDuration / ((int) Math.pow(2, 2)))); + private static @NotNull OCResult testSubTickParallelPerfectOC(int recipeDuration, int recipeTier, + long recipeVoltage, + int machineTier, + long maxVoltage) { + int ocAmount = machineTier - recipeTier; + if (recipeTier == ULV) ocAmount--; // no ULV overclocking + + OCResult ocResult = new OCResult(); + + // cannot overclock, so return the starting values + if (ocAmount <= 0) { + ocResult.init(recipeVoltage, recipeDuration); + return ocResult; + } + + OCParams ocParams = new OCParams(); + ocParams.initialize(recipeVoltage, recipeDuration, ocAmount); + + OverclockingLogic.subTickParallelOC(ocParams, ocResult, maxVoltage, PERFECT_DURATION_FACTOR, + STD_VOLTAGE_FACTOR); + + return ocResult; } - private static int[] testOC(int recipeDuration, int recipeTier, int recipeVoltage, int machineTier, - int maxVoltage) { - int numberOfOCs = machineTier - recipeTier; - if (recipeTier == ULV) numberOfOCs--; // no ULV overclocking + private static @NotNull OCResult testSubTickNonParallelOC(int recipeDuration, int recipeTier, long recipeVoltage, + int machineTier, + long maxVoltage) { + int ocAmount = machineTier - recipeTier; + if (recipeTier == ULV) ocAmount--; // no ULV overclocking + + OCResult ocResult = new OCResult(); // cannot overclock, so return the starting values - if (numberOfOCs <= 0) return new int[] { recipeVoltage, recipeDuration }; + if (ocAmount <= 0) { + ocResult.init(recipeVoltage, recipeDuration); + return ocResult; + } + + OCParams ocParams = new OCParams(); + ocParams.initialize(recipeVoltage, recipeDuration, ocAmount); + + OverclockingLogic.subTickNonParallelOC(ocParams, ocResult, maxVoltage, STD_DURATION_FACTOR, STD_VOLTAGE_FACTOR); - return OverclockingLogic.standardOverclockingLogic( - recipeVoltage, - maxVoltage, - recipeDuration, - numberOfOCs, - OverclockingLogic.STANDARD_OVERCLOCK_DURATION_DIVISOR, - OverclockingLogic.STANDARD_OVERCLOCK_VOLTAGE_MULTIPLIER); + return ocResult; } - private static int[] testHeatingOC(int recipeDuration, int recipeTier, int recipeVoltage, int machineTier, - int maxVoltage, - int recipeTemperature, int machineTemperature) { - int numberOfOCs = machineTier - recipeTier; - if (recipeTier == ULV) numberOfOCs--; // no ULV overclocking + private static @NotNull OCResult testHeatingOC(int recipeDuration, int recipeTier, long recipeVoltage, + int machineTier, long maxVoltage, int recipeTemperature, + int machineTemperature) { + int ocAmount = machineTier - recipeTier; + if (recipeTier == ULV) ocAmount--; // no ULV overclocking + + OCResult ocResult = new OCResult(); recipeVoltage = OverclockingLogic.applyCoilEUtDiscount(recipeVoltage, machineTemperature, recipeTemperature); // cannot overclock, so return the starting values - if (numberOfOCs <= 0) return new int[] { recipeVoltage, recipeDuration }; - - return OverclockingLogic.heatingCoilOverclockingLogic( - recipeVoltage, - maxVoltage, - recipeDuration, - numberOfOCs, - machineTemperature, + if (ocAmount <= 0) { + ocResult.init(recipeVoltage, recipeDuration); + return ocResult; + } + + OCParams ocParams = new OCParams(); + ocParams.initialize(recipeVoltage, recipeDuration, ocAmount); + + OverclockingLogic.heatingCoilNonSubTickOC(ocParams, ocResult, maxVoltage, machineTemperature, recipeTemperature); + + return ocResult; + } + + private static @NotNull OCResult testHeatingSubtickOC(int recipeDuration, int recipeTier, long recipeVoltage, + int machineTier, long maxVoltage, int recipeTemperature, + int machineTemperature) { + int ocAmount = machineTier - recipeTier; + if (recipeTier == ULV) ocAmount--; // no ULV overclocking + + OCResult ocResult = new OCResult(); + + recipeVoltage = OverclockingLogic.applyCoilEUtDiscount(recipeVoltage, machineTemperature, recipeTemperature); + + // cannot overclock, so return the starting values + if (ocAmount <= 0) { + ocResult.init(recipeVoltage, recipeDuration); + return ocResult; + } + + OCParams ocParams = new OCParams(); + ocParams.initialize(recipeVoltage, recipeDuration, ocAmount); + + OverclockingLogic.heatingCoilOC(ocParams, ocResult, maxVoltage, machineTemperature, recipeTemperature); + + return ocResult; } - private static int[] testFusionOC(int recipeDuration, int recipeTier, int recipeVoltage, int machineTier, - int maxVoltage) { - int numberOfOCs = machineTier - recipeTier; - if (recipeTier == ULV) numberOfOCs--; // no ULV overclocking + private static @NotNull OCResult testFusionOC(int recipeDuration, int recipeTier, long recipeVoltage, + int machineTier, long maxVoltage) { + int ocAmount = machineTier - recipeTier; + if (recipeTier == ULV) ocAmount--; // no ULV overclocking + + OCResult ocResult = new OCResult(); // cannot overclock, so return the starting values - if (numberOfOCs <= 0) return new int[] { recipeVoltage, recipeDuration }; - - return OverclockingLogic.standardOverclockingLogic( - recipeVoltage, - maxVoltage, - recipeDuration, - numberOfOCs, - OverclockingLogic.STANDARD_OVERCLOCK_DURATION_DIVISOR, - 2.0); + if (ocAmount <= 0) { + ocResult.init(recipeVoltage, recipeDuration); + return ocResult; + } + + OCParams ocParams = new OCParams(); + ocParams.initialize(recipeVoltage, recipeDuration, ocAmount); + + OverclockingLogic.subTickParallelOC(ocParams, ocResult, maxVoltage, PERFECT_HALF_DURATION_FACTOR, + PERFECT_HALF_VOLTAGE_FACTOR); + + return ocResult; } } diff --git a/src/test/java/gregtech/api/recipes/logic/ParallelLogicTest.java b/src/test/java/gregtech/api/recipes/logic/ParallelLogicTest.java index 06c0540d406..0b1de7c397a 100644 --- a/src/test/java/gregtech/api/recipes/logic/ParallelLogicTest.java +++ b/src/test/java/gregtech/api/recipes/logic/ParallelLogicTest.java @@ -878,7 +878,7 @@ public void doParallelRecipes_ExistingEUValueTest() { assertThat(testMaceratorRecipe, notNullValue()); // 2 is the default EUt value assigned to macerator recipes when not specified - assertThat(testMaceratorRecipe.getEUt(), is(2 * parallelAmount)); + assertThat(testMaceratorRecipe.getEUt(), is(2L * parallelAmount)); // 150 is the default duration value assigned to macerator recipes when not specified assertThat(testMaceratorRecipe.getDuration(), is(150)); diff --git a/src/test/java/gregtech/api/recipes/recipeproperties/RecipePropertyStorageTest.java b/src/test/java/gregtech/api/recipes/recipeproperties/RecipePropertyStorageTest.java deleted file mode 100644 index e3daea5e015..00000000000 --- a/src/test/java/gregtech/api/recipes/recipeproperties/RecipePropertyStorageTest.java +++ /dev/null @@ -1,138 +0,0 @@ -package gregtech.api.recipes.recipeproperties; - -import org.hamcrest.MatcherAssert; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import static org.hamcrest.CoreMatchers.is; - -public class RecipePropertyStorageTest { - - private static final String propInt1Key = "propInt1"; - - private static final DefaultProperty propInt1 = new DefaultProperty<>(propInt1Key, Integer.class); - private static final DefaultProperty propInt2 = new DefaultProperty<>("propInt2", Integer.class); - private static final DefaultProperty propInt1_2 = new DefaultProperty<>("propInt1", Integer.class); - private static final DefaultProperty wrongCast = new DefaultProperty<>("wrongCast", Integer.class); - - private RecipePropertyStorage storage; - - @BeforeEach - public void initTestStub() { - this.storage = new RecipePropertyStorage(); - } - - @Test - public void storing_unique_recipe_properties_succeeds() { - MatcherAssert.assertThat(storage.store(propInt1, 1), is(true)); - MatcherAssert.assertThat(storage.store(propInt2, 1), is(true)); - } - - @Test - public void storing_same_property_twice_fails() { - MatcherAssert.assertThat(storage.store(propInt1, 1), is(true)); - MatcherAssert.assertThat(storage.store(propInt1, 1), is(false)); - } - - @Test - public void storing_unique_properties_with_same_key_fails() { - MatcherAssert.assertThat(storage.store(propInt1, 1), is(true)); - MatcherAssert.assertThat(storage.store(propInt1_2, 1), is(false)); - } - - @Test - public void storing_property_with_wrong_cast_fails() { - MatcherAssert.assertThat(storage.store(wrongCast, "This is not int"), is(false)); - } - - @Test - public void storing_property_without_value_fails() { - MatcherAssert.assertThat(storage.store(propInt1, null), is(false)); - } - - @Test - public void get_size_returns_correct_value() { - storage.store(propInt1, 1); // succeeds - - MatcherAssert.assertThat(storage.getSize(), is(1)); - - storage.store(propInt2, 2); // succeeds - - MatcherAssert.assertThat(storage.getSize(), is(2)); - - storage.store(propInt1, 1); // fails - - MatcherAssert.assertThat(storage.getSize(), is(2)); - } - - @Test - public void get_recipe_properties_returns_correct_value() { - storage.store(propInt1, 1); // succeeds - storage.store(propInt2, 2); // succeeds - - Map, Object> map = new HashMap<>(); - map.put(propInt1, 1); - map.put(propInt2, 2); - Set, Object>> expectedProperties = map.entrySet(); - - Set, Object>> actualProperties = storage.getRecipeProperties(); - - MatcherAssert.assertThat(actualProperties.size(), is(2)); - MatcherAssert.assertThat( - actualProperties.containsAll(expectedProperties) && expectedProperties.containsAll(actualProperties), - is(true)); - } - - @Test - public void get_recipe_property_value_returns_correct_value_if_exists() { - final int expectedValue = 1; - storage.store(propInt1, expectedValue); // succeeds - - int actual = storage.getRecipePropertyValue(propInt1, 0); - - MatcherAssert.assertThat(actual, is(expectedValue)); - } - - @Test - public void get_recipe_property_value_returns_default_value_if_does_not_exists() { - final int expectedValue = 0; - storage.store(propInt1, 1); // succeeds - - int actual = storage.getRecipePropertyValue(propInt2, expectedValue); - - MatcherAssert.assertThat(actual, is(expectedValue)); - } - - @Test - // CT way - public void get_recipe_property_keys() { - storage.store(propInt1, 1); // succeeds - storage.store(propInt2, 2); // succeeds - - Set expectedKeys = new HashSet<>(); - expectedKeys.add(propInt1.getKey()); - expectedKeys.add(propInt2.getKey()); - - Set actualKeys = storage.getRecipePropertyKeys(); - - MatcherAssert.assertThat(expectedKeys.containsAll(actualKeys) && actualKeys.containsAll(expectedKeys), - is(true)); - } - - @Test - // CT way - public void get_raw_recipe_property_value_via_string_key() { - final int expectedValue = 1; - - storage.store(propInt1, expectedValue); // succeeds - - Object actualValue = storage.getRawRecipePropertyValue(propInt1.getKey()); - - MatcherAssert.assertThat(actualValue, is(expectedValue)); - } -} diff --git a/src/test/java/gregtech/api/unification/ElementsTest.java b/src/test/java/gregtech/api/unification/ElementsTest.java new file mode 100644 index 00000000000..eb5367a2f63 --- /dev/null +++ b/src/test/java/gregtech/api/unification/ElementsTest.java @@ -0,0 +1,50 @@ +package gregtech.api.unification; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class ElementsTest { + + @Test + public void test() { + assertEquals(Elements.Au, Elements.get("Gold")); + assertEquals(Elements.Au, Elements.get("gold")); + assertEquals(Elements.Au, Elements.get("Au")); + assertNull(Elements.get("_gold")); + assertNull(Elements.get("gold_")); + assertEquals(Elements.Au, Elements.get("Au")); + assertNull(Elements.get("au")); + assertNull(Elements.get("aU")); + assertEquals(Elements.U, Elements.get("Uranium")); + assertEquals(Elements.U235, Elements.get("Uranium-235")); + assertEquals(Elements.U238, Elements.get("Uranium-238")); + assertEquals(Elements.U238, Elements.get("U-238")); + assertNull(Elements.get("uranium_238")); + assertNull(Elements.get("uranium 238")); + assertNull(Elements.get("uranium238")); + assertNull(Elements.get("u-238")); + assertEquals(Elements.Nq1, Elements.get("NaquadahEnriched")); + assertEquals(Elements.Nq1, Elements.get("naquadahEnriched")); + assertNull(Elements.get("Naquadahenriched")); + assertNull(Elements.get("naquadahenriched")); + assertEquals(Elements.Nq1, Elements.get("naquadah_enriched")); + assertNull(Elements.get("NAQUADAH_ENRICHED")); + assertEquals(Elements.Nq1, Elements.get("Nq+")); + assertEquals(Elements.Nq2, Elements.get("*Nq*")); + + testElementName("gold", false); + testElementName("gold_12", false); + testElementName("Gold12", false); + testElementName("Gold-12", true); + testElementName("GOLD-12", true); + } + + private static void testElementName(String name, boolean works) { + if (works) { + Elements.add(-1, -1, -1, null, name, "Any", false); + } else { + assertThrows(IllegalArgumentException.class, () -> Elements.add(-1, -1, -1, null, name, "Any", false)); + } + } +} diff --git a/src/test/java/gregtech/api/util/TierByVoltageTest.java b/src/test/java/gregtech/api/util/TierByVoltageTest.java index b0f75d0ac86..fafe266f771 100644 --- a/src/test/java/gregtech/api/util/TierByVoltageTest.java +++ b/src/test/java/gregtech/api/util/TierByVoltageTest.java @@ -127,7 +127,7 @@ public void testVSpecialCases() { expectTier(0L, ULV, ULV); expectTier(2L, ULV, ULV); expectTier(Integer.MAX_VALUE + 1L, MAX, MAX); - expectTier(Long.MAX_VALUE, MAX, MAX); + expectTier(Long.MAX_VALUE, MAX, MAX_TRUE); expectTier(-1L, ULV, ULV); } diff --git a/src/test/java/gregtech/common/metatileentities/multiblock/hpca/HPCATest.java b/src/test/java/gregtech/common/metatileentities/multiblock/hpca/HPCATest.java index 3542313a3f0..fab2e1dbcd5 100644 --- a/src/test/java/gregtech/common/metatileentities/multiblock/hpca/HPCATest.java +++ b/src/test/java/gregtech/common/metatileentities/multiblock/hpca/HPCATest.java @@ -30,16 +30,16 @@ public void Test_Edge_No_Computation() { .coolingAmount(4))); final int maxCWUt = handler.getMaxCWUt(); - final int upkeepEUt = handler.getUpkeepEUt(); - final int maxEUt = handler.getMaxEUt(); + final long upkeepEUt = handler.getUpkeepEUt(); + final long maxEUt = handler.getMaxEUt(); final int maxCoolingDemand = handler.getMaxCoolantDemand(); final int maxCoolingAmount = handler.getMaxCoolingAmount(); int allocated; double temperatureChange; assertThat(maxCWUt, is(0)); - assertThat(upkeepEUt, is(32 * 4)); - assertThat(maxEUt, is(128 * 4)); + assertThat(upkeepEUt, is(32L * 4L)); + assertThat(maxEUt, is(128L * 4L)); assertThat(maxCoolingDemand, is(0)); assertThat(maxCoolingAmount, is(4 * 4)); @@ -69,14 +69,14 @@ public void Test_Edge_Equal_Upkeep_Max_EUt() { .coolingAmount(2))); final int maxCWUt = handler.getMaxCWUt(); - final int upkeepEUt = handler.getUpkeepEUt(); - final int maxEUt = handler.getMaxEUt(); + final long upkeepEUt = handler.getUpkeepEUt(); + final long maxEUt = handler.getMaxEUt(); final int maxCoolingDemand = handler.getMaxCoolingDemand(); final int maxCoolingAmount = handler.getMaxCoolingAmount(); int allocated, requested; double temperatureChange; - final int FIXED_EUT = 32 * 8; + final long FIXED_EUT = 32 * 8; assertThat(maxCWUt, is(4 * 4)); assertThat(upkeepEUt, is(FIXED_EUT)); assertThat(maxEUt, is(FIXED_EUT)); @@ -115,12 +115,13 @@ public void Test_Random() { .EUt(() -> r.nextInt(128)) .coolingAmount(() -> r.nextInt(128)))); - final int maxEUt = handler.getMaxEUt(); - final int upkeepEUt = handler.getUpkeepEUt(); + final long maxEUt = handler.getMaxEUt(); + final long upkeepEUt = handler.getUpkeepEUt(); final int maxCWUt = handler.getMaxCWUt(); final int maxCoolingDemand = handler.getMaxCoolingDemand(); final int maxCoolingAmount = handler.getMaxCoolingAmount(); - int allocated, requested, currentEUt; + int allocated, requested; + long currentEUt; double temperatureChange; // exit, we unit test these edge cases elsewhere