From bced14aedc55288a1e7dfd46b4e7097d6a353c26 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Mon, 26 Oct 2026 11:44:46 +0000 Subject: [PATCH 1/6] Port Steam Advantage to Minecraft 1.15.2 Keep saved machinery and drill state while using native rendering, interaction and entity APIs. Pin the matching Power build and keep the recipe and loot paths intact. --- .github/workflows/ci.yml | 49 +++-- .github/workflows/codeql-analysis.yml | 35 ++-- .github/workflows/validate-gradle-build.yml | 4 +- CHANGELOG.txt | 11 + README.md | 35 ++-- build.gradle | 47 +++-- gradle.properties | 32 +-- gradlew.bat | 168 ++++++++-------- .../mc/steamadvantage/SteamAdvantage.java | 4 +- .../steamadvantage/blocks/DrillBitBlock.java | 4 +- .../steamadvantage/blocks/PlatformBlock.java | 4 +- .../steamadvantage/blocks/PumpPipeBlock.java | 4 +- .../blocks/SteamTrackBlock.java | 6 - .../graphics/ClientRegistration.java | 8 +- .../graphics/DrillBitRenderer.java | 188 +++++++----------- .../mc/steamadvantage/items/MusketItem.java | 29 ++- .../machines/SteamElevatorTileEntity.java | 4 +- src/main/resources/META-INF/mods.toml | 4 +- src/main/resources/pack.mcmeta | 2 +- .../graphics/DrillBitRendererTest.java | 103 ++++++++++ .../resources/NativeLootContractTest.java | 4 +- 21 files changed, 422 insertions(+), 323 deletions(-) create mode 100644 src/test/java/zone/moddev/mc/steamadvantage/graphics/DrillBitRendererTest.java diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 80c3d53..d480255 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,16 +1,16 @@ -name: Steam Advantage 1.14 CI +name: Steam Advantage 1.15 CI on: push: - branches: [master-1.14.4, 'feature/**'] + branches: [master-1.15.2, 'feature/**'] pull_request: - branches: [master-1.14.4] + branches: [master-1.15.2] permissions: contents: read concurrency: - group: steamadvantage-1.14-${{ github.workflow }}-${{ github.ref }} + group: steamadvantage-1.15-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: @@ -25,7 +25,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/OreSpawn - ref: 9c2488cba02d317e3f31e24441dcc58273d8d0e6 + ref: 5613baf876747ed071cb7ad7e2aff4e0ce4f0a03 path: .ci-dependencies/OreSpawn - name: Use canonical LF dependency inputs # Use the same source bytes on hosted and local dependency builds. @@ -34,14 +34,19 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/BaseMetals - ref: 713802f93f2d1f650e1593fa35c487ea43add4a5 + ref: 1d166d917663d4b4a5a88a86440adc0ae761e393 path: .ci-dependencies/BaseMetals - - name: Check out PowerAdvantage 1.14.4 + - name: Check out PowerAdvantage 1.15.2 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/PowerAdvantage - ref: 1d498ca02b6795b16435f0ece35ac04c67ef6948 + ref: b15e2091e9647860bd90284aef6135a311692864 path: .ci-dependencies/PowerAdvantage + - name: Install pinned Java 25 Mavenizer runtime + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 + with: + distribution: temurin + java-version: '25.0.3+9.0.LTS' - name: Install Java 8 toolchain uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 with: @@ -50,11 +55,17 @@ jobs: - name: Install Java 17 for Gradle uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 with: - distribution: microsoft - java-version: '17' + distribution: temurin + java-version: '17.0.1+12' + - name: Use pinned build toolchains + shell: bash + run: >- + echo "GRADLE_OPTS=-Dorg.gradle.java.installations.paths=$JAVA_HOME,$JAVA_HOME_8_X64,$JAVA_HOME_25_X64 + -Dorg.gradle.java.installations.auto-detect=false + -Dorg.gradle.java.installations.auto-download=false" >> "$GITHUB_ENV" - name: Set up Gradle uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6 - - name: Build 1.14.4 dependency chain + - name: Build 1.15.2 dependency chain id: dependencies shell: bash run: | @@ -65,12 +76,12 @@ jobs: chmod +x "$orespawn/gradlew" "$basemetals/gradlew" "$power/gradlew" (cd "$orespawn" && ./gradlew jar --no-daemon --stacktrace) (cd "$basemetals" && ./gradlew jar --no-daemon --stacktrace) - osjar="$orespawn/build/libs-dev/OreSpawn-4.1.1.114041-deobf.jar" - bmjar="$basemetals/build/libs-dev/BaseMetals-3.0.1.114041-deobf.jar" + osjar="$orespawn/build/libs-dev/OreSpawn-4.1.1.115021-deobf.jar" + bmjar="$basemetals/build/libs-dev/BaseMetals-3.0.1.115021-deobf.jar" (cd "$power" && ./gradlew jar verifyReleaseDependencies \ -PbaseMetalsDeobfJar="$bmjar" -PoreSpawnDeobfJar="$osjar" \ --no-daemon --stacktrace) - powerjar="$power/build/libs-dev/PowerAdvantage-2.4.5.114041-deobf.jar" + powerjar="$power/build/libs-dev/PowerAdvantage-2.4.6.115021-deobf.jar" test -f "$osjar" && test -f "$bmjar" && test -f "$powerjar" echo "orespawn=$osjar" >> "$GITHUB_OUTPUT" echo "basemetals=$bmjar" >> "$GITHUB_OUTPUT" @@ -88,20 +99,20 @@ jobs: - name: Upload audited release candidate uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: - name: SteamAdvantage-1.14.4-${{ github.sha }} + name: SteamAdvantage-1.15.2-${{ github.sha }} if-no-files-found: error retention-days: 30 path: | - build/libs/SteamAdvantage-2.2.6.114041.jar - build/libs/SteamAdvantage-2.2.6.114041-sources.jar - build/libs/SteamAdvantage-2.2.6.114041-javadoc.jar + build/libs/SteamAdvantage-2.2.7.115021.jar + build/libs/SteamAdvantage-2.2.7.115021-sources.jar + build/libs/SteamAdvantage-2.2.7.115021-javadoc.jar build/release/SHA256SUMS CHANGELOG.txt - name: Upload diagnostics on failure if: failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: - name: SteamAdvantage-1.14.4-diagnostics-${{ github.sha }} + name: SteamAdvantage-1.15.2-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 9bf204f..f182126 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -2,9 +2,9 @@ name: CodeQL on: push: - branches: [master-1.14.4, 'feature/**'] + branches: [master-1.15.2, 'feature/**'] pull_request: - branches: [master-1.14.4] + branches: [master-1.15.2] schedule: - cron: '53 7 * * 4' @@ -25,7 +25,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/OreSpawn - ref: 9c2488cba02d317e3f31e24441dcc58273d8d0e6 + ref: 5613baf876747ed071cb7ad7e2aff4e0ce4f0a03 path: .ci-dependencies/OreSpawn - name: Use canonical LF dependency inputs # Use the same source bytes on hosted and local dependency builds. @@ -34,14 +34,19 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/BaseMetals - ref: 713802f93f2d1f650e1593fa35c487ea43add4a5 + ref: 1d166d917663d4b4a5a88a86440adc0ae761e393 path: .ci-dependencies/BaseMetals - - name: Check out PowerAdvantage 1.14.4 + - name: Check out PowerAdvantage 1.15.2 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/PowerAdvantage - ref: 1d498ca02b6795b16435f0ece35ac04c67ef6948 + ref: b15e2091e9647860bd90284aef6135a311692864 path: .ci-dependencies/PowerAdvantage + - name: Install pinned Java 25 Mavenizer runtime + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 + with: + distribution: temurin + java-version: '25.0.3+9.0.LTS' - name: Install Java 8 toolchain uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 with: @@ -50,11 +55,17 @@ jobs: - name: Install Java 17 for Gradle uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 with: - distribution: microsoft - java-version: '17' + distribution: temurin + java-version: '17.0.1+12' + - name: Use pinned build toolchains + shell: bash + run: >- + echo "GRADLE_OPTS=-Dorg.gradle.java.installations.paths=$JAVA_HOME,$JAVA_HOME_8_X64,$JAVA_HOME_25_X64 + -Dorg.gradle.java.installations.auto-detect=false + -Dorg.gradle.java.installations.auto-download=false" >> "$GITHUB_ENV" - name: Set up Gradle uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6 - - name: Build 1.14.4 dependency chain + - name: Build 1.15.2 dependency chain id: dependencies shell: bash run: | @@ -65,12 +76,12 @@ jobs: chmod +x "$orespawn/gradlew" "$basemetals/gradlew" "$power/gradlew" (cd "$orespawn" && ./gradlew jar --no-daemon --stacktrace) (cd "$basemetals" && ./gradlew jar --no-daemon --stacktrace) - osjar="$orespawn/build/libs-dev/OreSpawn-4.1.1.114041-deobf.jar" - bmjar="$basemetals/build/libs-dev/BaseMetals-3.0.1.114041-deobf.jar" + osjar="$orespawn/build/libs-dev/OreSpawn-4.1.1.115021-deobf.jar" + bmjar="$basemetals/build/libs-dev/BaseMetals-3.0.1.115021-deobf.jar" (cd "$power" && ./gradlew jar verifyReleaseDependencies \ -PbaseMetalsDeobfJar="$bmjar" -PoreSpawnDeobfJar="$osjar" \ --no-daemon --stacktrace) - powerjar="$power/build/libs-dev/PowerAdvantage-2.4.5.114041-deobf.jar" + powerjar="$power/build/libs-dev/PowerAdvantage-2.4.6.115021-deobf.jar" test -f "$osjar" && test -f "$bmjar" && test -f "$powerjar" echo "orespawn=$osjar" >> "$GITHUB_OUTPUT" echo "basemetals=$bmjar" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/validate-gradle-build.yml b/.github/workflows/validate-gradle-build.yml index c471b09..7d47484 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.14.4 + - master-1.15.2 - 'feature/**' pull_request: branches: - - master-1.14.4 + - master-1.15.2 permissions: contents: read diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 20b90ac..2d9f6f7 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,14 @@ +Steam Advantage 2.2.7.115021 + +- Target Minecraft 1.15.2 / Forge 31.2.57 with snapshot 20200514-1.15.1 mappings and MCP 20200515.085601. +- Pin the native Power Advantage 2.4.6.115021, Base Metals and OreSpawn development dependencies. +- Use native tile renderer registration, matrix stacks and lit vertex buffers without changing drill dimensions, UVs or animation axes. +- Register the steam track's cutout render layer on the client and retain non-solid helper blocks through native properties. +- Use native entity position accessors and action-result factories for elevators and muskets. +- Preserve registry identities, recipes, migration codecs, saved NBT, machine costs and output quantities. +- Pass 30 unit/resource tests, including all-facing renderer geometry, lighting/overlay and matrix-restoration regressions. +- Keep combined server/client gameplay and disposable-copy migration checks separate; 1.14 results do not qualify 1.15 worlds. + Steam Advantage 2.2.6.114041 - Save the drill's cached facing without reloading a chunk during its unload-save. diff --git a/README.md b/README.md index 095f45d..84103ed 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,30 @@ # SteamAdvantage -**Minecraft 1.14.4 port, version 2.2.6.114041.** Native compilation and 27 unit/resource tests pass. -The combined-mod automated checks also cover client resources, connected machinery, -drill movement, chunk lifecycle, restart persistence and disposable-copy migration. -The [1.14 test results](https://github.com/MinecraftModDevelopmentMods/PowerAdvantage/blob/master-1.14.4/docs/1.14/BROADER-QUALIFICATION.md) -describe the tested scenarios and remaining limits, not a guarantee for an entire modpack. +**Minecraft 1.15.2 port, version 2.2.7.115021.** Native compilation and 30 unit/resource +tests pass, including native drill-renderer geometry and matrix-stack checks. +Combined-mod server, client-resource, connected-machine and disposable-copy migration +checks have not yet been repeated for this port. The historical +[1.14 test results](https://github.com/MinecraftModDevelopmentMods/PowerAdvantage/blob/master-1.14.4/docs/1.14/BROADER-QUALIFICATION.md) +are not evidence of 1.15 gameplay or world-upgrade compatibility. -Steam Advantage adds steam-powered machines and infrastructure to Power Advantage for Minecraft 1.14.4. +Steam Advantage adds steam-powered machines and infrastructure to Power Advantage for Minecraft 1.15.2. Every crafting variant has an ingredient-triggered recipe-book discovery. See the [shared material checklist and discovery tests](https://github.com/MinecraftModDevelopmentMods/PowerAdvantage/blob/master-1.13.2/docs/1.13/RECIPE-DISCOVERY.md). Regenerate unlock JSON after recipe changes with `node tools/generate-recipe-unlocks.js`; `check` audits recipe coverage and criteria. Crushing recipes are deliberately excluded from the crafting book. -The historical [manufacturing progression protocol](https://github.com/MinecraftModDevelopmentMods/PowerAdvantage/blob/master-1.13.2/docs/1.13/MANUFACTURING-PROGRESSION.md) describes raw-material, processing and loot acquisition paths in every mode, including restart persistence. See the 1.14 test results above for this port's coverage. +The historical [manufacturing progression protocol](https://github.com/MinecraftModDevelopmentMods/PowerAdvantage/blob/master-1.13.2/docs/1.13/MANUFACTURING-PROGRESSION.md) describes raw-material, processing and loot acquisition paths in every mode, including restart persistence. Earlier results do not establish those outcomes on 1.15. -## Building Minecraft 1.14.4 +## Building Minecraft 1.15.2 -The `master-1.14.4` build targets Forge 28.2.26, snapshot `20190719-1.14.3` mappings, -and MCP `20190829.143755`. It uses ForgeGradle 7.0.34 and Gradle 9.6.1. -Run Gradle with Java 17; production code is compiled for Java 8. +The `master-1.15.2` build targets Forge 31.2.57, snapshot `20200514-1.15.1` mappings, +and MCP `20200515.085601`. It uses ForgeGradle 7.0.34 and Gradle 9.6.1. +Run Gradle with Temurin 17.0.1+12; production code is compiled with Temurin 8.0.502+7. +The Forge Mavenizer also requires Temurin 25.0.3+9.0.LTS. CI installs all three +explicitly and disables automatic toolchain detection and downloads. -Build the matching 1.14 PowerAdvantage, Base Metals and OreSpawn deobf jars first. +Build the matching 1.15 PowerAdvantage, Base Metals and OreSpawn deobf jars first. Dependency versions, checksums and the exact Power source reference belong in `gradle.properties`. Release audits reject missing or placeholder pins; do not -bypass those checks or substitute a 1.13 dependency. +bypass those checks or substitute a dependency from an earlier Minecraft version. With the standard sibling layout: ```text @@ -55,7 +58,7 @@ The Eclipse resource root is `build/resources/main`, so its builder copies expan ## Compatibility -The 1.14 source adaptations preserve machine callbacks, all six drill directions, native +The 1.15 source adaptations retain machine callbacks, all six drill directions, native helper-tile lifecycle, saved progress and target snapshots, energy/inventory NBT, legacy fluid contracts, musket loaded-state bytes and migration codecs. Native villager professions replace the removed smith careers (armorer, weaponsmith, toolsmith) and priest (cleric). @@ -67,8 +70,8 @@ in-world GUI, rendering, sound, control or musket interaction, multiplayer behav or compatibility with arbitrary third-party mods. Unit/resource tests alone are not runtime or world-upgrade evidence. -For an all-Advantage play-test, run `prepareCombinedEclipseLaunch` in the sibling PowerAdvantage checkout and select its `runClientAllAdvantage.launch`. The [native resource probe](https://github.com/MinecraftModDevelopmentMods/PowerAdvantage/blob/master-1.14.4/test-rig/client-resources/README.md) checks models, textures and names across all three mods. These resource checks do not replace gameplay testing. +The combined 1.15 harness must be prepared before an all-Advantage play-test. Its launch and resource probe belong to the sibling PowerAdvantage checkout. The [historical resource-probe protocol](https://github.com/MinecraftModDevelopmentMods/PowerAdvantage/blob/master-1.14.4/test-rig/client-resources/README.md) describes model, texture and name checks; its previous passes do not establish 1.15 rendering or gameplay results. The implementation namespace is `zone.moddev.mc.steamadvantage`. Runtime identities, registries, tile IDs, saved NBT, recipes, and assets remain stable. Steam registers its legacy state and NBT codecs with PowerAdvantage's shared migration hook so 1.10 and 1.12 worlds can be converted before Minecraft flattens old numeric block states. -The historical [1.13 migration guide](https://github.com/MinecraftModDevelopmentMods/PowerAdvantage/blob/master-1.13.2/docs/1.13/MIGRATION.md) explains the legacy conversion and backup process; the 1.14 test results above describe this port's coverage. Always make a whole-world backup before upgrading, keep the complete set of migration backups, and test only disposable copies. Check that every other mod supports the target version; these results do not qualify unrelated mods or an entire existing modpack. +The historical [1.13 migration guide](https://github.com/MinecraftModDevelopmentMods/PowerAdvantage/blob/master-1.13.2/docs/1.13/MIGRATION.md) explains the legacy conversion and backup process; it is not a 1.15 migration qualification. Always make a whole-world backup before upgrading, keep the complete set of migration backups, and test only disposable copies. Check that every other mod supports the target version; these results do not qualify unrelated mods or an entire existing modpack. diff --git a/build.gradle b/build.gradle index 23326f7..0c00296 100644 --- a/build.gradle +++ b/build.gradle @@ -94,7 +94,7 @@ minecraft { def forgeRunModClassesDirectory = layout.buildDirectory.dir('forge-run-mod-classes/main') def forgeMainOutputPath = forgeRunModClassesDirectory.get().asFile.absolutePath def mainModClasses = "${mod_id}%%${forgeMainOutputPath}${File.pathSeparator}${mod_id}%%${forgeMainOutputPath}" - def forge28RunTargets = [client: 'fmluserdevclient', server: 'fmluserdevserver', data: 'fmluserdevdata'] + def forge31RunTargets = [client: 'fmluserdevclient', server: 'fmluserdevserver', data: 'fmluserdevdata'] runs { configureEach { mainClass = 'net.minecraftforge.userdev.LaunchTesting' @@ -102,7 +102,7 @@ minecraft { systemProperty 'forge.logging.markers', 'REGISTRIES' systemProperty 'forge.logging.console.level', 'info' mods { steamadvantage { source sourceSets.main } } - environment 'target', forge28RunTargets[name] + environment 'target', forge31RunTargets[name] environment 'MCP_MAPPINGS', "${mapping_channel}_${mapping_version}" environment 'MCP_VERSION', mcp_version environment 'FORGE_VERSION', forge_version @@ -130,7 +130,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 1.14 launches.' + description = 'Merges classes and processed resources for Forge 1.15 launches.' dependsOn tasks.named('classes') from sourceSets.main.output into forgeRunModClassesDirectory @@ -178,18 +178,18 @@ if (!powerAdvantageDeobfJar.isFile()) { // These defaults follow the sibling MMD checkout layout. They are constants // here so another developer can override them without editing the script. def baseMetalsDeobfJar = file(providers.gradleProperty('baseMetalsDeobfJar') - .getOrElse('../../../../BaseMetals/BaseMetals 114/BaseMetals/build/libs-dev/' - + 'BaseMetals-3.0.1.114041-deobf.jar')) + .getOrElse('../../../../BaseMetals/BaseMetals 115/BaseMetals/build/libs-dev/' + + 'BaseMetals-3.0.1.115021-deobf.jar')) if (!baseMetalsDeobfJar.isFile()) { throw new GradleException("Missing Base Metals deobf jar at ${baseMetalsDeobfJar}. " - + "Build Base Metals 1.14 first, or pass -PbaseMetalsDeobfJar=.") + + "Build Base Metals 1.15 first, or pass -PbaseMetalsDeobfJar=.") } def oreSpawnDeobfJar = file(providers.gradleProperty('oreSpawnDeobfJar') - .getOrElse('../../../../MinecraftMineralogy/OS114/OreSpawn/build/libs-dev/' - + 'OreSpawn-4.1.1.114041-deobf.jar')) + .getOrElse('../../../../MinecraftMineralogy/OS115/OreSpawn/build/libs-dev/' + + 'OreSpawn-4.1.1.115021-deobf.jar')) if (!oreSpawnDeobfJar.isFile()) { throw new GradleException("Missing OreSpawn deobf jar at ${oreSpawnDeobfJar}. " - + "Build OreSpawn 1.14 first, or pass -PoreSpawnDeobfJar=.") + + "Build OreSpawn 1.15 first, or pass -PoreSpawnDeobfJar=.") } dependencies { @@ -341,14 +341,17 @@ tasks.register('verifyReleaseConfiguration') { group = 'verification' description = 'Validates release identity, target metadata, and dependency policy.' doLast { - if (project.mod_version != '2.2.6.114041') { + if (new JsonSlurper().parse(file('src/main/resources/pack.mcmeta')).pack.pack_format != 5) { + throw new GradleException('Minecraft 1.15.2 resources must use pack format 5') + } + if (project.mod_version != '2.2.7.115021') { throw new GradleException("Unexpected SteamAdvantage release version: ${project.mod_version}") } - if (project.minecraft_version != '1.14.4' - || project.forge_version != '28.2.26' + if (project.minecraft_version != '1.15.2' + || project.forge_version != '31.2.57' || project.mapping_channel != 'snapshot' - || project.mapping_version != '20190719-1.14.3' - || project.mcp_version != '20190829.143755') { + || project.mapping_version != '20200514-1.15.1' + || project.mcp_version != '20200515.085601') { throw new GradleException('Unexpected Minecraft, Forge, or mappings target') } if (project.loader_name != 'forge' || project.loader_code != '1' @@ -366,10 +369,10 @@ tasks.register('verifyReleaseConfiguration') { } if (project.cf_requirements != 'power-advantage,base-metals' || project.cf_optionals != '' - || project.cf_versions != '1.14.4') { + || project.cf_versions != '1.15.2') { throw new GradleException('Unexpected CurseForge dependency or game-version metadata') } - if (project.poweradvantage_version != '2.4.5.114041' + if (project.poweradvantage_version != '2.4.6.115021' || project.poweradvantage_source_repository != 'MinecraftModDevelopmentMods/PowerAdvantage' || !(project.poweradvantage_source_ref ==~ /[a-f0-9]{40}/) || !(project.poweradvantage_deobf_sha256 ==~ /[A-F0-9]{64}/)) { @@ -378,12 +381,12 @@ tasks.register('verifyReleaseConfiguration') { String mainSource = file( 'src/main/java/zone/moddev/mc/steamadvantage/SteamAdvantage.java').getText('UTF-8') if (!mainSource.contains('MODID = "steamadvantage"') - || !mainSource.contains('VERSION = "2.2.6.114041"')) { + || !mainSource.contains('VERSION = "2.2.7.115021"')) { throw new GradleException('SteamAdvantage source identity changed') } String metadata = file('src/main/resources/META-INF/mods.toml').getText('UTF-8').replace('\r\n', '\n') ['modId="steamadvantage"', 'modId="poweradvantage"', 'modId="basemetals"', - 'versionRange="[2.4.5.114041,3.0.0)"'].each { marker -> + 'versionRange="[2.4.6.115021,3.0.0)"'].each { marker -> if (!metadata.contains(marker)) { throw new GradleException("Source mods.toml is missing ${marker}") } @@ -419,9 +422,9 @@ tasks.register('verifyReleaseDependencies') { if (manifest.getValue('Implementation-Version') != project.poweradvantage_version) { throw new GradleException('PowerAdvantage dependency manifest has the wrong version') } - if (manifest.getValue('Built-On') != '1.14.4-28.2.26' + if (manifest.getValue('Built-On') != '1.15.2-31.2.57' || manifest.getValue('Built-On-Java') != '8') { - throw new GradleException('PowerAdvantage must be the native 1.14.4 Java 8 dependency') + throw new GradleException('PowerAdvantage must be the native 1.15.2 Java 8 dependency') } } String actualBaseMetalsHash = MessageDigest.getInstance('SHA-256') @@ -522,8 +525,8 @@ tasks.register('verifyReleaseArtifacts') { } def resourcePack = new JsonSlurper().parseText(zip.getInputStream(zip.getEntry('pack.mcmeta')) .getText(StandardCharsets.UTF_8.name())) - if (resourcePack.pack.pack_format != 4) { - throw new GradleException('Packaged resources must use native 1.14 pack format 4') + if (resourcePack.pack.pack_format != 5) { + throw new GradleException('Packaged resources must use native 1.15 pack format 5') } ['agent-notes/', '.codex/', 'src/test/', 'fernflower_abstract_parameter_names.txt', 'cyano/poweradvantage/', diff --git a/gradle.properties b/gradle.properties index fd46c88..2e6054b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,14 +5,14 @@ org.gradle.caching=true org.gradle.parallel=false net.minecraftforge.gradle.merge-source-sets=false -minecraft_version=1.14.4 -minecraft_version_range=[1.14.4] -forge_version=28.2.26 -forge_version_range=[28,) -loader_version_range=[28,) +minecraft_version=1.15.2 +minecraft_version_range=[1.15.2] +forge_version=31.2.57 +forge_version_range=[31.2.57,32) +loader_version_range=[31,) mapping_channel=snapshot -mapping_version=20190719-1.14.3 -mcp_version=20190829.143755 +mapping_version=20200514-1.15.1 +mcp_version=20200515.085601 loader_name=forge loader_code=1 @@ -25,23 +25,23 @@ curseforge_project_id=240984 mod_id=steamadvantage mod_name=Steam Advantage mod_license=GPL-3.0-only -mod_version=2.2.6.114041 +mod_version=2.2.7.115021 mod_group=zone.moddev.mc.steamadvantage mod_authors=DrCyano mod_description=Steam-powered machines and infrastructure for the Power Advantage platform. cf_requirements=power-advantage,base-metals cf_optionals= -cf_versions=1.14.4 +cf_versions=1.15.2 -poweradvantage_version=2.4.5.114041 +poweradvantage_version=2.4.6.115021 poweradvantage_source_repository=MinecraftModDevelopmentMods/PowerAdvantage # Exact Power Advantage source and development jar used by local and CI builds. -poweradvantage_source_ref=1d498ca02b6795b16435f0ece35ac04c67ef6948 -poweradvantage_deobf_sha256=8D8831D54B700FBFB2B9C43EE3D8D70D2B7E57185A4DBDF12202C47D5E387B39 +poweradvantage_source_ref=b15e2091e9647860bd90284aef6135a311692864 +poweradvantage_deobf_sha256=2C3ADBCA79859DFA2C14EF8DC9068BF9F202D72FDB1D37B51ED4DE1B5B7E866A -basemetals_version=3.0.1.114041 -basemetals_deobf_sha256=A14A87E3BF30964F901E715A9B4EF2F1E7317ABE7F9ACEBE60D8E6A900CA6EB2 +basemetals_version=3.0.1.115021 +basemetals_deobf_sha256=A98EAC370D908F14103DB6D064C738160161FDD7203F30905562B23EEE265210 -orespawn_version=4.1.1.114041 -orespawn_deobf_sha256=1807C3A43F6E854F4EC5741F75A52750B733CD81DC588CF0F666C6C3A489FBEF +orespawn_version=4.1.1.115021 +orespawn_deobf_sha256=358B13375A4B60622C491D6729290971A446FF14D524A600CA13710934DB3FDC diff --git a/gradlew.bat b/gradlew.bat index e95643d..f955316 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,84 +1,84 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/main/java/zone/moddev/mc/steamadvantage/SteamAdvantage.java b/src/main/java/zone/moddev/mc/steamadvantage/SteamAdvantage.java index c2aad97..730c678 100644 --- a/src/main/java/zone/moddev/mc/steamadvantage/SteamAdvantage.java +++ b/src/main/java/zone/moddev/mc/steamadvantage/SteamAdvantage.java @@ -30,12 +30,12 @@ import zone.moddev.mc.steamadvantage.migration.SteamLegacyMigrations; import zone.moddev.mc.steamadvantage.recipe.RecipeConditions; -/** Forge 1.14 entry point for Steam Advantage. */ +/** Forge 1.15 entry point for Steam Advantage. */ @Mod(SteamAdvantage.MODID) public final class SteamAdvantage { public static final String MODID = "steamadvantage"; public static final String NAME = "Steam Advantage"; - public static final String VERSION = "2.2.6.114041"; + public static final String VERSION = "2.2.7.115021"; public static final Logger LOGGER = LogManager.getLogger(MODID); public static float MUSKET_DAMAGE = 20.0F; diff --git a/src/main/java/zone/moddev/mc/steamadvantage/blocks/DrillBitBlock.java b/src/main/java/zone/moddev/mc/steamadvantage/blocks/DrillBitBlock.java index 03558dd..aa2b6d7 100644 --- a/src/main/java/zone/moddev/mc/steamadvantage/blocks/DrillBitBlock.java +++ b/src/main/java/zone/moddev/mc/steamadvantage/blocks/DrillBitBlock.java @@ -25,14 +25,12 @@ public class DrillBitBlock extends Block implements ITileEntityProvider { private static final VoxelShape SHAPE = VoxelShapes.create(0.25D, 0.25D, 0.25D, 0.75D, 0.75D, 0.75D); public DrillBitBlock() { - super(Block.Properties.create(Material.IRON).hardnessAndResistance(5.0F, 2000.0F)); + super(Block.Properties.create(Material.IRON).hardnessAndResistance(5.0F, 2000.0F).notSolid()); } @Override public TileEntity createNewTileEntity(IBlockReader world) { return new DrillBitTileEntity(); } @Override public VoxelShape getShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext context) { return SHAPE; } @Override public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext context) { return SHAPE; } - @Override public boolean isNormalCube(BlockState state, IBlockReader world, BlockPos pos) { return false; } - @Override public boolean isSolid(BlockState state) { return false; } @Override public List getDrops(BlockState state, LootContext.Builder context) { return Collections.emptyList(); } @Override diff --git a/src/main/java/zone/moddev/mc/steamadvantage/blocks/PlatformBlock.java b/src/main/java/zone/moddev/mc/steamadvantage/blocks/PlatformBlock.java index ff9349b..f21643d 100644 --- a/src/main/java/zone/moddev/mc/steamadvantage/blocks/PlatformBlock.java +++ b/src/main/java/zone/moddev/mc/steamadvantage/blocks/PlatformBlock.java @@ -29,15 +29,13 @@ public class PlatformBlock extends Block { }; public PlatformBlock() { - super(Block.Properties.create(Material.IRON).hardnessAndResistance(5.0F, 2000.0F)); + super(Block.Properties.create(Material.IRON).hardnessAndResistance(5.0F, 2000.0F).notSolid()); setDefaultState(getStateContainer().getBaseState().with(HEIGHT, 1)); } @Override protected void fillStateContainer(StateContainer.Builder builder) { builder.add(HEIGHT); } @Override public VoxelShape getShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext context) { return SHAPES[state.get(HEIGHT)]; } @Override public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext context) { return SHAPES[state.get(HEIGHT)]; } - @Override public boolean isNormalCube(BlockState state, IBlockReader world, BlockPos pos) { return false; } - @Override public boolean isSolid(BlockState state) { return false; } @Override public List getDrops(BlockState state, LootContext.Builder context) { return Collections.emptyList(); } @Override diff --git a/src/main/java/zone/moddev/mc/steamadvantage/blocks/PumpPipeBlock.java b/src/main/java/zone/moddev/mc/steamadvantage/blocks/PumpPipeBlock.java index 496eb22..3a0fb9f 100644 --- a/src/main/java/zone/moddev/mc/steamadvantage/blocks/PumpPipeBlock.java +++ b/src/main/java/zone/moddev/mc/steamadvantage/blocks/PumpPipeBlock.java @@ -20,13 +20,11 @@ public class PumpPipeBlock extends Block { private static final VoxelShape SHAPE = VoxelShapes.create(0.0D, 0.25D, 0.0D, 0.75D, 1.0D, 1.0D); public PumpPipeBlock() { - super(Block.Properties.create(Material.IRON).hardnessAndResistance(5.0F, 10.0F)); + super(Block.Properties.create(Material.IRON).hardnessAndResistance(5.0F, 10.0F).notSolid()); } @Override public VoxelShape getShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext context) { return SHAPE; } @Override public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext context) { return SHAPE; } - @Override public boolean isNormalCube(BlockState state, IBlockReader world, BlockPos pos) { return false; } - @Override public boolean isSolid(BlockState state) { return false; } @Override public List getDrops(BlockState state, LootContext.Builder context) { return Collections.emptyList(); } @Override diff --git a/src/main/java/zone/moddev/mc/steamadvantage/blocks/SteamTrackBlock.java b/src/main/java/zone/moddev/mc/steamadvantage/blocks/SteamTrackBlock.java index a3cca5b..231b3ad 100644 --- a/src/main/java/zone/moddev/mc/steamadvantage/blocks/SteamTrackBlock.java +++ b/src/main/java/zone/moddev/mc/steamadvantage/blocks/SteamTrackBlock.java @@ -3,21 +3,15 @@ import cyano.poweradvantage.api.simple.BlockSimplePowerConduit; import net.minecraft.block.material.Material; import net.minecraft.block.BlockState; -import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.world.IBlockReader; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; import zone.moddev.mc.steamadvantage.init.Power; public class SteamTrackBlock extends BlockSimplePowerConduit { public SteamTrackBlock() { super(Material.PISTON, 0.75F, 2.0F / 16.0F, Power.steam_power); } @Override public VoxelShape getShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext context) { return VoxelShapes.fullCube(); } @Override public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext context) { return VoxelShapes.fullCube(); } - @Override public boolean isNormalCube(BlockState state, IBlockReader world, BlockPos pos) { return false; } - @Override public boolean isSolid(BlockState state) { return false; } - @OnlyIn(Dist.CLIENT) @Override public BlockRenderLayer getRenderLayer() { return BlockRenderLayer.CUTOUT; } } diff --git a/src/main/java/zone/moddev/mc/steamadvantage/graphics/ClientRegistration.java b/src/main/java/zone/moddev/mc/steamadvantage/graphics/ClientRegistration.java index 2ac4591..1f43107 100644 --- a/src/main/java/zone/moddev/mc/steamadvantage/graphics/ClientRegistration.java +++ b/src/main/java/zone/moddev/mc/steamadvantage/graphics/ClientRegistration.java @@ -2,13 +2,17 @@ import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; -import zone.moddev.mc.steamadvantage.blocks.DrillBitTileEntity; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.RenderTypeLookup; +import zone.moddev.mc.steamadvantage.init.Blocks; +import zone.moddev.mc.steamadvantage.init.Entities; /** Client-only renderer registration. */ public final class ClientRegistration { private ClientRegistration() {} public static void onClientSetup(FMLClientSetupEvent event) { - ClientRegistry.bindTileEntitySpecialRenderer(DrillBitTileEntity.class, new DrillBitRenderer()); + ClientRegistry.bindTileEntityRenderer(Entities.DRILLBIT, DrillBitRenderer::new); + RenderTypeLookup.setRenderLayer(Blocks.steam_track, RenderType.getCutout()); } } diff --git a/src/main/java/zone/moddev/mc/steamadvantage/graphics/DrillBitRenderer.java b/src/main/java/zone/moddev/mc/steamadvantage/graphics/DrillBitRenderer.java index 6a95cee..5024790 100644 --- a/src/main/java/zone/moddev/mc/steamadvantage/graphics/DrillBitRenderer.java +++ b/src/main/java/zone/moddev/mc/steamadvantage/graphics/DrillBitRenderer.java @@ -1,121 +1,87 @@ package zone.moddev.mc.steamadvantage.graphics; -import zone.moddev.mc.steamadvantage.SteamAdvantage; -import zone.moddev.mc.steamadvantage.blocks.DrillBitTileEntity; -import net.minecraft.client.Minecraft; -import com.mojang.blaze3d.platform.GlStateManager; -import net.minecraft.client.renderer.RenderHelper; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.BufferBuilder; +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.vertex.IVertexBuilder; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.Vector3f; import net.minecraft.client.renderer.tileentity.TileEntityRenderer; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.util.Direction; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import zone.moddev.mc.steamadvantage.SteamAdvantage; +import zone.moddev.mc.steamadvantage.blocks.DrillBitTileEntity; -@OnlyIn(Dist.CLIENT) // This is needed for classes that extend client-only classes -public class DrillBitRenderer extends TileEntityRenderer{ - - - private final ResourceLocation texture = new ResourceLocation(SteamAdvantage.MODID+":textures/entity/drill_bit.png"); - - public DrillBitRenderer() { - } - - - @Override - public void render(final DrillBitTileEntity te, final double x, final double y, final double z, final float partialTick, final int destroyStage) { - GlStateManager.pushMatrix(); - try { - GlStateManager.translated(x, y, z); - render(te,te.getWorld(),te.getPos(),partialTick); - } finally { - GlStateManager.enableCull(); - GlStateManager.disableBlend(); - GlStateManager.shadeModel(7424); - RenderHelper.enableStandardItemLighting(); - GlStateManager.popMatrix(); - } - } - - private void render(DrillBitTileEntity e, World world, BlockPos pos, float partialTick){ - final Tessellator instance = Tessellator.getInstance(); - final BufferBuilder worldRenderer = instance.getBuffer(); - - this.bindTexture(texture); - - //This will make your block brightness dependent from surroundings lighting. - RenderHelper.disableStandardItemLighting(); - GlStateManager.blendFunc(770, 771); - GlStateManager.enableBlend(); - GlStateManager.disableCull(); - - if (Minecraft.isAmbientOcclusionEnabled()) - { - GlStateManager.shadeModel(7425); +@OnlyIn(Dist.CLIENT) +public class DrillBitRenderer extends TileEntityRenderer { + private static final ResourceLocation TEXTURE = + new ResourceLocation(SteamAdvantage.MODID, "textures/entity/drill_bit.png"); + + public DrillBitRenderer(TileEntityRendererDispatcher dispatcher) { + super(dispatcher); + } + + @Override + public void render(DrillBitTileEntity tile, float partialTick, MatrixStack matrices, + IRenderTypeBuffer buffers, int light, int overlay) { + renderGeometry(tile.getDirection(), tile.rotation + DrillBitTileEntity.ROTATION_PER_TICK * partialTick, + matrices, buffers.getBuffer(RenderType.getEntityTranslucent(TEXTURE)), light, overlay); + } + + static void renderGeometry(Direction.Axis axis, float rotation, MatrixStack matrices, + IVertexBuilder vertices, int light, int overlay) { + matrices.push(); + try { + matrices.translate(0.5D, 0.5D, 0.5D); + if (axis != Direction.Axis.Y) { + matrices.rotate(Vector3f.XP.rotationDegrees(90.0F)); + if (axis != Direction.Axis.Z) matrices.rotate(Vector3f.ZP.rotationDegrees(90.0F)); + } + matrices.rotate(Vector3f.YP.rotationDegrees(rotation)); + MatrixStack.Entry transform = matrices.getLast(); + final float radius = 0.25F; + // Retain the original six quads and UV layout; native buffers supply lighting and overlay. + vertex(transform, vertices, radius, 0.5F, -radius, 0, 0, 0, 0, -1, light, overlay); + vertex(transform, vertices, radius, -0.5F, -radius, 0, 1, 0, 0, -1, light, overlay); + vertex(transform, vertices, -radius, -0.5F, -radius, 0.5F, 1, 0, 0, -1, light, overlay); + vertex(transform, vertices, -radius, 0.5F, -radius, 0.5F, 0, 0, 0, -1, light, overlay); + + vertex(transform, vertices, -radius, 0.5F, radius, 0, 0, 0, 0, 1, light, overlay); + vertex(transform, vertices, -radius, -0.5F, radius, 0, 1, 0, 0, 1, light, overlay); + vertex(transform, vertices, radius, -0.5F, radius, 0.5F, 1, 0, 0, 1, light, overlay); + vertex(transform, vertices, radius, 0.5F, radius, 0.5F, 0, 0, 0, 1, light, overlay); + + vertex(transform, vertices, -radius, 0.5F, -radius, 0, 0, -1, 0, 0, light, overlay); + vertex(transform, vertices, -radius, -0.5F, -radius, 0, 1, -1, 0, 0, light, overlay); + vertex(transform, vertices, -radius, -0.5F, radius, 0.5F, 1, -1, 0, 0, light, overlay); + vertex(transform, vertices, -radius, 0.5F, radius, 0.5F, 0, -1, 0, 0, light, overlay); + + vertex(transform, vertices, radius, 0.5F, radius, 0, 0, 1, 0, 0, light, overlay); + vertex(transform, vertices, radius, -0.5F, radius, 0, 1, 1, 0, 0, light, overlay); + vertex(transform, vertices, radius, -0.5F, -radius, 0.5F, 1, 1, 0, 0, light, overlay); + vertex(transform, vertices, radius, 0.5F, -radius, 0.5F, 0, 1, 0, 0, light, overlay); + + vertex(transform, vertices, -radius, 0.5F, -radius, 0.5F, 0, 0, 1, 0, light, overlay); + vertex(transform, vertices, -radius, 0.5F, radius, 0.5F, 0.5F, 0, 1, 0, light, overlay); + vertex(transform, vertices, radius, 0.5F, radius, 1, 0.5F, 0, 1, 0, light, overlay); + vertex(transform, vertices, radius, 0.5F, -radius, 1, 0, 0, 1, 0, light, overlay); + + vertex(transform, vertices, -radius, -0.5F, radius, 0.5F, 0, 0, -1, 0, light, overlay); + vertex(transform, vertices, -radius, -0.5F, -radius, 0.5F, 0.5F, 0, -1, 0, light, overlay); + vertex(transform, vertices, radius, -0.5F, -radius, 1, 0.5F, 0, -1, 0, light, overlay); + vertex(transform, vertices, radius, -0.5F, radius, 1, 0, 0, -1, 0, light, overlay); + } finally { + matrices.pop(); } - else - { - GlStateManager.shadeModel(7424); - } - - final float sideU0 = 0; - final float sideU1 = 0.5f; - final float sideV0 = 0; - final float sideV1 = 1f; - final float endU0 = 0.5f; - final float endU1 = 1; - final float endV0 = 0; - final float endV1 = 0.5f; - final float radius = 0.25f; - - GlStateManager.translatef(0.5f, 0.5f, 0.5f); - if(e.getDirection() != Direction.Axis.Y){ - GlStateManager.rotatef(90, 1.0f, 0.0f, 0.0f); - if(e.getDirection() != Direction.Axis.Z){ - GlStateManager.rotatef(90, 0.0f, 0.0f, 1.0f); - } - } - GlStateManager.rotatef(e.rotation + DrillBitTileEntity.ROTATION_PER_TICK * partialTick, 0.0f, 1.0f, 0.0f); - - worldRenderer.begin(7, DefaultVertexFormats.POSITION_TEX); - worldRenderer.pos( radius, 0.5f, -radius).tex( sideU0, sideV0).endVertex(); - worldRenderer.pos( radius,-0.5f, -radius).tex( sideU0, sideV1).endVertex(); - worldRenderer.pos(-radius,-0.5f, -radius).tex( sideU1, sideV1).endVertex(); - worldRenderer.pos(-radius, 0.5f, -radius).tex( sideU1, sideV0).endVertex(); - - worldRenderer.pos(-radius, 0.5f, radius).tex( sideU0, sideV0).endVertex(); - worldRenderer.pos(-radius,-0.5f, radius).tex( sideU0, sideV1).endVertex(); - worldRenderer.pos( radius,-0.5f, radius).tex( sideU1, sideV1).endVertex(); - worldRenderer.pos( radius, 0.5f, radius).tex( sideU1, sideV0).endVertex(); - - worldRenderer.pos(-radius, 0.5f, -radius).tex( sideU0, sideV0).endVertex(); - worldRenderer.pos(-radius,-0.5f, -radius).tex( sideU0, sideV1).endVertex(); - worldRenderer.pos(-radius,-0.5f, radius).tex( sideU1, sideV1).endVertex(); - worldRenderer.pos(-radius, 0.5f, radius).tex( sideU1, sideV0).endVertex(); - - worldRenderer.pos( radius, 0.5f, radius).tex( sideU0, sideV0).endVertex(); - worldRenderer.pos( radius,-0.5f, radius).tex( sideU0, sideV1).endVertex(); - worldRenderer.pos( radius,-0.5f, -radius).tex( sideU1, sideV1).endVertex(); - worldRenderer.pos( radius, 0.5f, -radius).tex( sideU1, sideV0).endVertex(); - - worldRenderer.pos(-radius, 0.5f, -radius).tex( endU0, endV0).endVertex(); - worldRenderer.pos(-radius, 0.5f, radius).tex( endU0, endV1).endVertex(); - worldRenderer.pos( radius, 0.5f, radius).tex( endU1, endV1).endVertex(); - worldRenderer.pos( radius, 0.5f, -radius).tex( endU1, endV0).endVertex(); - - worldRenderer.pos(-radius,-0.5f, radius).tex( endU0, endV0).endVertex(); - worldRenderer.pos(-radius,-0.5f, -radius).tex( endU0, endV1).endVertex(); - worldRenderer.pos( radius,-0.5f, -radius).tex( endU1, endV1).endVertex(); - worldRenderer.pos( radius,-0.5f, radius).tex( endU1, endV0).endVertex(); - - instance.draw(); - RenderHelper.enableStandardItemLighting(); - - } - - + } + + private static void vertex(MatrixStack.Entry transform, IVertexBuilder vertices, + float x, float y, float z, float u, float v, + float normalX, float normalY, float normalZ, int light, int overlay) { + vertices.pos(transform.getMatrix(), x, y, z).color(255, 255, 255, 255).tex(u, v) + .overlay(overlay).lightmap(light) + .normal(transform.getNormal(), normalX, normalY, normalZ).endVertex(); + } } diff --git a/src/main/java/zone/moddev/mc/steamadvantage/items/MusketItem.java b/src/main/java/zone/moddev/mc/steamadvantage/items/MusketItem.java index 7d437c8..69d44da 100644 --- a/src/main/java/zone/moddev/mc/steamadvantage/items/MusketItem.java +++ b/src/main/java/zone/moddev/mc/steamadvantage/items/MusketItem.java @@ -32,7 +32,6 @@ import net.minecraft.nbt.CompoundNBT; import net.minecraft.network.play.server.SEntityVelocityPacket; import net.minecraft.util.ActionResult; -import net.minecraft.util.ActionResultType; import net.minecraft.util.Hand; import net.minecraft.particles.IParticleData; import net.minecraft.util.ResourceLocation; @@ -113,18 +112,18 @@ public UseAction getUseAction(ItemStack stack){ @Override public ActionResult onItemRightClick(World world, PlayerEntity playerEntity, Hand hand){ ItemStack srcItemStack = playerEntity.getHeldItem(hand); - if(hand != Hand.MAIN_HAND) return ActionResult.newResult(ActionResultType.PASS,srcItemStack); - if(!hasAmmo(playerEntity, srcItemStack)) return ActionResult.newResult(ActionResultType.FAIL,srcItemStack); + if(hand != Hand.MAIN_HAND) return ActionResult.resultPass(srcItemStack); + if(!hasAmmo(playerEntity, srcItemStack)) return ActionResult.resultFail(srcItemStack); if(isNotLoaded(srcItemStack) && EnchantmentHelper.getEnchantmentLevel(Enchantments.rapid_reload, srcItemStack) > 0){ // instant reload decrementAmmo(playerEntity,srcItemStack); startLoad(srcItemStack); playSound(SoundEvents.BLOCK_LEVER_CLICK,world,playerEntity); finishLoad(srcItemStack); - return ActionResult.newResult(ActionResultType.SUCCESS,srcItemStack); + return ActionResult.resultSuccess(srcItemStack); } playerEntity.setActiveHand(hand); - return ActionResult.newResult(ActionResultType.SUCCESS,srcItemStack); + return ActionResult.resultSuccess(srcItemStack); } @Override @@ -167,15 +166,15 @@ protected void fire(ItemStack srcItemStack, LivingEntity playerEntity, } Vec3d lookVector = playerEntity.getLookVec(); spawnParticle(ParticleTypes.EXPLOSION_EMITTER, world, - playerEntity.posX+lookVector.x, playerEntity.posY+playerEntity.getEyeHeight()+lookVector.y, playerEntity.posZ + lookVector.z); + playerEntity.getPosX()+lookVector.x, playerEntity.getPosY()+playerEntity.getEyeHeight()+lookVector.y, playerEntity.getPosZ() + lookVector.z); if(world.isRemote){ playerEntity.rotationPitch -= 15; return; } playSound(SoundEvents.ITEM_FLINTANDSTEEL_USE,world,playerEntity); - playBigSoundAtPosition(playerEntity.posX,playerEntity.posY,playerEntity.posZ, SoundEvents.ENTITY_FIREWORK_ROCKET_BLAST,SoundCategory.PLAYERS,2F,0.5F,world); + playBigSoundAtPosition(playerEntity.getPosX(),playerEntity.getPosY(),playerEntity.getPosZ(), SoundEvents.ENTITY_FIREWORK_ROCKET_BLAST,SoundCategory.PLAYERS,2F,0.5F,world); - Vec3d start = new Vec3d(playerEntity.posX, playerEntity.posY+playerEntity.getEyeHeight(),playerEntity.posZ); + Vec3d start = new Vec3d(playerEntity.getPosX(), playerEntity.getPosY()+playerEntity.getEyeHeight(),playerEntity.getPosZ()); start.add(MAX_RANGE * lookVector.x, MAX_RANGE * lookVector.y, MAX_RANGE * lookVector.z); RayTraceResult rayTrace = rayTraceBlocksAndEntities(world,MAX_RANGE,playerEntity); if(rayTrace == null){ @@ -188,11 +187,11 @@ protected void fire(ItemStack srcItemStack, LivingEntity playerEntity, e.attackEntityFrom(Power.musket_damage, getShotDamage()); if(EnchantmentHelper.getEnchantmentLevel(Enchantments.high_explosive, srcItemStack) > 0){ int lvl = EnchantmentHelper.getEnchantmentLevel(Enchantments.high_explosive, srcItemStack); - world.createExplosion(playerEntity, e.posX, e.posY+0.5, e.posZ, + world.createExplosion(playerEntity, e.getPosX(), e.getPosY()+0.5, e.getPosZ(), explodeFactor * lvl, Explosion.Mode.BREAK); - AxisAlignedBB fireArea = new AxisAlignedBB(e.posX-lvl, e.posY-lvl, e.posZ-lvl, - e.posX+lvl, e.posY+lvl, e.posZ+lvl); + AxisAlignedBB fireArea = new AxisAlignedBB(e.getPosX()-lvl, e.getPosY()-lvl, e.getPosZ()-lvl, + e.getPosX()+lvl, e.getPosY()+lvl, e.getPosZ()+lvl); List collateralDamage = world.getEntitiesWithinAABB(LivingEntity.class, fireArea); for(LivingEntity victim : collateralDamage){ victim.setFire(lvl); @@ -274,7 +273,7 @@ public boolean hitEntity(ItemStack stack, LivingEntity target, LivingEntity atta protected void playSound(SoundEvent sound, World world, Entity e){ if (!world.isRemote) { - playSoundAtPosition(e.posX, e.posY, e.posZ, sound,SoundCategory.PLAYERS,1F,1F,world); + playSoundAtPosition(e.getPosX(), e.getPosY(), e.getPosZ(), sound,SoundCategory.PLAYERS,1F,1F,world); } } @@ -368,7 +367,7 @@ public static void decrementAmmo(LivingEntity e, ItemStack musket) { public static RayTraceResult rayTraceBlocksAndEntities(World w, double maxRange, LivingEntity source){ double rangeSqr = maxRange * maxRange; - Vec3d rayOrigin = new Vec3d(source.posX, source.posY + source.getEyeHeight(), source.posZ); + Vec3d rayOrigin = new Vec3d(source.getPosX(), source.getPosY() + source.getEyeHeight(), source.getPosZ()); Vec3d rayDirection = source.getLookVec(); BlockPos srcPos = source.getPosition(); AxisAlignedBB aoi = new AxisAlignedBB(srcPos.getX() - maxRange, srcPos.getY() - maxRange, srcPos.getZ() - maxRange, @@ -377,7 +376,7 @@ public static RayTraceResult rayTraceBlocksAndEntities(World w, double maxRange, double closestDistSqr = Double.MAX_VALUE; Entity closestEntity = null; for(Entity e : entities){ - double distSqr = e.getDistanceSq(source.posX, source.posY, source.posZ); + double distSqr = e.getDistanceSq(source.getPosX(), source.getPosY(), source.getPosZ()); if(distSqr < rangeSqr){ // e is within range AxisAlignedBB box = e.getBoundingBox(); @@ -395,7 +394,7 @@ public static RayTraceResult rayTraceBlocksAndEntities(World w, double maxRange, return w.rayTraceBlocks(new RayTraceContext(rayOrigin, rayOrigin.add(mul(rayDirection, maxRange)), RayTraceContext.BlockMode.COLLIDER, RayTraceContext.FluidMode.SOURCE_ONLY, source)); } else { - Vec3d pos = new Vec3d(closestEntity.posX, closestEntity.posY+closestEntity.getEyeHeight(), closestEntity.posZ); + Vec3d pos = new Vec3d(closestEntity.getPosX(), closestEntity.getPosY()+closestEntity.getEyeHeight(), closestEntity.getPosZ()); RayTraceResult entityCollision = new EntityRayTraceResult(closestEntity, pos); return entityCollision; } diff --git a/src/main/java/zone/moddev/mc/steamadvantage/machines/SteamElevatorTileEntity.java b/src/main/java/zone/moddev/mc/steamadvantage/machines/SteamElevatorTileEntity.java index 3390870..8f57751 100644 --- a/src/main/java/zone/moddev/mc/steamadvantage/machines/SteamElevatorTileEntity.java +++ b/src/main/java/zone/moddev/mc/steamadvantage/machines/SteamElevatorTileEntity.java @@ -79,7 +79,7 @@ private boolean moveUp(){ getPos().getX()+1, topPos.getY(), getPos().getZ()+1)); for(Entity e : passengers){ - e.setPositionAndUpdate(e.posX,topPos.getY()+smallAmount, e.posZ); + e.setPositionAndUpdate(e.getPosX(),topPos.getY()+smallAmount, e.getPosZ()); e.fallDistance = 0; } return true; @@ -106,7 +106,7 @@ private boolean moveDown(){ new AxisAlignedBB(p.getX(),p.getY(),p.getZ(), p.getX()+1, p.getY()+2, p.getZ()+1)); for(Entity e : passengers){ - e.setPositionAndUpdate(e.posX, destination.getY()+smallAmount,e.posZ); + e.setPositionAndUpdate(e.getPosX(), destination.getY()+smallAmount,e.getPosZ()); e.fallDistance = 0; } return true; diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 4aee25d..2ee02b0 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 the Power Advantage [[dependencies.steamadvantage]] modId="poweradvantage" mandatory=true -versionRange="[2.4.5.114041,3.0.0)" +versionRange="[2.4.6.115021,3.0.0)" ordering="AFTER" side="BOTH" [[dependencies.steamadvantage]] modId="basemetals" mandatory=false -versionRange="[3.0.1.114041,4.0.0)" +versionRange="[3.0.1.115021,4.0.0)" ordering="AFTER" side="BOTH" diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta index 8be9850..e8e4d16 100644 --- a/src/main/resources/pack.mcmeta +++ b/src/main/resources/pack.mcmeta @@ -1,6 +1,6 @@ { "pack":{ - "pack_format":4, + "pack_format":5, "description":"Steam Advantage" } } diff --git a/src/test/java/zone/moddev/mc/steamadvantage/graphics/DrillBitRendererTest.java b/src/test/java/zone/moddev/mc/steamadvantage/graphics/DrillBitRendererTest.java new file mode 100644 index 0000000..d4d0be4 --- /dev/null +++ b/src/test/java/zone/moddev/mc/steamadvantage/graphics/DrillBitRendererTest.java @@ -0,0 +1,103 @@ +package zone.moddev.mc.steamadvantage.graphics; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.vertex.IVertexBuilder; +import java.util.ArrayList; +import java.util.List; +import net.minecraft.util.Direction; +import org.junit.Test; +import static org.junit.Assert.*; + +public class DrillBitRendererTest { + private static final int LIGHT = 0x00D000A0; + private static final int OVERLAY = 0x00090007; + private static final double EPSILON = 0.000001D; + + @Test public void everyFacingKeepsLegacyDimensionsUvsAndNativeVertexAttributes() { + for (Direction facing : Direction.values()) { + RecordingBuffer buffer = new RecordingBuffer(); + MatrixStack matrices = new MatrixStack(); + MatrixStack.Entry caller = matrices.getLast(); + DrillBitRenderer.renderGeometry(facing.getAxis(), 0, matrices, buffer, LIGHT, OVERLAY); + assertSame(caller, matrices.getLast()); + assertEquals(24, buffer.vertices.size()); + double[] minimum = { Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY }; + double[] maximum = { Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY }; + for (int i = 0; i < buffer.vertices.size(); i++) { + Vertex vertex = buffer.vertices.get(i); + for (int coordinate = 0; coordinate < 3; coordinate++) { + minimum[coordinate] = Math.min(minimum[coordinate], vertex.position[coordinate]); + maximum[coordinate] = Math.max(maximum[coordinate], vertex.position[coordinate]); + } + int corner = i % 4; + float expectedU = (i < 16 ? 0 : 0.5F) + (corner >= 2 ? 0.5F : 0); + float expectedV = (corner == 1 || corner == 2) ? (i < 16 ? 1 : 0.5F) : 0; + assertEquals(expectedU, vertex.u, 0); + assertEquals(expectedV, vertex.v, 0); + assertEquals(LIGHT, vertex.light); + assertEquals(OVERLAY, vertex.overlay); + assertArrayEquals(new int[] { 255, 255, 255, 255 }, vertex.color); + double normalLength = 0; + for (float component : vertex.normal) normalLength += component * component; + assertEquals(1, normalLength, EPSILON); + } + for (int coordinate = 0; coordinate < 3; coordinate++) { + boolean alongDrill = Direction.Axis.values()[coordinate] == facing.getAxis(); + assertEquals(alongDrill ? 0 : 0.25D, minimum[coordinate], EPSILON); + assertEquals(alongDrill ? 1 : 0.75D, maximum[coordinate], EPSILON); + } + } + } + + @Test public void rotationTransformsBothPositionsAndNormals() { + RecordingBuffer buffer = new RecordingBuffer(); + DrillBitRenderer.renderGeometry(Direction.Axis.Y, 90, new MatrixStack(), buffer, LIGHT, OVERLAY); + Vertex first = buffer.vertices.get(0); + assertArrayEquals(new double[] { 0.25D, 1, 0.25D }, first.position, EPSILON); + assertArrayEquals(new float[] { -1, 0, 0 }, first.normal, (float) EPSILON); + } + + @Test public void failedVertexSubmissionRestoresTheCallerMatrix() { + MatrixStack matrices = new MatrixStack(); + MatrixStack.Entry caller = matrices.getLast(); + try { + DrillBitRenderer.renderGeometry(Direction.Axis.X, 37, matrices, new RecordingBuffer() { + @Override public void endVertex() { throw new IllegalStateException("submission failed"); } + }, LIGHT, OVERLAY); + fail("Expected vertex submission failure"); + } catch (IllegalStateException expected) { + assertEquals("submission failed", expected.getMessage()); + } + assertSame(caller, matrices.getLast()); + } + + private static final class Vertex { + final double[] position = new double[3]; + final int[] color = new int[4]; + final float[] normal = new float[3]; + float u, v; + int overlay, light; + } + + private static class RecordingBuffer implements IVertexBuilder { + final List vertices = new ArrayList<>(); + private Vertex vertex = new Vertex(); + + @Override public IVertexBuilder pos(double x, double y, double z) { + vertex.position[0] = x; vertex.position[1] = y; vertex.position[2] = z; + return this; + } + @Override public IVertexBuilder color(int red, int green, int blue, int alpha) { + vertex.color[0] = red; vertex.color[1] = green; vertex.color[2] = blue; vertex.color[3] = alpha; + return this; + } + @Override public IVertexBuilder tex(float u, float v) { vertex.u = u; vertex.v = v; return this; } + @Override public IVertexBuilder overlay(int u, int v) { vertex.overlay = u | v << 16; return this; } + @Override public IVertexBuilder lightmap(int u, int v) { vertex.light = u | v << 16; return this; } + @Override public IVertexBuilder normal(float x, float y, float z) { + vertex.normal[0] = x; vertex.normal[1] = y; vertex.normal[2] = z; + return this; + } + @Override public void endVertex() { vertices.add(vertex); vertex = new Vertex(); } + } +} diff --git a/src/test/java/zone/moddev/mc/steamadvantage/resources/NativeLootContractTest.java b/src/test/java/zone/moddev/mc/steamadvantage/resources/NativeLootContractTest.java index b320881..6dae7f5 100644 --- a/src/test/java/zone/moddev/mc/steamadvantage/resources/NativeLootContractTest.java +++ b/src/test/java/zone/moddev/mc/steamadvantage/resources/NativeLootContractTest.java @@ -39,8 +39,8 @@ public class NativeLootContractTest { } } - @Test public void packUsesNative114Format() throws Exception { - assertEquals(4, read(ROOT.resolve("pack.mcmeta")).getAsJsonObject("pack").get("pack_format").getAsInt()); + @Test public void packUsesNative115Format() throws Exception { + assertEquals(5, read(ROOT.resolve("pack.mcmeta")).getAsJsonObject("pack").get("pack_format").getAsInt()); } private static JsonObject read(Path path) throws Exception { From 2c7d2c802c056f42298274e22ed6224b2566a5d0 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Mon, 26 Oct 2026 12:33:51 +0000 Subject: [PATCH 2/6] Use pinned JDKs in every hosted Gradle build --- .github/workflows/ci.yml | 15 +++++------ .github/workflows/codeql-analysis.yml | 15 +++++------ .../resources/BuildWorkflowContractTest.java | 25 +++++++++++++++++++ 3 files changed, 41 insertions(+), 14 deletions(-) create mode 100644 src/test/java/zone/moddev/mc/steamadvantage/resources/BuildWorkflowContractTest.java diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d480255..c234d05 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,11 +58,12 @@ jobs: distribution: temurin java-version: '17.0.1+12' - name: Use pinned build toolchains + # These are Gradle project properties, not JVM system properties. shell: bash run: >- - echo "GRADLE_OPTS=-Dorg.gradle.java.installations.paths=$JAVA_HOME,$JAVA_HOME_8_X64,$JAVA_HOME_25_X64 - -Dorg.gradle.java.installations.auto-detect=false - -Dorg.gradle.java.installations.auto-download=false" >> "$GITHUB_ENV" + echo "MMD_GRADLE_TOOLCHAINS=-Porg.gradle.java.installations.paths=$JAVA_HOME,$JAVA_HOME_8_X64,$JAVA_HOME_25_X64 + -Porg.gradle.java.installations.auto-detect=false + -Porg.gradle.java.installations.auto-download=false" >> "$GITHUB_ENV" - name: Set up Gradle uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6 - name: Build 1.15.2 dependency chain @@ -74,11 +75,11 @@ jobs: basemetals="$GITHUB_WORKSPACE/.ci-dependencies/BaseMetals" power="$GITHUB_WORKSPACE/.ci-dependencies/PowerAdvantage" chmod +x "$orespawn/gradlew" "$basemetals/gradlew" "$power/gradlew" - (cd "$orespawn" && ./gradlew jar --no-daemon --stacktrace) - (cd "$basemetals" && ./gradlew jar --no-daemon --stacktrace) + (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.1.115021-deobf.jar" bmjar="$basemetals/build/libs-dev/BaseMetals-3.0.1.115021-deobf.jar" - (cd "$power" && ./gradlew jar verifyReleaseDependencies \ + (cd "$power" && ./gradlew $MMD_GRADLE_TOOLCHAINS jar verifyReleaseDependencies \ -PbaseMetalsDeobfJar="$bmjar" -PoreSpawnDeobfJar="$osjar" \ --no-daemon --stacktrace) powerjar="$power/build/libs-dev/PowerAdvantage-2.4.6.115021-deobf.jar" @@ -89,7 +90,7 @@ jobs: echo "power_ref=$(git -C "$power" rev-parse HEAD)" >> "$GITHUB_OUTPUT" - name: Build and audit release artifacts run: >- - ./gradlew clean check build javadoc verifyReleaseDependencies verifyReleaseArtifacts + ./gradlew $MMD_GRADLE_TOOLCHAINS clean check build javadoc verifyReleaseDependencies verifyReleaseArtifacts writeReleaseChecksums verifyEclipseProductionClasspath -PpowerAdvantageDeobfJar=${{ steps.dependencies.outputs.power }} -Ppoweradvantage_source_ref=${{ steps.dependencies.outputs.power_ref }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index f182126..42ae611 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -58,11 +58,12 @@ jobs: distribution: temurin java-version: '17.0.1+12' - name: Use pinned build toolchains + # These are Gradle project properties, not JVM system properties. shell: bash run: >- - echo "GRADLE_OPTS=-Dorg.gradle.java.installations.paths=$JAVA_HOME,$JAVA_HOME_8_X64,$JAVA_HOME_25_X64 - -Dorg.gradle.java.installations.auto-detect=false - -Dorg.gradle.java.installations.auto-download=false" >> "$GITHUB_ENV" + echo "MMD_GRADLE_TOOLCHAINS=-Porg.gradle.java.installations.paths=$JAVA_HOME,$JAVA_HOME_8_X64,$JAVA_HOME_25_X64 + -Porg.gradle.java.installations.auto-detect=false + -Porg.gradle.java.installations.auto-download=false" >> "$GITHUB_ENV" - name: Set up Gradle uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6 - name: Build 1.15.2 dependency chain @@ -74,11 +75,11 @@ jobs: basemetals="$GITHUB_WORKSPACE/.ci-dependencies/BaseMetals" power="$GITHUB_WORKSPACE/.ci-dependencies/PowerAdvantage" chmod +x "$orespawn/gradlew" "$basemetals/gradlew" "$power/gradlew" - (cd "$orespawn" && ./gradlew jar --no-daemon --stacktrace) - (cd "$basemetals" && ./gradlew jar --no-daemon --stacktrace) + (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.1.115021-deobf.jar" bmjar="$basemetals/build/libs-dev/BaseMetals-3.0.1.115021-deobf.jar" - (cd "$power" && ./gradlew jar verifyReleaseDependencies \ + (cd "$power" && ./gradlew $MMD_GRADLE_TOOLCHAINS jar verifyReleaseDependencies \ -PbaseMetalsDeobfJar="$bmjar" -PoreSpawnDeobfJar="$osjar" \ --no-daemon --stacktrace) powerjar="$power/build/libs-dev/PowerAdvantage-2.4.6.115021-deobf.jar" @@ -94,7 +95,7 @@ jobs: - name: Compile SteamAdvantage production code run: | chmod +x ./gradlew - ./gradlew clean classes --rerun-tasks --no-build-cache --no-daemon --stacktrace \ + ./gradlew $MMD_GRADLE_TOOLCHAINS clean classes --rerun-tasks --no-build-cache --no-daemon --stacktrace \ -PpowerAdvantageDeobfJar=${{ steps.dependencies.outputs.power }} \ -Ppoweradvantage_source_ref=${{ steps.dependencies.outputs.power_ref }} \ -PbaseMetalsDeobfJar=${{ steps.dependencies.outputs.basemetals }} \ diff --git a/src/test/java/zone/moddev/mc/steamadvantage/resources/BuildWorkflowContractTest.java b/src/test/java/zone/moddev/mc/steamadvantage/resources/BuildWorkflowContractTest.java new file mode 100644 index 0000000..06ce7ac --- /dev/null +++ b/src/test/java/zone/moddev/mc/steamadvantage/resources/BuildWorkflowContractTest.java @@ -0,0 +1,25 @@ +package zone.moddev.mc.steamadvantage.resources; + +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import org.junit.Test; +import static org.junit.Assert.*; + +public class BuildWorkflowContractTest { + @Test public void everyHostedBuildUsesPinnedToolchainProjectProperties() throws Exception { + for (String name : new String[] {"ci.yml", "codeql-analysis.yml"}) { + String source = new String(Files.readAllBytes(Paths.get(".github/workflows", name)), + StandardCharsets.UTF_8); + assertTrue(name, source.contains("-Porg.gradle.java.installations.paths=")); + assertTrue(name, source.contains("-Porg.gradle.java.installations.auto-detect=false")); + assertTrue(name, source.contains("-Porg.gradle.java.installations.auto-download=false")); + assertFalse(name, source.contains("-Dorg.gradle.java.installations.")); + for (String line : source.split("\\R")) { + if (line.contains("./gradlew ") && !line.contains("chmod")) { + assertTrue(name + ": " + line, line.contains("./gradlew $MMD_GRADLE_TOOLCHAINS ")); + } + } + } + } +} From 7883d9b697a7c0961c721f01baa6ed1046d256de Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Mon, 26 Oct 2026 12:56:51 +0000 Subject: [PATCH 3/6] Preserve track properties and register recipes after parallel setup --- .github/workflows/ci.yml | 2 +- .github/workflows/codeql-analysis.yml | 2 +- CHANGELOG.txt | 2 + gradle.properties | 4 +- .../mc/steamadvantage/SteamAdvantage.java | 3 +- .../steamadvantage/blocks/PlatformBlock.java | 1 + .../blocks/SteamTrackBlock.java | 6 +- .../resources/NativeBlockPropertiesTest.java | 95 +++++++++++++++++++ .../RecipeRegistrationThreadTest.java | 49 ++++++++++ 9 files changed, 158 insertions(+), 6 deletions(-) create mode 100644 src/test/java/zone/moddev/mc/steamadvantage/resources/NativeBlockPropertiesTest.java create mode 100644 src/test/java/zone/moddev/mc/steamadvantage/resources/RecipeRegistrationThreadTest.java diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c234d05..65e2402 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/PowerAdvantage - ref: b15e2091e9647860bd90284aef6135a311692864 + ref: 75d24d2641e8123ff7a7f961d9a1e5a1d5203194 path: .ci-dependencies/PowerAdvantage - name: Install pinned Java 25 Mavenizer runtime uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 42ae611..e175454 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -40,7 +40,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/PowerAdvantage - ref: b15e2091e9647860bd90284aef6135a311692864 + ref: 75d24d2641e8123ff7a7f961d9a1e5a1d5203194 path: .ci-dependencies/PowerAdvantage - name: Install pinned Java 25 Mavenizer runtime uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 2d9f6f7..bab6a1b 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -6,6 +6,8 @@ Steam Advantage 2.2.7.115021 - Register the steam track's cutout render layer on the client and retain non-solid helper blocks through native properties. - Use native entity position accessors and action-result factories for elevators and muskets. - Preserve registry identities, recipes, migration codecs, saved NBT, machine costs and output quantities. +- Register recipe conditions after parallel setup to prevent intermittent missing recipes at startup. +- Retain the steam track's light transmission and keep tracks and elevator platforms from conducting redstone through their full-cube shapes. - Pass 30 unit/resource tests, including all-facing renderer geometry, lighting/overlay and matrix-restoration regressions. - Keep combined server/client gameplay and disposable-copy migration checks separate; 1.14 results do not qualify 1.15 worlds. diff --git a/gradle.properties b/gradle.properties index 2e6054b..9631502 100644 --- a/gradle.properties +++ b/gradle.properties @@ -37,8 +37,8 @@ cf_versions=1.15.2 poweradvantage_version=2.4.6.115021 poweradvantage_source_repository=MinecraftModDevelopmentMods/PowerAdvantage # Exact Power Advantage source and development jar used by local and CI builds. -poweradvantage_source_ref=b15e2091e9647860bd90284aef6135a311692864 -poweradvantage_deobf_sha256=2C3ADBCA79859DFA2C14EF8DC9068BF9F202D72FDB1D37B51ED4DE1B5B7E866A +poweradvantage_source_ref=75d24d2641e8123ff7a7f961d9a1e5a1d5203194 +poweradvantage_deobf_sha256=F5029356CB837E7D782BA59D4C3B961CE0AAA116B739F14DA63F0A13562A2D1F basemetals_version=3.0.1.115021 basemetals_deobf_sha256=A98EAC370D908F14103DB6D064C738160161FDD7203F30905562B23EEE265210 diff --git a/src/main/java/zone/moddev/mc/steamadvantage/SteamAdvantage.java b/src/main/java/zone/moddev/mc/steamadvantage/SteamAdvantage.java index 730c678..3bbbe8e 100644 --- a/src/main/java/zone/moddev/mc/steamadvantage/SteamAdvantage.java +++ b/src/main/java/zone/moddev/mc/steamadvantage/SteamAdvantage.java @@ -50,7 +50,6 @@ public SteamAdvantage() { Entities.init(); Enchantments.init(); GUI.init(); - RecipeConditions.register(); migrateLegacyConfiguration(); ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, SteamAdvantageConfig.SPEC); @@ -80,6 +79,8 @@ private static void migrateLegacyConfiguration() { } private void commonSetup(FMLCommonSetupEvent event) { + // CraftingHelper's shared condition map is not safe during parallel loading. + net.minecraftforge.fml.DeferredWorkQueue.runLater(RecipeConditions::register); SteamAdvantageConfig.apply(); Recipes.init(); TreasureChests.init(FMLPaths.CONFIGDIR.get()); diff --git a/src/main/java/zone/moddev/mc/steamadvantage/blocks/PlatformBlock.java b/src/main/java/zone/moddev/mc/steamadvantage/blocks/PlatformBlock.java index f21643d..07c7add 100644 --- a/src/main/java/zone/moddev/mc/steamadvantage/blocks/PlatformBlock.java +++ b/src/main/java/zone/moddev/mc/steamadvantage/blocks/PlatformBlock.java @@ -36,6 +36,7 @@ public PlatformBlock() { @Override protected void fillStateContainer(StateContainer.Builder builder) { builder.add(HEIGHT); } @Override public VoxelShape getShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext context) { return SHAPES[state.get(HEIGHT)]; } @Override public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext context) { return SHAPES[state.get(HEIGHT)]; } + @Override public boolean isNormalCube(BlockState state, IBlockReader world, BlockPos pos) { return false; } @Override public List getDrops(BlockState state, LootContext.Builder context) { return Collections.emptyList(); } @Override diff --git a/src/main/java/zone/moddev/mc/steamadvantage/blocks/SteamTrackBlock.java b/src/main/java/zone/moddev/mc/steamadvantage/blocks/SteamTrackBlock.java index 231b3ad..7a3ff6b 100644 --- a/src/main/java/zone/moddev/mc/steamadvantage/blocks/SteamTrackBlock.java +++ b/src/main/java/zone/moddev/mc/steamadvantage/blocks/SteamTrackBlock.java @@ -11,7 +11,11 @@ import zone.moddev.mc.steamadvantage.init.Power; public class SteamTrackBlock extends BlockSimplePowerConduit { - public SteamTrackBlock() { super(Material.PISTON, 0.75F, 2.0F / 16.0F, Power.steam_power); } + public SteamTrackBlock() { + super(Properties.create(Material.PISTON).hardnessAndResistance(0.75F).notSolid(), + 2.0F / 16.0F, Power.steam_power); + } @Override public VoxelShape getShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext context) { return VoxelShapes.fullCube(); } @Override public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext context) { return VoxelShapes.fullCube(); } + @Override public boolean isNormalCube(BlockState state, IBlockReader world, BlockPos pos) { return false; } } diff --git a/src/test/java/zone/moddev/mc/steamadvantage/resources/NativeBlockPropertiesTest.java b/src/test/java/zone/moddev/mc/steamadvantage/resources/NativeBlockPropertiesTest.java new file mode 100644 index 0000000..903f882 --- /dev/null +++ b/src/test/java/zone/moddev/mc/steamadvantage/resources/NativeBlockPropertiesTest.java @@ -0,0 +1,95 @@ +package zone.moddev.mc.steamadvantage.resources; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.shapes.IBooleanFunction; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.util.math.shapes.VoxelShapes; +import net.minecraft.util.registry.Bootstrap; +import net.minecraft.world.EmptyBlockReader; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import zone.moddev.mc.steamadvantage.blocks.PlatformBlock; +import zone.moddev.mc.steamadvantage.blocks.SteamTrackBlock; +import static org.junit.Assert.*; + +@RunWith(Parameterized.class) +public class NativeBlockPropertiesTest { + @Parameterized.Parameters(name = "{0}") + public static Collection cases() { + return Arrays.asList(new Object[][] { + {"steam_track", -1}, {"platform_height_0", 0}, {"platform_height_1", 1}, + {"platform_height_2", 2}, {"platform_height_3", 3}, {"platform_height_4", 4} + }); + } + + @Parameterized.Parameter public String name; + @Parameterized.Parameter(1) public int height; + private Block block; + + @BeforeClass public static void bootstrapNativeRegistries() { Bootstrap.register(); } + + @Before public void createNativeBlockAndStateCaches() { + block = height < 0 ? new SteamTrackBlock() : new PlatformBlock(); + for (BlockState state : block.getStateContainer().getValidStates()) state.cacheState(); + } + + @Test public void remainsNonSolid() { + for (BlockState state : states()) assertFalse(state.toString(), state.isSolid()); + } + + @Test public void remainsNonOpaque() { + for (BlockState state : states()) { + assertFalse(state.toString(), state.isOpaqueCube(EmptyBlockReader.INSTANCE, BlockPos.ZERO)); + } + } + + @Test public void retainsNativeOpacityForTheLegacyShape() { + // Native opacity is 1, not 0, for a non-solid block with a full-cube outline. + int expected = height < 0 || height == 4 ? 1 : 0; + for (BlockState state : states()) { + assertEquals(state.toString(), expected, state.getOpacity(EmptyBlockReader.INSTANCE, BlockPos.ZERO)); + } + } + + @Test public void remainsANonNormalCube() { + for (BlockState state : states()) { + assertFalse(state.toString(), state.isNormalCube(EmptyBlockReader.INSTANCE, BlockPos.ZERO)); + } + } + + @Test public void doesNotConductWeakPowerOnAnyFace() { + for (BlockState state : states()) { + for (Direction face : Direction.values()) { + // The native hook delegates to isNormalCube; these constant shapes need no world lookup. + assertFalse(state + " face=" + face, state.shouldCheckWeakPower(null, BlockPos.ZERO, face)); + } + } + } + + @Test public void preservesOutlineAndCollisionShapes() { + VoxelShape expected = height < 0 || height == 4 ? VoxelShapes.fullCube() + : height == 0 ? VoxelShapes.create(0.25D, 0.0D, 0.25D, 0.75D, 1.0D, 0.75D) + : VoxelShapes.create(0.0D, 0.0D, 0.0D, 1.0D, height * 0.25D, 1.0D); + if (height < 0) assertEquals(64, states().size()); + for (BlockState state : states()) { + assertFalse(state + " outline", VoxelShapes.compare(expected, + state.getShape(EmptyBlockReader.INSTANCE, BlockPos.ZERO), IBooleanFunction.NOT_SAME)); + assertFalse(state + " collision", VoxelShapes.compare(expected, + state.getCollisionShape(EmptyBlockReader.INSTANCE, BlockPos.ZERO), IBooleanFunction.NOT_SAME)); + } + } + + private Collection states() { + return height < 0 ? block.getStateContainer().getValidStates() + : Collections.singletonList(block.getDefaultState().with(PlatformBlock.HEIGHT, height)); + } +} diff --git a/src/test/java/zone/moddev/mc/steamadvantage/resources/RecipeRegistrationThreadTest.java b/src/test/java/zone/moddev/mc/steamadvantage/resources/RecipeRegistrationThreadTest.java new file mode 100644 index 0000000..e900e10 --- /dev/null +++ b/src/test/java/zone/moddev/mc/steamadvantage/resources/RecipeRegistrationThreadTest.java @@ -0,0 +1,49 @@ +package zone.moddev.mc.steamadvantage.resources; + +import java.io.InputStream; +import org.junit.Test; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.Handle; +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.InvokeDynamicInsnNode; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; +import static org.junit.Assert.*; + +public class RecipeRegistrationThreadTest { + @Test public void sharedForgeConditionsAreRegisteredAfterParallelSetup() throws Exception { + ClassNode node = new ClassNode(); + try (InputStream input = getClass().getResourceAsStream("/zone/moddev/mc/steamadvantage/SteamAdvantage.class")) { + assertNotNull(input); + new ClassReader(input).accept(node, 0); + } + String conditions = "zone/moddev/mc/steamadvantage/recipe/RecipeConditions"; + int queued = 0; + for (MethodNode method : node.methods) { + boolean registrationRunnable = false; + for (AbstractInsnNode instruction : method.instructions.toArray()) { + if (instruction instanceof MethodInsnNode) { + MethodInsnNode call = (MethodInsnNode) instruction; + assertFalse("Forge's condition HashMap is not safe during parallel loading", + call.owner.equals(conditions) && call.name.equals("register")); + if (call.owner.equals("net/minecraftforge/fml/DeferredWorkQueue") + && call.name.equals("runLater") && registrationRunnable) { + assertEquals("Register conditions during common setup", "commonSetup", method.name); + queued++; + registrationRunnable = false; + } + } + if (instruction instanceof InvokeDynamicInsnNode) { + for (Object argument : ((InvokeDynamicInsnNode) instruction).bsmArgs) { + if (argument instanceof Handle && ((Handle) argument).getOwner().equals(conditions) + && ((Handle) argument).getName().equals("register")) { + registrationRunnable = true; + } + } + } + } + } + assertEquals("Queue registration exactly once on Forge's loading thread", 1, queued); + } +} From 07f6a0503c57df0b51f7ac4370c0ff5eda0232f5 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Mon, 26 Oct 2026 14:28:28 +0000 Subject: [PATCH 4/6] Pin Base Metals 3.0.2 and matching local Power source Dependency sources are local-only. Publish the exact Base Metals and Power commits upstream before PR or hosted builds. --- .github/workflows/ci.yml | 8 +++++--- .github/workflows/codeql-analysis.yml | 8 +++++--- build.gradle | 2 +- gradle.properties | 6 +++--- .../resources/BuildWorkflowContractTest.java | 5 +++++ 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 65e2402..acf3fa6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,13 +34,15 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/BaseMetals - ref: 1d166d917663d4b4a5a88a86440adc0ae761e393 + # Local-only Base Metals source; publish upstream before PR/hosted builds. + ref: ac1781e7cade15045ffe0135077087b4d1722603 path: .ci-dependencies/BaseMetals - name: Check out PowerAdvantage 1.15.2 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/PowerAdvantage - ref: 75d24d2641e8123ff7a7f961d9a1e5a1d5203194 + # Local-only Power source; publish upstream before PR/hosted builds. + ref: 6666099a734eba16561d98c86f3f4bb1b7c742f7 path: .ci-dependencies/PowerAdvantage - name: Install pinned Java 25 Mavenizer runtime uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 @@ -78,7 +80,7 @@ jobs: (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.1.115021-deobf.jar" - bmjar="$basemetals/build/libs-dev/BaseMetals-3.0.1.115021-deobf.jar" + bmjar="$basemetals/build/libs-dev/BaseMetals-3.0.2.115021-deobf.jar" (cd "$power" && ./gradlew $MMD_GRADLE_TOOLCHAINS jar verifyReleaseDependencies \ -PbaseMetalsDeobfJar="$bmjar" -PoreSpawnDeobfJar="$osjar" \ --no-daemon --stacktrace) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e175454..d6a5280 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -34,13 +34,15 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/BaseMetals - ref: 1d166d917663d4b4a5a88a86440adc0ae761e393 + # Local-only Base Metals source; publish upstream before PR/hosted builds. + ref: ac1781e7cade15045ffe0135077087b4d1722603 path: .ci-dependencies/BaseMetals - name: Check out PowerAdvantage 1.15.2 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/PowerAdvantage - ref: 75d24d2641e8123ff7a7f961d9a1e5a1d5203194 + # Local-only Power source; publish upstream before PR/hosted builds. + ref: 6666099a734eba16561d98c86f3f4bb1b7c742f7 path: .ci-dependencies/PowerAdvantage - name: Install pinned Java 25 Mavenizer runtime uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 @@ -78,7 +80,7 @@ jobs: (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.1.115021-deobf.jar" - bmjar="$basemetals/build/libs-dev/BaseMetals-3.0.1.115021-deobf.jar" + bmjar="$basemetals/build/libs-dev/BaseMetals-3.0.2.115021-deobf.jar" (cd "$power" && ./gradlew $MMD_GRADLE_TOOLCHAINS jar verifyReleaseDependencies \ -PbaseMetalsDeobfJar="$bmjar" -PoreSpawnDeobfJar="$osjar" \ --no-daemon --stacktrace) diff --git a/build.gradle b/build.gradle index 0c00296..d6a77c8 100644 --- a/build.gradle +++ b/build.gradle @@ -179,7 +179,7 @@ if (!powerAdvantageDeobfJar.isFile()) { // here so another developer can override them without editing the script. def baseMetalsDeobfJar = file(providers.gradleProperty('baseMetalsDeobfJar') .getOrElse('../../../../BaseMetals/BaseMetals 115/BaseMetals/build/libs-dev/' - + 'BaseMetals-3.0.1.115021-deobf.jar')) + + 'BaseMetals-3.0.2.115021-deobf.jar')) if (!baseMetalsDeobfJar.isFile()) { throw new GradleException("Missing Base Metals deobf jar at ${baseMetalsDeobfJar}. " + "Build Base Metals 1.15 first, or pass -PbaseMetalsDeobfJar=.") diff --git a/gradle.properties b/gradle.properties index 9631502..f28d4e6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -37,11 +37,11 @@ cf_versions=1.15.2 poweradvantage_version=2.4.6.115021 poweradvantage_source_repository=MinecraftModDevelopmentMods/PowerAdvantage # Exact Power Advantage source and development jar used by local and CI builds. -poweradvantage_source_ref=75d24d2641e8123ff7a7f961d9a1e5a1d5203194 +poweradvantage_source_ref=6666099a734eba16561d98c86f3f4bb1b7c742f7 poweradvantage_deobf_sha256=F5029356CB837E7D782BA59D4C3B961CE0AAA116B739F14DA63F0A13562A2D1F -basemetals_version=3.0.1.115021 -basemetals_deobf_sha256=A98EAC370D908F14103DB6D064C738160161FDD7203F30905562B23EEE265210 +basemetals_version=3.0.2.115021 +basemetals_deobf_sha256=426FE639C97E1DE4F6624957E3CBDE68A5FB7D415A1047903A29DCB35FD9ADA2 orespawn_version=4.1.1.115021 orespawn_deobf_sha256=358B13375A4B60622C491D6729290971A446FF14D524A600CA13710934DB3FDC diff --git a/src/test/java/zone/moddev/mc/steamadvantage/resources/BuildWorkflowContractTest.java b/src/test/java/zone/moddev/mc/steamadvantage/resources/BuildWorkflowContractTest.java index 06ce7ac..11150a7 100644 --- a/src/test/java/zone/moddev/mc/steamadvantage/resources/BuildWorkflowContractTest.java +++ b/src/test/java/zone/moddev/mc/steamadvantage/resources/BuildWorkflowContractTest.java @@ -11,6 +11,11 @@ public class BuildWorkflowContractTest { for (String name : new String[] {"ci.yml", "codeql-analysis.yml"}) { String source = new String(Files.readAllBytes(Paths.get(".github/workflows", name)), StandardCharsets.UTF_8); + assertTrue(name, source.contains("ref: ac1781e7cade15045ffe0135077087b4d1722603")); + assertTrue(name, source.contains("BaseMetals-3.0.2.115021-deobf.jar")); + assertTrue(name, source.contains("Local-only Base Metals source; publish upstream before PR/hosted builds.")); + assertTrue(name, source.contains("ref: 6666099a734eba16561d98c86f3f4bb1b7c742f7")); + assertTrue(name, source.contains("Local-only Power source; publish upstream before PR/hosted builds.")); assertTrue(name, source.contains("-Porg.gradle.java.installations.paths=")); assertTrue(name, source.contains("-Porg.gradle.java.installations.auto-detect=false")); assertTrue(name, source.contains("-Porg.gradle.java.installations.auto-download=false")); From 9e5b1da435c3f4d04fe28c8b0e0a99aaae1d8103 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Mon, 26 Oct 2026 14:55:00 +0000 Subject: [PATCH 5/6] Clarify local 1.15 validation and unpublished dependency pins --- CHANGELOG.txt | 4 ++-- README.md | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index bab6a1b..1779308 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -8,8 +8,8 @@ Steam Advantage 2.2.7.115021 - Preserve registry identities, recipes, migration codecs, saved NBT, machine costs and output quantities. - Register recipe conditions after parallel setup to prevent intermittent missing recipes at startup. - Retain the steam track's light transmission and keep tracks and elevator platforms from conducting redstone through their full-cube shapes. -- Pass 30 unit/resource tests, including all-facing renderer geometry, lighting/overlay and matrix-restoration regressions. -- Keep combined server/client gameplay and disposable-copy migration checks separate; 1.14 results do not qualify 1.15 worlds. +- Add all-facing renderer, lighting, matrix-restoration and native block-property regressions. +- Record combined operating and disposable-copy migration results in Power Advantage's shared 1.15 test notes; manual acceptance remains separate. Steam Advantage 2.2.6.114041 diff --git a/README.md b/README.md index 84103ed..f3d80b8 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # SteamAdvantage -**Minecraft 1.15.2 port, version 2.2.7.115021.** Native compilation and 30 unit/resource -tests pass, including native drill-renderer geometry and matrix-stack checks. -Combined-mod server, client-resource, connected-machine and disposable-copy migration -checks have not yet been repeated for this port. The historical +**Minecraft 1.15.2 port candidate, version 2.2.7.115021.** See the +[shared test record](https://github.com/MinecraftModDevelopmentMods/PowerAdvantage/blob/master-1.15.2/docs/1.15/CURRENT-QUALIFICATION.md) +for exact jars, automated machine and upgrade results, and remaining manual +checks. This version is not published. The historical [1.14 test results](https://github.com/MinecraftModDevelopmentMods/PowerAdvantage/blob/master-1.14.4/docs/1.14/BROADER-QUALIFICATION.md) are not evidence of 1.15 gameplay or world-upgrade compatibility. @@ -25,6 +25,11 @@ Build the matching 1.15 PowerAdvantage, Base Metals and OreSpawn deobf jars firs Dependency versions, checksums and the exact Power source reference belong in `gradle.properties`. Release audits reject missing or placeholder pins; do not bypass those checks or substitute a dependency from an earlier Minecraft version. +Base Metals `3.0.2.115021` source `ac1781e7cade15045ffe0135077087b4d1722603` +and Power source `6666099a734eba16561d98c86f3f4bb1b7c742f7` are local-only and +unpublished. Publish both exact sources upstream before opening a PR or running +hosted builds; hosted reproducibility and publication readiness are not established. + With the standard sibling layout: ```text From 1a32262aecc1626f9d4fda0cb231439c805a8644 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Tue, 27 Oct 2026 10:35:40 +0000 Subject: [PATCH 6/6] Record accepted 1.15 visuals and recipe unlocks --- .github/workflows/ci.yml | 2 -- .github/workflows/codeql-analysis.yml | 2 -- CHANGELOG.txt | 1 + README.md | 10 +++++----- .../resources/BuildWorkflowContractTest.java | 2 -- 5 files changed, 6 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index acf3fa6..a7ab631 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,14 +34,12 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/BaseMetals - # Local-only Base Metals source; publish upstream before PR/hosted builds. ref: ac1781e7cade15045ffe0135077087b4d1722603 path: .ci-dependencies/BaseMetals - name: Check out PowerAdvantage 1.15.2 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/PowerAdvantage - # Local-only Power source; publish upstream before PR/hosted builds. ref: 6666099a734eba16561d98c86f3f4bb1b7c742f7 path: .ci-dependencies/PowerAdvantage - name: Install pinned Java 25 Mavenizer runtime diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index d6a5280..7a35df2 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -34,14 +34,12 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/BaseMetals - # Local-only Base Metals source; publish upstream before PR/hosted builds. ref: ac1781e7cade15045ffe0135077087b4d1722603 path: .ci-dependencies/BaseMetals - name: Check out PowerAdvantage 1.15.2 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/PowerAdvantage - # Local-only Power source; publish upstream before PR/hosted builds. ref: 6666099a734eba16561d98c86f3f4bb1b7c742f7 path: .ci-dependencies/PowerAdvantage - name: Install pinned Java 25 Mavenizer runtime diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 1779308..7fc6ea6 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -10,6 +10,7 @@ Steam Advantage 2.2.7.115021 - Retain the steam track's light transmission and keep tracks and elevator platforms from conducting redstone through their full-cube shapes. - Add all-facing renderer, lighting, matrix-restoration and native block-property regressions. - Record combined operating and disposable-copy migration results in Power Advantage's shared 1.15 test notes; manual acceptance remains separate. +- Record the accepted in-game visuals and recipe unlocks; the shared test record retains the remaining limits. Steam Advantage 2.2.6.114041 diff --git a/README.md b/README.md index f3d80b8..aca7e9a 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # SteamAdvantage -**Minecraft 1.15.2 port candidate, version 2.2.7.115021.** See the +**Minecraft 1.15.2, version 2.2.7.115021.** See the [shared test record](https://github.com/MinecraftModDevelopmentMods/PowerAdvantage/blob/master-1.15.2/docs/1.15/CURRENT-QUALIFICATION.md) for exact jars, automated machine and upgrade results, and remaining manual -checks. This version is not published. The historical +checks. Visuals and recipe unlocks were accepted on 27 October 2026. The historical [1.14 test results](https://github.com/MinecraftModDevelopmentMods/PowerAdvantage/blob/master-1.14.4/docs/1.14/BROADER-QUALIFICATION.md) are not evidence of 1.15 gameplay or world-upgrade compatibility. @@ -26,9 +26,9 @@ Dependency versions, checksums and the exact Power source reference belong in `gradle.properties`. Release audits reject missing or placeholder pins; do not bypass those checks or substitute a dependency from an earlier Minecraft version. Base Metals `3.0.2.115021` source `ac1781e7cade15045ffe0135077087b4d1722603` -and Power source `6666099a734eba16561d98c86f3f4bb1b7c742f7` are local-only and -unpublished. Publish both exact sources upstream before opening a PR or running -hosted builds; hosted reproducibility and publication readiness are not established. +and Power source `6666099a734eba16561d98c86f3f4bb1b7c742f7` are the exact tested +dependency pins. CI builds them before Steam Advantage; none is embedded in +the Steam Advantage jar. With the standard sibling layout: diff --git a/src/test/java/zone/moddev/mc/steamadvantage/resources/BuildWorkflowContractTest.java b/src/test/java/zone/moddev/mc/steamadvantage/resources/BuildWorkflowContractTest.java index 11150a7..6a0863a 100644 --- a/src/test/java/zone/moddev/mc/steamadvantage/resources/BuildWorkflowContractTest.java +++ b/src/test/java/zone/moddev/mc/steamadvantage/resources/BuildWorkflowContractTest.java @@ -13,9 +13,7 @@ public class BuildWorkflowContractTest { StandardCharsets.UTF_8); assertTrue(name, source.contains("ref: ac1781e7cade15045ffe0135077087b4d1722603")); assertTrue(name, source.contains("BaseMetals-3.0.2.115021-deobf.jar")); - assertTrue(name, source.contains("Local-only Base Metals source; publish upstream before PR/hosted builds.")); assertTrue(name, source.contains("ref: 6666099a734eba16561d98c86f3f4bb1b7c742f7")); - assertTrue(name, source.contains("Local-only Power source; publish upstream before PR/hosted builds.")); assertTrue(name, source.contains("-Porg.gradle.java.installations.paths=")); assertTrue(name, source.contains("-Porg.gradle.java.installations.auto-detect=false")); assertTrue(name, source.contains("-Porg.gradle.java.installations.auto-download=false"));