From a12aa92e25bfc1e5abe7feb6964aeedce264406a Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Mon, 9 Nov 2026 22:13:19 +0000 Subject: [PATCH 1/6] Port baseSteam to Minecraft 1.20.1 Keep the existing Steam machines, recipes and saved data while moving to Forge 47. Preserve track transparency, musket feedback and block behavior, and check Eclipse source roots as part of the build. --- .github/workflows/ci.yml | 48 ++-- .github/workflows/codeql-analysis.yml | 30 ++- .github/workflows/validate-gradle-build.yml | 6 +- CHANGELOG.txt | 7 + README.md | 41 ++-- build.gradle | 111 +++++---- gradle.properties | 48 ++-- gradle/forge45-mavenizer.init.gradle | 12 - ...enizer.gradle => forge47-mavenizer.gradle} | 14 +- .../moddev/mc/basesteam/SteamAdvantage.java | 4 +- .../mc/basesteam/blocks/DrillBitBlock.java | 10 +- .../mc/basesteam/blocks/PlatformBlock.java | 8 +- .../mc/basesteam/blocks/PumpPipeBlock.java | 8 +- .../blocks/SteamBlockProperties.java | 20 ++ .../mc/basesteam/blocks/SteamPipeBlock.java | 3 +- .../mc/basesteam/blocks/SteamTrackBlock.java | 3 +- .../graphics/ClientRegistration.java | 4 - .../mc/basesteam/gui/BlastFurnaceGUI.java | 7 +- .../mc/basesteam/gui/CoalBoilerGUI.java | 7 +- .../mc/basesteam/gui/ElectricBoilerGUI.java | 7 +- .../moddev/mc/basesteam/gui/GUIHelper.java | 29 ++- .../mc/basesteam/gui/GeothermalBoilerGUI.java | 7 +- .../moddev/mc/basesteam/gui/OilBoilerGUI.java | 5 +- .../mc/basesteam/gui/RockCrusherGUI.java | 5 +- .../mc/basesteam/gui/SteamDrillGUI.java | 5 +- .../moddev/mc/basesteam/gui/SteamPumpGUI.java | 5 +- .../mc/basesteam/gui/SteamStillGUI.java | 5 +- .../moddev/mc/basesteam/gui/SteamTankGUI.java | 5 +- .../moddev/mc/basesteam/items/MusketItem.java | 25 +- .../basesteam/machines/BlastFurnaceBlock.java | 3 +- .../machines/BlastFurnaceTileEntity.java | 3 +- .../basesteam/machines/CoalBoilerBlock.java | 3 +- .../machines/ElectricBoilerBlock.java | 3 +- .../machines/GeothermalBoilerBlock.java | 3 +- .../mc/basesteam/machines/OilBoilerBlock.java | 3 +- .../basesteam/machines/RockCrusherBlock.java | 3 +- .../machines/RockCrusherTileEntity.java | 4 +- .../basesteam/machines/SteamDrillBlock.java | 3 +- .../machines/SteamDrillTileEntity.java | 11 +- .../machines/SteamElevatorBlock.java | 3 +- .../mc/basesteam/machines/SteamPumpBlock.java | 3 +- .../basesteam/machines/SteamStillBlock.java | 3 +- .../mc/basesteam/machines/SteamTankBlock.java | 3 +- src/main/resources/META-INF/mods.toml | 4 +- .../basesteam/models/block/steam_track_0.json | 1 + .../models/block/steam_track_densuw.json | 1 + .../models/block/steam_track_desuw.json | 1 + .../models/block/steam_track_dnu.json | 1 + .../models/block/steam_track_ensw.json | 1 + .../basesteam/models/block/steam_track_n.json | 1 + .../models/block/steam_track_ns.json | 1 + .../models/block/steam_track_nsuw.json | 1 + .../models/block/steam_track_nsw.json | 1 + .../models/block/steam_track_nuw.json | 1 + .../models/block/steam_track_nw.json | 1 + .../basesteam/tags/blocks/musket_fragile.json | 221 ++++++++++++++++++ src/main/resources/pack.mcmeta | 4 +- .../mc/basesteam/gui/GUIHelperTest.java | 19 ++ .../items/MusketTargetingContractTest.java | 32 ++- .../CoalBoilerFillPersistenceTest.java | 2 +- .../RockCrusherReloadRedstoneTest.java | 2 +- .../machines/SteamDrillPersistenceTest.java | 18 ++ .../SteamOperationalPumpSourceTest.java | 5 +- .../WaterBoilerTankNotificationTest.java | 2 +- .../resources/BuildWorkflowContractTest.java | 28 +-- .../resources/ClientResourceContractTest.java | 34 +++ .../MusketFragileTagContractTest.java | 36 +++ .../resources/NativeBlockPropertiesTest.java | 11 + .../resources/NativeLootContractTest.java | 6 +- tools/verify-native-port.js | 14 +- 70 files changed, 689 insertions(+), 300 deletions(-) delete mode 100644 gradle/forge45-mavenizer.init.gradle rename gradle/{forge45-mavenizer.gradle => forge47-mavenizer.gradle} (60%) create mode 100644 src/main/java/zone/moddev/mc/basesteam/blocks/SteamBlockProperties.java create mode 100644 src/main/resources/data/basesteam/tags/blocks/musket_fragile.json create mode 100644 src/test/java/zone/moddev/mc/basesteam/resources/MusketFragileTagContractTest.java diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f84583a..dd79563 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,16 +1,16 @@ -name: baseSteam 1.19 CI +name: baseSteam 1.20 CI on: push: - branches: [master-1.19.4, feature/basesteam-1.19.4-port] + branches: [master-1.20.1, feature/basesteam-1.20.1-port] pull_request: - branches: [master-1.19.4] + branches: [master-1.20.1] permissions: contents: read concurrency: - group: basesteam-1.19-${{ github.workflow }}-${{ github.ref }} + group: basesteam-1.20-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: @@ -28,19 +28,19 @@ jobs: power_ref=$(sed -n 's/^poweradvantage_source_ref=//p' gradle.properties | tr -d '\r') power_hash=$(sed -n 's/^poweradvantage_deobf_sha256=//p' gradle.properties | tr -d '\r') if [[ ! "$power_ref" =~ ^[a-f0-9]{40}$ || ! "$power_hash" =~ ^[A-F0-9]{64}$ ]]; then - echo "::error::The exact basePower 1.19 dependency pin is pending." + echo "::error::The exact basePower 1.20.1 dependency pin is pending." exit 1 fi bm_ref=$(sed -n 's/^basemetals_source_commit=//p' gradle.properties | tr -d '\r') bm_hash=$(sed -n 's/^basemetals_deobf_sha256=//p' gradle.properties | tr -d '\r') if [[ ! "$bm_ref" =~ ^[a-f0-9]{40}$ || ! "$bm_hash" =~ ^[A-F0-9]{64}$ ]]; then - echo "::error::The exact Base Metals 1.19 dependency pin is pending." + echo "::error::The exact Base Metals 1.20.1 dependency pin is pending." exit 1 fi os_ref=$(sed -n 's/^orespawn_source_commit=//p' gradle.properties | tr -d '\r') os_hash=$(sed -n 's/^orespawn_deobf_sha256=//p' gradle.properties | tr -d '\r') if [[ ! "$os_ref" =~ ^[a-f0-9]{40}$ || ! "$os_hash" =~ ^[A-F0-9]{64}$ ]]; then - echo "::error::The exact OreSpawn 1.19 dependency pin is pending." + echo "::error::The exact OreSpawn 1.20.1 dependency pin is pending." exit 1 fi echo "ORESPAWN_SOURCE_REF=$os_ref" >> "$GITHUB_ENV" @@ -61,7 +61,7 @@ jobs: repository: MinecraftModDevelopmentMods/BaseMetals ref: ${{ env.BASEMETALS_SOURCE_REF }} path: .ci-dependencies/BaseMetals - - name: Check out basePower 1.19.4 + - name: Check out basePower 1.20.1 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/basePower @@ -91,7 +91,7 @@ jobs: -Porg.gradle.java.installations.auto-download=false" >> "$GITHUB_ENV" - name: Set up Gradle uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6 - - name: Build 1.19.4 dependency chain + - name: Build 1.20.1 dependency chain id: dependencies shell: bash run: | @@ -103,20 +103,18 @@ jobs: test "$(git -C "$power" rev-parse HEAD)" = "$POWERADVANTAGE_SOURCE_REF" test "$(git -C "$basemetals" rev-parse HEAD)" = "$BASEMETALS_SOURCE_REF" mavenizer="$orespawn/ci-fixtures/tools/minecraft-mavenizer-0.5.21-orespawn-compat.jar" - mavenizer_init="$GITHUB_WORKSPACE/gradle/forge45-mavenizer.init.gradle" - mavenizer_script="$GITHUB_WORKSPACE/gradle/forge45-mavenizer.gradle" - printf '%s %s\n' '341B3FB10ABA6EA7DC612FBE519DC290A1C81867AED5DD320ACD783688AC49DE' "$mavenizer" | sha256sum -c - + printf '%s %s\n' '416DCA4797BC55826F0DDCF03FDC405F1990FC15C2133FA27A1F143BF7976177' "$mavenizer" | sha256sum -c - chmod +x "$orespawn/gradlew" "$basemetals/gradlew" "$power/gradlew" (cd "$orespawn" && ./gradlew $MMD_GRADLE_TOOLCHAINS jar --no-daemon --stacktrace) (cd "$basemetals" && ./gradlew $MMD_GRADLE_TOOLCHAINS jar --no-daemon --stacktrace) - osjar="$orespawn/build/libs-dev/OreSpawn-4.1.0.119041-deobf.jar" - bmjar="$basemetals/build/libs-dev/BaseMetals-3.1.2.119041-deobf.jar" + osjar="$orespawn/build/libs-dev/OreSpawn-4.1.0.120011-deobf.jar" + bm_version=$(sed -n 's/^basemetals_version=//p' "$GITHUB_WORKSPACE/gradle.properties" | tr -d '\r') + bmjar="$basemetals/build/libs-dev/BaseMetals-$bm_version-deobf.jar" (cd "$power" && ./gradlew $MMD_GRADLE_TOOLCHAINS jar unitBootstrapJar verifyReleaseDependencies \ - -I "$mavenizer_init" "-Pforge45MavenizerScript=$mavenizer_script" \ - "-Pforge45MavenizerJar=$mavenizer" \ + "-Pforge47MavenizerJar=$mavenizer" \ -PbaseMetalsDeobfJar="$bmjar" -PoreSpawnDeobfJar="$osjar" \ --no-daemon --stacktrace) - powerjar="$power/build/libs-dev/basePower-2.4.11.119041-deobf.jar" + powerjar="$power/build/libs-dev/basePower-2.4.12.120011-deobf.jar" bootstrap="$power/build/unit-bootstrap/forge-native-unit-bootstrap.jar" test -f "$osjar" && test -f "$bmjar" && test -f "$powerjar" && test -f "$bootstrap" echo "orespawn=$osjar" >> "$GITHUB_OUTPUT" @@ -124,11 +122,15 @@ jobs: echo "power=$powerjar" >> "$GITHUB_OUTPUT" echo "bootstrap=$bootstrap" >> "$GITHUB_OUTPUT" echo "mavenizer=$mavenizer" >> "$GITHUB_OUTPUT" + - name: Verify source layout and recipe unlocks + run: | + node tools/verify-native-port.js + node tools/generate-recipe-unlocks.js --check - name: Build and audit release artifacts run: >- ./gradlew $MMD_GRADLE_TOOLCHAINS clean check build javadoc verifyReleaseDependencies verifyReleaseArtifacts writeReleaseChecksums verifyEclipseProductionClasspath - "-Pforge45MavenizerJar=${{ steps.dependencies.outputs.mavenizer }}" + "-Pforge47MavenizerJar=${{ steps.dependencies.outputs.mavenizer }}" -PforgeCapabilityBootstrapJar=${{ steps.dependencies.outputs.bootstrap }} -PpowerAdvantageDeobfJar=${{ steps.dependencies.outputs.power }} -PbaseMetalsDeobfJar=${{ steps.dependencies.outputs.basemetals }} @@ -137,20 +139,20 @@ jobs: - name: Upload audited release candidate uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: - name: baseSteam-1.19.4-${{ github.sha }} + name: baseSteam-1.20.1-${{ github.sha }} if-no-files-found: error retention-days: 30 path: | - build/libs/baseSteam-2.2.12.119041.jar - build/libs/baseSteam-2.2.12.119041-sources.jar - build/libs/baseSteam-2.2.12.119041-javadoc.jar + build/libs/baseSteam-2.2.13.120011.jar + build/libs/baseSteam-2.2.13.120011-sources.jar + build/libs/baseSteam-2.2.13.120011-javadoc.jar build/release/SHA256SUMS CHANGELOG.txt - name: Upload diagnostics on failure if: failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: - name: baseSteam-1.19.4-diagnostics-${{ github.sha }} + name: baseSteam-1.20.1-diagnostics-${{ github.sha }} if-no-files-found: ignore retention-days: 14 path: | diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 0089a00..6983c2d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -2,9 +2,9 @@ name: CodeQL on: push: - branches: [master-1.19.4, feature/basesteam-1.19.4-port] + branches: [master-1.20.1, feature/basesteam-1.20.1-port] pull_request: - branches: [master-1.19.4] + branches: [master-1.20.1] schedule: - cron: '53 7 * * 4' @@ -28,19 +28,19 @@ jobs: power_ref=$(sed -n 's/^poweradvantage_source_ref=//p' gradle.properties | tr -d '\r') power_hash=$(sed -n 's/^poweradvantage_deobf_sha256=//p' gradle.properties | tr -d '\r') if [[ ! "$power_ref" =~ ^[a-f0-9]{40}$ || ! "$power_hash" =~ ^[A-F0-9]{64}$ ]]; then - echo "::error::The exact basePower 1.19 dependency pin is pending." + echo "::error::The exact basePower 1.20.1 dependency pin is pending." exit 1 fi bm_ref=$(sed -n 's/^basemetals_source_commit=//p' gradle.properties | tr -d '\r') bm_hash=$(sed -n 's/^basemetals_deobf_sha256=//p' gradle.properties | tr -d '\r') if [[ ! "$bm_ref" =~ ^[a-f0-9]{40}$ || ! "$bm_hash" =~ ^[A-F0-9]{64}$ ]]; then - echo "::error::The exact Base Metals 1.19 dependency pin is pending." + echo "::error::The exact Base Metals 1.20.1 dependency pin is pending." exit 1 fi os_ref=$(sed -n 's/^orespawn_source_commit=//p' gradle.properties | tr -d '\r') os_hash=$(sed -n 's/^orespawn_deobf_sha256=//p' gradle.properties | tr -d '\r') if [[ ! "$os_ref" =~ ^[a-f0-9]{40}$ || ! "$os_hash" =~ ^[A-F0-9]{64}$ ]]; then - echo "::error::The exact OreSpawn 1.19 dependency pin is pending." + echo "::error::The exact OreSpawn 1.20.1 dependency pin is pending." exit 1 fi echo "ORESPAWN_SOURCE_REF=$os_ref" >> "$GITHUB_ENV" @@ -61,7 +61,7 @@ jobs: repository: MinecraftModDevelopmentMods/BaseMetals ref: ${{ env.BASEMETALS_SOURCE_REF }} path: .ci-dependencies/BaseMetals - - name: Check out basePower 1.19.4 + - name: Check out basePower 1.20.1 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/basePower @@ -91,7 +91,7 @@ jobs: -Porg.gradle.java.installations.auto-download=false" >> "$GITHUB_ENV" - name: Set up Gradle uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6 - - name: Build 1.19.4 dependency chain + - name: Build 1.20.1 dependency chain id: dependencies shell: bash run: | @@ -103,20 +103,18 @@ jobs: test "$(git -C "$power" rev-parse HEAD)" = "$POWERADVANTAGE_SOURCE_REF" test "$(git -C "$basemetals" rev-parse HEAD)" = "$BASEMETALS_SOURCE_REF" mavenizer="$orespawn/ci-fixtures/tools/minecraft-mavenizer-0.5.21-orespawn-compat.jar" - mavenizer_init="$GITHUB_WORKSPACE/gradle/forge45-mavenizer.init.gradle" - mavenizer_script="$GITHUB_WORKSPACE/gradle/forge45-mavenizer.gradle" - printf '%s %s\n' '341B3FB10ABA6EA7DC612FBE519DC290A1C81867AED5DD320ACD783688AC49DE' "$mavenizer" | sha256sum -c - + printf '%s %s\n' '416DCA4797BC55826F0DDCF03FDC405F1990FC15C2133FA27A1F143BF7976177' "$mavenizer" | sha256sum -c - chmod +x "$orespawn/gradlew" "$basemetals/gradlew" "$power/gradlew" (cd "$orespawn" && ./gradlew $MMD_GRADLE_TOOLCHAINS jar --no-daemon --stacktrace) (cd "$basemetals" && ./gradlew $MMD_GRADLE_TOOLCHAINS jar --no-daemon --stacktrace) - osjar="$orespawn/build/libs-dev/OreSpawn-4.1.0.119041-deobf.jar" - bmjar="$basemetals/build/libs-dev/BaseMetals-3.1.2.119041-deobf.jar" + osjar="$orespawn/build/libs-dev/OreSpawn-4.1.0.120011-deobf.jar" + bm_version=$(sed -n 's/^basemetals_version=//p' "$GITHUB_WORKSPACE/gradle.properties" | tr -d '\r') + bmjar="$basemetals/build/libs-dev/BaseMetals-$bm_version-deobf.jar" (cd "$power" && ./gradlew $MMD_GRADLE_TOOLCHAINS jar unitBootstrapJar verifyReleaseDependencies \ - -I "$mavenizer_init" "-Pforge45MavenizerScript=$mavenizer_script" \ - "-Pforge45MavenizerJar=$mavenizer" \ + "-Pforge47MavenizerJar=$mavenizer" \ -PbaseMetalsDeobfJar="$bmjar" -PoreSpawnDeobfJar="$osjar" \ --no-daemon --stacktrace) - powerjar="$power/build/libs-dev/basePower-2.4.11.119041-deobf.jar" + powerjar="$power/build/libs-dev/basePower-2.4.12.120011-deobf.jar" bootstrap="$power/build/unit-bootstrap/forge-native-unit-bootstrap.jar" test -f "$osjar" && test -f "$bmjar" && test -f "$powerjar" && test -f "$bootstrap" echo "orespawn=$osjar" >> "$GITHUB_OUTPUT" @@ -132,7 +130,7 @@ jobs: run: | chmod +x ./gradlew ./gradlew $MMD_GRADLE_TOOLCHAINS clean classes --rerun-tasks --no-build-cache --no-daemon --stacktrace \ - "-Pforge45MavenizerJar=${{ steps.dependencies.outputs.mavenizer }}" \ + "-Pforge47MavenizerJar=${{ steps.dependencies.outputs.mavenizer }}" \ -PforgeCapabilityBootstrapJar=${{ steps.dependencies.outputs.bootstrap }} \ -PpowerAdvantageDeobfJar=${{ steps.dependencies.outputs.power }} \ -PbaseMetalsDeobfJar=${{ steps.dependencies.outputs.basemetals }} \ diff --git a/.github/workflows/validate-gradle-build.yml b/.github/workflows/validate-gradle-build.yml index 81f747c..b641914 100644 --- a/.github/workflows/validate-gradle-build.yml +++ b/.github/workflows/validate-gradle-build.yml @@ -3,11 +3,11 @@ name: Validate Gradle Wrapper on: push: branches: - - master-1.19.4 - - feature/basesteam-1.19.4-port + - master-1.20.1 + - feature/basesteam-1.20.1-port pull_request: branches: - - master-1.19.4 + - master-1.20.1 permissions: contents: read diff --git a/CHANGELOG.txt b/CHANGELOG.txt index ea7425f..e0430b2 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,10 @@ +baseSteam 2.2.13.120011 (local Minecraft 1.20.1 port) + +- Move to Minecraft 1.20.1, Forge 47.4.10 and Java 17 with basePower 2.4.12.120011. +- Keep Steam machines, recipes, saves and the shared creative tab as before. +- Preserve steam track transparency, machine piston resistance and hidden helper drops. +- Keep musket reload feedback and fragile-block hits using the new item and block APIs. + baseSteam 2.2.12.119041 (local Minecraft 1.19.4 port) - Target Minecraft 1.19.4 / Forge 45.4.0 and Java 17 with basePower 2.4.11.119041. diff --git a/README.md b/README.md index 0544ec6..ad6b17e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # baseSteam -**Minecraft 1.19.4 (Forge), version 2.2.12.119041. Local port.** +**Minecraft 1.20.1 (Forge), version 2.2.13.120011. Local port.** baseSteam, formerly Steam Advantage, adds boilers, steam-powered machines, pumps, storage, elevators and a blackpowder musket to basePower. Its items and @@ -12,7 +12,7 @@ Back up your world and test the upgrade on a copy. Replace Steam Advantage and Power Advantage with baseSteam and basePower; do not install both sets of mods. The migration recognizes old Steam Advantage IDs and keeps the registry paths, machine settings and saved data used by earlier baseSteam versions. The -Minecraft 1.19.4 world upgrade still needs verification for this candidate. +Minecraft 1.20.1 world upgrade still needs verification for this candidate. Existing `basesteam-common.toml` settings take precedence. When that file is absent, baseSteam can copy `steamadvantage-common.toml` or import settings from an @@ -20,12 +20,12 @@ older `.cfg` file. The old config is left in place. ## Build Target -Minecraft 1.19.4, Forge 45.4.0, official 1.19.4 mappings and MCP -20230314.122934. ForgeGradle 7.0.34 and Gradle 9.6.1 run on Java 17. +Minecraft 1.20.1, Forge 47.4.0, official 1.20.1 mappings and MCP +20230612.114412. ForgeGradle 7.0.34 and Gradle 9.6.1 run on Java 17. Production compilation and launches use Temurin 17, class major 61. Mavenizer uses Java 25. The build requires the -[checksum-verified Forge 45 compatibility JAR](ci-fixtures/tools/README.md) -from the local OreSpawn 1.19.4 checkout or `-Pforge45MavenizerJar=`. +checksum-verified Forge 47 compatibility JAR +from the local OreSpawn 1.20.1 checkout or `-Pforge47MavenizerJar=`. It is not tracked here. Java 8 is only for older build utilities. @@ -33,21 +33,25 @@ The mod ID and resource namespace are `basesteam`; the Java implementation namespace is `zone.moddev.mc.basesteam`. The shared `cyano.poweradvantage.api` names remain in use. -basePower 2.4.11.119041 is required. Base Metals 3.1.2.119041 remains optional -in Forge and requires OreSpawn 4.1.0.119041 when installed. The CurseForge +basePower 2.4.12.120011 is required. Base Metals 3.1.2.120011 remains optional +in Forge and requires OreSpawn 4.1.0.120011 when installed. The CurseForge install metadata lists basePower and Base Metals. No dependency is embedded. ## Local Verification -Use the checked-in Gradle wrapper and supply explicit paths to the development -jars matching the pins in `gradle.properties`. Use a Steam-only Gradle user +Use the checked-in Gradle wrapper. With the usual sibling checkout layout the +build finds the basePower, Base Metals and OreSpawn development jars and the +basePower test bootstrap. Use explicit properties for alternate checkout paths. +All dependency jars must match the pins in `gradle.properties`. Use a Steam-only Gradle user home and the test-only Forge capability bootstrap. Player JARs are distinct from development and published JARs. Before a packaged smoke, run `verifyPlayerDependencies` with explicit `powerAdvantagePlayerJar`, -`baseMetalsPlayerJar` and `oreSpawnPlayerJar` project properties. +`baseMetalsPlayerJar` and `oreSpawnPlayerJar` project properties. The OreSpawn +paths default to `D:/MinecraftMineralogy/OS1201/OreSpawn` in the usual checkout +layout; the same SHA-256 checks apply to defaults and overrides. -Use the coordinated basePower 1.19.4 candidate and matching frozen JARs. -Pending pins fail closed. No 1.18.2 artifacts may satisfy the 1.19.4 audits. +Use the coordinated basePower 1.20.1 candidate and matching frozen JARs. +Pending pins fail closed. No 1.19.4 artifacts may satisfy the 1.20.1 audits. For example, from the Steam checkout in PowerShell: @@ -68,12 +72,13 @@ $env:GRADLE_USER_HOME = $env:BASESTEAM_GRADLE_USER_HOME ``` On other platforms use `./gradlew`. The artifact family is -`baseSteam-2.2.12.119041.jar`, plus sources and Javadoc. The development jar +`baseSteam-2.2.13.120011.jar`, plus sources and Javadoc. The development jar stays under `build/libs-dev`. `node tools/verify-native-port.js` and `node tools/generate-recipe-unlocks.js --check` -run without the dependency jars. [1.19.4 port status](docs/PORT119-STATUS.md) -tracks current checks. [1.18.2 port status](docs/PORT118-STATUS.md) is historical. +run without the dependency jars. The source check also verifies Java package +paths, which Buildship requires even when Gradle can compile misplaced files. +[1.19.4 port status](docs/PORT119-STATUS.md) is historical. [1.18.2 port status](docs/PORT118-STATUS.md) is historical. ## Port Details @@ -81,7 +86,7 @@ Native block-entity factories preserve their actual constructor position and block state. Loading NBT does not replace that position, including when a drill moves along a track. Power's shared native ticker retains per-tick work before the eight-tick power update on both logical sides. The drill-bit helper has its -own native ticker. Minecraft 1.19.4 uses `saveAdditional` for native saves, +own native ticker. Minecraft 1.20.1 uses `saveAdditional` for native saves, and the drill-bit direction packet carries the native block-entity type. The port retains first-loaded-tick redstone sampling in the crusher and furnace, @@ -117,6 +122,8 @@ drills in six directions and track moves with inventory and energy, helper rotation and cleanup, pumps, stills, elevator rides, GUI captions and controls, musket last-cartridge firing, terrain boundaries, sounds and enchantments, multiplayer synchronization and capability unload/reload. +Check that steam tracks render with transparent gaps, and that ordinary musket +shots still break fragile blocks and ignite TNT without breaking solid stone. Use disposable whole-world copies for upgrades. Preserve original worlds and backups; never reopen an upgraded world with an older Minecraft version. diff --git a/build.gradle b/build.gradle index b050e77..55bc1e1 100644 --- a/build.gradle +++ b/build.gradle @@ -14,22 +14,8 @@ plugins { id 'net.minecraftforge.gradle' version '7.0.34' } -apply from: 'gradle/forge45-mavenizer.gradle' - -def mavenizerFixtureHashes = [ - (file('ci-fixtures/tools/minecraft-source-compatibility.json')): - '33A3217261EBB8F37D45F50BD2F8CE70B221C014A5C15F4C5F8F9091AD6D1EC8', - (file('ci-fixtures/tools/minecraft-mavenizer-0.5.21-orespawn-compat.patch')): - 'D856190DEF5574716C5E4F4379912C451B1F5952B0B111576651A98EECF58544', - (file('ci-fixtures/tools/LICENSE-MAVENIZER.txt')): - '20C17D8B8C48A600800DFD14F95D5CB9FF47066A9641DDEAB48DC54AEC96E331' -] -mavenizerFixtureHashes.each { fixture, expected -> - if (!fixture.isFile() || MessageDigest.getInstance('SHA-256').digest(fixture.bytes) - .encodeHex().toString().toUpperCase(Locale.ROOT) != expected) { - throw new GradleException("Missing or invalid Forge 45 Mavenizer fixture: ${fixture.name}") - } -} +apply from: 'gradle/forge47-mavenizer.gradle' + group = project.mod_group version = project.mod_version base.archivesName = 'baseSteam' @@ -139,7 +125,7 @@ sourceSets.main.resources { def forgeRunModClassesDirectory = layout.buildDirectory.dir('forge-run-mod-classes/main') def prepareForgeRunModClasses = tasks.register('prepareForgeRunModClasses', Sync) { group = 'ide' - description = 'Merges classes and processed resources for Forge 45 launches.' + description = 'Merges classes and processed resources for Forge 47 launches.' dependsOn tasks.named('classes') from sourceSets.main.output into forgeRunModClassesDirectory @@ -177,10 +163,21 @@ repositories { // Only code and launch tasks require the exact jars; source/resource checks can run independently. def explicitJar = { String property -> providers.gradleProperty(property).map { file(it) }.getOrNull() } -def powerAdvantageDeobfJar = explicitJar('powerAdvantageDeobfJar') -def baseMetalsDeobfJar = explicitJar('baseMetalsDeobfJar') -def oreSpawnDeobfJar = explicitJar('oreSpawnDeobfJar') -def developmentJars = files([powerAdvantageDeobfJar, baseMetalsDeobfJar, oreSpawnDeobfJar].findAll { it != null }) +def powerRoot = '../../PowerAdvantage' +def baseMetalsRoot = '../../../../BaseMetals/BaseMetals 1201/BaseMetals' +def powerAdvantageDeobfJar = explicitJar('powerAdvantageDeobfJar') ?: file( + "${powerRoot}/build/libs-dev/basePower-${project.poweradvantage_version}-deobf.jar") +def baseMetalsDeobfJar = explicitJar('baseMetalsDeobfJar') ?: file( + "${baseMetalsRoot}/build/libs-dev/BaseMetals-${project.basemetals_version}-deobf.jar") +def oreSpawnRoot = '../../../../MinecraftMineralogy/OS1201/OreSpawn' +def oreSpawnJar = { String variant -> + String directory = variant == 'Deobf' ? 'libs-dev' : 'libs' + String classifier = variant == 'Deobf' ? '-deobf' : '' + explicitJar("oreSpawn${variant}Jar") ?: file( + "${oreSpawnRoot}/build/${directory}/OreSpawn-${project.orespawn_version}${classifier}.jar") +} +def oreSpawnDeobfJar = oreSpawnJar('Deobf') +def developmentJars = files(powerAdvantageDeobfJar, baseMetalsDeobfJar, oreSpawnDeobfJar) dependencies { implementation minecraft.dependency( @@ -218,7 +215,9 @@ def committedPin = { String key, pattern -> } pinned } -def forgeCapabilityBootstrapJar = providers.gradleProperty('forgeCapabilityBootstrapJar').map { file(it) } +def forgeCapabilityBootstrapJar = providers.gradleProperty('forgeCapabilityBootstrapJar') + .map { file(it) } + .orElse(file("${powerRoot}/build/unit-bootstrap/forge-native-unit-bootstrap.jar")) tasks.withType(Test).configureEach { inputs.files(forgeCapabilityBootstrapJar) inputs.property('powerBootstrapSha256', providers.gradleProperty('poweradvantage_test_bootstrap_sha256')) @@ -362,9 +361,9 @@ def expectedReleaseFiles = providers.provider { def preparedReleaseDir = providers.gradleProperty('preparedReleaseDir') def verifyPackFormats = { pack -> - if (pack.pack_format != 13 || pack['forge:server_data_pack_format'] != 12 + if (pack.pack_format != 15 || pack['forge:server_data_pack_format'] != 15 || pack.containsKey('forge:resource_pack_format') || pack.containsKey('forge:data_pack_format')) { - throw new GradleException('Minecraft 1.19.4 requires resource pack format 13 and data pack format 12') + throw new GradleException('Minecraft 1.20.1 requires resource and data pack format 15') } } @@ -373,15 +372,15 @@ tasks.register('verifyReleaseConfiguration') { description = 'Validates release identity, target metadata, and dependency policy.' doLast { verifyPackFormats(new JsonSlurper().parse(file('src/main/resources/pack.mcmeta')).pack) - if (project.mod_version != '2.2.12.119041') { + if (project.mod_version != '2.2.13.120011') { throw new GradleException("Unexpected baseSteam release version: ${project.mod_version}") } - if (project.minecraft_version != '1.19.4' || project.minecraft_version_range != '[1.19.4]' - || project.forge_version != '45.4.0' || project.forge_version_range != '[45.4.0,46)' - || project.loader_version_range != '[45,46)' + if (project.minecraft_version != '1.20.1' || project.minecraft_version_range != '[1.20.1]' + || project.forge_version != '47.4.10' || project.forge_version_range != '[47.4.10,48)' + || project.loader_version_range != '[47,48)' || project.mapping_channel != 'official' - || project.mapping_version != '1.19.4' - || project.mcp_version != '20230314.122934') { + || project.mapping_version != '1.20.1' + || project.mcp_version != '20230612.114412') { throw new GradleException('Unexpected Minecraft, Forge, or mappings target') } if (project.loader_name != 'forge' || project.loader_code != '1' @@ -401,27 +400,27 @@ tasks.register('verifyReleaseConfiguration') { } if (project.cf_requirements != 'basepower,base-metals' || project.cf_optionals != '' - || project.cf_versions != '1.19.4') { + || project.cf_versions != '1.20.1') { throw new GradleException('Unexpected CurseForge dependency or game-version metadata') } - if (project.basemetals_version != '3.1.2.119041' - || project.orespawn_version != '4.1.0.119041') { + if (project.basemetals_version != '3.1.2.120011' + || project.orespawn_version != '4.1.0.120011') { throw new GradleException('Unexpected development API versions') } - if (project.poweradvantage_version != '2.4.11.119041' + if (project.poweradvantage_version != '2.4.12.120011' || project.poweradvantage_source_repository != 'MinecraftModDevelopmentMods/basePower') { throw new GradleException('Unexpected basePower compile dependency identity') } String mainSource = file( 'src/main/java/zone/moddev/mc/basesteam/SteamAdvantage.java').getText('UTF-8') if (!mainSource.contains('MODID = "basesteam"') - || !mainSource.contains('VERSION = "2.2.12.119041"')) { + || !mainSource.contains('VERSION = "2.2.13.120011"')) { throw new GradleException('baseSteam source identity changed') } String metadata = file('src/main/resources/META-INF/mods.toml').getText('UTF-8').replace('\r\n', '\n') ['modId="basesteam"', 'displayName="baseSteam"', - 'modId="basepower"\nmandatory=true\nversionRange="[2.4.11.119041,3.0.0)"', - 'modId="basemetals"\nmandatory=false\nversionRange="[3.1.2.119041,4.0.0)"'].each { marker -> + 'modId="basepower"\nmandatory=true\nversionRange="[2.4.12.120011,3.0.0)"', + 'modId="basemetals"\nmandatory=false\nversionRange="[3.1.2.120011,4.0.0)"'].each { marker -> if (!metadata.contains(marker)) { throw new GradleException("Source mods.toml is missing ${marker}") } @@ -482,9 +481,9 @@ def auditCompanions = { boolean player -> String pin = player ? 'player' : 'deobf' committedPin('basemetals_source_commit', /[a-f0-9]{40}/) committedPin('orespawn_source_commit', /[a-f0-9]{40}/) - auditJar(explicitJar("baseMetals${variant}Jar"), "baseMetals${variant}Jar", "basemetals_${pin}_sha256", + auditJar(player ? explicitJar("baseMetals${variant}Jar") : baseMetalsDeobfJar, "baseMetals${variant}Jar", "basemetals_${pin}_sha256", 'basemetals', project.basemetals_version, baseMetalsApi) - auditJar(explicitJar("oreSpawn${variant}Jar"), "oreSpawn${variant}Jar", "orespawn_${pin}_sha256", + auditJar(oreSpawnJar(variant), "oreSpawn${variant}Jar", "orespawn_${pin}_sha256", 'orespawn', project.orespawn_version, oreSpawnApi) } @@ -871,7 +870,7 @@ eclipse { model.entries.add(processed) } } - synchronizationTasks 'isolateEclipseProductionRuns' + synchronizationTasks 'verifyJavaSourceLayout', 'isolateEclipseProductionRuns' } tasks.named('eclipseClasspath') { dependsOn tasks.named('processResources') } @@ -888,6 +887,8 @@ tasks.register('configureEclipseBuildship') { 'connection.gradle.user.home' : gradle.gradleUserHomeDir.canonicalPath, 'connection.project.dir' : '', 'gradle.user.home' : gradle.gradleUserHomeDir.canonicalPath, + 'java.home' : javaToolchains.launcherFor(java.toolchain) + .get().metadata.installationPath.asFile.canonicalPath, 'override.workspace.settings' : 'true' ].each { key, value -> preferences.setProperty(key, value) } preferencesFile.parentFile.mkdirs() @@ -902,7 +903,7 @@ tasks.register('isolateEclipseProductionRuns') { group = 'ide' description = 'Normalizes ForgeGradle Eclipse launches for production-only execution.' dependsOn tasks.named('genEclipseRuns') - dependsOn tasks.named('configureEclipseBuildship') + dependsOn tasks.named('configureEclipseBuildship'), tasks.named('verifyNativeDevelopmentDependencies') dependsOn prepareEclipseResources doLast { obsoleteForgeGradle2EclipseLaunches.each { String name, String mainClass -> @@ -1009,10 +1010,31 @@ tasks.register('isolateEclipseProductionRuns') { } } +def verifyJavaSourceLayout = tasks.register('verifyJavaSourceLayout') { + group = 'verification' + description = 'Checks package paths in every configured Java source root for Eclipse.' + doLast { + sourceSets.each { sourceSet -> + sourceSet.java.srcDirs.each { root -> + fileTree(root) { include '**/*.java' }.each { source -> + def relativePath = root.toPath().relativize(source.toPath()) + String expected = relativePath.parent?.collect { it.toString() }?.join('.') ?: '' + def declaration = source.getText('UTF-8') =~ /(?m)^\s*package\s+([\w.]+)\s*;/ + String actual = declaration.find() ? declaration.group(1) : '' + if (actual != expected) { + throw new GradleException("${sourceSet.name}: ${relativePath} declares '${actual}', " + + "but Eclipse expects '${expected}' under ${root}.") + } + } + } + } + } +} + tasks.register('verifyEclipseProductionClasspath') { group = 'verification' description = 'Verifies the generated Eclipse project and production launches.' - dependsOn tasks.named('eclipse') + dependsOn tasks.named('eclipse'), verifyJavaSourceLayout dependsOn tasks.named('isolateEclipseProductionRuns') doLast { File preferencesFile = file('.settings/org.eclipse.buildship.core.prefs') @@ -1086,7 +1108,7 @@ tasks.register('verifyEclipseProductionClasspath') { if (!arguments.contains('--main cpw.mods.bootstraplauncher.BootstrapLauncher') || !vmArguments.contains('--add-opens java.base/java.lang.invoke=ALL-UNNAMED') || contents.contains('net.minecraftforge.userdev.LaunchTesting')) { - throw new GradleException("${name} must retain the native Forge 45 bootstrap and Java 17 module access") + throw new GradleException("${name} must retain the native Forge 47 bootstrap and Java 17 module access") } if (launch.booleanAttribute.find { it.@key.text() == 'org.eclipse.jdt.launching.ATTR_EXCLUDE_TEST_CODE' @@ -1146,7 +1168,7 @@ tasks.register('verifyEclipseProductionClasspath') { || !arguments.contains("--fml.mcVersion ${project.minecraft_version}") || !arguments.contains("--fml.forgeVersion ${project.forge_version}") || !arguments.contains("--fml.mcpVersion ${project.mcp_version}")) { - throw new GradleException("${name} does not target the exact Forge 45 development runtime") + throw new GradleException("${name} does not target the exact Forge 47 development runtime") } } } @@ -1334,6 +1356,7 @@ tasks.register('verifyRecipeTagGuards') { } tasks.named('check') { + dependsOn verifyJavaSourceLayout dependsOn tasks.named('verifyReleaseConfiguration') dependsOn tasks.named('verifyModelAssets') dependsOn tasks.named('verifyRepositoryHygiene') diff --git a/gradle.properties b/gradle.properties index 5d7e518..9ca7fa4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,15 +5,15 @@ org.gradle.caching=true org.gradle.parallel=false net.minecraftforge.gradle.merge-source-sets=false -minecraft_version=1.19.4 -minecraft_version_range=[1.19.4] -forge_version=45.4.0 -forge_installer_sha256=6643BB8C21F409CC528FF656DAF60C206D304CC77BF529BBBAB4B336004DFC53 -forge_version_range=[45.4.0,46) -loader_version_range=[45,46) +minecraft_version=1.20.1 +minecraft_version_range=[1.20.1] +forge_version=47.4.10 +forge_installer_sha256=1912760B4CB6B803D8A826DE603C9076B1DA71EC2765E9A1F8C1CA78F65278E3 +forge_version_range=[47.4.10,48) +loader_version_range=[47,48) mapping_channel=official -mapping_version=1.19.4 -mcp_version=20230314.122934 +mapping_version=1.20.1 +mcp_version=20230612.114412 loader_name=forge loader_code=1 @@ -26,36 +26,36 @@ curseforge_project_id=1781373 mod_id=basesteam mod_name=baseSteam mod_license=GPL-3.0-only -mod_version=2.2.12.119041 +mod_version=2.2.13.120011 mod_group=zone.moddev.mc.basesteam mod_authors=DrCyano mod_description=Steam-powered machines and infrastructure for basePower. cf_requirements=basepower,base-metals cf_optionals= -cf_versions=1.19.4 +cf_versions=1.20.1 -poweradvantage_version=2.4.11.119041 +poweradvantage_version=2.4.12.120011 poweradvantage_source_repository=MinecraftModDevelopmentMods/basePower -# Verified local checkpoint; not a hosted/merged source pin. -poweradvantage_source_ref=c9995315e2aee9d9bffec8eb8b1191ad8a0faeb7 -poweradvantage_deobf_sha256=512FDEC9275B33533EF773C110E6229E0F07268775FAD4B5942A15B68A9EB87D +# Exact local checkpoints for coordinated testing, not published source pins. +poweradvantage_source_ref=c7843fdaaa9e407948a0aa6bc1e6d5562eac7bbe +poweradvantage_deobf_sha256=4FD489774396CC4776CBF21DCCE30DA0AD14E9542AE2FA7F58BFD767EB5D4F0F # Player jar is a separate runtime input, not a development jar or publication claim. -poweradvantage_player_sha256=E1689C1147F6F6F93F6516D9188A279093D6CCC2FF1FBEB506468B876BA03E60 +poweradvantage_player_sha256=7CBDDD402CB9BA79DB4037ABF03A213666E7E1FE12E5B8C2A32ABF67CC2F3AE6 poweradvantage_test_bootstrap_sha256=A93CD83EC42B09B730CB7715C10C6E53D47B22B557EFE68EDC95241D53BD4EB3 poweradvantage_test_bootstrap_source_sha256=0FB05554D6446BD5561BF9DE47B9F173E6F6C28E39A2BC877D359BB363CB1ABE -basemetals_version=3.1.2.119041 -basemetals_source_commit=a9fdd6842f2a2e1e2e5b9a0abf9178d5675df044 -basemetals_deobf_sha256=0AA993D6BADA54B11548EB5BE150CE0939232291F2D215B7DBAF149857976B2F -basemetals_player_sha256=991EA843EEDF5FA1E42E9984A07573C7D03D74230482230440E44EDCA895FA39 +basemetals_version=3.1.2.120011 +basemetals_source_commit=d9614e3d26a3b57ddff9703861f18a283c7e8358 +basemetals_deobf_sha256=A67EB0CB74971E53D528C4D4F1275AE007106D7F8F71DFE4A16FB50411BDCC28 +basemetals_player_sha256=30FC6777300E0E48FBB63E3250E86122DAFA38CCA5AD5878CB795C72B7CCCCDE -orespawn_version=4.1.0.119041 -orespawn_source_commit=444d86ef48db2bf54422901b067c51d5832197fc -orespawn_deobf_sha256=BE6973F68F1C310DFF8CDF89C12B34C62D68CAEA326C0F1528E486EE3ABC1000 -orespawn_player_sha256=1B2ECAA546E7FFB35863AC1D9FF92504471EE857045DCD01A068C5CA7F53CFFD +orespawn_version=4.1.0.120011 +orespawn_source_commit=9d9db6cd315c9fce542808aa2551c94bf9267e93 +orespawn_deobf_sha256=A0B096894DC48308D59455F7EC67AB0BBF7EB02354D903024A9E9E876EB07CBB +orespawn_player_sha256=E6BDE47C1BB0BF4D08396F1D1FD5B1D2D3F8A5DF09905F279D39E2601D7FE4B0 # Published runtime bytes are distinct from development API jars. basemetals_public_sha256=PENDING -orespawn_public_sha256=PENDING +orespawn_public_sha256=E6BDE47C1BB0BF4D08396F1D1FD5B1D2D3F8A5DF09905F279D39E2601D7FE4B0 diff --git a/gradle/forge45-mavenizer.init.gradle b/gradle/forge45-mavenizer.init.gradle deleted file mode 100644 index 3f28260..0000000 --- a/gradle/forge45-mavenizer.init.gradle +++ /dev/null @@ -1,12 +0,0 @@ -// Configure the pinned dependency builds without editing their checkouts. -gradle.beforeProject { Project p -> - if (p == p.rootProject) { - p.pluginManager.withPlugin('net.minecraftforge.gradle') { - def script = p.providers.gradleProperty('forge45MavenizerScript').get() - if (!p.providers.gradleProperty('forge45MavenizerJar').isPresent()) { - throw new GradleException('Supply -Pforge45MavenizerJar= for a pinned dependency build.') - } - p.apply(from: p.file(script)) - } - } -} diff --git a/gradle/forge45-mavenizer.gradle b/gradle/forge47-mavenizer.gradle similarity index 60% rename from gradle/forge45-mavenizer.gradle rename to gradle/forge47-mavenizer.gradle index f99e82a..a3fd70d 100644 --- a/gradle/forge45-mavenizer.gradle +++ b/gradle/forge47-mavenizer.gradle @@ -1,18 +1,18 @@ import java.security.MessageDigest import org.gradle.jvm.toolchain.JvmVendorSpec -// OreSpawn's Forge 45 fixture fixes eight decompiled record accessors. +// OreSpawn's Forge 47 fixture fixes eight decompiled record accessors. def tool = 'ci-fixtures/tools/minecraft-mavenizer-0.5.21-orespawn-compat.jar' -def defaultJar = "../../../../MinecraftMineralogy/OS119/OreSpawn/${tool}" -def fixture = file(providers.gradleProperty('forge45MavenizerJar').getOrElse(defaultJar)) -def expected = '341B3FB10ABA6EA7DC612FBE519DC290A1C81867AED5DD320ACD783688AC49DE' +def defaultJar = "../../../../MinecraftMineralogy/OS1201/OreSpawn/${tool}" +def fixture = file(providers.gradleProperty('forge47MavenizerJar').getOrElse(defaultJar)) +def expected = '416DCA4797BC55826F0DDCF03FDC405F1990FC15C2133FA27A1F143BF7976177' if (!fixture.isFile()) { - throw new GradleException("Forge 45 requires OreSpawn's Mavenizer fixture: ${fixture}. " - + "Use -Pforge45MavenizerJar= for another checkout layout.") + throw new GradleException("Forge 47 requires OreSpawn's Mavenizer fixture: ${fixture}. " + + "Use -Pforge47MavenizerJar= for another checkout layout.") } def actual = MessageDigest.getInstance('SHA-256').digest(fixture.bytes).encodeHex().toString().toUpperCase(Locale.ROOT) if (actual != expected) { - throw new GradleException("Forge 45 Mavenizer fixture SHA-256 mismatch: expected ${expected}, got ${actual}") + throw new GradleException("Forge 47 Mavenizer fixture SHA-256 mismatch: expected ${expected}, got ${actual}") } fgtools.configure('mavenizer') { diff --git a/src/main/java/zone/moddev/mc/basesteam/SteamAdvantage.java b/src/main/java/zone/moddev/mc/basesteam/SteamAdvantage.java index 5f44166..3cef4ac 100644 --- a/src/main/java/zone/moddev/mc/basesteam/SteamAdvantage.java +++ b/src/main/java/zone/moddev/mc/basesteam/SteamAdvantage.java @@ -28,12 +28,12 @@ import zone.moddev.mc.basesteam.migration.SteamConfigMigration; import zone.moddev.mc.basesteam.recipe.RecipeConditions; -/** Forge 1.19.4 entry point for baseSteam. */ +/** Forge 1.20.1 entry point for baseSteam. */ @Mod(SteamAdvantage.MODID) public final class SteamAdvantage { public static final String MODID = "basesteam"; public static final String NAME = "baseSteam"; - public static final String VERSION = "2.2.12.119041"; + public static final String VERSION = "2.2.13.120011"; public static final Logger LOGGER = LogManager.getLogger(MODID); public static float MUSKET_DAMAGE = 20.0F; diff --git a/src/main/java/zone/moddev/mc/basesteam/blocks/DrillBitBlock.java b/src/main/java/zone/moddev/mc/basesteam/blocks/DrillBitBlock.java index 623e66e..1e57274 100644 --- a/src/main/java/zone/moddev/mc/basesteam/blocks/DrillBitBlock.java +++ b/src/main/java/zone/moddev/mc/basesteam/blocks/DrillBitBlock.java @@ -2,30 +2,25 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.EntityBlock; -import net.minecraft.world.level.material.Material; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.core.Direction; -import java.util.Collections; -import java.util.List; import net.minecraft.core.BlockPos; import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.Explosion; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; -import net.minecraft.world.item.ItemStack; import zone.moddev.mc.basesteam.init.Power; -/** Hidden moving drill helper. It deliberately has no item form or drops. */ +/** Hidden moving drill helper. Its item stays hidden and never drops. */ public class DrillBitBlock extends Block implements EntityBlock { private static final VoxelShape SHAPE = Shapes.box(0.25D, 0.25D, 0.25D, 0.75D, 0.75D, 0.75D); public DrillBitBlock() { - super(Block.Properties.of(Material.METAL).strength(5.0F, 2000.0F).noOcclusion()); + super(SteamBlockProperties.metalHelper(2000.0F)); } @Override public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new DrillBitTileEntity(pos, state); } @@ -38,7 +33,6 @@ public net.minecraft.world.level.block.entity.BlockEntit } @Override public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { return SHAPE; } @Override public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { return SHAPE; } - @Override public List getDrops(BlockState state, LootContext.Builder context) { return Collections.emptyList(); } @Override public void entityInside(BlockState state, Level world, BlockPos pos, Entity victim) { diff --git a/src/main/java/zone/moddev/mc/basesteam/blocks/PlatformBlock.java b/src/main/java/zone/moddev/mc/basesteam/blocks/PlatformBlock.java index d1f5bb7..4100996 100644 --- a/src/main/java/zone/moddev/mc/basesteam/blocks/PlatformBlock.java +++ b/src/main/java/zone/moddev/mc/basesteam/blocks/PlatformBlock.java @@ -1,18 +1,13 @@ package zone.moddev.mc.basesteam.blocks; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.material.Material; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.state.properties.IntegerProperty; import net.minecraft.world.level.block.state.StateDefinition; -import java.util.Collections; -import java.util.List; import net.minecraft.core.BlockPos; import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import zone.moddev.mc.basesteam.init.Blocks; @@ -29,7 +24,7 @@ public class PlatformBlock extends Block { }; public PlatformBlock() { - super(Block.Properties.of(Material.METAL).strength(5.0F, 2000.0F).noOcclusion() + super(SteamBlockProperties.metalHelper(2000.0F) .isRedstoneConductor((state, world, pos) -> false) .isSuffocating((state, world, pos) -> false) .isViewBlocking((state, world, pos) -> false)); @@ -39,7 +34,6 @@ public PlatformBlock() { @Override protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(HEIGHT); } @Override public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { return SHAPES[state.getValue(HEIGHT)]; } @Override public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { return SHAPES[state.getValue(HEIGHT)]; } - @Override public List getDrops(BlockState state, LootContext.Builder context) { return Collections.emptyList(); } @Override public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean moving) { diff --git a/src/main/java/zone/moddev/mc/basesteam/blocks/PumpPipeBlock.java b/src/main/java/zone/moddev/mc/basesteam/blocks/PumpPipeBlock.java index b37defc..dbdb175 100644 --- a/src/main/java/zone/moddev/mc/basesteam/blocks/PumpPipeBlock.java +++ b/src/main/java/zone/moddev/mc/basesteam/blocks/PumpPipeBlock.java @@ -1,16 +1,11 @@ package zone.moddev.mc.basesteam.blocks; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.material.Material; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.item.ItemStack; -import java.util.Collections; -import java.util.List; import net.minecraft.core.BlockPos; import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.Explosion; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; @@ -20,12 +15,11 @@ public class PumpPipeBlock extends Block { private static final VoxelShape SHAPE = Shapes.box(0.0D, 0.25D, 0.0D, 0.75D, 1.0D, 1.0D); public PumpPipeBlock() { - super(Block.Properties.of(Material.METAL).strength(5.0F, 10.0F).noOcclusion()); + super(SteamBlockProperties.metalHelper(10.0F)); } @Override public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { return SHAPE; } @Override public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { return SHAPE; } - @Override public List getDrops(BlockState state, LootContext.Builder context) { return Collections.emptyList(); } @Override public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean moving) { diff --git a/src/main/java/zone/moddev/mc/basesteam/blocks/SteamBlockProperties.java b/src/main/java/zone/moddev/mc/basesteam/blocks/SteamBlockProperties.java new file mode 100644 index 0000000..8f17043 --- /dev/null +++ b/src/main/java/zone/moddev/mc/basesteam/blocks/SteamBlockProperties.java @@ -0,0 +1,20 @@ +package zone.moddev.mc.basesteam.blocks; + +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.material.MapColor; +import net.minecraft.world.level.material.PushReaction; + +/** Native block properties matching the old piston-like construction material. */ +final class SteamBlockProperties { + private SteamBlockProperties() {} + + static Block.Properties pistonLike() { + return Block.Properties.of().mapColor(MapColor.STONE).pushReaction(PushReaction.BLOCK) + .forceSolidOn().strength(0.75F); + } + + static Block.Properties metalHelper(float resistance) { + return Block.Properties.of().mapColor(MapColor.METAL).forceSolidOn().strength(5.0F, resistance) + .noOcclusion().noLootTable(); + } +} diff --git a/src/main/java/zone/moddev/mc/basesteam/blocks/SteamPipeBlock.java b/src/main/java/zone/moddev/mc/basesteam/blocks/SteamPipeBlock.java index d4c0b1d..a8558b0 100644 --- a/src/main/java/zone/moddev/mc/basesteam/blocks/SteamPipeBlock.java +++ b/src/main/java/zone/moddev/mc/basesteam/blocks/SteamPipeBlock.java @@ -1,12 +1,11 @@ package zone.moddev.mc.basesteam.blocks; import zone.moddev.mc.basesteam.init.Power; -import net.minecraft.world.level.material.Material; public class SteamPipeBlock extends cyano.poweradvantage.api.simple.BlockSimplePowerConduit{ public SteamPipeBlock() { - super(Material.PISTON, 0.75f, 2f/16f, Power.steam_power); + super(SteamBlockProperties.pistonLike(), 2f/16f, Power.steam_power); } } diff --git a/src/main/java/zone/moddev/mc/basesteam/blocks/SteamTrackBlock.java b/src/main/java/zone/moddev/mc/basesteam/blocks/SteamTrackBlock.java index 8de83d9..932a78a 100644 --- a/src/main/java/zone/moddev/mc/basesteam/blocks/SteamTrackBlock.java +++ b/src/main/java/zone/moddev/mc/basesteam/blocks/SteamTrackBlock.java @@ -1,7 +1,6 @@ package zone.moddev.mc.basesteam.blocks; import cyano.poweradvantage.api.simple.BlockSimplePowerConduit; -import net.minecraft.world.level.material.Material; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.core.BlockPos; import net.minecraft.world.phys.shapes.VoxelShape; @@ -12,7 +11,7 @@ public class SteamTrackBlock extends BlockSimplePowerConduit { public SteamTrackBlock() { - super(Properties.of(Material.PISTON).strength(0.75F).noOcclusion() + super(SteamBlockProperties.pistonLike().noOcclusion() .isRedstoneConductor((state, world, pos) -> false) .isSuffocating((state, world, pos) -> false) .isViewBlocking((state, world, pos) -> false), diff --git a/src/main/java/zone/moddev/mc/basesteam/graphics/ClientRegistration.java b/src/main/java/zone/moddev/mc/basesteam/graphics/ClientRegistration.java index 2c02d43..213a3a2 100644 --- a/src/main/java/zone/moddev/mc/basesteam/graphics/ClientRegistration.java +++ b/src/main/java/zone/moddev/mc/basesteam/graphics/ClientRegistration.java @@ -2,13 +2,10 @@ import net.minecraftforge.client.event.EntityRenderersEvent; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.ItemBlockRenderTypes; import net.minecraft.client.renderer.item.ItemProperties; import net.minecraft.resources.ResourceLocation; import zone.moddev.mc.basesteam.init.Items; import zone.moddev.mc.basesteam.items.MusketItem; -import zone.moddev.mc.basesteam.init.Blocks; import zone.moddev.mc.basesteam.init.Entities; /** Client-only renderer registration. */ @@ -21,7 +18,6 @@ public static void registerRenderers(EntityRenderersEvent.RegisterRenderers even public static void onClientSetup(FMLClientSetupEvent event) { event.enqueueWork(() -> { - ItemBlockRenderTypes.setRenderLayer(Blocks.steam_track, RenderType.cutout()); ItemProperties.register(Items.blackpowder_musket, new ResourceLocation("loaded"), (item, world, entity, seed) -> MusketItem.isLoaded(item) ? 1.0F : 0.0F); ItemProperties.register(Items.blackpowder_musket, new ResourceLocation("loading"), diff --git a/src/main/java/zone/moddev/mc/basesteam/gui/BlastFurnaceGUI.java b/src/main/java/zone/moddev/mc/basesteam/gui/BlastFurnaceGUI.java index 204d4cd..207b71a 100644 --- a/src/main/java/zone/moddev/mc/basesteam/gui/BlastFurnaceGUI.java +++ b/src/main/java/zone/moddev/mc/basesteam/gui/BlastFurnaceGUI.java @@ -21,7 +21,7 @@ public BlastFurnaceGUI() { @Override public void onTake(Player player, ItemStack stack) { - stack.onCraftedBy(player.level, player, stack.getCount()); + stack.onCraftedBy(player.level(), player, stack.getCount()); super.onTake(player, stack); } @Override @@ -47,8 +47,7 @@ public void onTake(Player player, ItemStack stack) * @param guiContainer This is the instance of GUIContainer that is drawing * the GUI. You need to use it to draw on the screen. For example:
-com.mojang.blaze3d.systems.RenderSystem.setShaderTexture(0, arrowTexture);
-guiContainer.blit(x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
+guiContainer.blit(arrowTexture, x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
 	   
* @param x This is the x coordinate (in pixels) from the top-left corner of * the GUI @@ -85,7 +84,7 @@ public void drawGUIDecorations(Object srcEntity, GUIContainer guiContainer, int GUIHelper.drawFlameProgress(x+30, y+46, 1f - target.getBurnLevel(), guiContainer); - GUIHelper.drawNeedle(x+tempPivotX, y+tempPivotY, z, temp); + GUIHelper.drawNeedle(guiContainer, x+tempPivotX, y+tempPivotY, z, temp); for(int i = 0; i < 3; i++){ GUIHelper.drawDownArrowProgress(arrowX+18*i,arrowY,progress[i],guiContainer); } diff --git a/src/main/java/zone/moddev/mc/basesteam/gui/CoalBoilerGUI.java b/src/main/java/zone/moddev/mc/basesteam/gui/CoalBoilerGUI.java index 28026a5..7460705 100644 --- a/src/main/java/zone/moddev/mc/basesteam/gui/CoalBoilerGUI.java +++ b/src/main/java/zone/moddev/mc/basesteam/gui/CoalBoilerGUI.java @@ -34,8 +34,7 @@ public CoalBoilerGUI() { * @param guiContainer This is the instance of GUIContainer that is drawing * the GUI. You need to use it to draw on the screen. For example:
-com.mojang.blaze3d.systems.RenderSystem.setShaderTexture(0, arrowTexture);
-guiContainer.blit(x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
+guiContainer.blit(arrowTexture, x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
 	   
* @param x This is the x coordinate (in pixels) from the top-left corner of * the GUI @@ -71,8 +70,8 @@ public void drawGUIDecorations(Object srcEntity, GUIContainer guiContainer, int oldWater = water; lastUpdate = t; - GUIHelper.drawNeedle(x+steamPivotX, y+steamPivotY, z, steam); - GUIHelper.drawNeedle(x+waterPivotX, y+waterPivotY, z, water); + GUIHelper.drawNeedle(guiContainer, x+steamPivotX, y+steamPivotY, z, steam); + GUIHelper.drawNeedle(guiContainer, x+waterPivotX, y+waterPivotY, z, water); GUIHelper.drawFlameProgress(x+80,y+58,1f-burn,guiContainer); } diff --git a/src/main/java/zone/moddev/mc/basesteam/gui/ElectricBoilerGUI.java b/src/main/java/zone/moddev/mc/basesteam/gui/ElectricBoilerGUI.java index a23ac18..cba6a30 100644 --- a/src/main/java/zone/moddev/mc/basesteam/gui/ElectricBoilerGUI.java +++ b/src/main/java/zone/moddev/mc/basesteam/gui/ElectricBoilerGUI.java @@ -34,8 +34,7 @@ public ElectricBoilerGUI() { * @param guiContainer This is the instance of GUIContainer that is drawing * the GUI. You need to use it to draw on the screen. For example:
-com.mojang.blaze3d.systems.RenderSystem.setShaderTexture(0, arrowTexture);
-guiContainer.blit(x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
+guiContainer.blit(arrowTexture, x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
 	   
* @param x This is the x coordinate (in pixels) from the top-left corner of * the GUI @@ -70,8 +69,8 @@ public void drawGUIDecorations(Object srcEntity, GUIContainer guiContainer, int oldWater = water; lastUpdate = t; - GUIHelper.drawNeedle(x+leftPivotX, y+leftPivotY, z, electricity); - GUIHelper.drawNeedle(x+rightPivotX, y+rightPivotY, z, water); + GUIHelper.drawNeedle(guiContainer, x+leftPivotX, y+leftPivotY, z, electricity); + GUIHelper.drawNeedle(guiContainer, x+rightPivotX, y+rightPivotY, z, water); } diff --git a/src/main/java/zone/moddev/mc/basesteam/gui/GUIHelper.java b/src/main/java/zone/moddev/mc/basesteam/gui/GUIHelper.java index 2130ccb..127d292 100644 --- a/src/main/java/zone/moddev/mc/basesteam/gui/GUIHelper.java +++ b/src/main/java/zone/moddev/mc/basesteam/gui/GUIHelper.java @@ -3,6 +3,8 @@ import cyano.poweradvantage.api.simple.SimpleMachineGUI.GUIContainer; import zone.moddev.mc.basepower.gui.FluidTankGUI; import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import net.minecraft.resources.ResourceLocation; @@ -23,6 +25,29 @@ public static float maxDelta(float newValue,float oldValue,float maxChange){ return newValue; } + public static void drawNeedle(GUIContainer container, float pivotX, float pivotY, float zLevel, float value) { + PoseStack pose = container.getMatrices(); + pose.pushPose(); + try { + positionNeedle(pose, pivotX, pivotY, zLevel, value); + container.blit(0, 0, 176, 0, 7, 35); + } finally { + pose.popPose(); + } + } + + static void positionNeedle(PoseStack pose, float pivotX, float pivotY, float zLevel, float value) { + pose.translate(pivotX, pivotY, zLevel); + pose.mulPose(Axis.ZP.rotationDegrees(needleRotation(value))); + pose.translate(-3.5F, -17.5F, 0.0F); + } + + private static float needleRotation(float value) { + return (displayLevel(value) - 0.5F) * 180.0F; + } + + /** @deprecated Use the screen-aware overload to draw with the machine texture. */ + @Deprecated public static void drawNeedle(float pivotX, float pivotY, float zLevel, float value) { value = displayLevel(value); @@ -112,9 +137,7 @@ public static void drawFluidBar(FluidStack fs, float barHeight, int xPos, int yP if(barHeight > 0){ FluidTankGUI.drawFluidFilledRectangle(guiContainer,fs,x+xPos, y+yPos+barSlotHeight-h,w, h,z); } - com.mojang.blaze3d.systems.RenderSystem.setShaderTexture(0, displayImage); - - guiContainer.blit(x+xPos-texMarginW, y+yPos-texMarginH, texOverlayX, texOverlayY, texOverlayW, texOverlayH); // x, y, textureOffsetX, textureOffsetY, width, height) + guiContainer.blit(displayImage, x+xPos-texMarginW, y+yPos-texMarginH, texOverlayX, texOverlayY, texOverlayW, texOverlayH); // x, y, textureOffsetX, textureOffsetY, width, height) } diff --git a/src/main/java/zone/moddev/mc/basesteam/gui/GeothermalBoilerGUI.java b/src/main/java/zone/moddev/mc/basesteam/gui/GeothermalBoilerGUI.java index e134547..25ecca3 100644 --- a/src/main/java/zone/moddev/mc/basesteam/gui/GeothermalBoilerGUI.java +++ b/src/main/java/zone/moddev/mc/basesteam/gui/GeothermalBoilerGUI.java @@ -34,8 +34,7 @@ public GeothermalBoilerGUI() { * @param guiContainer This is the instance of GUIContainer that is drawing * the GUI. You need to use it to draw on the screen. For example:
-com.mojang.blaze3d.systems.RenderSystem.setShaderTexture(0, arrowTexture);
-guiContainer.blit(x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
+guiContainer.blit(arrowTexture, x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
 	   
* @param x This is the x coordinate (in pixels) from the top-left corner of * the GUI @@ -70,8 +69,8 @@ public void drawGUIDecorations(Object srcEntity, GUIContainer guiContainer, int oldWater = water; lastUpdate = t; - GUIHelper.drawNeedle(x+leftPivotX, y+leftPivotY, z, temp); - GUIHelper.drawNeedle(x+rightPivotX, y+rightPivotY, z, water); + GUIHelper.drawNeedle(guiContainer, x+leftPivotX, y+leftPivotY, z, temp); + GUIHelper.drawNeedle(guiContainer, x+rightPivotX, y+rightPivotY, z, water); } diff --git a/src/main/java/zone/moddev/mc/basesteam/gui/OilBoilerGUI.java b/src/main/java/zone/moddev/mc/basesteam/gui/OilBoilerGUI.java index 77a8404..317348d 100644 --- a/src/main/java/zone/moddev/mc/basesteam/gui/OilBoilerGUI.java +++ b/src/main/java/zone/moddev/mc/basesteam/gui/OilBoilerGUI.java @@ -34,8 +34,7 @@ public OilBoilerGUI() { * @param guiContainer This is the instance of GUIContainer that is drawing * the GUI. You need to use it to draw on the screen. For example:
-com.mojang.blaze3d.systems.RenderSystem.setShaderTexture(0, arrowTexture);
-guiContainer.blit(x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
+guiContainer.blit(arrowTexture, x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
 	   
* @param x This is the x coordinate (in pixels) from the top-left corner of * the GUI @@ -64,7 +63,7 @@ public void drawGUIDecorations(Object srcEntity, GUIContainer guiContainer, int oldSteam = steam; lastUpdate = t; - GUIHelper.drawNeedle(x+steamPivotX, y+steamPivotY, z, steam); + GUIHelper.drawNeedle(guiContainer, x+steamPivotX, y+steamPivotY, z, steam); float fluidLevel = (float)target.getWaterTank().getFluidAmount() / (float)target.getWaterTank().getCapacity(); diff --git a/src/main/java/zone/moddev/mc/basesteam/gui/RockCrusherGUI.java b/src/main/java/zone/moddev/mc/basesteam/gui/RockCrusherGUI.java index 48d8b0e..1dfe92f 100644 --- a/src/main/java/zone/moddev/mc/basesteam/gui/RockCrusherGUI.java +++ b/src/main/java/zone/moddev/mc/basesteam/gui/RockCrusherGUI.java @@ -33,8 +33,7 @@ public RockCrusherGUI() { * @param guiContainer This is the instance of GUIContainer that is drawing * the GUI. You need to use it to draw on the screen. For example:
-com.mojang.blaze3d.systems.RenderSystem.setShaderTexture(0, arrowTexture);
-guiContainer.blit(x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
+guiContainer.blit(arrowTexture, x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
 	   
* @param x This is the x coordinate (in pixels) from the top-left corner of * the GUI @@ -65,7 +64,7 @@ public void drawGUIDecorations(Object srcEntity, GUIContainer guiContainer, int oldSteam = steam; lastUpdate = t; - GUIHelper.drawNeedle(x+steamPivotX, y+steamPivotY, z, steam); + GUIHelper.drawNeedle(guiContainer, x+steamPivotX, y+steamPivotY, z, steam); GUIHelper.drawDownArrowProgress(x+44,y+46,progress,guiContainer); } diff --git a/src/main/java/zone/moddev/mc/basesteam/gui/SteamDrillGUI.java b/src/main/java/zone/moddev/mc/basesteam/gui/SteamDrillGUI.java index a1d01a1..8575d52 100644 --- a/src/main/java/zone/moddev/mc/basesteam/gui/SteamDrillGUI.java +++ b/src/main/java/zone/moddev/mc/basesteam/gui/SteamDrillGUI.java @@ -33,8 +33,7 @@ public SteamDrillGUI() { * @param guiContainer This is the instance of GUIContainer that is drawing * the GUI. You need to use it to draw on the screen. For example:
-com.mojang.blaze3d.systems.RenderSystem.setShaderTexture(0, arrowTexture);
-guiContainer.blit(x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
+guiContainer.blit(arrowTexture, x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
 	   
* @param x This is the x coordinate (in pixels) from the top-left corner of * the GUI @@ -65,7 +64,7 @@ public void drawGUIDecorations(Object srcEntity, GUIContainer guiContainer, int oldSteam = steam; lastUpdate = t; - GUIHelper.drawNeedle(x+steamPivotX, y+steamPivotY, z, steam); + GUIHelper.drawNeedle(guiContainer, x+steamPivotX, y+steamPivotY, z, steam); GUIHelper.drawDownArrowProgress(x+44,y+46,progress,guiContainer); } diff --git a/src/main/java/zone/moddev/mc/basesteam/gui/SteamPumpGUI.java b/src/main/java/zone/moddev/mc/basesteam/gui/SteamPumpGUI.java index 47e53e9..79e72f1 100644 --- a/src/main/java/zone/moddev/mc/basesteam/gui/SteamPumpGUI.java +++ b/src/main/java/zone/moddev/mc/basesteam/gui/SteamPumpGUI.java @@ -34,8 +34,7 @@ public SteamPumpGUI() { * @param guiContainer This is the instance of GUIContainer that is drawing * the GUI. You need to use it to draw on the screen. For example:
-com.mojang.blaze3d.systems.RenderSystem.setShaderTexture(0, arrowTexture);
-guiContainer.blit(x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
+guiContainer.blit(arrowTexture, x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
 	   
* @param x This is the x coordinate (in pixels) from the top-left corner of * the GUI @@ -64,7 +63,7 @@ public void drawGUIDecorations(Object srcEntity, GUIContainer guiContainer, int oldSteam = steam; lastUpdate = t; - GUIHelper.drawNeedle(x+steamPivotX, y+steamPivotY, z, steam); + GUIHelper.drawNeedle(guiContainer, x+steamPivotX, y+steamPivotY, z, steam); float fluidLevel = (float)target.getTank().getFluidAmount() / (float)target.getTank().getCapacity(); FluidStack fs = target.getTank().getFluid(); diff --git a/src/main/java/zone/moddev/mc/basesteam/gui/SteamStillGUI.java b/src/main/java/zone/moddev/mc/basesteam/gui/SteamStillGUI.java index b999cc8..4c77f4c 100644 --- a/src/main/java/zone/moddev/mc/basesteam/gui/SteamStillGUI.java +++ b/src/main/java/zone/moddev/mc/basesteam/gui/SteamStillGUI.java @@ -34,8 +34,7 @@ public SteamStillGUI() { * @param guiContainer This is the instance of GUIContainer that is drawing * the GUI. You need to use it to draw on the screen. For example:
-com.mojang.blaze3d.systems.RenderSystem.setShaderTexture(0, arrowTexture);
-guiContainer.blit(x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
+guiContainer.blit(arrowTexture, x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
 	   
* @param x This is the x coordinate (in pixels) from the top-left corner of * the GUI @@ -64,7 +63,7 @@ public void drawGUIDecorations(Object srcEntity, GUIContainer guiContainer, int oldSteam = steam; lastUpdate = t; - GUIHelper.drawNeedle(x+steamPivotX, y+steamPivotY, z, steam); + GUIHelper.drawNeedle(guiContainer, x+steamPivotX, y+steamPivotY, z, steam); float fluidLevel = (float)target.getOutputTank().getFluidAmount() / (float)target.getOutputTank().getCapacity(); FluidStack fs = target.getOutputTank().getFluid(); diff --git a/src/main/java/zone/moddev/mc/basesteam/gui/SteamTankGUI.java b/src/main/java/zone/moddev/mc/basesteam/gui/SteamTankGUI.java index 467afac..a4429c1 100644 --- a/src/main/java/zone/moddev/mc/basesteam/gui/SteamTankGUI.java +++ b/src/main/java/zone/moddev/mc/basesteam/gui/SteamTankGUI.java @@ -33,8 +33,7 @@ public SteamTankGUI() { * @param guiContainer This is the instance of GUIContainer that is drawing * the GUI. You need to use it to draw on the screen. For example:
-com.mojang.blaze3d.systems.RenderSystem.setShaderTexture(0, arrowTexture);
-guiContainer.blit(x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
+guiContainer.blit(arrowTexture, x+79, y+35, 0, 0, arrowLength, 17); // x, y, textureOffsetX, textureOffsetY, width, height)
 	   
* @param x This is the x coordinate (in pixels) from the top-left corner of * the GUI @@ -63,7 +62,7 @@ public void drawGUIDecorations(Object srcEntity, GUIContainer guiContainer, int oldSteam = steam; lastUpdate = t; - GUIHelper.drawNeedle(x+steamPivotX, y+steamPivotY, z, steam); + GUIHelper.drawNeedle(guiContainer, x+steamPivotX, y+steamPivotY, z, steam); } diff --git a/src/main/java/zone/moddev/mc/basesteam/items/MusketItem.java b/src/main/java/zone/moddev/mc/basesteam/items/MusketItem.java index 3f1f8c7..563018a 100644 --- a/src/main/java/zone/moddev/mc/basesteam/items/MusketItem.java +++ b/src/main/java/zone/moddev/mc/basesteam/items/MusketItem.java @@ -14,7 +14,8 @@ import zone.moddev.mc.basesteam.init.Power; import net.minecraft.world.level.block.TntBlock; import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.material.Material; +import net.minecraft.core.registries.Registries; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.item.enchantment.EnchantmentHelper; import net.minecraft.world.entity.Entity; @@ -55,6 +56,8 @@ @SuppressWarnings("deprecation") public class MusketItem extends net.minecraft.world.item.Item{ + private static final TagKey FRAGILE_TARGETS = TagKey.create(Registries.BLOCK, + new ResourceLocation(SteamAdvantage.MODID, "musket_fragile")); public static final String NBT_DATA_KEY_LOADED = "loaded"; @@ -111,8 +114,8 @@ public InteractionResultHolder use(Level world, Player playerEntity, } @Override - public void onUsingTick(ItemStack stack, LivingEntity player, int count){ - if(player.level.isClientSide && count % 7 == 3 && isNotLoaded(stack)){ + public void onUseTick(Level level, LivingEntity player, ItemStack stack, int count){ + if(level.isClientSide && count % 7 == 3 && isNotLoaded(stack)){ // indicator to player that the gun is loading player.playSound(SoundType.STONE.getStepSound(), 0.5f, 1.0f); } @@ -189,19 +192,11 @@ protected void fire(ItemStack srcItemStack, LivingEntity playerEntity, BlockPos coord = ((BlockHitResult) rayTrace).getBlockPos(); if(!world.isOutsideBuildHeight(coord) && world.hasChunkAt(coord) && !world.isEmptyBlock(coord)){ BlockState bs = world.getBlockState(coord); - Material blockMat = bs.getMaterial(); - if(blockMat == net.minecraft.world.level.material.Material.GLASS - || blockMat == net.minecraft.world.level.material.Material.LEAVES - || blockMat == net.minecraft.world.level.material.Material.DECORATION - || blockMat == net.minecraft.world.level.material.Material.PLANT - || blockMat == net.minecraft.world.level.material.Material.REPLACEABLE_PLANT - || blockMat == net.minecraft.world.level.material.Material.WEB){ + if (bs.is(FRAGILE_TARGETS)) { world.destroyBlock(coord, true); - } else if (blockMat == net.minecraft.world.level.material.Material.EXPLOSIVE){ - if(world.getBlockState(coord).getBlock() instanceof TntBlock){ - TntBlock.explode(world, coord); - world.removeBlock(coord, false); - } + } else if (bs.getBlock() instanceof TntBlock) { + TntBlock.explode(world, coord); + world.removeBlock(coord, false); } } if(EnchantmentHelper.getItemEnchantmentLevel(Enchantments.high_explosive, srcItemStack) > 0){ diff --git a/src/main/java/zone/moddev/mc/basesteam/machines/BlastFurnaceBlock.java b/src/main/java/zone/moddev/mc/basesteam/machines/BlastFurnaceBlock.java index c2db0bf..8b3c39f 100644 --- a/src/main/java/zone/moddev/mc/basesteam/machines/BlastFurnaceBlock.java +++ b/src/main/java/zone/moddev/mc/basesteam/machines/BlastFurnaceBlock.java @@ -3,7 +3,6 @@ import cyano.poweradvantage.api.ConduitType; import cyano.poweradvantage.api.PoweredEntity; import zone.moddev.mc.basesteam.init.Power; -import net.minecraft.world.level.material.Material; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.core.BlockPos; import net.minecraft.world.level.Level; @@ -17,7 +16,7 @@ public class BlastFurnaceBlock extends cyano.poweradvantage.api.simple.BlockSimp public BlastFurnaceBlock() { - super(Material.PISTON, 0.75f, Power.steam_power); + super(machineProperties(0.75F), Power.steam_power); } @Override diff --git a/src/main/java/zone/moddev/mc/basesteam/machines/BlastFurnaceTileEntity.java b/src/main/java/zone/moddev/mc/basesteam/machines/BlastFurnaceTileEntity.java index 2df620e..21af33e 100644 --- a/src/main/java/zone/moddev/mc/basesteam/machines/BlastFurnaceTileEntity.java +++ b/src/main/java/zone/moddev/mc/basesteam/machines/BlastFurnaceTileEntity.java @@ -141,8 +141,7 @@ private boolean canSmelt(int slot) { if(output.isEmpty()) return false; ItemStack outputSlot = inventory[slot+3]; if(outputSlot == null) return true; - return (ItemStack.isSame(output, outputSlot) - && ItemStack.tagMatches(output, outputSlot) + return (ItemStack.isSameItemSameTags(output, outputSlot) && (output.getCount() + outputSlot.getCount()) <= outputSlot.getMaxStackSize()); } diff --git a/src/main/java/zone/moddev/mc/basesteam/machines/CoalBoilerBlock.java b/src/main/java/zone/moddev/mc/basesteam/machines/CoalBoilerBlock.java index d1bd7ac..64d02a1 100644 --- a/src/main/java/zone/moddev/mc/basesteam/machines/CoalBoilerBlock.java +++ b/src/main/java/zone/moddev/mc/basesteam/machines/CoalBoilerBlock.java @@ -5,7 +5,6 @@ import zone.moddev.mc.basepower.conduitnetwork.ConduitRegistry; import zone.moddev.mc.basepower.init.Fluids; import zone.moddev.mc.basesteam.init.Power; -import net.minecraft.world.level.material.Material; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.core.BlockPos; import net.minecraft.world.level.Explosion; @@ -22,7 +21,7 @@ public class CoalBoilerBlock extends cyano.poweradvantage.api.simple.BlockSimple public CoalBoilerBlock() { - super(Material.PISTON, 0.75f, Power.steam_power, Fluids.fluidConduit_general); + super(machineProperties(0.75F), Power.steam_power, Fluids.fluidConduit_general); } @Override diff --git a/src/main/java/zone/moddev/mc/basesteam/machines/ElectricBoilerBlock.java b/src/main/java/zone/moddev/mc/basesteam/machines/ElectricBoilerBlock.java index c701c1d..82b718f 100644 --- a/src/main/java/zone/moddev/mc/basesteam/machines/ElectricBoilerBlock.java +++ b/src/main/java/zone/moddev/mc/basesteam/machines/ElectricBoilerBlock.java @@ -5,7 +5,6 @@ import zone.moddev.mc.basepower.conduitnetwork.ConduitRegistry; import zone.moddev.mc.basepower.init.Fluids; import zone.moddev.mc.basesteam.init.Power; -import net.minecraft.world.level.material.Material; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.core.BlockPos; import net.minecraft.world.level.Explosion; @@ -17,7 +16,7 @@ public class ElectricBoilerBlock extends cyano.poweradvantage.api.simple.BlockS public ElectricBoilerBlock() { - super(Material.PISTON, 0.75f, Power.steam_power, ElectricBoilerTileEntity.ELECTRIC_POWER, Fluids.fluidConduit_general); + super(machineProperties(0.75F), Power.steam_power, ElectricBoilerTileEntity.ELECTRIC_POWER, Fluids.fluidConduit_general); } @Override diff --git a/src/main/java/zone/moddev/mc/basesteam/machines/GeothermalBoilerBlock.java b/src/main/java/zone/moddev/mc/basesteam/machines/GeothermalBoilerBlock.java index c710bd0..0a62b57 100644 --- a/src/main/java/zone/moddev/mc/basesteam/machines/GeothermalBoilerBlock.java +++ b/src/main/java/zone/moddev/mc/basesteam/machines/GeothermalBoilerBlock.java @@ -5,7 +5,6 @@ import zone.moddev.mc.basepower.conduitnetwork.ConduitRegistry; import zone.moddev.mc.basepower.init.Fluids; import zone.moddev.mc.basesteam.init.Power; -import net.minecraft.world.level.material.Material; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.core.BlockPos; import net.minecraft.world.level.Explosion; @@ -14,7 +13,7 @@ public class GeothermalBoilerBlock extends cyano.poweradvantage.api.simple.BlockSimplePowerMachine{ public GeothermalBoilerBlock() { - super(Material.PISTON, 0.75f, Power.steam_power, Fluids.fluidConduit_general); + super(machineProperties(0.75F), Power.steam_power, Fluids.fluidConduit_general); } @Override diff --git a/src/main/java/zone/moddev/mc/basesteam/machines/OilBoilerBlock.java b/src/main/java/zone/moddev/mc/basesteam/machines/OilBoilerBlock.java index 92c2ee5..64541b1 100644 --- a/src/main/java/zone/moddev/mc/basesteam/machines/OilBoilerBlock.java +++ b/src/main/java/zone/moddev/mc/basesteam/machines/OilBoilerBlock.java @@ -5,7 +5,6 @@ import zone.moddev.mc.basepower.conduitnetwork.ConduitRegistry; import zone.moddev.mc.basepower.init.Fluids; import zone.moddev.mc.basesteam.init.Power; -import net.minecraft.world.level.material.Material; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.core.BlockPos; import net.minecraft.world.level.Explosion; @@ -22,7 +21,7 @@ public class OilBoilerBlock extends cyano.poweradvantage.api.simple.BlockSimpleP public OilBoilerBlock() { - super(Material.PISTON, 0.75f, Power.steam_power, Fluids.fluidConduit_general); + super(machineProperties(0.75F), Power.steam_power, Fluids.fluidConduit_general); } @Override diff --git a/src/main/java/zone/moddev/mc/basesteam/machines/RockCrusherBlock.java b/src/main/java/zone/moddev/mc/basesteam/machines/RockCrusherBlock.java index d40da62..9ee77a5 100644 --- a/src/main/java/zone/moddev/mc/basesteam/machines/RockCrusherBlock.java +++ b/src/main/java/zone/moddev/mc/basesteam/machines/RockCrusherBlock.java @@ -3,7 +3,6 @@ import cyano.poweradvantage.api.ConduitType; import cyano.poweradvantage.api.PoweredEntity; import zone.moddev.mc.basesteam.init.Power; -import net.minecraft.world.level.material.Material; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.core.BlockPos; import net.minecraft.world.level.Level; @@ -17,7 +16,7 @@ public class RockCrusherBlock extends cyano.poweradvantage.api.simple.BlockSimpl public RockCrusherBlock() { - super(Material.PISTON, 0.75f, Power.steam_power); + super(machineProperties(0.75F), Power.steam_power); } @Override diff --git a/src/main/java/zone/moddev/mc/basesteam/machines/RockCrusherTileEntity.java b/src/main/java/zone/moddev/mc/basesteam/machines/RockCrusherTileEntity.java index 6e41f55..53227d5 100644 --- a/src/main/java/zone/moddev/mc/basesteam/machines/RockCrusherTileEntity.java +++ b/src/main/java/zone/moddev/mc/basesteam/machines/RockCrusherTileEntity.java @@ -59,7 +59,7 @@ public void tickUpdate(boolean isServerWorld) { } // reset progress when item in slot changes ItemStack input = inventory[0]; - if(itemCheck != null && (input == null || input.isEmpty() || ItemStack.isSame(itemCheck, input) == false)){ + if(itemCheck != null && (input == null || input.isEmpty() || !ItemStack.isSameItem(itemCheck, input))){ progress = 0; } itemCheck = (input == null || input.isEmpty()) ? null : input.copy(); @@ -190,7 +190,7 @@ public void onDataFieldUpdate() { private int canAddToOutputInventory(ItemStack output) { for(int i = 1; i < inventory.length; i++){ if(inventory[i] == null) {return i;} - if(ItemStack.isSame(output, inventory[i]) && ItemStack.tagMatches(output, inventory[i]) + if(ItemStack.isSameItemSameTags(output, inventory[i]) && (inventory[i].getCount() + output.getCount()) <= inventory[i].getMaxStackSize()){ return i; } diff --git a/src/main/java/zone/moddev/mc/basesteam/machines/SteamDrillBlock.java b/src/main/java/zone/moddev/mc/basesteam/machines/SteamDrillBlock.java index 268ad58..edeb118 100644 --- a/src/main/java/zone/moddev/mc/basesteam/machines/SteamDrillBlock.java +++ b/src/main/java/zone/moddev/mc/basesteam/machines/SteamDrillBlock.java @@ -5,7 +5,6 @@ import zone.moddev.mc.basepower.conduitnetwork.ConduitRegistry; import zone.moddev.mc.basesteam.blocks.DrillBitTileEntity; import zone.moddev.mc.basesteam.init.Power; -import net.minecraft.world.level.material.Material; import net.minecraft.world.level.block.state.properties.DirectionProperty; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.BlockStateProperties; @@ -32,7 +31,7 @@ public class SteamDrillBlock extends GUIBlock implements ITypedConduit { public static final DirectionProperty FACING = BlockStateProperties.FACING; public SteamDrillBlock(){ - super(Material.PISTON, 0.75f); + super(machineProperties(0.75F)); this.registerDefaultState(getStateDefinition().any().setValue(FACING, Direction.DOWN)); } diff --git a/src/main/java/zone/moddev/mc/basesteam/machines/SteamDrillTileEntity.java b/src/main/java/zone/moddev/mc/basesteam/machines/SteamDrillTileEntity.java index 1065e17..52097ad 100644 --- a/src/main/java/zone/moddev/mc/basesteam/machines/SteamDrillTileEntity.java +++ b/src/main/java/zone/moddev/mc/basesteam/machines/SteamDrillTileEntity.java @@ -131,8 +131,7 @@ private boolean hasSpaceForItems(List items) { private boolean canStack(ItemStack newItem, ItemStack slot) { if(slot == null || newItem == null) return true; - return ItemStack.isSame(newItem, slot) - && ItemStack.tagMatches(newItem, slot) + return ItemStack.isSameItemSameTags(newItem, slot) && (newItem.getCount() + slot.getCount() <= slot.getMaxStackSize()); } @@ -141,8 +140,7 @@ public ItemStack addItem(ItemStack in){ if(inventory[i] == null){ inventory[i] = in; return null; - } else if(ItemStack.isSame(in, inventory[i]) - && ItemStack.tagMatches(in, inventory[i])){ + } else if(ItemStack.isSameItemSameTags(in, inventory[i])){ // are stackable int maxStackSize = inventory[i].getMaxStackSize(); if(inventory[i].getCount() >= maxStackSize){ @@ -264,7 +262,7 @@ public void onDataFieldUpdate() { break; } if(powerAdvantageWorld().getBlockState(n).getBlock() != Blocks.drillbit){ - if(powerAdvantageWorld().isEmptyBlock(n) || powerAdvantageWorld().getBlockState(n).getMaterial().isReplaceable()){ + if(powerAdvantageWorld().isEmptyBlock(n) || powerAdvantageWorld().getBlockState(n).canBeReplaced()){ // this block is not worth mining, replace it DrillBitTileEntity.createDrillBitBlock(powerAdvantageWorld(), n, f); this.subtractEnergy(ENERGY_COST_DRILLBIT, Power.steam_power); @@ -451,8 +449,7 @@ private void inventoryTransfer(BlockPos adj, Direction otherFace) { inv.setChanged(); this.setChanged(); return; - } else if(ItemStack.isSame(theirItem, inventory[mySlot]) - && ItemStack.tagMatches(theirItem, inventory[mySlot]) + } else if(ItemStack.isSameItemSameTags(theirItem, inventory[mySlot]) && theirItem.getCount() < theirItem.getMaxStackSize() && theirItem.getCount() < inv.getMaxStackSize()){ theirItem.grow(1); diff --git a/src/main/java/zone/moddev/mc/basesteam/machines/SteamElevatorBlock.java b/src/main/java/zone/moddev/mc/basesteam/machines/SteamElevatorBlock.java index 18042db..d061eda 100644 --- a/src/main/java/zone/moddev/mc/basesteam/machines/SteamElevatorBlock.java +++ b/src/main/java/zone/moddev/mc/basesteam/machines/SteamElevatorBlock.java @@ -3,7 +3,6 @@ import cyano.poweradvantage.api.ConduitType; import cyano.poweradvantage.api.PoweredEntity; import zone.moddev.mc.basesteam.init.Power; -import net.minecraft.world.level.material.Material; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.core.BlockPos; import net.minecraft.world.level.Level; @@ -17,7 +16,7 @@ public class SteamElevatorBlock extends cyano.poweradvantage.api.simple.BlockSim public SteamElevatorBlock() { - super(Material.PISTON, 0.75f, Power.steam_power); + super(machineProperties(0.75F), Power.steam_power); } @Override diff --git a/src/main/java/zone/moddev/mc/basesteam/machines/SteamPumpBlock.java b/src/main/java/zone/moddev/mc/basesteam/machines/SteamPumpBlock.java index 4830820..ea97183 100644 --- a/src/main/java/zone/moddev/mc/basesteam/machines/SteamPumpBlock.java +++ b/src/main/java/zone/moddev/mc/basesteam/machines/SteamPumpBlock.java @@ -6,7 +6,6 @@ import zone.moddev.mc.basepower.init.Fluids; import zone.moddev.mc.basesteam.init.Blocks; import zone.moddev.mc.basesteam.init.Power; -import net.minecraft.world.level.material.Material; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.core.BlockPos; import net.minecraft.world.level.Explosion; @@ -23,7 +22,7 @@ public class SteamPumpBlock extends cyano.poweradvantage.api.simple.BlockSimpleP public SteamPumpBlock() { - super(Material.PISTON, 0.75f, Power.steam_power, Fluids.fluidConduit_general); + super(machineProperties(0.75F), Power.steam_power, Fluids.fluidConduit_general); } @Override diff --git a/src/main/java/zone/moddev/mc/basesteam/machines/SteamStillBlock.java b/src/main/java/zone/moddev/mc/basesteam/machines/SteamStillBlock.java index 9828a27..e8fc782 100644 --- a/src/main/java/zone/moddev/mc/basesteam/machines/SteamStillBlock.java +++ b/src/main/java/zone/moddev/mc/basesteam/machines/SteamStillBlock.java @@ -5,7 +5,6 @@ import zone.moddev.mc.basepower.conduitnetwork.ConduitRegistry; import zone.moddev.mc.basepower.init.Fluids; import zone.moddev.mc.basesteam.init.Power; -import net.minecraft.world.level.material.Material; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.core.BlockPos; import net.minecraft.world.level.Explosion; @@ -22,7 +21,7 @@ public class SteamStillBlock extends cyano.poweradvantage.api.simple.BlockSimple public SteamStillBlock() { - super(Material.PISTON, 0.75f, Power.steam_power, Fluids.fluidConduit_general); + super(machineProperties(0.75F), Power.steam_power, Fluids.fluidConduit_general); } @Override diff --git a/src/main/java/zone/moddev/mc/basesteam/machines/SteamTankBlock.java b/src/main/java/zone/moddev/mc/basesteam/machines/SteamTankBlock.java index 415a981..cd65238 100644 --- a/src/main/java/zone/moddev/mc/basesteam/machines/SteamTankBlock.java +++ b/src/main/java/zone/moddev/mc/basesteam/machines/SteamTankBlock.java @@ -3,7 +3,6 @@ import cyano.poweradvantage.api.ConduitType; import cyano.poweradvantage.api.PoweredEntity; import zone.moddev.mc.basesteam.init.Power; -import net.minecraft.world.level.material.Material; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.core.BlockPos; @@ -12,7 +11,7 @@ public class SteamTankBlock extends cyano.poweradvantage.api.simple.BlockSimplePowerMachine { public SteamTankBlock(){ - super(Material.PISTON, 0.75f, Power.steam_power); + super(machineProperties(0.75F), Power.steam_power); } @Override diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 717642a..789343a 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -14,14 +14,14 @@ description='''Steam-powered machines and infrastructure for basePower.''' [[dependencies.basesteam]] modId="basepower" mandatory=true -versionRange="[2.4.11.119041,3.0.0)" +versionRange="[2.4.12.120011,3.0.0)" ordering="AFTER" side="BOTH" [[dependencies.basesteam]] modId="basemetals" mandatory=false -versionRange="[3.1.2.119041,4.0.0)" +versionRange="[3.1.2.120011,4.0.0)" ordering="AFTER" side="BOTH" diff --git a/src/main/resources/assets/basesteam/models/block/steam_track_0.json b/src/main/resources/assets/basesteam/models/block/steam_track_0.json index 0750c36..64e8f3a 100644 --- a/src/main/resources/assets/basesteam/models/block/steam_track_0.json +++ b/src/main/resources/assets/basesteam/models/block/steam_track_0.json @@ -1,5 +1,6 @@ { "parent": "basepower:block/steel_frame", + "render_type": "minecraft:cutout", "textures": { "texture": "basesteam:blocks/steam_pipe", "particle": "basepower:materials/brass", diff --git a/src/main/resources/assets/basesteam/models/block/steam_track_densuw.json b/src/main/resources/assets/basesteam/models/block/steam_track_densuw.json index 7430fd1..bdc326a 100644 --- a/src/main/resources/assets/basesteam/models/block/steam_track_densuw.json +++ b/src/main/resources/assets/basesteam/models/block/steam_track_densuw.json @@ -1,5 +1,6 @@ { "parent": "basepower:block/steel_frame", + "render_type": "minecraft:cutout", "textures": { "texture": "basesteam:blocks/steam_pipe", "particle": "basepower:materials/brass", diff --git a/src/main/resources/assets/basesteam/models/block/steam_track_desuw.json b/src/main/resources/assets/basesteam/models/block/steam_track_desuw.json index 04263e2..04ae287 100644 --- a/src/main/resources/assets/basesteam/models/block/steam_track_desuw.json +++ b/src/main/resources/assets/basesteam/models/block/steam_track_desuw.json @@ -1,5 +1,6 @@ { "parent": "basepower:block/steel_frame", + "render_type": "minecraft:cutout", "textures": { "texture": "basesteam:blocks/steam_pipe", "particle": "basepower:materials/brass", diff --git a/src/main/resources/assets/basesteam/models/block/steam_track_dnu.json b/src/main/resources/assets/basesteam/models/block/steam_track_dnu.json index 81635ae..1706612 100644 --- a/src/main/resources/assets/basesteam/models/block/steam_track_dnu.json +++ b/src/main/resources/assets/basesteam/models/block/steam_track_dnu.json @@ -1,5 +1,6 @@ { "parent": "basepower:block/steel_frame", + "render_type": "minecraft:cutout", "textures": { "texture": "basesteam:blocks/steam_pipe", "particle": "basepower:materials/brass", diff --git a/src/main/resources/assets/basesteam/models/block/steam_track_ensw.json b/src/main/resources/assets/basesteam/models/block/steam_track_ensw.json index 9195ff2..cde5d4d 100644 --- a/src/main/resources/assets/basesteam/models/block/steam_track_ensw.json +++ b/src/main/resources/assets/basesteam/models/block/steam_track_ensw.json @@ -1,5 +1,6 @@ { "parent": "basepower:block/steel_frame", + "render_type": "minecraft:cutout", "textures": { "texture": "basesteam:blocks/steam_pipe", "particle": "basepower:materials/brass", diff --git a/src/main/resources/assets/basesteam/models/block/steam_track_n.json b/src/main/resources/assets/basesteam/models/block/steam_track_n.json index 7bcdce2..88620ac 100644 --- a/src/main/resources/assets/basesteam/models/block/steam_track_n.json +++ b/src/main/resources/assets/basesteam/models/block/steam_track_n.json @@ -1,5 +1,6 @@ { "parent": "basepower:block/steel_frame", + "render_type": "minecraft:cutout", "textures": { "texture": "basesteam:blocks/steam_pipe", "particle": "basepower:materials/brass", diff --git a/src/main/resources/assets/basesteam/models/block/steam_track_ns.json b/src/main/resources/assets/basesteam/models/block/steam_track_ns.json index 81e41f2..4c1700e 100644 --- a/src/main/resources/assets/basesteam/models/block/steam_track_ns.json +++ b/src/main/resources/assets/basesteam/models/block/steam_track_ns.json @@ -1,5 +1,6 @@ { "parent": "basepower:block/steel_frame", + "render_type": "minecraft:cutout", "textures": { "texture": "basesteam:blocks/steam_pipe", "particle": "basepower:materials/brass", diff --git a/src/main/resources/assets/basesteam/models/block/steam_track_nsuw.json b/src/main/resources/assets/basesteam/models/block/steam_track_nsuw.json index ff91233..d1f33d9 100644 --- a/src/main/resources/assets/basesteam/models/block/steam_track_nsuw.json +++ b/src/main/resources/assets/basesteam/models/block/steam_track_nsuw.json @@ -1,5 +1,6 @@ { "parent": "basepower:block/steel_frame", + "render_type": "minecraft:cutout", "textures": { "texture": "basesteam:blocks/steam_pipe", "particle": "basepower:materials/brass", diff --git a/src/main/resources/assets/basesteam/models/block/steam_track_nsw.json b/src/main/resources/assets/basesteam/models/block/steam_track_nsw.json index 775a307..e45a11d 100644 --- a/src/main/resources/assets/basesteam/models/block/steam_track_nsw.json +++ b/src/main/resources/assets/basesteam/models/block/steam_track_nsw.json @@ -1,5 +1,6 @@ { "parent": "basepower:block/steel_frame", + "render_type": "minecraft:cutout", "textures": { "texture": "basesteam:blocks/steam_pipe", "particle": "basepower:materials/brass", diff --git a/src/main/resources/assets/basesteam/models/block/steam_track_nuw.json b/src/main/resources/assets/basesteam/models/block/steam_track_nuw.json index c37df03..2c616b8 100644 --- a/src/main/resources/assets/basesteam/models/block/steam_track_nuw.json +++ b/src/main/resources/assets/basesteam/models/block/steam_track_nuw.json @@ -1,5 +1,6 @@ { "parent": "basepower:block/steel_frame", + "render_type": "minecraft:cutout", "textures": { "texture": "basesteam:blocks/steam_pipe", "particle": "basepower:materials/brass", diff --git a/src/main/resources/assets/basesteam/models/block/steam_track_nw.json b/src/main/resources/assets/basesteam/models/block/steam_track_nw.json index e9f0d90..1646262 100644 --- a/src/main/resources/assets/basesteam/models/block/steam_track_nw.json +++ b/src/main/resources/assets/basesteam/models/block/steam_track_nw.json @@ -1,5 +1,6 @@ { "parent": "basepower:block/steel_frame", + "render_type": "minecraft:cutout", "textures": { "texture": "basesteam:blocks/steam_pipe", "particle": "basepower:materials/brass", diff --git a/src/main/resources/data/basesteam/tags/blocks/musket_fragile.json b/src/main/resources/data/basesteam/tags/blocks/musket_fragile.json new file mode 100644 index 0000000..7603842 --- /dev/null +++ b/src/main/resources/data/basesteam/tags/blocks/musket_fragile.json @@ -0,0 +1,221 @@ +{ + "replace": false, + "values": [ + "minecraft:acacia_button", + "minecraft:acacia_leaves", + "minecraft:acacia_sapling", + "minecraft:activator_rail", + "minecraft:allium", + "minecraft:attached_melon_stem", + "minecraft:attached_pumpkin_stem", + "minecraft:azalea", + "minecraft:azalea_leaves", + "minecraft:azure_bluet", + "minecraft:bamboo_button", + "minecraft:beacon", + "minecraft:beetroots", + "minecraft:big_dripleaf", + "minecraft:big_dripleaf_stem", + "minecraft:birch_button", + "minecraft:birch_leaves", + "minecraft:birch_sapling", + "minecraft:black_candle", + "minecraft:black_stained_glass", + "minecraft:black_stained_glass_pane", + "minecraft:blue_candle", + "minecraft:blue_orchid", + "minecraft:blue_stained_glass", + "minecraft:blue_stained_glass_pane", + "minecraft:brown_candle", + "minecraft:brown_mushroom", + "minecraft:brown_stained_glass", + "minecraft:brown_stained_glass_pane", + "minecraft:candle", + "minecraft:carrots", + "minecraft:cave_vines", + "minecraft:cave_vines_plant", + "minecraft:cherry_button", + "minecraft:cherry_leaves", + "minecraft:cherry_sapling", + "minecraft:chorus_flower", + "minecraft:chorus_plant", + "minecraft:cobweb", + "minecraft:cocoa", + "minecraft:comparator", + "minecraft:conduit", + "minecraft:cornflower", + "minecraft:creeper_head", + "minecraft:creeper_wall_head", + "minecraft:crimson_button", + "minecraft:crimson_fungus", + "minecraft:cyan_candle", + "minecraft:cyan_stained_glass", + "minecraft:cyan_stained_glass_pane", + "minecraft:dandelion", + "minecraft:dark_oak_button", + "minecraft:dark_oak_leaves", + "minecraft:dark_oak_sapling", + "minecraft:dead_bush", + "minecraft:detector_rail", + "minecraft:dragon_head", + "minecraft:dragon_wall_head", + "minecraft:end_rod", + "minecraft:fern", + "minecraft:flower_pot", + "minecraft:flowering_azalea", + "minecraft:flowering_azalea_leaves", + "minecraft:glass", + "minecraft:glass_pane", + "minecraft:glow_lichen", + "minecraft:glowstone", + "minecraft:grass", + "minecraft:gray_candle", + "minecraft:gray_stained_glass", + "minecraft:gray_stained_glass_pane", + "minecraft:green_candle", + "minecraft:green_stained_glass", + "minecraft:green_stained_glass_pane", + "minecraft:hanging_roots", + "minecraft:jungle_button", + "minecraft:jungle_leaves", + "minecraft:jungle_sapling", + "minecraft:ladder", + "minecraft:large_fern", + "minecraft:lever", + "minecraft:light_blue_candle", + "minecraft:light_blue_stained_glass", + "minecraft:light_blue_stained_glass_pane", + "minecraft:light_gray_candle", + "minecraft:light_gray_stained_glass", + "minecraft:light_gray_stained_glass_pane", + "minecraft:lilac", + "minecraft:lily_of_the_valley", + "minecraft:lily_pad", + "minecraft:lime_candle", + "minecraft:lime_stained_glass", + "minecraft:lime_stained_glass_pane", + "minecraft:magenta_candle", + "minecraft:magenta_stained_glass", + "minecraft:magenta_stained_glass_pane", + "minecraft:mangrove_button", + "minecraft:mangrove_leaves", + "minecraft:mangrove_propagule", + "minecraft:melon_stem", + "minecraft:moss_carpet", + "minecraft:nether_wart", + "minecraft:oak_button", + "minecraft:oak_leaves", + "minecraft:oak_sapling", + "minecraft:orange_candle", + "minecraft:orange_stained_glass", + "minecraft:orange_stained_glass_pane", + "minecraft:orange_tulip", + "minecraft:oxeye_daisy", + "minecraft:peony", + "minecraft:piglin_head", + "minecraft:piglin_wall_head", + "minecraft:pink_candle", + "minecraft:pink_petals", + "minecraft:pink_stained_glass", + "minecraft:pink_stained_glass_pane", + "minecraft:pink_tulip", + "minecraft:player_head", + "minecraft:player_wall_head", + "minecraft:polished_blackstone_button", + "minecraft:poppy", + "minecraft:potatoes", + "minecraft:potted_acacia_sapling", + "minecraft:potted_allium", + "minecraft:potted_azalea_bush", + "minecraft:potted_azure_bluet", + "minecraft:potted_bamboo", + "minecraft:potted_birch_sapling", + "minecraft:potted_blue_orchid", + "minecraft:potted_brown_mushroom", + "minecraft:potted_cactus", + "minecraft:potted_cherry_sapling", + "minecraft:potted_cornflower", + "minecraft:potted_crimson_fungus", + "minecraft:potted_crimson_roots", + "minecraft:potted_dandelion", + "minecraft:potted_dark_oak_sapling", + "minecraft:potted_dead_bush", + "minecraft:potted_fern", + "minecraft:potted_flowering_azalea_bush", + "minecraft:potted_jungle_sapling", + "minecraft:potted_lily_of_the_valley", + "minecraft:potted_mangrove_propagule", + "minecraft:potted_oak_sapling", + "minecraft:potted_orange_tulip", + "minecraft:potted_oxeye_daisy", + "minecraft:potted_pink_tulip", + "minecraft:potted_poppy", + "minecraft:potted_red_mushroom", + "minecraft:potted_red_tulip", + "minecraft:potted_spruce_sapling", + "minecraft:potted_torchflower", + "minecraft:potted_warped_fungus", + "minecraft:potted_warped_roots", + "minecraft:potted_white_tulip", + "minecraft:potted_wither_rose", + "minecraft:powered_rail", + "minecraft:pumpkin_stem", + "minecraft:purple_candle", + "minecraft:purple_stained_glass", + "minecraft:purple_stained_glass_pane", + "minecraft:rail", + "minecraft:red_candle", + "minecraft:red_mushroom", + "minecraft:red_stained_glass", + "minecraft:red_stained_glass_pane", + "minecraft:red_tulip", + "minecraft:redstone_torch", + "minecraft:redstone_wall_torch", + "minecraft:redstone_wire", + "minecraft:repeater", + "minecraft:rose_bush", + "minecraft:scaffolding", + "minecraft:sea_lantern", + "minecraft:skeleton_skull", + "minecraft:skeleton_wall_skull", + "minecraft:small_dripleaf", + "minecraft:soul_torch", + "minecraft:soul_wall_torch", + "minecraft:spore_blossom", + "minecraft:spruce_button", + "minecraft:spruce_leaves", + "minecraft:spruce_sapling", + "minecraft:stone_button", + "minecraft:sugar_cane", + "minecraft:sunflower", + "minecraft:sweet_berry_bush", + "minecraft:tall_grass", + "minecraft:tinted_glass", + "minecraft:torch", + "minecraft:torchflower", + "minecraft:torchflower_crop", + "minecraft:tripwire", + "minecraft:tripwire_hook", + "minecraft:twisting_vines", + "minecraft:twisting_vines_plant", + "minecraft:vine", + "minecraft:wall_torch", + "minecraft:warped_button", + "minecraft:warped_fungus", + "minecraft:weeping_vines", + "minecraft:weeping_vines_plant", + "minecraft:wheat", + "minecraft:white_candle", + "minecraft:white_stained_glass", + "minecraft:white_stained_glass_pane", + "minecraft:white_tulip", + "minecraft:wither_rose", + "minecraft:wither_skeleton_skull", + "minecraft:wither_skeleton_wall_skull", + "minecraft:yellow_candle", + "minecraft:yellow_stained_glass", + "minecraft:yellow_stained_glass_pane", + "minecraft:zombie_head", + "minecraft:zombie_wall_head" + ] +} diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta index 0d628d2..d432f64 100644 --- a/src/main/resources/pack.mcmeta +++ b/src/main/resources/pack.mcmeta @@ -1,7 +1,7 @@ { "pack":{ - "pack_format":13, - "forge:server_data_pack_format":12, + "pack_format":15, + "forge:server_data_pack_format":15, "description":"baseSteam" } } diff --git a/src/test/java/zone/moddev/mc/basesteam/gui/GUIHelperTest.java b/src/test/java/zone/moddev/mc/basesteam/gui/GUIHelperTest.java index 1de5899..e18b274 100644 --- a/src/test/java/zone/moddev/mc/basesteam/gui/GUIHelperTest.java +++ b/src/test/java/zone/moddev/mc/basesteam/gui/GUIHelperTest.java @@ -1,5 +1,7 @@ package zone.moddev.mc.basesteam.gui; +import com.mojang.blaze3d.vertex.PoseStack; +import org.joml.Vector3f; import org.junit.Test; import static org.junit.Assert.*; @@ -12,6 +14,23 @@ public class GUIHelperTest { assertEquals(1F, GUIHelper.displayLevel(15F), 0F); } + @Test public void needleSweepsLeftToRightThroughTheSamePivot() { + for (float value : new float[] {0F, 0.25F, 0.5F, 0.75F, 1F, Float.NaN}) { + PoseStack pose = new PoseStack(); + GUIHelper.positionNeedle(pose, 44F, 40F, 1F, value); + var transform = pose.last().pose(); + var pivot = transform.transformPosition(new Vector3f(3.5F, 17.5F, 0F)); + assertEquals(44F, pivot.x, 0.0001F); + assertEquals(40F, pivot.y, 0.0001F); + assertEquals(1F, pivot.z, 0.0001F); + var tip = transform.transformPosition(new Vector3f(3.5F, 0F, 0F)); + // Independent geometry from the previous native vertex implementation. + double legacyAngle = (1D - (Float.isNaN(value) ? 0D : value)) * Math.PI; + assertEquals(44D + Math.cos(legacyAngle) * 17.5D, tip.x, 0.0001D); + assertEquals(40D - Math.sin(legacyAngle) * 17.5D, tip.y, 0.0001D); + } + } + @Test public void nonfiniteReadingsAreSafeToDraw() { for (float value : new float[]{Float.NaN, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY}) { assertEquals(0F, GUIHelper.displayLevel(value), 0F); diff --git a/src/test/java/zone/moddev/mc/basesteam/items/MusketTargetingContractTest.java b/src/test/java/zone/moddev/mc/basesteam/items/MusketTargetingContractTest.java index d88323d..6b1864f 100644 --- a/src/test/java/zone/moddev/mc/basesteam/items/MusketTargetingContractTest.java +++ b/src/test/java/zone/moddev/mc/basesteam/items/MusketTargetingContractTest.java @@ -11,6 +11,7 @@ import org.objectweb.asm.ClassReader; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldInsnNode; import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodNode; import static org.junit.Assert.*; @@ -49,12 +50,24 @@ public class MusketTargetingContractTest { assertEquals(Vec3.ZERO, hit.get()); } - @Test public void targetingUsesLoadedServerEntitiesAndTerrainBeforeEntitySelection() throws Exception { - ClassNode node = new ClassNode(); - try (InputStream input = getClass().getResourceAsStream("/zone/moddev/mc/basesteam/items/MusketItem.class")) { - assertNotNull(input); - new ClassReader(input).accept(node, 0); + @Test public void nativeUseTickRetainsTheClientReloadSound() throws Exception { + MethodNode useTick = musketBytecode().methods.stream().filter(method -> method.name.equals("onUseTick")) + .findFirst().orElseThrow(() -> new AssertionError("Missing Minecraft's onUseTick override")); + boolean clientGate = false, loadGate = false, sound = false; + for (AbstractInsnNode instruction : useTick.instructions.toArray()) { + if (instruction instanceof FieldInsnNode field && field.name.equals("isClientSide")) clientGate = true; + if (!(instruction instanceof MethodInsnNode call)) continue; + if (call.name.equals("isNotLoaded")) loadGate = true; + if (call.name.equals("playSound")) { + assertTrue("Reload sound must be client-only and stop when loaded", clientGate && loadGate); + sound = true; + } } + assertTrue("Native use tick no longer plays reload feedback", sound); + } + + @Test public void targetingUsesLoadedServerEntitiesAndTerrainBeforeEntitySelection() throws Exception { + ClassNode node = musketBytecode(); MethodNode trace = node.methods.stream().filter(method -> method.name.equals("rayTraceBlocksAndEntities")) .findFirst().orElseThrow(() -> new AssertionError("Missing targeting method")); boolean terrain = false, loadedEntities = false, boundedSelection = false, spectatorFilter = false; @@ -74,6 +87,15 @@ public class MusketTargetingContractTest { assertTrue("Loaded-entity iteration must preserve the previous spectator exclusion", spectatorFilter); } + private ClassNode musketBytecode() throws Exception { + ClassNode node = new ClassNode(); + try (InputStream input = getClass().getResourceAsStream("/zone/moddev/mc/basesteam/items/MusketItem.class")) { + assertNotNull(input); + new ClassReader(input).accept(node, 0); + } + return node; + } + private static AABB around(Vec3 center) { return new AABB(center.x - 0.5, center.y - 0.5, center.z - 0.5, center.x + 0.5, center.y + 0.5, center.z + 0.5); diff --git a/src/test/java/zone/moddev/mc/basesteam/machines/CoalBoilerFillPersistenceTest.java b/src/test/java/zone/moddev/mc/basesteam/machines/CoalBoilerFillPersistenceTest.java index 16bd084..a9a1957 100644 --- a/src/test/java/zone/moddev/mc/basesteam/machines/CoalBoilerFillPersistenceTest.java +++ b/src/test/java/zone/moddev/mc/basesteam/machines/CoalBoilerFillPersistenceTest.java @@ -215,6 +215,6 @@ private static SaveWorld world(boolean remote) { } } private static final class SaveWorld extends net.minecraft.server.level.ServerLevel { - private SaveWorld() { super(null, null, null, null, null, null, null, false, 0L, java.util.Collections.emptyList(), false); } + private SaveWorld() { super(null, null, null, null, null, null, null, false, 0L, java.util.Collections.emptyList(), false, null); } } } diff --git a/src/test/java/zone/moddev/mc/basesteam/machines/RockCrusherReloadRedstoneTest.java b/src/test/java/zone/moddev/mc/basesteam/machines/RockCrusherReloadRedstoneTest.java index 8bee790..a279aac 100644 --- a/src/test/java/zone/moddev/mc/basesteam/machines/RockCrusherReloadRedstoneTest.java +++ b/src/test/java/zone/moddev/mc/basesteam/machines/RockCrusherReloadRedstoneTest.java @@ -83,7 +83,7 @@ private static final class ControlSample extends RuntimeException {} private static final class ControlWorld extends ServerLevel { boolean powered, stopAtFirstSample; int samples; - private ControlWorld() { super(null, null, null, null, null, null, null, false, 0L, java.util.Collections.emptyList(), false); } + private ControlWorld() { super(null, null, null, null, null, null, null, false, 0L, java.util.Collections.emptyList(), false, null); } @Override public boolean hasNeighborSignal(BlockPos pos) { samples++; if (stopAtFirstSample) throw new ControlSample(); diff --git a/src/test/java/zone/moddev/mc/basesteam/machines/SteamDrillPersistenceTest.java b/src/test/java/zone/moddev/mc/basesteam/machines/SteamDrillPersistenceTest.java index d5ad3fc..1da373c 100644 --- a/src/test/java/zone/moddev/mc/basesteam/machines/SteamDrillPersistenceTest.java +++ b/src/test/java/zone/moddev/mc/basesteam/machines/SteamDrillPersistenceTest.java @@ -92,6 +92,24 @@ public class SteamDrillPersistenceTest { assertEquals(23, output.getCount()); } + @Test public void drillOutputDoesNotMergeStacksWithDifferentTags() { + SteamDrillTileEntity drill = new SteamDrillTileEntity(); + ItemStack first = new ItemStack(net.minecraft.world.item.Items.COBBLESTONE, 8); + first.getOrCreateTag().putString("source", "first"); + ItemStack different = new ItemStack(net.minecraft.world.item.Items.COBBLESTONE, 4); + different.getOrCreateTag().putString("source", "second"); + ItemStack matching = first.copy(); + matching.setCount(3); + + assertNull(drill.addItem(first)); + assertNull(drill.addItem(different)); + assertNull(drill.addItem(matching)); + assertEquals(11, drill.getItem(0).getCount()); + assertEquals("first", drill.getItem(0).getTag().getString("source")); + assertEquals(4, drill.getItem(1).getCount()); + assertEquals("second", drill.getItem(1).getTag().getString("source")); + } + @Test public void serializationNeverLooksUpTheWorldOrInfersNeighbours() throws Exception { ClassNode node = new ClassNode(); try (InputStream input = SteamDrillTileEntity.class.getResourceAsStream("SteamDrillTileEntity.class")) { diff --git a/src/test/java/zone/moddev/mc/basesteam/machines/SteamOperationalPumpSourceTest.java b/src/test/java/zone/moddev/mc/basesteam/machines/SteamOperationalPumpSourceTest.java index 75116c0..b680e99 100644 --- a/src/test/java/zone/moddev/mc/basesteam/machines/SteamOperationalPumpSourceTest.java +++ b/src/test/java/zone/moddev/mc/basesteam/machines/SteamOperationalPumpSourceTest.java @@ -7,7 +7,6 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.BucketPickup; -import net.minecraft.world.level.material.Material; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.Fluids; @@ -55,7 +54,7 @@ public class SteamOperationalPumpSourceTest { } @Test public void unsupportedModSourceIsNeverReplacedOrCredited() { - Block host = new Block(Block.Properties.of(Material.STONE)) { + Block host = new Block(Block.Properties.of()) { @Override public FluidState getFluidState(BlockState state) { return Fluids.WATER.defaultFluidState(); } }; BlockState source = host.defaultBlockState(); @@ -130,7 +129,7 @@ private static MethodNode method(ClassNode node, String name) { private static final class RefusingSource extends Block implements BucketPickup { private int pickups; - private RefusingSource() { super(Block.Properties.of(Material.STONE)); } + private RefusingSource() { super(Block.Properties.of()); } @Override public FluidState getFluidState(BlockState state) { return Fluids.WATER.defaultFluidState(); } @Override public net.minecraft.world.item.ItemStack pickupBlock(LevelAccessor world, BlockPos pos, BlockState state) { pickups++; diff --git a/src/test/java/zone/moddev/mc/basesteam/machines/WaterBoilerTankNotificationTest.java b/src/test/java/zone/moddev/mc/basesteam/machines/WaterBoilerTankNotificationTest.java index 71c2b02..524409e 100644 --- a/src/test/java/zone/moddev/mc/basesteam/machines/WaterBoilerTankNotificationTest.java +++ b/src/test/java/zone/moddev/mc/basesteam/machines/WaterBoilerTankNotificationTest.java @@ -161,6 +161,6 @@ private static Level world(boolean client) { } catch (ReflectiveOperationException failure) { throw new AssertionError(failure); } } private static final class SaveWorld extends net.minecraft.server.level.ServerLevel { - private SaveWorld() { super(null, null, null, null, null, null, null, false, 0L, java.util.Collections.emptyList(), false); } + private SaveWorld() { super(null, null, null, null, null, null, null, false, 0L, java.util.Collections.emptyList(), false, null); } } } diff --git a/src/test/java/zone/moddev/mc/basesteam/resources/BuildWorkflowContractTest.java b/src/test/java/zone/moddev/mc/basesteam/resources/BuildWorkflowContractTest.java index 7fa157e..034ecd6 100644 --- a/src/test/java/zone/moddev/mc/basesteam/resources/BuildWorkflowContractTest.java +++ b/src/test/java/zone/moddev/mc/basesteam/resources/BuildWorkflowContractTest.java @@ -8,8 +8,7 @@ public class BuildWorkflowContractTest { @Test public void everyHostedBuildUsesPinnedToolchainProjectProperties() throws Exception { - assertTrue(Files.isRegularFile(Paths.get("gradle/forge45-mavenizer.init.gradle"))); - assertTrue(Files.isRegularFile(Paths.get("gradle/forge45-mavenizer.gradle"))); + assertTrue(Files.isRegularFile(Paths.get("gradle/forge47-mavenizer.gradle"))); java.util.Properties pins = new java.util.Properties(); try (java.io.Reader reader = Files.newBufferedReader(Paths.get("gradle.properties"), StandardCharsets.UTF_8)) { pins.load(reader); @@ -26,19 +25,20 @@ public class BuildWorkflowContractTest { String source = new String(Files.readAllBytes(Paths.get(".github/workflows", name)), StandardCharsets.UTF_8); assertTrue(name, source.contains("ref: ${{ env.BASEMETALS_SOURCE_REF }}")); - assertTrue(name, source.contains("BaseMetals-" + pins.getProperty("basemetals_version") + "-deobf.jar")); + assertTrue(name, source.contains("sed -n 's/^basemetals_version=//p'")); + assertTrue(name, source.contains("BaseMetals-$bm_version-deobf.jar")); assertTrue(name, source.contains("repository: " + pins.getProperty("poweradvantage_source_repository"))); assertTrue(name, source.contains("basePower-" + pins.getProperty("poweradvantage_version") + "-deobf.jar")); assertTrue(name, source.contains("ref: ${{ env.ORESPAWN_SOURCE_REF }}")); assertTrue(name, source.contains("ref: ${{ env.POWERADVANTAGE_SOURCE_REF }}")); - assertTrue(name, source.contains("The exact basePower 1.19 dependency pin is pending.")); - assertTrue(name, source.contains("The exact Base Metals 1.19 dependency pin is pending.")); - assertTrue(name, source.contains("The exact OreSpawn 1.19 dependency pin is pending.")); + assertTrue(name, source.contains("The exact basePower 1.20.1 dependency pin is pending.")); + assertTrue(name, source.contains("The exact Base Metals 1.20.1 dependency pin is pending.")); + assertTrue(name, source.contains("The exact OreSpawn 1.20.1 dependency pin is pending.")); assertTrue(name, source.contains("^[a-f0-9]{40}$")); assertTrue(name, source.contains("^[A-F0-9]{64}$")); int pinCheck = source.indexOf("Validate coordinated dependency pins"); assertTrue(name, pinCheck >= 0 && pinCheck < source.indexOf("Check out pinned Base Metals") - && pinCheck < source.indexOf("Check out basePower 1.19.4")); + && pinCheck < source.indexOf("Check out basePower 1.20.1")); assertFalse(name, source.contains("-Ppoweradvantage_source_ref=")); assertTrue(name, source.contains("-Porg.gradle.java.installations.paths=")); assertTrue(name, source.contains("-Porg.gradle.java.installations.auto-detect=false")); @@ -47,24 +47,20 @@ public class BuildWorkflowContractTest { assertTrue(name, source.contains("jar unitBootstrapJar verifyReleaseDependencies")); assertTrue(name, source.contains("-PforgeCapabilityBootstrapJar=${{ steps.dependencies.outputs.bootstrap }}")); assertTrue(name, source.contains("mavenizer=\"$orespawn/ci-fixtures/tools/minecraft-mavenizer-0.5.21-orespawn-compat.jar\"")); - assertTrue(name, source.contains("341B3FB10ABA6EA7DC612FBE519DC290A1C81867AED5DD320ACD783688AC49DE")); + assertTrue(name, source.contains("416DCA4797BC55826F0DDCF03FDC405F1990FC15C2133FA27A1F143BF7976177")); int toolCheck = source.indexOf("| sha256sum -c -"); assertTrue(name, toolCheck >= 0 && toolCheck < source.indexOf("(cd \"$basemetals\"")); - assertTrue(name, source.contains("mavenizer_init=\"$GITHUB_WORKSPACE/gradle/forge45-mavenizer.init.gradle\"")); - assertTrue(name, source.contains("mavenizer_script=\"$GITHUB_WORKSPACE/gradle/forge45-mavenizer.gradle\"")); - assertFalse(name, source.contains("$power/gradle/forge45-mavenizer")); assertTrue(name, source.contains( "(cd \"$basemetals\" && ./gradlew $MMD_GRADLE_TOOLCHAINS jar --no-daemon --stacktrace)")); - String initArgs = "-I \"$mavenizer_init\" \"-Pforge45MavenizerScript=$mavenizer_script\""; - String toolArg = "\"-Pforge45MavenizerJar=$mavenizer\""; + String toolArg = "\"-Pforge47MavenizerJar=$mavenizer\""; int powerStart = source.indexOf("(cd \"$power\""); int powerEnd = source.indexOf("\n powerjar=", powerStart); assertTrue(name, powerStart >= 0 && powerEnd > powerStart); String powerBuild = source.substring(powerStart, powerEnd); - assertTrue(name, powerBuild.contains(initArgs) && powerBuild.contains(toolArg)); - assertEquals(name, 1L, source.lines().filter(line -> line.contains(initArgs)).count()); + assertTrue(name, powerBuild.contains(toolArg)); + assertFalse(name, powerBuild.contains("MavenizerScript")); assertEquals(name, 1L, source.lines().filter(line -> line.contains(toolArg)).count()); - assertTrue(name, source.contains("\"-Pforge45MavenizerJar=${{ steps.dependencies.outputs.mavenizer }}\"")); + assertTrue(name, source.contains("\"-Pforge47MavenizerJar=${{ steps.dependencies.outputs.mavenizer }}\"")); for (String line : source.split("\\R")) { if (line.contains("./gradlew ") && !line.contains("chmod")) { assertTrue(name + ": " + line, line.contains("./gradlew $MMD_GRADLE_TOOLCHAINS ")); diff --git a/src/test/java/zone/moddev/mc/basesteam/resources/ClientResourceContractTest.java b/src/test/java/zone/moddev/mc/basesteam/resources/ClientResourceContractTest.java index 044bf76..696223c 100644 --- a/src/test/java/zone/moddev/mc/basesteam/resources/ClientResourceContractTest.java +++ b/src/test/java/zone/moddev/mc/basesteam/resources/ClientResourceContractTest.java @@ -5,6 +5,8 @@ import com.google.gson.JsonParser; import org.junit.Test; import java.io.Reader; +import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -49,6 +51,38 @@ public class ClientResourceContractTest { } } + @Test public void everyTrackModelDeclaresNativeCutoutRendering() throws Exception { + Path models = ASSETS.resolve("models/block"); + try (Stream files = Files.list(models)) { + var tracks = files.filter(path -> path.getFileName().toString().startsWith("steam_track_")).toList(); + assertEquals(11, tracks.size()); + for (Path track : tracks) { + assertEquals(track.toString(), "minecraft:cutout", read(track).get("render_type").getAsString()); + } + } + } + + @Test public void needleArtIsSymmetricForTheNativeUnmirroredBlit() throws Exception { + try (Stream files = Files.list(ASSETS.resolve("textures/gui/container"))) { + var needles = files.filter(path -> path.toString().endsWith(".png")).toList(); + assertEquals(10, needles.size()); + for (Path texture : needles) { + BufferedImage image = ImageIO.read(texture.toFile()); + boolean hasVisibleArt = false; + for (int y = 0; y < 35; y++) { + for (int x = 176; x <= 182; x++) { + int left = image.getRGB(x, y); + int right = image.getRGB(358 - x, y); + if ((left >>> 24) == 0 && (right >>> 24) == 0) continue; + hasVisibleArt = true; + assertEquals(texture + " needle at " + x + "," + y, left, right); + } + } + assertTrue(texture + " has no visible needle", hasVisibleArt); + } + } + } + @Test public void modernAliasesRetainEveryLegacyTranslation() throws Exception { try (Stream files = Files.walk(ASSETS.resolve("lang"))) { for (Path file : (Iterable) files.filter(p -> p.toString().endsWith(".json"))::iterator) { diff --git a/src/test/java/zone/moddev/mc/basesteam/resources/MusketFragileTagContractTest.java b/src/test/java/zone/moddev/mc/basesteam/resources/MusketFragileTagContractTest.java new file mode 100644 index 0000000..456fb87 --- /dev/null +++ b/src/test/java/zone/moddev/mc/basesteam/resources/MusketFragileTagContractTest.java @@ -0,0 +1,36 @@ +package zone.moddev.mc.basesteam.resources; + +import com.google.gson.JsonParser; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.MessageDigest; +import java.util.HexFormat; +import java.util.TreeSet; +import org.junit.Test; +import static org.junit.Assert.*; + +public class MusketFragileTagContractTest { + @Test public void vanillaDefaultsMatchThePreviousMaterialRule() throws Exception { + Path path = Path.of("src/main/resources/data/basesteam/tags/blocks/musket_fragile.json"); + try (var reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) { + var tag = JsonParser.parseReader(reader).getAsJsonObject(); + assertFalse("Other packs must be able to extend the fragile block list", tag.get("replace").getAsBoolean()); + var blocks = new TreeSet(); + tag.getAsJsonArray("values").forEach(value -> + assertTrue("Duplicate fragile block " + value, blocks.add(value.getAsString()))); + assertTrue(blocks.contains("minecraft:glass_pane")); + assertTrue(blocks.contains("minecraft:oak_leaves")); + assertTrue(blocks.contains("minecraft:torch")); + assertFalse(blocks.contains("minecraft:tnt")); + assertFalse(blocks.contains("minecraft:stone")); + assertFalse(blocks.contains("minecraft:water")); + // Oracle: the sorted vanilla block IDs matching the six fragile Material + // values, read from the actual Forge 45.4.0 block registry. + assertEquals(216, blocks.size()); + byte[] digest = MessageDigest.getInstance("SHA-256") + .digest(String.join("\n", blocks).getBytes(StandardCharsets.UTF_8)); + assertEquals("F8C8CC9719BEEE0926FA793229D0C190A2EEEF514E0F6500CC4D3C50D61FF2BE", HexFormat.of().withUpperCase().formatHex(digest)); + } + } +} diff --git a/src/test/java/zone/moddev/mc/basesteam/resources/NativeBlockPropertiesTest.java b/src/test/java/zone/moddev/mc/basesteam/resources/NativeBlockPropertiesTest.java index 45d8860..f2e18a1 100644 --- a/src/test/java/zone/moddev/mc/basesteam/resources/NativeBlockPropertiesTest.java +++ b/src/test/java/zone/moddev/mc/basesteam/resources/NativeBlockPropertiesTest.java @@ -12,6 +12,8 @@ import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.level.EmptyBlockGetter; +import net.minecraft.world.level.material.PushReaction; +import net.minecraft.world.level.storage.loot.BuiltInLootTables; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -84,6 +86,15 @@ public static Collection cases() { } } + @Test public void retainsPistonReactionAndHiddenHelperLootPolicy() { + for (BlockState state : states()) { + assertFalse("A solid helper must not be washed away", + state.canBeReplaced(net.minecraft.world.level.material.Fluids.WATER)); + assertEquals(height < 0 ? PushReaction.BLOCK : PushReaction.NORMAL, state.getPistonPushReaction()); + } + if (height >= 0) assertEquals(BuiltInLootTables.EMPTY, block.getLootTable()); + } + @Test public void fullCollisionHelpersNeitherSuffocateNorBlockTheView() { for (BlockState state : states()) { assertFalse(state.toString(), state.isSuffocating(EmptyBlockGetter.INSTANCE, BlockPos.ZERO)); diff --git a/src/test/java/zone/moddev/mc/basesteam/resources/NativeLootContractTest.java b/src/test/java/zone/moddev/mc/basesteam/resources/NativeLootContractTest.java index 3227ff9..12b5f70 100644 --- a/src/test/java/zone/moddev/mc/basesteam/resources/NativeLootContractTest.java +++ b/src/test/java/zone/moddev/mc/basesteam/resources/NativeLootContractTest.java @@ -39,10 +39,10 @@ public class NativeLootContractTest { } } - @Test public void packUsesNative119ResourceAndDataFormats() throws Exception { + @Test public void packUsesNative1201ResourceAndDataFormats() throws Exception { JsonObject pack = read(ROOT.resolve("pack.mcmeta")).getAsJsonObject("pack"); - assertEquals(13, pack.get("pack_format").getAsInt()); - assertEquals(12, pack.get("forge:server_data_pack_format").getAsInt()); + assertEquals(15, pack.get("pack_format").getAsInt()); + assertEquals(15, pack.get("forge:server_data_pack_format").getAsInt()); assertFalse(pack.has("forge:resource_pack_format")); assertFalse(pack.has("forge:data_pack_format")); } diff --git a/tools/verify-native-port.js b/tools/verify-native-port.js index def553a..1ee06be 100644 --- a/tools/verify-native-port.js +++ b/tools/verify-native-port.js @@ -23,11 +23,11 @@ for (const name of files(resources).filter(name => /\.(json|mcmeta)$/.test(name) json.set(name, JSON.parse(text)); } assert.deepEqual(json.get(`${resources}/pack.mcmeta`).pack, { - pack_format: 13, 'forge:server_data_pack_format': 12, description: 'baseSteam' + pack_format: 15, 'forge:server_data_pack_format': 15, description: 'baseSteam' }); const metadata = read(`${resources}/META-INF/mods.toml`); assert.match(metadata, /modId="basesteam"/); -assert.match(metadata, /modId="basepower"\r?\nmandatory=true\r?\nversionRange="\[2\.4\.11\.119041,3\.0\.0\)"/); +assert.match(metadata, /modId="basepower"\r?\nmandatory=true\r?\nversionRange="\[2\.4\.12\.120011,3\.0\.0\)"/); assert.match(metadata, /modId="basemetals"\r?\nmandatory=false/); assert.doesNotMatch(metadata, /dependencies\.steamadvantage|modId="(?:steamadvantage|poweradvantage)"/); @@ -51,10 +51,18 @@ function verifyModelReferences(value, name) { for (const [name, content] of json) { if (name.startsWith(assets)) verifyModelReferences(content, name); } +for (const sourceRoot of ['src/main/java', 'src/test/java']) { + for (const name of files(sourceRoot).filter(name => name.endsWith('.java'))) { + const declared = /^package\s+([\w.]+);/m.exec(read(name))?.[1]; + const expected = path.posix.dirname(name.slice(sourceRoot.length + 1)).replaceAll('/', '.'); + assert.equal(declared, expected, `${name}: source root must match the package (Eclipse/Buildship)`); + } +} const source = files('src/main/java').filter(name => name.endsWith('.java')); for (const name of source) { const text = read(name); assert(!/net\.minecraft\.(?:block|tileentity|entity|item|inventory)\./.test(text), name); + assert(!/net\.minecraft\.world\.level\.material\.Material;|\.getMaterial\(\)/.test(text), name); assert(!/setPosition\(|setLevelAndPosition\(|ITickableTileEntity|\[native code\]/.test(text), name); assert(!/getDeclaredField\("(?:level|world|worldPosition)"\)/.test(text), name); assert(!/zone\.moddev\.mc\.(?:steamadvantage|poweradvantage)\b/.test(text), name); @@ -95,5 +103,5 @@ for (const id of pickaxe.values.map(value => value.split(':')[1]).filter(id => ! } const tests = files('src/test/java').filter(name => name.endsWith('.java')); const testCount = tests.reduce((sum, name) => sum + (read(name).match(/@Test\b/g) || []).length, 0); -console.log(`BASESTEAM_NATIVE119_SOURCE_PASS json=${json.size} java=${source.length} factories=${ids.length} harvest=${pickaxe.values.length} testMethods=${testCount}`); +console.log(`BASESTEAM_NATIVE1201_SOURCE_PASS json=${json.size} java=${source.length} factories=${ids.length} harvest=${pickaxe.values.length} testMethods=${testCount}`); console.log('Source checks only. Compilation, executed tests, packaged runtime and manual acceptance are separate.'); From 3e0ea7e4e09f0154438eeac23ba6f470549d65d2 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Mon, 9 Nov 2026 22:50:11 +0000 Subject: [PATCH 2/6] Pin the basePower build with the 1.19 world upgrade fix --- README.md | 4 ++-- gradle.properties | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ad6b17e..0b5159f 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Back up your world and test the upgrade on a copy. Replace Steam Advantage and Power Advantage with baseSteam and basePower; do not install both sets of mods. The migration recognizes old Steam Advantage IDs and keeps the registry paths, machine settings and saved data used by earlier baseSteam versions. The -Minecraft 1.20.1 world upgrade still needs verification for this candidate. +combined world upgrade and restart checks are run from the basePower test rig. Existing `basesteam-common.toml` settings take precedence. When that file is absent, baseSteam can copy `steamadvantage-common.toml` or import settings from an @@ -20,7 +20,7 @@ older `.cfg` file. The old config is left in place. ## Build Target -Minecraft 1.20.1, Forge 47.4.0, official 1.20.1 mappings and MCP +Minecraft 1.20.1, Forge 47.4.10, official 1.20.1 mappings and MCP 20230612.114412. ForgeGradle 7.0.34 and Gradle 9.6.1 run on Java 17. Production compilation and launches use Temurin 17, class major 61. Mavenizer uses Java 25. The build requires the diff --git a/gradle.properties b/gradle.properties index 9ca7fa4..4f569ab 100644 --- a/gradle.properties +++ b/gradle.properties @@ -38,10 +38,10 @@ cf_versions=1.20.1 poweradvantage_version=2.4.12.120011 poweradvantage_source_repository=MinecraftModDevelopmentMods/basePower # Exact local checkpoints for coordinated testing, not published source pins. -poweradvantage_source_ref=c7843fdaaa9e407948a0aa6bc1e6d5562eac7bbe -poweradvantage_deobf_sha256=4FD489774396CC4776CBF21DCCE30DA0AD14E9542AE2FA7F58BFD767EB5D4F0F +poweradvantage_source_ref=83a3f028ffad220fe2f3cc4983a9340dde2295a8 +poweradvantage_deobf_sha256=21A2A3007BA076D219E6836707EF365E2031823A09D5E3DC2A92DD88BD67EA01 # Player jar is a separate runtime input, not a development jar or publication claim. -poweradvantage_player_sha256=7CBDDD402CB9BA79DB4037ABF03A213666E7E1FE12E5B8C2A32ABF67CC2F3AE6 +poweradvantage_player_sha256=E6835ECB04D3F2D5F54731694F7B8D87F06B4A0A9DDB18AA5EDD70EE0E1B099A poweradvantage_test_bootstrap_sha256=A93CD83EC42B09B730CB7715C10C6E53D47B22B557EFE68EDC95241D53BD4EB3 poweradvantage_test_bootstrap_source_sha256=0FB05554D6446BD5561BF9DE47B9F173E6F6C28E39A2BC877D359BB363CB1ABE From 17c6b8467d5c488e101b53b992537d6d9b251b87 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Mon, 9 Nov 2026 22:59:41 +0000 Subject: [PATCH 3/6] Quote Forge paths in Eclipse launches --- build.gradle | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/build.gradle b/build.gradle index 55bc1e1..ade17f4 100644 --- a/build.gradle +++ b/build.gradle @@ -933,6 +933,17 @@ tasks.register('isolateEclipseProductionRuns') { String mainOutput = file('bin/main').absolutePath String eclipseModClasses = "${project.mod_id}%%${mainOutput}" modClasses[0].@value = eclipseModClasses + def vmArguments = launchXml.stringAttribute.find { it.@key == 'org.eclipse.jdt.launching.VM_ARGUMENTS' } + if (vmArguments != null) { + // ForgeGradle leaves these path arguments bare even when a directory contains spaces. + vmArguments.@value = (vmArguments.@value as String) + .replaceAll(/(? + "\"${argument}\"" + } + .replaceAll(/(? + "-p \"${argument}\"" + } + } contents = groovy.xml.XmlUtil.serialize(launchXml) } launch.setText(contents.replace('\r\n', '\n'), 'UTF-8') @@ -1105,6 +1116,11 @@ tasks.register('verifyEclipseProductionClasspath') { String vmArguments = launch.stringAttribute.find { it.@key.text() == 'org.eclipse.jdt.launching.VM_ARGUMENTS' }.@value.text() + def legacyFile = vmArguments =~ /(?:^|\s)"-DlegacyClassPath\.file=([^"]+)"(?=\s|$)/ + if (!legacyFile.find() || !file(legacyFile.group(1)).isFile() + || !(vmArguments =~ /(?:^|\s)-p\s+"[^"]+"/).find()) { + throw new GradleException("${name} must quote the Forge classpath and module paths") + } if (!arguments.contains('--main cpw.mods.bootstraplauncher.BootstrapLauncher') || !vmArguments.contains('--add-opens java.base/java.lang.invoke=ALL-UNNAMED') || contents.contains('net.minecraftforge.userdev.LaunchTesting')) { From 3cc27b325fb07c2fab35678c35846267e73f38f3 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Tue, 10 Nov 2026 11:37:58 +0000 Subject: [PATCH 4/6] Prepare the Minecraft 1.20.1 source release --- .github/verify-published-pins.sh | 33 +++++++++++++++++++ .github/workflows/ci.yml | 19 ++++++++--- .github/workflows/codeql-analysis.yml | 8 +++-- CHANGELOG.txt | 4 +-- README.md | 9 ++--- gradle.properties | 4 ++- .../resources/BuildWorkflowContractTest.java | 12 +++++-- 7 files changed, 72 insertions(+), 17 deletions(-) create mode 100644 .github/verify-published-pins.sh diff --git a/.github/verify-published-pins.sh b/.github/verify-published-pins.sh new file mode 100644 index 0000000..d8b13b8 --- /dev/null +++ b/.github/verify-published-pins.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -euo pipefail + +value() { sed -n "s/^$1=//p" gradle.properties | tr -d '\r'; } + +require_merged() { + local repo="$1" ref="$2" status + [[ "$ref" =~ ^[a-f0-9]{40}$ ]] + status="$(gh api "repos/MinecraftModDevelopmentMods/$repo/compare/$ref...master-1.20.1" --jq '.status')" + case "$status" in + identical|ahead) ;; + *) echo "::error::$repo $ref is not on upstream master-1.20.1 ($status)."; exit 1 ;; + esac +} + +file_id="$(value poweradvantage_public_file_id)" +expected="$(value poweradvantage_player_sha256)" +if [[ ! "$file_id" =~ ^[1-9][0-9]*$ || ! "$expected" =~ ^[A-F0-9]{64}$ ]]; then + echo '::error::A verified public basePower 1.20.1 file ID and player checksum are required.' + exit 1 +fi +require_merged basePower "$(value poweradvantage_source_ref)" +require_merged BaseMetals "$(value basemetals_source_commit)" + +player="${RUNNER_TEMP:?}/basePower-public-player.jar" +curl --fail --silent --show-error --location --proto '=https' --proto-redir '=https' \ + --output "$player" "https://www.curseforge.com/api/v1/mods/1780140/files/$file_id/download" +read -r actual _ < <(sha256sum < "$player") +if [[ "${actual^^}" != "$expected" ]]; then + echo "::error::Public basePower file $file_id SHA-256 is ${actual^^}, expected $expected." + exit 1 +fi +printf 'power_player=%s\n' "$player" >> "${GITHUB_OUTPUT:?}" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dd79563..ece00a6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: baseSteam 1.20 CI on: push: - branches: [master-1.20.1, feature/basesteam-1.20.1-port] + branches: [master-1.20.1, feature/basesteam-1.20.1-port, feature/prepare-basesteam-1.20.1] pull_request: branches: [master-1.20.1] @@ -21,6 +21,11 @@ jobs: steps: - name: Check out baseSteam uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - name: Verify merged dependency pins and public basePower bytes + id: public-pins + env: + GH_TOKEN: ${{ github.token }} + run: bash .github/verify-published-pins.sh - name: Validate coordinated dependency pins shell: bash run: | @@ -104,9 +109,8 @@ jobs: test "$(git -C "$basemetals" rev-parse HEAD)" = "$BASEMETALS_SOURCE_REF" mavenizer="$orespawn/ci-fixtures/tools/minecraft-mavenizer-0.5.21-orespawn-compat.jar" printf '%s %s\n' '416DCA4797BC55826F0DDCF03FDC405F1990FC15C2133FA27A1F143BF7976177' "$mavenizer" | sha256sum -c - - chmod +x "$orespawn/gradlew" "$basemetals/gradlew" "$power/gradlew" - (cd "$orespawn" && ./gradlew $MMD_GRADLE_TOOLCHAINS jar --no-daemon --stacktrace) - (cd "$basemetals" && ./gradlew $MMD_GRADLE_TOOLCHAINS jar --no-daemon --stacktrace) + (cd "$orespawn" && ./gradlew $MMD_GRADLE_TOOLCHAINS assemble --no-daemon --stacktrace) + (cd "$basemetals" && ./gradlew $MMD_GRADLE_TOOLCHAINS assemble --no-daemon --stacktrace) osjar="$orespawn/build/libs-dev/OreSpawn-4.1.0.120011-deobf.jar" bm_version=$(sed -n 's/^basemetals_version=//p' "$GITHUB_WORKSPACE/gradle.properties" | tr -d '\r') bmjar="$basemetals/build/libs-dev/BaseMetals-$bm_version-deobf.jar" @@ -119,6 +123,8 @@ jobs: test -f "$osjar" && test -f "$bmjar" && test -f "$powerjar" && test -f "$bootstrap" echo "orespawn=$osjar" >> "$GITHUB_OUTPUT" echo "basemetals=$bmjar" >> "$GITHUB_OUTPUT" + echo "orespawn_player=$orespawn/build/libs/OreSpawn-4.1.0.120011.jar" >> "$GITHUB_OUTPUT" + echo "basemetals_player=$basemetals/build/libs/BaseMetals-$bm_version.jar" >> "$GITHUB_OUTPUT" echo "power=$powerjar" >> "$GITHUB_OUTPUT" echo "bootstrap=$bootstrap" >> "$GITHUB_OUTPUT" echo "mavenizer=$mavenizer" >> "$GITHUB_OUTPUT" @@ -128,9 +134,12 @@ jobs: node tools/generate-recipe-unlocks.js --check - name: Build and audit release artifacts run: >- - ./gradlew $MMD_GRADLE_TOOLCHAINS clean check build javadoc verifyReleaseDependencies verifyReleaseArtifacts + ./gradlew $MMD_GRADLE_TOOLCHAINS clean check build javadoc verifyReleaseDependencies verifyPlayerDependencies verifyReleaseArtifacts writeReleaseChecksums verifyEclipseProductionClasspath "-Pforge47MavenizerJar=${{ steps.dependencies.outputs.mavenizer }}" + "-PpowerAdvantagePlayerJar=${{ steps.public-pins.outputs.power_player }}" + "-PbaseMetalsPlayerJar=${{ steps.dependencies.outputs.basemetals_player }}" + "-PoreSpawnPlayerJar=${{ steps.dependencies.outputs.orespawn_player }}" -PforgeCapabilityBootstrapJar=${{ steps.dependencies.outputs.bootstrap }} -PpowerAdvantageDeobfJar=${{ steps.dependencies.outputs.power }} -PbaseMetalsDeobfJar=${{ steps.dependencies.outputs.basemetals }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 6983c2d..85b0f0e 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -2,7 +2,7 @@ name: CodeQL on: push: - branches: [master-1.20.1, feature/basesteam-1.20.1-port] + branches: [master-1.20.1, feature/basesteam-1.20.1-port, feature/prepare-basesteam-1.20.1] pull_request: branches: [master-1.20.1] schedule: @@ -21,6 +21,11 @@ jobs: steps: - name: Check out baseSteam uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - name: Verify merged dependency pins and public basePower bytes + id: public-pins + env: + GH_TOKEN: ${{ github.token }} + run: bash .github/verify-published-pins.sh - name: Validate coordinated dependency pins shell: bash run: | @@ -104,7 +109,6 @@ jobs: test "$(git -C "$basemetals" rev-parse HEAD)" = "$BASEMETALS_SOURCE_REF" mavenizer="$orespawn/ci-fixtures/tools/minecraft-mavenizer-0.5.21-orespawn-compat.jar" printf '%s %s\n' '416DCA4797BC55826F0DDCF03FDC405F1990FC15C2133FA27A1F143BF7976177' "$mavenizer" | sha256sum -c - - chmod +x "$orespawn/gradlew" "$basemetals/gradlew" "$power/gradlew" (cd "$orespawn" && ./gradlew $MMD_GRADLE_TOOLCHAINS jar --no-daemon --stacktrace) (cd "$basemetals" && ./gradlew $MMD_GRADLE_TOOLCHAINS jar --no-daemon --stacktrace) osjar="$orespawn/build/libs-dev/OreSpawn-4.1.0.120011-deobf.jar" diff --git a/CHANGELOG.txt b/CHANGELOG.txt index e0430b2..ac8bea4 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,11 +1,11 @@ -baseSteam 2.2.13.120011 (local Minecraft 1.20.1 port) +baseSteam 2.2.13.120011 (Minecraft 1.20.1 / Forge) - Move to Minecraft 1.20.1, Forge 47.4.10 and Java 17 with basePower 2.4.12.120011. - Keep Steam machines, recipes, saves and the shared creative tab as before. - Preserve steam track transparency, machine piston resistance and hidden helper drops. - Keep musket reload feedback and fragile-block hits using the new item and block APIs. -baseSteam 2.2.12.119041 (local Minecraft 1.19.4 port) +baseSteam 2.2.12.119041 (Minecraft 1.19.4 / Forge) - Target Minecraft 1.19.4 / Forge 45.4.0 and Java 17 with basePower 2.4.11.119041. - Adapt native registrations, rendering, damage, sound, fuel and recipe calls. diff --git a/README.md b/README.md index 0b5159f..d4ba4f6 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # baseSteam -**Minecraft 1.20.1 (Forge), version 2.2.13.120011. Local port.** +**Minecraft 1.20.1 (Forge), version 2.2.13.120011** baseSteam, formerly Steam Advantage, adds boilers, steam-powered machines, pumps, storage, elevators and a blackpowder musket to basePower. Its items and -blocks use the shared basePower creative tab. This version is not published. +blocks use the shared basePower creative tab. ## Upgrading a World @@ -50,8 +50,9 @@ from development and published JARs. Before a packaged smoke, run paths default to `D:/MinecraftMineralogy/OS1201/OreSpawn` in the usual checkout layout; the same SHA-256 checks apply to defaults and overrides. -Use the coordinated basePower 1.20.1 candidate and matching frozen JARs. -Pending pins fail closed. No 1.19.4 artifacts may satisfy the 1.20.1 audits. +Local builds use the exact inputs in `gradle.properties`. Hosted release +checks also require the merged basePower source and a matching public player +download. Do not use 1.19.4 jars with this branch. For example, from the Steam checkout in PowerShell: diff --git a/gradle.properties b/gradle.properties index 4f569ab..9ae9678 100644 --- a/gradle.properties +++ b/gradle.properties @@ -39,6 +39,8 @@ poweradvantage_version=2.4.12.120011 poweradvantage_source_repository=MinecraftModDevelopmentMods/basePower # Exact local checkpoints for coordinated testing, not published source pins. poweradvantage_source_ref=83a3f028ffad220fe2f3cc4983a9340dde2295a8 +# The local checkpoint remains usable for local checks, never for hosted release CI. +poweradvantage_public_file_id=PENDING poweradvantage_deobf_sha256=21A2A3007BA076D219E6836707EF365E2031823A09D5E3DC2A92DD88BD67EA01 # Player jar is a separate runtime input, not a development jar or publication claim. poweradvantage_player_sha256=E6835ECB04D3F2D5F54731694F7B8D87F06B4A0A9DDB18AA5EDD70EE0E1B099A @@ -46,7 +48,7 @@ poweradvantage_test_bootstrap_sha256=A93CD83EC42B09B730CB7715C10C6E53D47B22B557E poweradvantage_test_bootstrap_source_sha256=0FB05554D6446BD5561BF9DE47B9F173E6F6C28E39A2BC877D359BB363CB1ABE basemetals_version=3.1.2.120011 -basemetals_source_commit=d9614e3d26a3b57ddff9703861f18a283c7e8358 +basemetals_source_commit=b4795d413b3d356406c351c5e7e29406789f3f30 basemetals_deobf_sha256=A67EB0CB74971E53D528C4D4F1275AE007106D7F8F71DFE4A16FB50411BDCC28 basemetals_player_sha256=30FC6777300E0E48FBB63E3250E86122DAFA38CCA5AD5878CB795C72B7CCCCDE diff --git a/src/test/java/zone/moddev/mc/basesteam/resources/BuildWorkflowContractTest.java b/src/test/java/zone/moddev/mc/basesteam/resources/BuildWorkflowContractTest.java index 034ecd6..bd16aa3 100644 --- a/src/test/java/zone/moddev/mc/basesteam/resources/BuildWorkflowContractTest.java +++ b/src/test/java/zone/moddev/mc/basesteam/resources/BuildWorkflowContractTest.java @@ -36,8 +36,9 @@ public class BuildWorkflowContractTest { assertTrue(name, source.contains("The exact OreSpawn 1.20.1 dependency pin is pending.")); assertTrue(name, source.contains("^[a-f0-9]{40}$")); assertTrue(name, source.contains("^[A-F0-9]{64}$")); + int publicCheck = source.indexOf("bash .github/verify-published-pins.sh"); int pinCheck = source.indexOf("Validate coordinated dependency pins"); - assertTrue(name, pinCheck >= 0 && pinCheck < source.indexOf("Check out pinned Base Metals") + assertTrue(name, publicCheck >= 0 && publicCheck < pinCheck && pinCheck < source.indexOf("Check out pinned Base Metals") && pinCheck < source.indexOf("Check out basePower 1.20.1")); assertFalse(name, source.contains("-Ppoweradvantage_source_ref=")); assertTrue(name, source.contains("-Porg.gradle.java.installations.paths=")); @@ -50,8 +51,13 @@ public class BuildWorkflowContractTest { assertTrue(name, source.contains("416DCA4797BC55826F0DDCF03FDC405F1990FC15C2133FA27A1F143BF7976177")); int toolCheck = source.indexOf("| sha256sum -c -"); assertTrue(name, toolCheck >= 0 && toolCheck < source.indexOf("(cd \"$basemetals\"")); - assertTrue(name, source.contains( - "(cd \"$basemetals\" && ./gradlew $MMD_GRADLE_TOOLCHAINS jar --no-daemon --stacktrace)")); + String metalsTask = name.equals("ci.yml") ? "assemble" : "jar"; + assertTrue(name, source.contains("(cd \"$basemetals\" && ./gradlew $MMD_GRADLE_TOOLCHAINS " + + metalsTask + " --no-daemon --stacktrace)")); + if (name.equals("ci.yml")) { + assertTrue(source.contains("verifyPlayerDependencies")); + assertTrue(source.contains("-PpowerAdvantagePlayerJar=${{ steps.public-pins.outputs.power_player }}")); + } String toolArg = "\"-Pforge47MavenizerJar=$mavenizer\""; int powerStart = source.indexOf("(cd \"$power\""); int powerEnd = source.indexOf("\n powerjar=", powerStart); From ec0e528ba27d6affaee0d0b8c86a6a0a0f82a851 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Tue, 10 Nov 2026 11:41:45 +0000 Subject: [PATCH 5/6] Use the merged basePower 1.20.1 source candidate --- gradle.properties | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index 9ae9678..bed1ef9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -37,9 +37,8 @@ cf_versions=1.20.1 poweradvantage_version=2.4.12.120011 poweradvantage_source_repository=MinecraftModDevelopmentMods/basePower -# Exact local checkpoints for coordinated testing, not published source pins. -poweradvantage_source_ref=83a3f028ffad220fe2f3cc4983a9340dde2295a8 -# The local checkpoint remains usable for local checks, never for hosted release CI. +# Merged source candidate; public player verification is still pending. +poweradvantage_source_ref=6943b5be9478d846801ed5e7f7422df3e8f6e86a poweradvantage_public_file_id=PENDING poweradvantage_deobf_sha256=21A2A3007BA076D219E6836707EF365E2031823A09D5E3DC2A92DD88BD67EA01 # Player jar is a separate runtime input, not a development jar or publication claim. From 87ff99c55a480475a165c033f2d4dbc6b47cd9ab Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Tue, 10 Nov 2026 12:14:02 +0000 Subject: [PATCH 6/6] Pin the published basePower 1.20.1 build --- gradle.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index bed1ef9..4afb0dd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -37,9 +37,9 @@ cf_versions=1.20.1 poweradvantage_version=2.4.12.120011 poweradvantage_source_repository=MinecraftModDevelopmentMods/basePower -# Merged source candidate; public player verification is still pending. +# Build against the merged source and verify the matching public player jar. poweradvantage_source_ref=6943b5be9478d846801ed5e7f7422df3e8f6e86a -poweradvantage_public_file_id=PENDING +poweradvantage_public_file_id=9540451 poweradvantage_deobf_sha256=21A2A3007BA076D219E6836707EF365E2031823A09D5E3DC2A92DD88BD67EA01 # Player jar is a separate runtime input, not a development jar or publication claim. poweradvantage_player_sha256=E6835ECB04D3F2D5F54731694F7B8D87F06B4A0A9DDB18AA5EDD70EE0E1B099A @@ -58,5 +58,5 @@ orespawn_player_sha256=E6BDE47C1BB0BF4D08396F1D1FD5B1D2D3F8A5DF09905F279D39E2601 # Published runtime bytes are distinct from development API jars. -basemetals_public_sha256=PENDING +basemetals_public_sha256=30FC6777300E0E48FBB63E3250E86122DAFA38CCA5AD5878CB795C72B7CCCCDE orespawn_public_sha256=E6BDE47C1BB0BF4D08396F1D1FD5B1D2D3F8A5DF09905F279D39E2601D7FE4B0