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 b55cf3d..ece00a6 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, feature/prepare-basesteam-1.20.1] 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: @@ -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: | @@ -28,19 +33,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 +66,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 +96,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,48 +108,38 @@ 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" - printf '%s %s\n' '341B3FB10ABA6EA7DC612FBE519DC290A1C81867AED5DD320ACD783688AC49DE' "$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" + printf '%s %s\n' '416DCA4797BC55826F0DDCF03FDC405F1990FC15C2133FA27A1F143BF7976177' "$mavenizer" | sha256sum -c - + (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" (cd "$power" && ./gradlew $MMD_GRADLE_TOOLCHAINS jar unitBootstrapJar verifyReleaseDependencies \ - "-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" 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" - - name: Download the released player jars - id: player - shell: bash + - name: Verify source layout and recipe unlocks run: | - set -euo pipefail - directory="$RUNNER_TEMP/base-steam-published" - mkdir "$directory" - fetch() { - curl --fail --silent --show-error --location --proto '=https' --proto-redir '=https' \ - --output "$directory/$1.jar" "$2" - echo "$1=$directory/$1.jar" >> "$GITHUB_OUTPUT" - } - maven="https://maven.moddev.zone/releases/zone/moddev/mc" - fetch power "$maven/basepower/basePower/2.4.11.119041/basePower-2.4.11.119041.jar?ci=$GITHUB_RUN_ID" - fetch metals "$maven/basemetals/BaseMetals/3.1.2.119041/BaseMetals-3.1.2.119041.jar?ci=$GITHUB_RUN_ID" - fetch orespawn 'https://www.curseforge.com/api/v1/mods/245586/files/9171353/download' + 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 verifyPlayerDependencies verifyReleaseArtifacts writeReleaseChecksums verifyEclipseProductionClasspath - "-Pforge45MavenizerJar=${{ steps.dependencies.outputs.mavenizer }}" - "-PpowerAdvantagePlayerJar=${{ steps.player.outputs.power }}" - "-PbaseMetalsPlayerJar=${{ steps.player.outputs.metals }}" - "-PoreSpawnPlayerJar=${{ steps.player.outputs.orespawn }}" + "-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 }} @@ -153,20 +148,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 2d5d7dc..85b0f0e 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, feature/prepare-basesteam-1.20.1] pull_request: - branches: [master-1.19.4] + branches: [master-1.20.1] schedule: - cron: '53 7 * * 4' @@ -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: | @@ -28,19 +33,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 +66,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 +96,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,17 +108,17 @@ 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" - printf '%s %s\n' '341B3FB10ABA6EA7DC612FBE519DC290A1C81867AED5DD320ACD783688AC49DE' "$mavenizer" | sha256sum -c - - chmod +x "$orespawn/gradlew" "$basemetals/gradlew" "$power/gradlew" + printf '%s %s\n' '416DCA4797BC55826F0DDCF03FDC405F1990FC15C2133FA27A1F143BF7976177' "$mavenizer" | sha256sum -c - (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 \ - "-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" @@ -129,7 +134,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 66be540..ac8bea4 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,9 +1,15 @@ -baseSteam 2.2.12.119041 (Minecraft 1.19.4) +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 (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. - Retain Steam save IDs, machine data and optional Base Metals recipes. -- Build against the released basePower 2.4.11.119041 and test with the Base Metals migration fix. baseSteam 2.2.11.118021 (local Minecraft 1.18.2 candidate) diff --git a/README.md b/README.md index 1ddd8fe..d4ba4f6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # baseSteam -**Minecraft 1.19.4 (Forge), version 2.2.12.119041.** +**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 @@ -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 -upgrade tests run existing boilers, pumps and drills after a full restart. +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,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.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 -[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,26 @@ 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 -home and the test-only Forge capability bootstrap. Use the published player -jars for packaged tests, not the development jars. Before a packaged smoke, run +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 released basePower 2.4.11.119041 and the exact dependencies in -`gradle.properties`. The 1.18.2 jars cannot substitute for these inputs. +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: @@ -68,12 +73,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 +87,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 +123,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..ade17f4 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 -> @@ -932,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') @@ -1009,10 +1021,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') @@ -1083,10 +1116,15 @@ 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')) { - 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 +1184,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 +1372,7 @@ tasks.register('verifyRecipeTagGuards') { } tasks.named('check') { + dependsOn verifyJavaSourceLayout dependsOn tasks.named('verifyReleaseConfiguration') dependsOn tasks.named('verifyModelAssets') dependsOn tasks.named('verifyRepositoryHygiene') diff --git a/docs/PORT119-STATUS.md b/docs/PORT119-STATUS.md index 98fea19..e424eae 100644 --- a/docs/PORT119-STATUS.md +++ b/docs/PORT119-STATUS.md @@ -1,4 +1,4 @@ -# baseSteam 1.19.4 port +# baseSteam 1.19.4 local port - Source: accepted 1.18.2 `d10c56cf021e6bd701e973cda90358495844a45f`, cloned locally with `--no-hardlinks` onto @@ -6,9 +6,7 @@ - Target: baseSteam `2.2.12.119041`, basePower `2.4.11.119041`, Minecraft `1.19.4`, Forge `45.4.0`, official mappings, MCP `20230314.122934`, Temurin 17, ForgeGradle `7.0.34`, and Gradle `9.6.1`. -- The release uses basePower `2.4.11.119041` and the published Base Metals - migration fix. Earlier checkpoints below describe the local port before - those dependency releases. All upgrade tests use copies. +- No external publication, tag, deployment, upstream change or protected world. ## Tooling @@ -20,10 +18,10 @@ build-only input from the pinned OreSpawn checkout, checked by SHA-256. Java 25 is not a production toolchain. Use a separate Steam Gradle user home or the agreed warm cache with distinct project state. -CI and CodeQL build the pinned basePower and Base Metals sources with their own -Forge 45 setup. Steam supplies the verified OreSpawn Mavenizer jar to basePower -without applying a second Gradle init script. -The dependency commits and artifact checksums are in `gradle.properties`. +CI and CodeQL apply Steam's Forge 45 Mavenizer adapter only to the pinned +basePower checkout, which predates the tool setup. The pinned Base Metals +checkout already verifies and configures its own tool, so it builds normally. +Neither dependency pin changes. ## Compatibility diff --git a/gradle.properties b/gradle.properties index c73cf76..4afb0dd 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,37 @@ 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 -# Development jar rebuilt from the released basePower source. -poweradvantage_source_ref=4af5c7d5d490162cddc7f1e4fc72cc602b42bb32 -poweradvantage_deobf_sha256=512FDEC9275B33533EF773C110E6229E0F07268775FAD4B5942A15B68A9EB87D -# Player jar is the exact published build, not the development jar. -poweradvantage_player_sha256=E1689C1147F6F6F93F6516D9188A279093D6CCC2FF1FBEB506468B876BA03E60 +# Build against the merged source and verify the matching public player jar. +poweradvantage_source_ref=6943b5be9478d846801ed5e7f7422df3e8f6e86a +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 poweradvantage_test_bootstrap_sha256=A93CD83EC42B09B730CB7715C10C6E53D47B22B557EFE68EDC95241D53BD4EB3 poweradvantage_test_bootstrap_source_sha256=0FB05554D6446BD5561BF9DE47B9F173E6F6C28E39A2BC877D359BB363CB1ABE -basemetals_version=3.1.2.119041 -basemetals_source_commit=5791a793aa3a1ca1aa3fcb36e6d4a2d865e7d2d3 -basemetals_deobf_sha256=0AA993D6BADA54B11548EB5BE150CE0939232291F2D215B7DBAF149857976B2F -basemetals_player_sha256=991EA843EEDF5FA1E42E9984A07573C7D03D74230482230440E44EDCA895FA39 +basemetals_version=3.1.2.120011 +basemetals_source_commit=b4795d413b3d356406c351c5e7e29406789f3f30 +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=991EA843EEDF5FA1E42E9984A07573C7D03D74230482230440E44EDCA895FA39 -orespawn_public_sha256=1B2ECAA546E7FFB35863AC1D9FF92504471EE857045DCD01A068C5CA7F53CFFD +basemetals_public_sha256=30FC6777300E0E48FBB63E3250E86122DAFA38CCA5AD5878CB795C72B7CCCCDE +orespawn_public_sha256=E6BDE47C1BB0BF4D08396F1D1FD5B1D2D3F8A5DF09905F279D39E2601D7FE4B0 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 4a2c615..bd16aa3 100644 --- a/src/test/java/zone/moddev/mc/basesteam/resources/BuildWorkflowContractTest.java +++ b/src/test/java/zone/moddev/mc/basesteam/resources/BuildWorkflowContractTest.java @@ -8,7 +8,7 @@ public class BuildWorkflowContractTest { @Test public void everyHostedBuildUsesPinnedToolchainProjectProperties() throws Exception { - 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); @@ -25,19 +25,21 @@ 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 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") - && pinCheck < source.indexOf("Check out basePower 1.19.4")); + 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=")); assertTrue(name, source.contains("-Porg.gradle.java.installations.auto-detect=false")); @@ -46,21 +48,25 @@ 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\"")); - assertFalse(name, source.contains("forge45-mavenizer.init.gradle") || source.contains("-Pforge45MavenizerScript")); - assertTrue(name, source.contains( - "(cd \"$basemetals\" && ./gradlew $MMD_GRADLE_TOOLCHAINS jar --no-daemon --stacktrace)")); - String toolArg = "\"-Pforge45MavenizerJar=$mavenizer\""; + 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); assertTrue(name, powerStart >= 0 && powerEnd > powerStart); String powerBuild = source.substring(powerStart, powerEnd); assertTrue(name, powerBuild.contains(toolArg)); - assertFalse(name, powerBuild.contains("-I ") || powerBuild.contains("--init-script")); + 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.');