diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..2dc7c427 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +* text=auto +*.java text eol=lf +*.gradle text eol=lf +*.json text eol=lf +*.yml text eol=lf +*.py text eol=lf +*.sh text eol=lf +gradlew text eol=lf +gradlew.bat text eol=crlf +*.png binary +*.jar binary diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..9fb4fda5 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,230 @@ +name: Modern Metals 1.12 CI + +on: + push: + branches: + - master-1.12 + - 'feature/**' + pull_request: + branches: + - master-1.12 + +permissions: + contents: read + +concurrency: + group: modernmetals-1.12-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + cold-forge-bootstrap: + name: Cold Forge bootstrap + runs-on: ubuntu-latest + timeout-minutes: 75 + + steps: + - name: Check out source + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + + - name: Install pinned Java 25 ForgeGradle Mavenizer runtime + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 + with: + distribution: temurin + java-version: '25.0.3+9.0.LTS' + + - name: Install pinned Java 8 compilation toolchain + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 + with: + distribution: temurin + java-version: '8.0.502+7' + + - name: Install pinned Java 17 Gradle runtime + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 + with: + distribution: temurin + java-version: '17.0.1+12' + + - name: Stage checksum-verified legacy dependencies + id: dependencies + shell: bash + run: | + set -euo pipefail + mirror="$RUNNER_TEMP/legacy-dependency-mirror" + bash gradle/stage-legacy-dependencies.sh "$mirror" + echo "repository=$mirror" >> "$GITHUB_OUTPUT" + + - name: Bootstrap Forge from an empty cache + shell: bash + env: + GRADLE_USER_HOME: ${{ runner.temp }}/modernmetals-cold-gradle + run: | + set -euo pipefail + test ! -e .gradle + test ! -e "$GRADLE_USER_HOME" + mkdir -p "$GRADLE_USER_HOME" + chmod +x ./gradlew + gradle_args=( + classes verifyReleaseDependencies + -PlegacyDependencyVerificationRepository="${{ steps.dependencies.outputs.repository }}" + --no-daemon --no-build-cache --stacktrace --max-workers=2 + -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 + ) + ./gradlew "${gradle_args[@]}" + + - name: Verify same-cache bootstrap offline + shell: bash + env: + GRADLE_USER_HOME: ${{ runner.temp }}/modernmetals-cold-gradle + run: | + set -euo pipefail + gradle_args=( + classes verifyReleaseDependencies + -PlegacyDependencyVerificationRepository="${{ steps.dependencies.outputs.repository }}" + --rerun-tasks --offline --no-daemon --no-build-cache --stacktrace --max-workers=2 + -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 + ) + ./gradlew "${gradle_args[@]}" + + build: + name: Build, test, and audit + runs-on: ubuntu-latest + timeout-minutes: 90 + + steps: + - name: Check out source + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + + - name: Install pinned Java 25 ForgeGradle Mavenizer runtime + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 + with: + distribution: temurin + java-version: '25.0.3+9.0.LTS' + + - name: Install pinned Java 8 compilation and runtime toolchain + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 + with: + distribution: temurin + java-version: '8.0.502+7' + + - name: Install pinned Java 17 Gradle runtime + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 + with: + distribution: temurin + java-version: '17.0.1+12' + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6 + + - name: Stage checksum-verified dependencies + id: dependencies + shell: bash + run: | + set -euo pipefail + mirror="$RUNNER_TEMP/legacy-dependency-mirror" + bash gradle/stage-legacy-dependencies.sh "$mirror" + echo "repository=$mirror" >> "$GITHUB_OUTPUT" + + - name: Prepare clean packaged Forge runtime + id: forge + shell: bash + run: | + set -euo pipefail + runtime="$RUNNER_TEMP/forge-1.12.2-2859-runtime" + bash gradle/prepare-packaged-forge-runtime.sh "$runtime" "$JAVA_HOME_8_X64/bin/java" + echo "runtime=$runtime" >> "$GITHUB_OUTPUT" + + - name: Set up Python for the provider audit + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 + with: + python-version: '3.12' + + - name: Install the pinned provider schema validator + run: python -m pip install -r tools/validation/requirements.txt + + - name: Build, test, audit, qualify runtimes, and generate Eclipse launches + shell: bash + run: | + set -euo pipefail + chmod +x ./gradlew + gradle_args=( + clean check build javadoc verifyReleaseDependencies verifyReleaseArtifacts + writeReleaseChecksums prepareEclipse verifyProjectResources packagedForgeRuntimeTest + -PpythonExecutable=python3 + -PpackagedForgeRuntimeOutput="$RUNNER_TEMP/modernmetals-packaged-checks" + -PreleaseBuild=true + -PlegacyDependencyVerificationRepository="${{ steps.dependencies.outputs.repository }}" + -PpackagedForgeRuntimeRoot="${{ steps.forge.outputs.runtime }}" + --no-daemon --stacktrace --max-workers=2 + -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 + ) + ./gradlew "${gradle_args[@]}" + cp build/release/SHA256SUMS "$RUNNER_TEMP/first-SHA256SUMS" + + - name: Verify the prepared release bundle + shell: bash + run: | + set -euo pipefail + bundle="$RUNNER_TEMP/release-input" + mkdir -p "$bundle" + cp build/libs/ModernMetals-2.5.1.112021{,-sources,-javadoc}.jar "$bundle/" + cp build/release/SHA256SUMS CHANGELOG.txt "$bundle/" + ./gradlew verifyPreparedReleaseArtifacts verifyMavenCoordinates \ + -PpreparedReleaseDir="$bundle" \ + -PlegacyDependencyVerificationRepository="${{ steps.dependencies.outputs.repository }}" \ + -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 \ + --offline --no-daemon --stacktrace --max-workers=2 + + - name: Verify reproducible release archives + shell: bash + run: | + set -euo pipefail + gradle_args=( + clean build javadoc verifyReleaseArtifacts writeReleaseChecksums + -PreleaseBuild=true + -PlegacyDependencyVerificationRepository="${{ steps.dependencies.outputs.repository }}" + --offline --no-daemon --no-build-cache --stacktrace --max-workers=2 + -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 + ) + ./gradlew "${gradle_args[@]}" + cmp "$RUNNER_TEMP/first-SHA256SUMS" build/release/SHA256SUMS + + - name: Upload audited release candidate + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: ModernMetals-1.12.2-${{ github.sha }} + if-no-files-found: error + retention-days: 30 + path: | + build/libs/ModernMetals-2.5.1.112021.jar + build/libs/ModernMetals-2.5.1.112021-sources.jar + build/libs/ModernMetals-2.5.1.112021-javadoc.jar + build/release/SHA256SUMS + CHANGELOG.txt + + - name: Upload bounded diagnostics on failure + if: failure() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: ModernMetals-1.12.2-diagnostics-${{ github.sha }} + if-no-files-found: ignore + retention-days: 14 + path: | + build/test-results/** + build/reports/** + ${{ runner.temp }}/modernmetals-packaged-checks/**/*-console.log + ${{ runner.temp }}/modernmetals-packaged-checks/**/logs/*.log + ${{ runner.temp }}/modernmetals-packaged-checks/**/crash-reports/*.txt + ${{ runner.temp }}/modernmetals-packaged-checks/**/*-modern.json + ${{ runner.temp }}/modernmetals-packaged-checks/**/*-review.json + ${{ runner.temp }}/modernmetals-packaged-checks/**/*-launch.json + build/problems/** diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000..1b38e932 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,80 @@ +name: CodeQL + +on: + push: + branches: + - master-1.12 + - 'feature/**' + pull_request: + branches: + - master-1.12 + schedule: + - cron: '47 7 * * 4' + +permissions: + actions: read + contents: read + security-events: write + +jobs: + analyze: + name: Analyze Java + runs-on: ubuntu-latest + timeout-minutes: 60 + + steps: + - name: Check out source + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + + - name: Install pinned Java 25 ForgeGradle Mavenizer runtime + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 + with: + distribution: temurin + java-version: '25.0.3+9.0.LTS' + + - name: Install pinned Java 8 compilation toolchain + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 + with: + distribution: temurin + java-version: '8.0.502+7' + + - name: Install pinned Java 17 Gradle runtime + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 + with: + distribution: temurin + java-version: '17.0.1+12' + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6 + + - name: Initialize CodeQL + uses: github/codeql-action/init@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4 + with: + languages: java-kotlin + + - name: Stage checksum-verified dependencies + id: dependencies + shell: bash + run: | + set -euo pipefail + mirror="$RUNNER_TEMP/legacy-dependency-mirror" + bash gradle/stage-legacy-dependencies.sh "$mirror" + echo "repository=$mirror" >> "$GITHUB_OUTPUT" + + - name: Compile production code + shell: bash + run: | + set -euo pipefail + chmod +x ./gradlew + gradle_args=( + clean classes + -PlegacyDependencyVerificationRepository="${{ steps.dependencies.outputs.repository }}" + --no-daemon --no-build-cache --stacktrace --max-workers=2 + -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 + ) + ./gradlew "${gradle_args[@]}" + + - name: Analyze + uses: github/codeql-action/analyze@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4 diff --git a/.github/workflows/deploy-release.yml b/.github/workflows/deploy-release.yml index ff396ac4..8b698848 100644 --- a/.github/workflows/deploy-release.yml +++ b/.github/workflows/deploy-release.yml @@ -89,8 +89,8 @@ jobs: exit 1 fi - if [[ "$target_suffix" != 110021 ]]; then - echo 'Only the qualified Minecraft 1.10.2 Forge target is supported by this dispatcher' >&2; exit 1 + if [[ "$target_suffix" != 110021 && "$target_suffix" != 111021 && "$target_suffix" != 112021 ]]; then + echo 'Only the Minecraft 1.10.2, 1.11.2 and 1.12.2 Forge targets are supported by this dispatcher' >&2; exit 1 fi loader_code="${target_suffix: -1}" @@ -295,8 +295,12 @@ jobs: fi curseforge_dependencies+=('243157(optional)') - if [[ " ${curseforge_dependencies[*]} " != *' 240967(required) '* ]]; then - echo 'Base Metals must be a required relation for this 1.10 release' >&2; exit 1 + if [[ "$target_suffix" == 112021 ]]; then + if [[ " ${curseforge_dependencies[*]} " != *' 261744(required) '* ]]; then + echo 'MMDLib must be a required relation for the Minecraft 1.12.2 release' >&2; exit 1 + fi + elif [[ " ${curseforge_dependencies[*]} " != *' 240967(required) '* ]]; then + echo 'Base Metals must be a required relation for this target' >&2; exit 1 fi release_sha="$(git rev-parse HEAD)" diff --git a/.github/workflows/release-on-tag.yml b/.github/workflows/release-on-tag.yml new file mode 100644 index 00000000..718b4afa --- /dev/null +++ b/.github/workflows/release-on-tag.yml @@ -0,0 +1,89 @@ +name: Start Modern Metals release from tag + +on: + push: + tags: + - '*.*.*.*' + +permissions: + actions: read + contents: read + +concurrency: + group: modernmetals-release-starter-${{ github.ref_name }} + cancel-in-progress: false + +jobs: + validate-release-tag: + name: Validate tag for manual release confirmation + if: github.repository == 'MinecraftModDevelopmentMods/ModernMetals' + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Check out tagged source + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + fetch-depth: 0 + + - name: Validate release tag, target metadata, and prior CI + env: + GH_TOKEN: ${{ github.token }} + shell: bash + run: | + set -euo pipefail + + value() { sed -n "s/^$1=//p" gradle.properties; } + release_version="$(value mod_version)" + minecraft_version="$(value minecraft_version)" + loader_name="$(value loader_name)" + loader_code="$(value loader_code)" + + IFS=. read -r mc_major mc_minor mc_patch extra <<<"$minecraft_version" + mc_patch="${mc_patch:-0}" + if [[ -n "${extra:-}" || ! "$mc_major" =~ ^[0-9]+$ || ! "$mc_minor" =~ ^[0-9]+$ \ + || ! "$mc_patch" =~ ^[0-9]+$ || "$loader_name:$loader_code" != 'forge:1' ]]; then + echo "Invalid target metadata $minecraft_version/$loader_name/$loader_code" >&2 + exit 1 + fi + printf -v minor_padded '%02d' "$((10#$mc_minor))" + printf -v patch_padded '%02d' "$((10#$mc_patch))" + target_suffix="${mc_major}${minor_padded}${patch_padded}${loader_code}" + + if [[ ! "$release_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.${target_suffix}$ ]]; then + echo "mod_version $release_version does not match target $target_suffix" >&2 + exit 1 + fi + if [[ "$GITHUB_REF_NAME" != "$release_version" ]]; then + echo "Release tag must equal mod_version $release_version; found $GITHUB_REF_NAME" >&2 + exit 1 + fi + + successful_ci="$(gh api \ + "repos/$GITHUB_REPOSITORY/commits/$GITHUB_SHA/check-runs?per_page=100" \ + --jq '[.check_runs[] | select(.name == "Build, test, and audit" and .conclusion == "success")] | length')" + if [[ "$successful_ci" -lt 1 ]]; then + echo "The tagged commit has no successful Build, test, and audit check" >&2 + exit 1 + fi + + - name: Record the required manual publication step + env: + RELEASE_WORKFLOW_URL: https://github.com/${{ github.repository }}/actions/workflows/deploy-release.yml + shell: bash + run: | + { + echo "## Release candidate validated" + echo + echo "Tag \`$GITHUB_REF_NAME\` matches the selected target and has a successful Build, test, and audit check." + echo + echo "**Nothing has been published.**" + echo + echo "To continue, open [Release Modern Metals]($RELEASE_WORKFLOW_URL), select **Run workflow**, and enter:" + echo + echo "- release_version: \`$GITHUB_REF_NAME\`" + echo "- release_commit: \`$GITHUB_SHA\`" + echo "- tested_jar_sha256: SHA-256 of the tested game jar" + echo "- curseforge_release_level: \`release\`, \`beta\`, or \`alpha\`" + echo "- confirm_live_publication: \`true\`" + } >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/validate-gradle-build.yml b/.github/workflows/validate-gradle-build.yml new file mode 100644 index 00000000..cc6223df --- /dev/null +++ b/.github/workflows/validate-gradle-build.yml @@ -0,0 +1,23 @@ +name: Validate Gradle Wrapper + +on: + push: + branches: + - master-1.12 + - 'feature/**' + pull_request: + branches: + - master-1.12 + +permissions: + contents: read + +jobs: + validation: + name: Validation + runs-on: ubuntu-latest + steps: + - name: Check out source + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - name: Validate wrapper integrity + uses: gradle/actions/wrapper-validation@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6 diff --git a/.gitignore b/.gitignore index bc1ca2d0..3a14b223 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,6 @@ bin *.launch .settings -.settings/* .metadata .classpath .project @@ -21,14 +20,19 @@ build # other eclipse run -classes /README.txt /forge-*-changelog.txt secret.json -libs/* -!/libs/README.txt - +# Local context and generated verification +/AGENTS.md +/agent-notes/ +/.codex/ +/.verification*/ +/release-candidates/ +__pycache__/ +*.pyc .DS_Store -bugreport.md +Thumbs.db +desktop.ini diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index dd5385bb..00000000 --- a/.travis.yml +++ /dev/null @@ -1,29 +0,0 @@ -language: java -os: linux -dist: trusty -addons: - apt: - update: true - packages: -# - oracle-java8-installer -git: - quiet: true -arch: amd64 -before_cache: - - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ -cache: - directories: - - $HOME/.gradle/caches/ - - $HOME/.gradle/wrapper/ -notifications: - email: false -jdk: - - oraclejdk8 -before_install: skip -install: skip -before_script: - - chmod a+x gradlew -script: - - ./gradlew setupCIWorkspace -S - - ./gradlew clean build -S diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 26da6009..e155d9d0 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1 +1,11 @@ +2.5.1.112021 for 1.12.2 + +- Updated the build to ForgeGradle 7 and moved Modern Metals to the ModDev Zone namespace. +- Switched ore generation to OreSpawn 4 and added ore overlays that use the active stone texture. +- Kept titanium ore optional. Rutile and magnesium still make titanium. +- Added a settings screen in Forge and OreSpawn. Modern Metals follows Base Metals' Fantasy Level when installed with a compatible version. +- Added damage from contact with molten metal and kept ore processing in MMDLib's shared crusher registry. +- Fixed stainless steel and nichrome blend recipes while keeping the Chrome ore-dictionary alias. +- Fixed plate and door models when Base Metals isn't installed. + *Metals family wide cleanups and bugfixes diff --git a/README.md b/README.md index c9413ec3..8a695443 100644 --- a/README.md +++ b/README.md @@ -1,75 +1,39 @@ -[![](https://img.shields.io/badge/Discord-MMD-green.svg?style=flat&logo=Discord)](https://discord.mcmoddev.com) -[![](http://cf.way2muchnoise.eu/modern-metals.svg)](https://www.curseforge.com/minecraft/mc-mods/modern-metals) -[![](http://cf.way2muchnoise.eu/versions/modern-metals.svg)](https://www.curseforge.com/minecraft/mc-mods/modern-metals) -[![Build Status](https://travis-ci.org/jriwanek/ModernMetals.svg?branch=master)](https://travis-ci.org/jriwanek/ModernMetals) - -### ModernMetals -Addon to BaseMetals supporting Modern Metals - -Content -------- -Bars - -Doors - -Ores - -Plates - -Trapdoors - -Armor - -Tools: Crackhammers, Axes, Hoes, Pickaxes, Shovels, Fishing Rods - -Ores, Blocks, Ingots & Nuggets - -Powders & Blends (Ingot and Nugget size) - -Rods - -Gears - -Weapons: Swords, Bows, Arrows, Crossbows & Bolts - -Materials ---------- -Aluminum - -Aluminum Brass - -Cadmium - -Chromium - -Iridium - -Lithium - -Magnesium - -Manganese - -Niter - -Osmium - -Phosphorous - -Plutonium - -Rutile - -Silicon - -Sulfur - -Tantalum - -Titanium - -Tungsten - -Uranium - -Zirconium +# Modern Metals for Minecraft 1.12.2 + +Modern Metals adds industrial metals and alloys, including aluminum, chromium, +osmium and titanium. It adds their ores and molten forms, equipment, building +blocks and Crack Hammer processing. + +Install Forge 14.23.5.2859, [MMDLib 1.0.0-rc2.36][mmdlib] and +[OreSpawn 4.1.3.112021][orespawn]. Modern Metals also works alongside +[Base Metals 2.6.1.112021][basemetals]. Base Metals supplies additional +ingredients for alloys that use its steel, zinc, brass or nickel. + +The Modern Metals settings are available from Forge's Mods list and OreSpawn's +Mods list. Fantasy Level comes from a compatible Base Metals installation. +When running Modern Metals by itself, set Fantasy Level in +`config/ModernMetals.cfg` or in the settings screen. Low Fantasy restricts +implausible gear and building recipes. Existing items remain usable. Restart +Minecraft after changing the setting. + +Titanium is made from rutile and magnesium by default. The optional titanium +ore rule can be enabled in OreSpawn. Existing chunks keep their ores. OreSpawn +uses its native profile for new chunks and can import supported legacy files. +Back up a world and its configs before upgrading from OreSpawn 3. + +[mmdlib]: https://www.curseforge.com/minecraft/mc-mods/mmdlib/files/2712947 +[orespawn]: https://maven.moddev.zone/releases/zone/moddev/mc/orespawn/OreSpawn/4.1.3.112021/ +[basemetals]: https://maven.moddev.zone/releases/zone/moddev/mc/basemetals/BaseMetals/2.6.1.112021/ + +## Building + +The Gradle wrapper runs on Java 17, ForgeGradle's Mavenizer uses Java 25, and +the game and compiler use Java 8. Run `./gradlew check build +verifyProjectResources writeReleaseChecksums prepareEclipse`. To stage a +local mirror first, run `python gradle/stage-legacy-dependencies.py ` +and pass `-PlegacyDependencyVerificationRepository=` to Gradle. +The runtime jar, sources and Javadocs are written to `build/libs`. + +CI builds from the pinned jars, audits the package and checks disposable Forge +servers. The release workflow takes an explicitly confirmed version, commit +and game jar checksum. The update feed should be advanced after publication. diff --git a/build.gradle b/build.gradle index 56ee5834..c82efaa5 100644 --- a/build.gradle +++ b/build.gradle @@ -1,448 +1,174 @@ -buildscript { - repositories { - jcenter() - maven { - name = 'forge' - url = 'http://files.minecraftforge.net/maven' - } - maven { - name = 'gradle' - url 'https://plugins.gradle.org/m2/' - } - maven { - name = 'sonatype' - url = 'https://oss.sonatype.org/content/groups/public' - } - } - dependencies { - classpath "net.minecraftforge.gradle:ForgeGradle:${project.fg_version}" - classpath 'org.junit.platform:junit-platform-gradle-plugin:1.2.+' -// classpath 'com.jaredsburrows:gradle-checker-framework-plugin:0.2.1' - } -} +import org.apache.tools.ant.filters.FixCrLfFilter plugins { -//id 'com.github.spotbugs' version '1.6.2' - id 'com.matthewprenger.cursegradle' version '1.4.0' - id 'org.sonarqube' version '3.0' -} - -apply plugin: 'net.minecraftforge.gradle.forge' -apply plugin: 'com.matthewprenger.cursegradle' -apply plugin: 'maven-publish' -apply plugin: 'org.sonarqube' -apply plugin: 'org.junit.platform.gradle.plugin' -apply plugin: 'jacoco' -//apply plugin: 'com.github.spotbugs' -//apply plugin: 'com.jaredsburrows.checkerframework' - -repositories { - mavenLocal() - mavenCentral() -} - -dependencies { - testCompile('org.junit.jupiter:junit-jupiter-api:5.2.+') - testCompile('org.junit.platform:junit-platform-launcher:1.2.+') - testRuntime('org.junit.jupiter:junit-jupiter-engine:5.2.+') - testCompile('org.mockito:mockito-core:2.+') -} - -project.afterEvaluate { - def junitPlatformTestTask = project.tasks.getByName('junitPlatformTest') - - // configure jacoco to analyze the junitPlatformTest task - jacoco { - // this tool version is compatible with - toolVersion = '0.8.1' - applyTo junitPlatformTestTask - } - - // create junit platform jacoco task - project.task(type: JacocoReport, "junitPlatformJacocoReport", - { - sourceDirectories = files("./src/main") - classDirectories = files("$buildDir/classes/main") - executionData junitPlatformTestTask - }) -} - -junitPlatform { - // platformVersion '1.2.0' - // logManager 'org.apache.logging.log4j.jul.LogManager' - reportsDir file("${project.buildDir}/test-results/junit-platform") - // enableStandardTestTask true - // selectors (optional) - // filters (optional) -} - -/* -spotbugs { - toolVersion = '3.1.5' -} -*/ - -tasks.withType(JavaCompile) { - options.encoding = 'UTF-8' - options.compilerArgs = [ - '-Xlint:deprecation', // deprecation, rawtypes, cast, unchecked, all -// '-Xdiags:verbose', -// '-Werror' - ] -} - -javadoc { - failOnError = false -} - -test { -// useJUnitPlatform() -/* - useJUnitPlatform { - includeTags 'fast', 'smoke & feature-a' - // excludeTags 'slow', 'ci' - includeEngines 'junit-jupiter' - // excludeEngines 'junit-vintage' - } -*/ -} - -def mod_file = getModFile() -def short_version = getVersion('VERSION', mod_file) -version = mc_version + '-' + short_version -def display_version = short_version - -if (System.getenv().BUILD_NUMBER) { - version += '.' + System.getenv().BUILD_NUMBER - display_version += '.' + System.getenv().BUILD_NUMBER -} - -sourceCompatibility = targetCompatibility = '1.8' - -eclipse.project { - buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder' - natures 'org.eclipse.buildship.core.gradleprojectnature' -} - -class Secrets { - def data = null - - def getProperty(String key) { - return data ? data[key] : '' - } -} - -import groovy.json.JsonSlurper - -def secretFile -if (System.getenv().SECRET_FILE) { - secretFile = file System.getenv().SECRET_FILE -} else { - secretFile = file 'secret.json' -} - -project.ext.secret = new Secrets() -if (secretFile.exists()) { - secretFile.withReader { - project.ext.secret.data = new JsonSlurper().parse it - } + id 'java' + id 'eclipse' + id 'idea' + id 'maven-publish' + id 'net.minecraftforge.renamer' version '1.1.5' + id 'net.minecraftforge.gradle' version '7.0.34' +} + +group = project.mod_group +version = project.mod_version +base.archivesName = 'ModernMetals' + +if (!(project.version ==~ /\d+\.\d+\.\d+\.112021/)) { + throw new GradleException('Use Major.Minor.Patch.112021 for Minecraft 1.12.2 on Forge.') +} + +// Gradle and Mavenizer use modern JDKs; the mod and game still use Java 8. +java { + toolchain.languageVersion = JavaLanguageVersion.of(8) + withSourcesJar() + withJavadocJar() +} +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' + sourceCompatibility = targetCompatibility = '1.8' + options.compilerArgs.addAll(['-Xmaxerrs', '1000']) +} +tasks.named('compileTestJava', JavaCompile) { options.compilerArgs.add('-proc:none') } +tasks.withType(Test).configureEach { useJUnitPlatform() } +tasks.withType(Javadoc).configureEach { + failOnError = false + options.encoding = 'UTF-8' + options.addStringOption('Xdoclint:none', '-quiet') + options.addStringOption('docencoding', 'UTF-8') + options.addStringOption('charset', 'UTF-8') + options.addBooleanOption('notimestamp', true) +} +tasks.withType(AbstractArchiveTask).configureEach { + preserveFileTimestamps = false + reproducibleFileOrder = true + includeEmptyDirs = false + exclude '**/desktop.ini', '**/Thumbs.db', '**/.DS_Store' +} +// Mapped dependency bytes no longer match their original signatures. Keep the +// verified downloads intact and strip signatures only from renamed copies. +tasks.withType(net.minecraftforge.renamer.gradle.RenameJar).configureEach { + additionalArgs.addAll('--strip-sigs', 'ALL', '--disable-abstract-param') +} + +def textPatterns = ['cfg', 'css', 'html', 'info', 'java', 'js', 'json', 'lang', 'mcmeta', 'md', 'properties', 'txt', 'xml'] + .collect { "**/*.${it}".toString() } +def normalizeText = { details -> + details.filter(FixCrLfFilter, eol: FixCrLfFilter.CrLf.newInstance('lf'), + eof: FixCrLfFilter.AddAsisRemove.newInstance('asis')) +} + +// Preserve the tested game jar's line endings for this compatibility list. +def legacyApiList = 'META-INF/modernmetals-legacy-api.list' +def normalizeLegacyApi = { details -> + details.filter(FixCrLfFilter, eol: FixCrLfFilter.CrLf.newInstance('crlf'), + eof: FixCrLfFilter.AddAsisRemove.newInstance('asis')) +} + +def developmentOutput = layout.buildDirectory.dir('forge12-development/main') +def prepareDevelopmentMod = tasks.register('prepareDevelopmentMod', Sync) { + group = 'ide' + description = 'Merges production classes and processed resources for Forge 1.12 launches.' + dependsOn tasks.named('classes') + from tasks.named('compileJava', JavaCompile).flatMap { it.destinationDirectory } + from sourceSets.main.output.resourcesDir + into developmentOutput } minecraft { - version = project.forge_mc_version + '-' + project.forge_version - runDir = 'run' - mappings = project.mcp_mappings - - if (project.hasProperty('signSHA1')) { - replace '@FINGERPRINT@', project.findProperty('signSHA1') - } else { - replace '@FINGERPRINT@', '' - } - - if (project.hasProperty('coreplugin')) { - clientJvmArgs += '-Dfml.coreMods.load=' + project.coreplugin - serverJvmArgs += '-Dfml.coreMods.load=' + project.coreplugin - } - - if (project.hasProperty('mc_username')) { - clientRunArgs += ['--username', project.mc_username] - if (project.hasProperty('mc_password')) { - clientRunArgs += ['--password', project.mc_password] + mappings channel: project.mappings_channel, version: project.mappings_version + if (gradle.startParameter.offline) mavenizerArguments.add('--offline') + runs { + configureEach { + workingDir.convention layout.projectDirectory.dir( + providers.gradleProperty('modernMetalsRunDirectory').getOrElse('run')) + environment 'MC_VERSION', project.minecraft_version + environment 'MOD_CLASSES', developmentOutput.get().asFile.absolutePath + systemProperty 'fml.coreMods.load', project.coreplugin + systemProperty 'log4j.skipJansi', 'true' + systemProperty 'forge.logging.console.level', 'info' + systemProperty 'log4j.configurationFile', file('gradle/ide/log4j2.xml').toURI().toString() + if (providers.gradleProperty('modernMetalsLaunchProbePhase').isPresent()) { + systemProperty 'launch.phase', providers.gradleProperty('modernMetalsLaunchProbePhase').get() + } + } + register('client') + register('server') { args 'nogui' } } - } - if (project.hasProperty('mc_uuid')) { - clientRunArgs += ['--uuid', project.mc_uuid] - } - - // disable server gui - serverRunArgs += 'nogui' - - // skip the screen to confirm that you want to load a world with missing registry entries - serverJvmArgs += '-Dfml.doNotBackup=true' - clientJvmArgs += '-Dfml.doNotBackup=true' - - // skip having to confirm on server - serverJvmArgs += '-Dfml.queryResult=confirm' - - //skip jansi warnings in the log - serverJvmArgs += '-Dlog4j.skipJansi=true' - clientJvmArgs += '-Dlog4j.skipJansi=true' - - if (project.hasProperty('client_args')) { - clientJvmArgs += project.client_args - } - if (project.hasProperty('server_args')) { - serverJvmArgs += project.server_args - } -} - -repositories { - maven { - name 'MMD' - url 'https://maven.mcmoddev.com/' - } - maven { // CoFH - name 'Covers Maven' - url 'http://maven.covers1624.net/' - } - maven { // Mantle, TCon, JEI - name 'DVS1 Maven FS' - url 'http://dvs1.progwml6.com/files/maven/' - } - maven { - name = 'CurseForge' - url = 'https://minecraft.curseforge.com/api/maven/' - } -} - -dependencies { - deobfProvided "com.mcmoddev:AdditionalLootTables:${mc_version}-${alt_version}" - deobfProvided "com.mcmoddev:OreSpawn:${mc_version}-${orespawn_version}" - deobfProvided "com.mcmoddev:MMDLib:${mc_version}-${mmdlib_version}" - - deobfProvided ("slimeknights.mantle:Mantle:${mc_version}-${mantle_version}") { - exclude group: 'mezz.jei' - } - - deobfProvided ("slimeknights:TConstruct:${mc_version}.2-${tconstruct_version}") { - exclude group: 'mezz.jei' - } - - deobfProvided ("constructs-armory:conarm:${mc_version}.2:${conarm_version}") { - exclude group: 'mezz.jei' - } - - // CoFHCore for TE integration - deobfProvided ("cofh:CoFHCore:${mc_version}-${cofhcore_version}:universal") { - exclude group: 'mezz.jei' - } -} - -processResources { - inputs.property 'version', project.version - inputs.property 'mcversion', project.minecraft.version - - from (sourceSets.main.resources.srcDirs) { - include 'mcmod.info' - expand 'version': short_version, 'mcversion': project.minecraft.version - } - - from (sourceSets.main.resources.srcDirs) { - exclude 'mcmod.info' - } - - rename '(.+_at.cfg)', 'META-INF/$1' } -jar { - manifest { - if (project.hasProperty('coreplugin')) { - attributes 'FMLCorePluginContainsFMLMod': 'true' - attributes 'FMLCorePlugin': project.coreplugin +tasks.matching { it.name in ['runClient', 'runServer'] }.configureEach { + dependsOn prepareDevelopmentMod + dependsOn 'prepareJava8Launcher' + doFirst { + Set splitOutputs = sourceSets.main.output.files.collect { it.canonicalFile } as Set + classpath = files(developmentOutput, tasks.named('prepareJava8Launcher'), classpath.filter { + !splitOutputs.contains(it.canonicalFile) && it.name != 'slime-launcher-0.2.2.jar' + }) + environment 'MC_VERSION', project.minecraft_version + environment 'MOD_CLASSES', developmentOutput.get().asFile.absolutePath } -// attributes 'FMLAT' : '' - } -} - -task apiJar(type: Jar) { - classifier = 'apiClasses' - from apiClasses -} - -task deobfJar(type: Jar) { - classifier = 'deobf' - from sourceSets.main.output -} - -task signJar(type: SignJar, dependsOn: reobfJar) { - // Skips if the keyStore property is missing. - onlyIf { - project.hasProperty('keyStore') - } - - // findProperty allows us to reference the property without it existing. - // Using project.propName would cause the script to fail validation if - // the property did not exist. - keyStore = project.findProperty('keyStore') - alias = project.findProperty('keyStoreAlias') - storePass = project.findProperty('keyStorePass') - keyPass = project.findProperty('keyStoreKeyPass') - inputFile = jar.archivePath - outputFile = jar.archivePath -} - -build.dependsOn signJar - -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from javadoc.getDestinationDir() } -artifacts { - if (project.hasProperty('doAPIJar')) { - archives apiJar - } - if (project.hasProperty('doDeobfJar')) { - archives deobfJar - } - if (project.hasProperty('doSourceJar')) { - archives sourceJar - } - if (project.hasProperty('doJavadocJar')) { - archives javadocJar - } -} +def legacyMirror = file(providers.gradleProperty('legacyDependencyVerificationRepository') + .orElse(providers.gradleProperty('legacyDependencyRepository')) + .getOrElse('.gradle/legacy-dependencies')) +def legacyRepository = { String remote -> legacyMirror.isDirectory() ? legacyMirror.toURI() : uri(remote) } -publishing { - publications { - mavenJava(MavenPublication) { - groupId project.group - artifactId project.archivesBaseName - version project.version - from components.java - if (project.hasProperty('doSourceJar')) { - artifact sourceJar { - classifier 'sources' - } - } - if (project.hasProperty('doAPIJar')) { - artifact apiJar { - classifier 'api' - } - } - if (project.hasProperty('doDeobfJar')) { - artifact deobfJar { - classifier 'deobf' - } - } - if (project.hasProperty('doJavadocJar')) { - artifact javadocJar { - classifier 'javadoc' - } - } - } - } - repositories { +repositories { + minecraft.mavenizer(it) + maven fg.forgeMaven + maven fg.minecraftLibsMaven maven { - credentials { - username secret.username - password secret.password - } - url secret.url + name = 'VerifiedLegacyMirror' + url = legacyMirror.toURI() + metadataSources { artifact() } } - } -} - -curseforge { - if (project.hasProperty('cf_project_id') && project.hasProperty('cf_release_type') && project.hasProperty('cf_changelog_filename') && - ((project.cf_release_type == 'alpha') || (project.cf_release_type == 'beta') || (project.cf_release_type == 'release'))) { - apiKey = secret.curseforgeAPIKey - project { - id = project.cf_project_id - changelog = file(project.cf_changelog_filename) - releaseType = project.cf_release_type - addGameVersion(project.mc_version) - mainArtifact(jar) { - displayName = "$project.description $display_version" - relations { - requiredLibrary 'mmd-orespawn' - requiredLibrary 'mmdlib' - optionalLibrary 'additional-loot-tables' - } - } - if (project.hasProperty('doAPIJar')) { - addArtifact(apiJar) { - displayName = "$project.description $display_version API" - } - } - if (project.hasProperty('doSourceJar')) { - addArtifact(sourceJar) { - displayName = "$project.description $display_version Sources" - } - } - if (project.hasProperty('doDeobfJar')) { - addArtifact(deobfJar) { - displayName = "$project.description $display_version Development" - } - } - if (project.hasProperty('doJavadocJar')) { - addArtifact(javadocJar) { - displayName = "$project.description $display_version Javadoc" - } - } + exclusiveContent { + forRepository { maven { url = legacyRepository('https://www.cursemaven.com'); metadataSources { artifact() } } } + filter { includeGroup 'curse.maven' } } - } -} - -sonarqube { - properties { - property 'sonar.host.url', secret.sonarHost - property 'sonar.organization', secret.sonarOrganization - property 'sonar.login', secret.sonarToken - // property 'sonar.projectName', project.archivesBaseName - // property 'sonar.projectKey', "$project.group:$project.archivesBaseName" - // property 'sonar.branch.name', 'master-1.12' - // property 'sonar.branch.target', '' - property 'sonar.junit.reportPaths', "${project.buildDir}/test-results/junit-platform/*.xml" - property 'sonar.jacoco.reportPaths', "${project.buildDir}/jacoco/junitPlatformTest.exec" - } -} - -String getModFile() { - String path = '' - FileTree tree = fileTree(dir: 'src/main/java') - tree.include '**/*.java' - tree.visit { element -> - if (element.file.isFile()) { - element.file.eachLine { String s -> - s = s.trim() - if (s.startsWith('@Mod(')) { - path = "src/main/java/$element.relativePath" - } - } + exclusiveContent { + forRepository { maven { url = legacyRepository('https://maven.moddev.zone/releases'); metadataSources { artifact() } } } + filter { includeGroup 'zone.moddev.mc.basemetals'; includeGroup 'zone.moddev.mc.orespawn' } } - } - return path -} - -String getVersion(String type, String mod_file) { - String major = '0' - String revision = '0' - String patch = '0' - File file = file(mod_file) - def prefix = ~/^(?:public|protected|private) static final String $type = ".*$/ - file.eachLine { String s -> - s = s.trim() - if (s ==~ prefix || prefix.matcher(s).matches()) { - String[] bits = s.split("=") - String interesting = bits[1].trim() - interesting = interesting.substring(1, interesting.length() - 2) - String[] pts = interesting.trim().split("\\.") - - major = pts[0] ?: '0' - revision = pts[1] ?: '0' - patch = pts[2] ?: '0' + mavenCentral() +} + +apply from: 'gradle/dependencies.gradle' +renamer.mappings.from minecraft.dependency.toSrgFile + +tasks.named('processResources', ProcessResources) { + filteringCharset = 'UTF-8' + exclude '**/desktop.ini', '**/Thumbs.db', '**/.DS_Store' + inputs.property 'version', project.version + inputs.property 'mcversion', project.minecraft_version + filesMatching('mcmod.info') { expand version: project.version, mcversion: project.minecraft_version } + rename '(.+_at.cfg)', 'META-INF/$1' + filesMatching('**/*.lang') { details -> details.name = details.name.toLowerCase(Locale.ROOT) } + filesMatching(textPatterns, normalizeText) + filesMatching(legacyApiList, normalizeLegacyApi) +} + +tasks.named('jar', Jar) { + archiveClassifier = 'deobf' + destinationDirectory = layout.buildDirectory.dir('libs-dev') + manifest.attributes( + 'Implementation-Title': 'ModernMetals', 'Implementation-Version': project.version, + 'Maven-Artifact': "${project.group}:ModernMetals:${project.version}", + 'Built-On-Java': '8', 'Built-On': "${project.minecraft_version}-${project.forge_version}", + 'FMLCorePluginContainsFMLMod': 'true', 'FMLCorePlugin': project.coreplugin) +} +['sourcesJar', 'javadocJar'].each { name -> + tasks.named(name, Jar) { + filteringCharset = 'UTF-8' + filesMatching(textPatterns, normalizeText) + filesMatching(legacyApiList, normalizeLegacyApi) } - } - return "$major.$revision.$patch" } + +ext.modernMetalsBuild = [developmentOutput: developmentOutput].asImmutable() +apply from: 'gradle/ore-models.gradle' +apply from: 'gradle/release/artifacts.gradle' +apply from: 'gradle/release/publishing.gradle' +apply from: 'gradle/verification/runtime.gradle' +apply from: 'gradle/ide/eclipse.gradle' diff --git a/gradle.properties b/gradle.properties index 9d62a18e..6b585402 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,57 +1,33 @@ -org.gradle.daemon = false +org.gradle.jvmargs=-Xmx3G +org.gradle.daemon=false +org.gradle.configuration-cache=false +org.gradle.caching=true +org.gradle.parallel=false +net.minecraftforge.gradle.merge-source-sets=false -group = com.mcmoddev -archivesBaseName = ModernMetals -name = ModernMetals -description = Modern Metals +minecraft_version=1.12.2 +forge_version=14.23.5.2859 +mappings_channel=stable +mappings_version=39-1.12 -mc_version = 1.12 +mod_id=modernmetals +mod_group=zone.moddev.mc.modernmetals +mod_version=2.5.1.112021 +mod_artifact=ModernMetals +loader_name=forge +loader_code=1 +java_version=8 +java_toolchain_version=8.0.502+7 +java_setup_version=8.0.502+7 +gradle_java_version=17 +gradle_java_setup_version=17.0.1+12 +mavenizer_java_version=25.0.3+9 +curseforge_project_id=244357 +cf_requirements=mmd-orespawn,mmdlib +orespawn_curse_project_id=245586 +coreplugin=zone.moddev.mc.modernmetals.compat.ModernMetalsLoadingPlugin +orespawn_version=4.1.3.112021 +orespawn_version_range=[4.1.3.112021,5.0.0) -fg_version = 2.3-SNAPSHOT -forge_mc_version = 1.12.2 -forge_version = 14.23.5.2768 -mcp_mappings = stable_39 - -cf_project_id = 244357 -cf_release_type = release -cf_changelog_filename = CHANGELOG.txt - -// coreplugin = - -doSourceJar = true -// doAPIJar -doDeobfJar = true -doJavadocJar = true - -ccl_version=3.1.3.+ -ccc_version=2.4.1.+ -nei_version=2.4.0.+ -jei_version=4.7.5.+ -mantle_version=1.3.2.+ -tconstruct_version=2.10.1.87 -conarm_version=1.2.0 -mcmp_version=2.3.3 -mcmp_experimental_version=2.0.1_31 -top_version=1.4.18-10 -alt_version=2.0.3.39 -orespawn_version=3.2.+ -tesla_version=1.0.63 -bge_version=2.5.0-beta+ -bme_version=2.5.0-beta+ -bmi_version=2.5.0-beta+ -fme_version=2.5.0-beta+ -mme_version=2.5.0-beta+ -mmdlib_version=1.0.0-rc+ -cofhcore_version=4.3.6.+ -mekanism_version=9efd716ea0 -ic2_version=2.8.73-ex112 -minetweaker_version=3.+ -mtlib_version=3.+ -ct_version=4.1.9.+ -ct_api_version=4.1.9.+ -hwyla_version=1.8.23-B38_1.12 -veinminer_version=1.12-0.38.2.647+b31535a -endercore_version=+ -enderio_version=+ -thermal_foundation_version=+ -thermal_expansion_version=+ +mmdlib_version=1.0.0-rc2.36 +forge_installer_sha256=DBBA1CD1BF34A4B82148BAC50A6150F63FFCB2D5DC7D88A0508C27FDCFF15B76 diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle new file mode 100644 index 00000000..f6e2d664 --- /dev/null +++ b/gradle/dependencies.gradle @@ -0,0 +1,65 @@ +import groovy.json.JsonSlurper +import java.security.MessageDigest + +def specs = new JsonSlurper().parse(file('gradle/dependencies.json')) +def mapped = specs.collectEntries { [(it.id): renamer.dependency(it.coordinate)] } + +configurations { + legacyModArtifacts { canBeConsumed = false; transitive = false } + java8LauncherArtifact { canBeConsumed = false; transitive = false } +} +dependencies { + implementation minecraft.dependency("net.minecraftforge:forge:${minecraft_version}-${forge_version}") + java8LauncherArtifact 'net.minecraftforge:slime-launcher:0.2.2' + compileOnly 'org.lwjgl.lwjgl:lwjgl_util:2.9.4-nightly-20150209' + specs.each { spec -> + if (spec.runtime) implementation mapped[spec.id] + else compileOnly mapped[spec.id] + legacyModArtifacts spec.coordinate + } + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.2' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.2' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.10.2' +} + +// Forge 1.12's mod scanner cannot read Java 11 multi-release entries. They are +// unused on Java 8, so omit them from the development launcher copy. +tasks.register('prepareJava8Launcher', Jar) { + dependsOn configurations.java8LauncherArtifact + archiveFileName = 'slime-launcher-0.2.2-java8.jar' + destinationDirectory = layout.buildDirectory.dir('development-dependencies') + from { zipTree(configurations.java8LauncherArtifact.singleFile) } + exclude 'META-INF/versions/**', 'META-INF/MANIFEST.MF', 'META-INF/*.SF', 'META-INF/*.RSA', 'META-INF/*.DSA' +} + +// Verify the original files, not renamed copies whose bytes depend on mappings. +tasks.register('verifyReleaseDependencies') { + group = 'verification' + description = 'Checks every pinned integration API against its SHA-256.' + inputs.file 'gradle/dependencies.json' + doLast { + def artifacts = configurations.legacyModArtifacts.resolvedConfiguration.resolvedArtifacts + specs.each { spec -> + def parts = spec.coordinate.split(':') + def artifact = artifacts.find { it.moduleVersion.id.group == parts[0] + && it.name == parts[1] && it.moduleVersion.id.version == parts[2] } + if (artifact == null) throw new GradleException("Missing ${spec.coordinate}") + String actual = MessageDigest.getInstance('SHA-256').digest(artifact.file.bytes).encodeHex().toString() + if (!actual.equalsIgnoreCase(spec.sha256)) { + throw new GradleException("Checksum mismatch for ${spec.coordinate}: ${actual}") + } + if (spec.id == 'orespawn') { + new java.util.jar.JarFile(artifact.file).withCloseable { jar -> + def metadata = new JsonSlurper().parse(jar.getInputStream(jar.getJarEntry('mcmod.info'))) + if (!metadata.any { it.modid == 'orespawn' && it.version == project.orespawn_version } + || jar.getJarEntry('zone/moddev/mc/orespawn/api/OreSpawnApi.class') == null + || jar.manifest.mainAttributes.getValue('OreSpawn-API-Version') != '1') { + throw new GradleException('Wrong OreSpawn identity or public API.') + } + } + } + } + } +} +tasks.named('compileJava') { dependsOn tasks.named('verifyReleaseDependencies') } +tasks.named('check') { dependsOn tasks.named('verifyReleaseDependencies') } diff --git a/gradle/dependencies.json b/gradle/dependencies.json new file mode 100644 index 00000000..5982e876 --- /dev/null +++ b/gradle/dependencies.json @@ -0,0 +1,58 @@ +[ + { + "id": "mmdlib", + "coordinate": "curse.maven:mmdlib-261744:2712947", + "repository": "https://www.cursemaven.com", + "sha256": "FE2229E6755A5FD306C33CC22DCCF055378D371339133E4912C5DC9213E360AF", + "runtime": true + }, + { + "id": "orespawn", + "coordinate": "zone.moddev.mc.orespawn:OreSpawn:4.1.3.112021", + "repository": "https://maven.moddev.zone/releases", + "sha256": "5B5929CCDEB055679FD6D7B9629BF94F06085A6ECD791FD08D0500F666C079DD", + "runtime": true + }, + { + "id": "basemetals", + "coordinate": "zone.moddev.mc.basemetals:BaseMetals:2.6.1.112021", + "repository": "https://maven.moddev.zone/releases", + "sha256": "FBAE982E308DCC1AC4281A5372560D06C8BB3A027EE290EDA4AC6875F5680FDC", + "runtime": false + }, + { + "id": "alt", + "coordinate": "curse.maven:additional-loot-tables-243157:2691613", + "repository": "https://www.cursemaven.com", + "sha256": "D5661DBF99859E8C9CF29704AB0FD4A132D062031A4023A0FF5E6F9D06ACE3E2", + "runtime": false + }, + { + "id": "mantle", + "coordinate": "curse.maven:tinkers-mantle-74924:2550550", + "repository": "https://www.cursemaven.com", + "sha256": "7758817445D55B65581A34A906EE01155C4598FDDF06E7D72944C840A1105184", + "runtime": false + }, + { + "id": "tconstruct", + "coordinate": "curse.maven:tinkers-construct-74072:2571785", + "repository": "https://www.cursemaven.com", + "sha256": "B1E21352C7BCEC95E33769308D9E70CC83E8F3A97C27FB94F4F0F55CE3CF96F2", + "runtime": false + }, + { + "id": "conarm", + "coordinate": "curse.maven:constructs-armory-287683:2622725", + "repository": "https://www.cursemaven.com", + "sha256": "C1EB6F2BB127652D8FDEAC21FF4BF376F17804E2A5B8EDF14C7C082497AF58A1", + "runtime": false + }, + { + "id": "cofhcore", + "coordinate": "curse.maven:cofh-core-69162:2920433", + "repository": "https://www.cursemaven.com", + "sha256": "E07B0C48DEF9CE8CFAA4CF7A7C656BF7F7D6815F74FBCC2957DD43EFA78486A9", + "runtime": false + } +] diff --git a/gradle/ide/eclipse.gradle b/gradle/ide/eclipse.gradle new file mode 100644 index 00000000..842c8ca1 --- /dev/null +++ b/gradle/ide/eclipse.gradle @@ -0,0 +1,206 @@ +def escapeXml = { String text -> + text.replace('&', '&').replace('"', '"').replace('<', '<').replace('>', '>') +} + +eclipse { + project { + buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder' + natures 'org.eclipse.buildship.core.gradleprojectnature' + } + classpath { + downloadSources = true + downloadJavadoc = true + file.beforeMerged { classpath -> + Set managed = ['src/main/java', 'src/main/resources', 'src/test/java', + 'build/resources/main', 'tools/validation/legacy111', + 'tools/validation/legacy111/migration-probe', + 'tools/validation/legacy111/launch-probe', + 'tools/validation/legacy111/orespawn-probe'] as Set + classpath.entries.removeAll { it.kind == 'src' && managed.contains(it.path) } + } + file.whenMerged { classpath -> + // Eclipse must copy the expanded metadata, not the source placeholders. + classpath.entries.findAll { it.kind == 'src' && it.path == 'src/main/resources' }.each { + it.path = 'build/resources/main' + } + classpath.entries.findAll { it.kind == 'src' && !it.path.startsWith('src/main/') }.each { + if (it.path != 'build/resources/main') it.entryAttributes['test'] = 'true' + } + } + file.withXml { provider -> + Node root = provider.asNode() + root.classpathentry.findAll { it.@kind == 'lib' }.each { root.remove(it) } + if (!root.classpathentry.any { it.@path == 'org.eclipse.buildship.core.gradleclasspathcontainer' }) { + root.appendNode('classpathentry', [kind: 'con', path: 'org.eclipse.buildship.core.gradleclasspathcontainer']) + } + } + } + synchronizationTasks 'genEclipseRuns' +} +idea.module { downloadSources = true; downloadJavadoc = true } + +def configureBuildship = tasks.register('configureEclipseBuildship') { + group = 'ide' + doLast { + File target = file('.settings/org.eclipse.buildship.core.prefs') + Properties values = new Properties() + if (target.isFile()) target.withInputStream { values.load(it) } + [ + 'eclipse.preferences.version': '1', + 'connection.gradle.distribution': 'GRADLE_DISTRIBUTION(WRAPPER)', + 'connection.gradle.user.home': gradle.gradleUserHomeDir.canonicalPath, + 'gradle.user.home': gradle.gradleUserHomeDir.canonicalPath, + 'connection.java.home': System.getProperty('java.home'), + 'java.home': System.getProperty('java.home'), + 'connection.project.dir': '', 'override.workspace.settings': 'true' + ].each { key, value -> values.setProperty(key, value) } + target.parentFile.mkdirs() + target.withOutputStream { values.store(it, 'Generated by configureEclipseBuildship.') } + } +} + +tasks.register('isolateEclipseProductionRuns') { + group = 'ide' + description = 'Quotes launcher paths and keeps optional API jars and tests out of ordinary launches.' + dependsOn configureBuildship, tasks.named('processResources'), tasks.named('prepareJava8Launcher') + doLast { + // Copy, rather than Sync: Eclipse owns and compiles the classes in bin/main. + copy { from layout.buildDirectory.dir('resources/main'); into file('bin/main') } + file('run').mkdirs() + List runtime = configurations.runtimeClasspath.files.collect { it.canonicalFile } + ['runClient.launch', 'runServer.launch'].each { name -> + File launch = file(name) + if (!launch.isFile()) throw new GradleException("Missing generated launch: ${name}") + String text = launch.getText('UTF-8').replace('\r\n', '\n') + text = text.replace(escapeXml(configurations.java8LauncherArtifact.singleFile.canonicalPath), + escapeXml(tasks.named('prepareJava8Launcher', Jar).get().archiveFile.get().asFile.canonicalPath)) + def arguments = text =~ /()/ + if (arguments.count != 1) throw new GradleException("Malformed launcher arguments: ${name}") + String args = arguments[0][2] + ['cache', 'metadata', 'to-srg', 'to-obf'].each { flag -> + int start = args.indexOf("--${flag} ") + if (start < 0) throw new GradleException("Missing --${flag} in ${name}") + start += flag.length() + 3 + int end = args.indexOf(' --', start) + if (end < 0) throw new GradleException("Unterminated --${flag} in ${name}") + String value = args.substring(start, end) + if (!value.startsWith('"')) args = args.substring(0, start) + '"' + value + '"' + args.substring(end) + } + text = text.replace(arguments[0][0], arguments[0][1] + args + arguments[0][3]) + text = text.replaceAll(//, + '') + String modClasses = '' + if (text.contains('key="MOD_CLASSES"')) { + text = text.replaceAll(//, + java.util.regex.Matcher.quoteReplacement(modClasses)) + } else { + text = text.replace('', ' ' + modClasses + '\n ') + } + List lines = text.split('\n', -1) as List + def entries = (0.. + String memento = '' + ' ' + }.join('\n') + text = lines.join('\n') + if (!text.contains('ATTR_EXCLUDE_TEST_CODE')) { + text = text.replace('', + ' \n') + } + launch.setText(text, 'UTF-8') + } + } +} +tasks.named('genEclipseRuns') { finalizedBy tasks.named('isolateEclipseProductionRuns') } +tasks.named('eclipse') { dependsOn tasks.named('genEclipseRuns') } + +def verifyJavaSourceLayout = tasks.register('verifyJavaSourceLayout') { + group = 'verification' + description = 'Checks that Java package names match their source folders, as Eclipse requires.' + inputs.files(provider { sourceSets.collect { it.java } }) + doLast { + List mismatches = [] + sourceSets.each { sourceSet -> + sourceSet.java.visit { entry -> + if (entry.directory || !entry.name.endsWith('.java')) return + + String path = entry.relativePath.pathString + int separator = path.lastIndexOf('/') + String expected = separator < 0 ? '' : path.substring(0, separator).replace('/', '.') + def declaration = entry.file.getText('UTF-8') =~ /(?m)^\s*package\s+([\w.]+)\s*;/ + String declared = declaration.find() ? declaration.group(1) : '' + + if (declared != expected) { + mismatches.add("${sourceSet.name}: ${path} declares '${declared}', expected '${expected}'") + } + } + } + if (!mismatches.isEmpty()) { + throw new GradleException('Java packages do not match their source folders:\n' + mismatches.join('\n')) + } + } +} + +tasks.named('check') { dependsOn verifyJavaSourceLayout } + +tasks.register('verifyEclipseProductionClasspath') { + group = 'verification' + dependsOn tasks.named('genEclipseRuns'), verifyJavaSourceLayout + mustRunAfter tasks.named('eclipse') + doLast { + List runtime = configurations.runtimeClasspath.files.collect { it.canonicalFile } + Set optional = configurations.compileClasspath.files.collect { it.canonicalFile } as Set + optional.removeAll(runtime) + ['runClient.launch', 'runServer.launch'].each { name -> + String text = file(name).getText('UTF-8').replace('\\', '/') + if (!text.contains('MAIN_TYPE" value="net.minecraftforge.launcher.Main"') + || !text.contains('StandardVMType/JavaSE-8') + || !text.contains('MC_VERSION" value="1.12.2"') + || !text.contains('ATTR_EXCLUDE_TEST_CODE') + || text.contains('gradleclasspathcontainer') || text.contains('bin/test') + || text.contains('slime-launcher-0.2.2.jar') + || text.contains('junit-') || text.contains('legacy111-probe')) { + throw new GradleException("Unsafe production launch: ${name}") + } + if (runtime.any { !text.contains(it.path.replace('\\', '/')) } + || optional.any { text.contains(it.path.replace('\\', '/')) }) { + throw new GradleException("Runtime/compile-only separation failed in ${name}") + } + ['cache', 'metadata', 'to-srg', 'to-obf'].each { flag -> + if (!text.contains("--${flag} "")) throw new GradleException("Unquoted --${flag} in ${name}") + } + } + String info = file('bin/main/mcmod.info').getText('UTF-8') + if (info.contains('${version}') || !info.contains(project.version.toString())) { + throw new GradleException('Eclipse is using unprocessed resources.') + } + def classpath = new groovy.xml.XmlSlurper().parse(file('.classpath')) + List sourcePaths = classpath.classpathentry.findAll { it.@kind == 'src' }.collect { it.@path.text() } + if (sourcePaths.size() != sourcePaths.unique(false).size() + || sourcePaths.contains('tools/validation/legacy111')) { + throw new GradleException('Eclipse retains stale or duplicate source-folder entries.') + } + classpath.classpathentry.findAll { it.@kind == 'src' && !it.@path.text().startsWith('src/main/') + && it.@path.text() != 'build/resources/main' }.each { + if (!it.attributes.attribute.any { it.@name == 'test' && it.@value == 'true' }) { + throw new GradleException("Non-production Eclipse source is not marked as test code: ${it.@path}") + } + } + } +} +tasks.register('prepareEclipse') { + group = 'ide' + description = 'Generates Eclipse metadata and verifies Java 8 production-only launches.' + dependsOn tasks.named('eclipse'), tasks.named('verifyEclipseProductionClasspath'), 'writeEclipseCompileClasspath' +} + +tasks.register('writeEclipseCompileClasspath') { + group = 'verification' + description = 'Writes the resolved editor classpath for headless Eclipse compiler checks.' + doLast { + File target = layout.buildDirectory.file('ide/compile-classpath.txt').get().asFile + target.parentFile.mkdirs() + target.setText(configurations.compileClasspath.asPath, 'UTF-8') + } +} diff --git a/gradle/ide/log4j2.xml b/gradle/ide/log4j2.xml new file mode 100644 index 00000000..a770e981 --- /dev/null +++ b/gradle/ide/log4j2.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/gradle/ore-models.gradle b/gradle/ore-models.gradle new file mode 100644 index 00000000..cd503373 --- /dev/null +++ b/gradle/ore-models.gradle @@ -0,0 +1,71 @@ +import groovy.json.JsonOutput + +// Forge 1.12 has no GatherDataEvent. Generate the equivalent model resources +// before processResources, without launching Minecraft or writing into src. +def assets = layout.projectDirectory.dir('src/main/resources/assets/modernmetals') +def overlayFiles = fileTree(assets.dir('textures/blocks/ore_overlays')) { include '*_ore.png' } +def oreStates = fileTree(assets.dir('blockstates')) { include '*_ore.json' } +def generated = layout.buildDirectory.dir('generated/ore-models') + +def generateOreModels = tasks.register('generateOreModels') { + group = 'build' + description = 'Generates the Forge 1.12 ore models from KiriCattus’s overlays.' + inputs.files(overlayFiles, oreStates).withPathSensitivity(PathSensitivity.RELATIVE) + outputs.dir(generated) + + doLast { + def names = overlayFiles.files.collect { it.name - '.png' }.sort() + def expected = oreStates.files.collect { it.name - '.json' }.findAll { it != 'thorium_ore' }.sort() + if (names != expected) { + throw new GradleException("Ore overlays do not match ore blockstates: missing ${expected - names}, extra ${names - expected}") + } + + def dir = generated.get().dir('assets/modernmetals/models/block').asFile + dir.mkdirs() + def writeModel = { String name, Map model -> + new File(dir, "${name}.json").setText(JsonOutput.prettyPrint(JsonOutput.toJson(model)) + '\n', 'UTF-8') + } + def cube = { Number from, Number to, String texture -> + def faces = ['down', 'up', 'north', 'south', 'west', 'east'].collectEntries { face -> + [(face): [texture: texture, cullface: face, uv: [0, 0, 16, 16]]] + } + [from: [from, from, from], to: [to, to, to], faces: faces] + } + // Same two cubes and offset as Base Metals, with the legacy texture paths. + writeModel('ore_overlay', [ + parent: 'minecraft:block/block', + elements: [cube(0, 16, '#base'), cube(-0.05, 16.05, '#overlay')] + ]) + names.each { name -> + writeModel(name, [ + parent: 'modernmetals:block/ore_overlay', + textures: [particle: 'minecraft:blocks/stone', base: 'minecraft:blocks/stone', + overlay: "modernmetals:blocks/ore_overlays/${name}"] + ]) + } + // Clean up only obsolete ore JSON files in this task's own output directory. + dir.listFiles().findAll { it.isFile() && it.name.endsWith('_ore.json') && !(it.name - '.json' in names) }.each { + if (!it.delete()) throw new GradleException("Could not remove stale generated ore model ${it.name}") + } + } +} + +tasks.named('processResources', ProcessResources) { + dependsOn generateOreModels + from generated + duplicatesStrategy = DuplicatesStrategy.FAIL + doFirst { + // Copy tasks can leave the old flat textures behind after an incremental upgrade. + overlayFiles.files.each { overlay -> + def flat = new File(destinationDir, "assets/modernmetals/textures/blocks/${overlay.name}") + if (flat.isFile() && !flat.delete()) { + throw new GradleException("Could not remove obsolete processed texture ${flat.name}") + } + } + } +} + +tasks.named('sourcesJar', Jar) { + dependsOn generateOreModels + from generated +} diff --git a/gradle/prepare-packaged-forge-runtime.sh b/gradle/prepare-packaged-forge-runtime.sh new file mode 100644 index 00000000..016bea12 --- /dev/null +++ b/gradle/prepare-packaged-forge-runtime.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [[ $# -ne 2 ]]; then + echo "usage: $0 " >&2 + exit 2 +fi + +runtime="$1" +java8="$2" +version="1.12.2-14.23.5.2859" +installer="${runtime}/forge-${version}-installer.jar" +expected="$(sed -n 's/^forge_installer_sha256=//p' gradle.properties)" + +if [[ -e "$runtime" ]] && [[ -n "$(find "$runtime" -mindepth 1 -maxdepth 1 -print -quit)" ]]; then + echo "Packaged Forge destination must be empty: $runtime" >&2 + exit 1 +fi +mkdir -p "$runtime" + +curl --fail --location --silent --show-error \ + "https://maven.minecraftforge.net/net/minecraftforge/forge/${version}/forge-${version}-installer.jar" \ + --output "$installer" +actual="$(sha256sum "$installer" | awk '{print toupper($1)}')" +if [[ "$actual" != "$expected" ]]; then + echo "Forge installer SHA-256 is $actual; expected $expected" >&2 + exit 1 +fi + +"$java8" -jar "$installer" --installServer "$runtime" +installed="$runtime/forge-${version}.jar" +universal="$runtime/forge-${version}-universal.jar" +test -f "$installed" +cp "$installed" "$universal" +test -f "$runtime/forge-${version}-universal.jar" +test -f "$runtime/minecraft_server.1.12.2.jar" +test -d "$runtime/libraries" diff --git a/gradle/release/artifacts.gradle b/gradle/release/artifacts.gradle new file mode 100644 index 00000000..4b4030ff --- /dev/null +++ b/gradle/release/artifacts.gradle @@ -0,0 +1,185 @@ +import groovy.json.JsonSlurper +import java.security.MessageDigest +import java.util.jar.Manifest +import java.util.zip.ZipFile + +def releaseJar = renamer.classes(tasks.named('jar', Jar)) { + map.from minecraft.dependency.toSrgFile + archiveClassifier = null + output = layout.buildDirectory.file("libs/ModernMetals-${project.version}.jar") +} +['apiElements', 'runtimeElements'].each { name -> + configurations.named(name) { artifacts.clear() } + artifacts.add(name, releaseJar) +} +tasks.named('assemble') { dependsOn releaseJar, tasks.named('sourcesJar'), tasks.named('javadocJar') } + +tasks.register('verifyJava8Toolchain') { + group = 'verification' + description = 'Checks Java 8 compatibility; exact compiler versions are required only for release builds.' + doLast { + def compiler = javaToolchains.compilerFor { languageVersion = JavaLanguageVersion.of(8) }.get().metadata + if (compiler.languageVersion.asInt() != 8) throw new GradleException('Minecraft 1.12 requires Java 8.') + if (providers.gradleProperty('releaseBuild').getOrElse('false').toBoolean() + && (compiler.javaRuntimeVersion != '1.8.0_502-b07' + || System.getProperty('java.runtime.version') != '17.0.1+12')) { + throw new GradleException('Release builds require Temurin 8u502-b07 and Gradle on 17.0.1+12.') + } + if (providers.gradleProperty('releaseBuild').getOrElse('false').toBoolean()) { + def mavenizer = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(25) }.get().metadata + if (mavenizer.javaRuntimeVersion != '25.0.3+9-LTS') { + throw new GradleException('Release setup requires Mavenizer on Temurin 25.0.3+9.') + } + } + } +} + +tasks.register('verifyReleaseConfiguration') { + group = 'verification' + dependsOn tasks.named('verifyJava8Toolchain') + doLast { + if (project.group != 'zone.moddev.mc.modernmetals' || project.version != '2.5.1.112021' + || project.minecraft_version != '1.12.2' || project.forge_version != '14.23.5.2859' + || project.mappings_channel != 'stable' || project.mappings_version != '39-1.12') { + throw new GradleException('Modern Metals target, mappings or Maven identity changed.') + } + String source = file('src/main/java/zone/moddev/mc/modernmetals/ModernMetals.java').getText('UTF-8') + if (!source.contains('VERSION = "' + project.version + '"') || !source.contains('MODID = "modernmetals"')) { + throw new GradleException('The mod identity differs from the build metadata.') + } + if (project.orespawn_version != '4.1.3.112021' + || project.orespawn_version_range != '[4.1.3.112021,5.0.0)' + || !source.contains('required-after:orespawn@' + project.orespawn_version_range) + || !source.contains('required-after:forge@[14.23.5.2859,)')) { + throw new GradleException('The OreSpawn or Forge runtime requirement changed.') + } + if (!source.contains('required-after:mmdlib@[1.0.0-rc2,2.0.0)') + || source.contains('required-after:basemetals')) { + throw new GradleException('Modern Metals requires the standalone MMDLib. Base Metals remains optional.') + } + } +} + +def expectedFiles = ['', '-sources', '-javadoc'].collect { "ModernMetals-${project.version}${it}.jar".toString() }.asImmutable() +def preparedDirectory = providers.gradleProperty('preparedReleaseDir') +def auditJars = { File directory -> + ['','-sources','-javadoc'].each { suffix -> + File jar = new File(directory, "ModernMetals-${project.version}${suffix}.jar") + if (!jar.isFile() || jar.length() == 0) throw new GradleException("Missing ${jar.name}") + new ZipFile(jar).withCloseable { zip -> + zip.entries().each { entry -> + String path = entry.name.toLowerCase(Locale.ROOT) + if (path.startsWith('review/') || path.contains('probe') || path.contains('fixture') + || path.contains('agent-notes') || path.contains('agents.md') || path.contains('.codex') + || path.contains('.agents') || path.contains('claude') || path.contains('gemini') + || path.tokenize('/').any { it in ['desktop.ini', 'thumbs.db', '.ds_store'] } + || path.startsWith('tools/') || path.startsWith('reference/') + || path.startsWith('com/mcmoddev/lib/') || path.startsWith('zone/moddev/mc/basemetals/') || path.startsWith('zone/moddev/mc/mmdlib/') + || path.startsWith('com/mcmoddev/orespawn/') + || path == 'assets/modernmetals/orespawn/modernmetals.json' + || path.startsWith('org/junit/') || path.startsWith('net/minecraft/')) { + throw new GradleException("Non-production entry in ${jar.name}: ${entry.name}") + } + def date = entry.timeLocal + if (!entry.directory && !(date.toString() in ['1980-01-01T00:00', '1980-02-01T00:00'])) { + throw new GradleException("Volatile archive timestamp: ${entry.name}") + } + if (!entry.directory && path ==~ /.*\.(java|html|css|js|json|lang|mcmeta|md|txt|xml|cfg|info|properties)/) { + def decoder = java.nio.charset.StandardCharsets.UTF_8.newDecoder() + .onMalformedInput(java.nio.charset.CodingErrorAction.REPORT) + .onUnmappableCharacter(java.nio.charset.CodingErrorAction.REPORT) + String content = decoder.decode(java.nio.ByteBuffer.wrap(zip.getInputStream(entry).bytes)).toString() + if (path != 'meta-inf/modernmetals-legacy-api.list' && content.contains('\r')) throw new GradleException("Non-LF text in ${entry.name}") + } + if (!entry.directory && path ==~ /.*\.(class|java|html|json|info|xml|properties|txt|md|lang|cfg)/) { + String content = new String(zip.getInputStream(entry).bytes, + java.nio.charset.StandardCharsets.ISO_8859_1) + if (content.contains(project.projectDir.absolutePath) + || content.contains('/home/runner/work/')) { + throw new GradleException("Local build path in ${entry.name}") + } + } + if (entry.name.endsWith('.class')) { + byte[] data = zip.getInputStream(entry).bytes + int major = ((data[6] & 255) << 8) | (data[7] & 255) + if (major != 52) throw new GradleException("Not Java 8 bytecode: ${entry.name}") + String constants = new String(data, java.nio.charset.StandardCharsets.ISO_8859_1) + if (constants.contains(project.projectDir.absolutePath)) { + throw new GradleException("Local path in ${entry.name}") + } + } + } + if (suffix == '') { + def manifest = new Manifest(zip.getInputStream(zip.getEntry('META-INF/MANIFEST.MF'))).mainAttributes + if (manifest.getValue('Maven-Artifact') != "${project.group}:ModernMetals:${project.version}" + || manifest.getValue('FMLCorePlugin') != project.coreplugin + || manifest.keySet().any { it.toString().toLowerCase().contains('timestamp') }) { + throw new GradleException('Incorrect release manifest.') + } + def info = new JsonSlurper().parse(zip.getInputStream(zip.getEntry('mcmod.info')))[0] + if (info.modid != 'modernmetals' || info.version != project.version || info.mcversion != '1.12.2') { + throw new GradleException('Incorrect processed mcmod.info.') + } + if (zip.getEntry('zone/moddev/mc/modernmetals/ModernMetals.class') == null + || zip.getEntry('META-INF/modernmetals-legacy-api.list') == null) { + throw new GradleException('Missing mod entry point or legacy API map.') + } + } + } + } +} + +tasks.register('verifyReleaseArtifacts') { + group = 'verification' + description = 'Audits the shipped jars for Java 8 bytecode, metadata and test isolation.' + dependsOn tasks.named('assemble'), tasks.named('verifyReleaseConfiguration'), tasks.named('verifyReleaseDependencies') + doLast { auditJars(layout.buildDirectory.dir('libs').get().asFile) } +} + +tasks.register('writeReleaseChecksums') { + group = 'verification' + dependsOn tasks.named('verifyReleaseArtifacts') + doLast { + File directory = layout.buildDirectory.dir('libs').get().asFile + List lines = ['','-sources','-javadoc'].collect { suffix -> + File jar = new File(directory, "ModernMetals-${project.version}${suffix}.jar") + MessageDigest.getInstance('SHA-256').digest(jar.bytes).encodeHex().toString() + ' ' + jar.name + } + File sums = layout.buildDirectory.file('release/SHA256SUMS').get().asFile + sums.parentFile.mkdirs() + sums.setText(lines.join('\n') + '\n', 'UTF-8') + } +} +tasks.named('check') { dependsOn tasks.named('verifyReleaseConfiguration') } + +tasks.register('verifyPreparedReleaseArtifacts') { + group = 'verification' + description = 'Verifies a previously built bundle without rebuilding its jars.' + doLast { + if (!preparedDirectory.isPresent()) throw new GradleException('Set preparedReleaseDir to the immutable release bundle.') + File directory = file(preparedDirectory.get()) + Set expected = (expectedFiles + ['SHA256SUMS', 'CHANGELOG.txt']) as Set + if (!directory.isDirectory() || directory.listFiles().collect { it.name }.toSet() != expected) { + throw new GradleException('The prepared release must contain exactly three jars, SHA256SUMS and CHANGELOG.txt.') + } + List lines = new File(directory, 'SHA256SUMS').readLines('UTF-8') + if (lines.size() != 3) throw new GradleException('The prepared checksum list must contain exactly three files.') + Set checked = [] as Set + lines.each { line -> + def match = line =~ /^([a-fA-F0-9]{64}) (ModernMetals-[^\/\\]+\.jar)$/ + if (!match.matches() || !expectedFiles.contains(match[0][2]) || !checked.add(match[0][2])) { + throw new GradleException('Invalid or duplicate prepared checksum entry.') + } + File jar = new File(directory, match[0][2]) + String actual = MessageDigest.getInstance('SHA-256').digest(jar.bytes).encodeHex().toString() + if (!actual.equalsIgnoreCase(match[0][1])) throw new GradleException("Prepared checksum mismatch: ${jar.name}") + } + if (!new File(directory, 'CHANGELOG.txt').getText('UTF-8').startsWith(project.version.toString() + ' for 1.12.2')) { + throw new GradleException('The prepared changelog belongs to a different release.') + } + auditJars(directory) + } +} + +ext.modernMetalsRelease = [jar: releaseJar, expectedFiles: expectedFiles, + preparedDirectory: preparedDirectory].asImmutable() diff --git a/gradle/release/publishing.gradle b/gradle/release/publishing.gradle new file mode 100644 index 00000000..ce2b8dbe --- /dev/null +++ b/gradle/release/publishing.gradle @@ -0,0 +1,96 @@ +import groovy.xml.XmlSlurper + +def releaseJar = project.ext.modernMetalsRelease.jar +def expectedReleaseFiles = project.ext.modernMetalsRelease.expectedFiles +def preparedReleaseDir = project.ext.modernMetalsRelease.preparedDirectory + +// A normal build does not publish anything; publishing needs credentials. +def mavenUploadUrl = providers.environmentVariable('MAVEN_UPLOAD_URL') + .map { it.trim() }.filter { !it.isEmpty() } + .orElse('https://invalid.invalid/missing-maven-upload-url') +def mavenUploadUsername = providers.environmentVariable('MAVEN_UPLOAD_USERNAME') +def mavenUploadPassword = providers.environmentVariable('MAVEN_UPLOAD_PASSWORD') + +publishing { + publications { + mavenJava(MavenPublication) { + groupId = project.group.toString() + artifactId = base.archivesName.get() + version = project.version.toString() + if (preparedReleaseDir.isPresent()) { + File prepared = file(preparedReleaseDir.get()) + artifact(new File(prepared, expectedReleaseFiles[0])) + artifact(new File(prepared, expectedReleaseFiles[1])) { classifier = 'sources' } + artifact(new File(prepared, expectedReleaseFiles[2])) { classifier = 'javadoc' } + } else { + artifact(releaseJar) + artifact(tasks.named('sourcesJar')) + artifact(tasks.named('javadocJar')) + } + pom { + name = 'Modern Metals' + description = 'Metals, alloys, equipment and Crack Hammer processing for Minecraft 1.12.2.' + url = 'https://github.com/MinecraftModDevelopmentMods/ModernMetals' + licenses { + license { + name = 'GNU Lesser General Public License, Version 2.1' + url = 'https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt' + } + } + scm { + connection = 'scm:git:https://github.com/MinecraftModDevelopmentMods/ModernMetals.git' + developerConnection = 'scm:git:ssh://git@github.com/MinecraftModDevelopmentMods/ModernMetals.git' + url = 'https://github.com/MinecraftModDevelopmentMods/ModernMetals' + } + } + } + } + repositories { + maven { + name = 'release' + url = uri(mavenUploadUrl.get()) + credentials { + username = mavenUploadUsername.orNull ?: '' + password = mavenUploadPassword.orNull ?: '' + } + } + } +} + +tasks.register('validateMavenReleaseCredentials') { + group = 'publishing' + doLast { + if (!providers.environmentVariable('MAVEN_UPLOAD_URL').getOrElse('').trim() + || !mavenUploadUsername.getOrElse('').trim() || !mavenUploadPassword.getOrElse('').trim()) { + throw new GradleException('MAVEN_UPLOAD_URL, MAVEN_UPLOAD_USERNAME, and MAVEN_UPLOAD_PASSWORD are required') + } + URI target = uri(providers.environmentVariable('MAVEN_UPLOAD_URL').get()) + if (target.scheme != 'https' || !target.host || target.host == 'invalid.invalid' + || !mavenUploadUsername.get().trim() || !mavenUploadPassword.get().trim()) { + throw new GradleException('Maven release publication requires an HTTPS repository and non-empty credentials') + } + } +} + +tasks.withType(PublishToMavenRepository).configureEach { + dependsOn tasks.named('validateMavenReleaseCredentials') + dependsOn 'verifyMavenCoordinates' + if (preparedReleaseDir.isPresent()) { + dependsOn tasks.named('verifyPreparedReleaseArtifacts') + } else { + dependsOn tasks.named('verifyReleaseArtifacts') + } +} + +tasks.register('verifyMavenCoordinates') { + group = 'verification' + dependsOn tasks.named('generatePomFileForMavenJavaPublication') + doLast { + def pom = new XmlSlurper(false, false).parse(layout.buildDirectory.file('publications/mavenJava/pom-default.xml').get().asFile) + def actual = [pom.groupId.text(), pom.artifactId.text(), pom.version.text()] + def expected = ['zone.moddev.mc.modernmetals', 'ModernMetals', project.version.toString()] + if (actual != expected) throw new GradleException("Wrong Maven coordinate: ${actual.join(':')}") + } +} + +tasks.named('check') { dependsOn tasks.named('verifyMavenCoordinates') } diff --git a/gradle/stage-legacy-dependencies.py b/gradle/stage-legacy-dependencies.py new file mode 100644 index 00000000..48030759 --- /dev/null +++ b/gradle/stage-legacy-dependencies.py @@ -0,0 +1,53 @@ +"""Build a checksum-verified Maven mirror from downloads or an existing Gradle cache.""" + +import argparse +import hashlib +import json +import time +import urllib.error +import urllib.request +from pathlib import Path + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("destination", type=Path) + parser.add_argument("--cache", type=Path, help="Existing Gradle user home; matching files are verified before reuse") + args = parser.parse_args() + specs = json.loads(Path(__file__).with_name("dependencies.json").read_text(encoding="utf-8")) + + for spec in specs: + group, artifact, version, *classifier = spec["coordinate"].split(":") + filename = f"{artifact}-{version}" + ("-" + classifier[0] if classifier else "") + ".jar" + relative = Path(group.replace(".", "/")) / artifact / version / filename + target = args.destination.resolve() / relative + target.parent.mkdir(parents=True, exist_ok=True) + + if not target.exists(): + cached = list((args.cache / "caches/modules-2/files-2.1" / group / artifact / version).glob("*/" + filename)) if args.cache else [] + if cached: + data = cached[0].read_bytes() + else: + url = spec["repository"].rstrip("/") + "/" + relative.as_posix() + request = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"}) + for attempt in range(3): + try: + with urllib.request.urlopen(request, timeout=30) as response: + data = response.read() + break + except (OSError, urllib.error.URLError): + if attempt == 2: + raise + print(f"Retrying {spec['coordinate']}", flush=True) + time.sleep(2) + if hashlib.sha256(data).hexdigest().upper() != spec["sha256"]: + raise ValueError(f"Checksum mismatch: {spec['coordinate']}") + target.write_bytes(data) + + if hashlib.sha256(target.read_bytes()).hexdigest().upper() != spec["sha256"]: + raise ValueError(f"Checksum mismatch in mirror: {target}") + print(spec["id"], spec["sha256"], flush=True) + + +if __name__ == "__main__": + main() diff --git a/gradle/stage-legacy-dependencies.sh b/gradle/stage-legacy-dependencies.sh new file mode 100644 index 00000000..530f8933 --- /dev/null +++ b/gradle/stage-legacy-dependencies.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [[ $# -ne 1 ]]; then + echo "usage: $0 " >&2 + exit 2 +fi + +"${PYTHON:-python3}" "$(dirname "$0")/stage-legacy-dependencies.py" "$1" diff --git a/gradle/verification/runtime.gradle b/gradle/verification/runtime.gradle new file mode 100644 index 00000000..24ac44c8 --- /dev/null +++ b/gradle/verification/runtime.gradle @@ -0,0 +1,35 @@ +tasks.register('verifyProjectResources', Exec) { + group = 'verification' + dependsOn tasks.named('processResources') + commandLine providers.gradleProperty('pythonExecutable').getOrElse('python3'), + 'tools/validation/legacy112/audit_resources.py', 'build/resources/main' +} + +sourceSets { + runtimeProbe { + java.srcDirs = ['tools/validation/legacy112/runtime-probe'] + compileClasspath = sourceSets.main.compileClasspath + sourceSets.main.output + } +} + +def probe = tasks.register('runtimeProbeJar', Jar) { + archiveFileName = 'modernmetals-probe.jar' + destinationDirectory = layout.buildDirectory.dir('test-mods') + from sourceSets.runtimeProbe.output +} +def packagedProbe = renamer.classes(probe) { + map.from minecraft.dependency.toSrgFile + output = layout.buildDirectory.file('test-mods/modernmetals-probe-packaged.jar') +} +tasks.register('packagedForgeRuntimeTest', Exec) { + group = 'verification' + dependsOn 'verifyReleaseArtifacts', packagedProbe + doFirst { + def launcher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(8) }.get() + commandLine providers.gradleProperty('pythonExecutable').getOrElse('python3'), + 'tools/validation/legacy112/run_packaged_suite.py', '--java', launcher.executablePath.asFile.absolutePath, + '--template', file(providers.gradleProperty('packagedForgeRuntimeRoot').get()).absolutePath, + '--output', file(providers.gradleProperty('packagedForgeRuntimeOutput').getOrElse('build/packaged-forge-checks')).absolutePath, + '--mirror', file(providers.gradleProperty('legacyDependencyVerificationRepository').getOrElse('.gradle/legacy-dependencies')).absolutePath + } +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 0d4a9516..b1b8ef56 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a95009c3..dbe66e1d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,10 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip +distributionSha256Sum=9c0f7faeeb306cb14e4279a3e084ca6b596894089a0638e68a07c945a32c9e14 +distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip +networkTimeout=10000 +retries=0 +retryBackOffMs=500 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index cccdd3d5..249efbb0 100755 --- a/gradlew +++ b/gradlew @@ -1,78 +1,128 @@ -#!/usr/bin/env sh +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# gradlew start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh gradlew +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -81,92 +131,118 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" fi +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index f9553162..a51ec4f5 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,84 +1,82 @@ -@if "%DEBUG%" == "" @echo off +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem -@rem Gradle startup script for Windows +@rem gradlew startup script for Windows @rem @rem ########################################################################## -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal +@rem Set local scope for the variables, and ensure extensions are enabled +setlocal EnableExtensions set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @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= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @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 +if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 -goto fail +"%COMSPEC%" /c exit 1 :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 -goto fail - -: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=%* +"%COMSPEC%" /c exit 1 :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 +@rem Execute gradlew +@rem endlocal doesn't take effect until after the line is parsed and variables are expanded +@rem which allows us to clear the local environment before executing the java command +endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel -:omega +:exitWithErrorLevel +@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts +"%COMSPEC%" /c exit %ERRORLEVEL% diff --git a/settings.gradle b/settings.gradle index 0e64f4a2..c4091f15 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,5 @@ -rootProject.name = archivesBaseName -enableFeaturePreview('STABLE_PUBLISHING') +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' +} + +rootProject.name = 'ModernMetals' diff --git a/src/main/java/com/mcmoddev/modernmetals/init/Recipes.java b/src/main/java/com/mcmoddev/modernmetals/init/Recipes.java deleted file mode 100644 index 14c12deb..00000000 --- a/src/main/java/com/mcmoddev/modernmetals/init/Recipes.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.mcmoddev.modernmetals.init; - -import com.mcmoddev.lib.data.SharedStrings; -import com.mcmoddev.lib.init.Materials; -import com.mcmoddev.lib.material.MMDMaterial; -import com.mcmoddev.modernmetals.data.MaterialNames; - -/** - * - * @author Jasmine Iwanek - * - */ -public class Recipes extends com.mcmoddev.lib.init.Recipes { - - private Recipes() { - throw new IllegalAccessError(SharedStrings.NOT_INSTANTIABLE); - } - - /** - * - */ - public static void init() { - initModSpecificRecipes(); - } - - private static void initModSpecificRecipes() { - if (Materials.hasMaterial(MaterialNames.ALUMINUM)) { - final MMDMaterial aluminum = Materials.getMaterialByName(MaterialNames.ALUMINUM); - - addAdditionalOredicts(aluminum, "Aluminium"); - addAdditionalOredicts(aluminum, "Bauxite"); - } - - if (Materials.hasMaterial(MaterialNames.ALUMINUM_BRASS)) { - final MMDMaterial aluminumBrass = Materials.getMaterialByName(MaterialNames.ALUMINUM_BRASS); - - addAdditionalOredicts(aluminumBrass, "AluminumBrass"); - addAdditionalOredicts(aluminumBrass, "Aluminiumbrass"); - addAdditionalOredicts(aluminumBrass, "AluminiumBrass"); - addAdditionalOredicts(aluminumBrass, "Alubrass"); - addAdditionalOredicts(aluminumBrass, "AluBrass"); - } - - if (Materials.hasMaterial(MaterialNames.CHROMIUM)) { - addAdditionalOredicts(MaterialNames.CHROMIUM, "Chrome"); - } - - if (Materials.hasMaterial(MaterialNames.GALVANIZED_STEEL)) { - final MMDMaterial galvanizedSteel = Materials.getMaterialByName(MaterialNames.GALVANIZED_STEEL); - - addAdditionalOredicts(galvanizedSteel, "GalvinizedSteel"); - } - - if (Materials.hasMaterial(MaterialNames.NICHROME)) { - final MMDMaterial nichrome = Materials.getMaterialByName(MaterialNames.NICHROME); - - addAdditionalOredicts(nichrome, "Nichrome"); - } - - if (Materials.hasMaterial(MaterialNames.STAINLESS_STEEL)) { - final MMDMaterial stainlessSteel = Materials.getMaterialByName(MaterialNames.STAINLESS_STEEL); - - addAdditionalOredicts(stainlessSteel, "StainlessSteel"); - } - - if (Materials.hasMaterial(MaterialNames.TUNGSTEN)) { - addAdditionalOredicts(MaterialNames.TUNGSTEN, "Wolfram"); - } - } -} diff --git a/src/main/java/com/mcmoddev/modernmetals/init/VillagerTrades.java b/src/main/java/com/mcmoddev/modernmetals/init/VillagerTrades.java deleted file mode 100644 index f30a5e6e..00000000 --- a/src/main/java/com/mcmoddev/modernmetals/init/VillagerTrades.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.mcmoddev.modernmetals.init; - -import com.mcmoddev.lib.data.SharedStrings; - -/** - * - * @author Jasmine Iwanek - * - */ -public class VillagerTrades extends com.mcmoddev.lib.init.VillagerTrades { - private VillagerTrades() { - throw new IllegalAccessError(SharedStrings.NOT_INSTANTIABLE); - } - - /** - * - */ - public static void init() { - registerCommonTrades(); - } -} diff --git a/src/main/java/com/mcmoddev/modernmetals/proxy/CommonProxy.java b/src/main/java/com/mcmoddev/modernmetals/proxy/CommonProxy.java deleted file mode 100644 index b6f5cad5..00000000 --- a/src/main/java/com/mcmoddev/modernmetals/proxy/CommonProxy.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.mcmoddev.modernmetals.proxy; - -import java.util.HashSet; - -import com.mcmoddev.lib.data.SharedStrings; -import com.mcmoddev.lib.oregen.FallbackGenerator; -import com.mcmoddev.lib.util.Config.Options; -import com.mcmoddev.modernmetals.data.MaterialNames; -import com.mcmoddev.modernmetals.init.ItemGroups; -import com.mcmoddev.modernmetals.init.Recipes; -import com.mcmoddev.modernmetals.init.VillagerTrades; -import com.mcmoddev.modernmetals.util.MMeConfig; - -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.common.MissingModsException; -import net.minecraftforge.fml.common.event.FMLInitializationEvent; -import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.registry.GameRegistry; -import net.minecraftforge.fml.common.versioning.ArtifactVersion; -import net.minecraftforge.fml.common.versioning.DefaultArtifactVersion; - -/** - * Modern Metals Common Proxy. - * - * @author Jasmine Iwanek - * - */ -public class CommonProxy { - - /** - * - * @param event The Event. - */ - @SuppressWarnings("deprecation") - public void preInit(final FMLPreInitializationEvent event) { - - if ((Options.requireMMDOreSpawn()) && (!Loader.isModLoaded(SharedStrings.ORESPAWN_MODID))) { - if (Options.fallbackOrespawn()) { - GameRegistry.registerWorldGenerator(new FallbackGenerator(), 0); - } else { - final HashSet orespawnMod = new HashSet<>(); - orespawnMod.add(new DefaultArtifactVersion(SharedStrings.ORESPAWN_VERSION)); - throw new MissingModsException(orespawnMod, SharedStrings.ORESPAWN_MODID, - SharedStrings.ORESPAWN_MISSING_TEXT); - } - } - - VillagerTrades.init(); - } - - /** - * - * @param event The Event. - */ - public void init(final FMLInitializationEvent event) { - Recipes.init(); - - ItemGroups.setupIcons(MaterialNames.ALUMINUM); - } - - /** - * - * @param event The Event. - */ - public void postInit(FMLPostInitializationEvent event) { - MMeConfig.postInit(); - } -} diff --git a/src/main/java/com/mcmoddev/orespawn/ModernMetalsOreSpawn.java b/src/main/java/com/mcmoddev/orespawn/ModernMetalsOreSpawn.java deleted file mode 100644 index f94f81c9..00000000 --- a/src/main/java/com/mcmoddev/orespawn/ModernMetalsOreSpawn.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.mcmoddev.orespawn; - -import com.mcmoddev.modernmetals.ModernMetals; -import com.mcmoddev.orespawn.api.os3.OS3API; -import com.mcmoddev.orespawn.api.plugin.IOreSpawnPlugin; -import com.mcmoddev.orespawn.api.plugin.OreSpawnPlugin; - -@OreSpawnPlugin(modid = ModernMetals.MODID, resourcePath = "orespawn") -public class ModernMetalsOreSpawn implements IOreSpawnPlugin { - - @Override - public void register(final OS3API apiInterface) { - // nothing for us to do - all of our ores are in the - // jar and the code handles that - } -} diff --git a/src/main/java/com/mcmoddev/modernmetals/ModernMetals.java b/src/main/java/zone/moddev/mc/modernmetals/ModernMetals.java similarity index 74% rename from src/main/java/com/mcmoddev/modernmetals/ModernMetals.java rename to src/main/java/zone/moddev/mc/modernmetals/ModernMetals.java index f9a8a720..34a2b367 100644 --- a/src/main/java/com/mcmoddev/modernmetals/ModernMetals.java +++ b/src/main/java/zone/moddev/mc/modernmetals/ModernMetals.java @@ -1,10 +1,11 @@ -package com.mcmoddev.modernmetals; +package zone.moddev.mc.modernmetals; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.mcmoddev.modernmetals.proxy.CommonProxy; -import com.mcmoddev.modernmetals.util.MMeConfig; +import zone.moddev.mc.modernmetals.proxy.CommonProxy; +import zone.moddev.mc.modernmetals.content.ContentPolicy; +import zone.moddev.mc.modernmetals.util.MMeConfig; import com.mcmoddev.lib.data.SharedStrings; import net.minecraft.launchwrapper.Launch; @@ -28,10 +29,10 @@ modid = ModernMetals.MODID, name = ModernMetals.NAME, version = ModernMetals.VERSION, - dependencies = "required-after:forge@[14.21.1.2387,);required-after:mmdlib;after:tconstruct;after:conarm;before:buildingbricks", - acceptedMinecraftVersions = "[1.12,)", - certificateFingerprint = "@FINGERPRINT@", - updateJSON = ModernMetals.UPDATEJSON) + dependencies = "required-after:forge@[14.23.5.2859,);required-after:mmdlib@[1.0.0-rc2,2.0.0);required-after:orespawn@[4.1.3.112021,5.0.0);after:basemetals;after:tconstruct;after:conarm;before:buildingbricks", + acceptedMinecraftVersions = "[1.12.2]", + updateJSON = ModernMetals.UPDATEJSON, + guiFactory = "zone.moddev.mc.modernmetals.client.ModernMetalsGuiFactory") public class ModernMetals { @Instance @@ -48,11 +49,11 @@ public class ModernMetals { * increased whenever a change is made that has the potential to break * compatibility with other mods that depend on this one. */ - protected static final String VERSION = "2.5.0-rc2"; + protected static final String VERSION = "2.5.1.112021"; protected static final String UPDATEJSON = SharedStrings.UPDATE_JSON_URL + "ModernMetals/master/update.json"; - private static final String PROXY_BASE = SharedStrings.MMD_PROXY_GROUP + MODID + SharedStrings.DOT_PROXY_DOT; + private static final String PROXY_BASE = "zone.moddev.mc.modernmetals.proxy."; @SidedProxy(clientSide = PROXY_BASE + SharedStrings.CLIENTPROXY, serverSide = PROXY_BASE + SharedStrings.SERVERPROXY) @@ -75,6 +76,7 @@ public void onFingerprintViolation(FMLFingerprintViolationEvent event) { @EventHandler public static void constructing(final FMLConstructionEvent event) { MMeConfig.init(); + ContentPolicy.initialize(); } /** @@ -83,22 +85,18 @@ public static void constructing(final FMLConstructionEvent event) { */ @EventHandler public static void preInit(final FMLPreInitializationEvent event) { - ModernMetals.logger.fatal("FMLPreInitializationEvent"); proxy.preInit(event); -// MinecraftForge.EVENT_BUS.register(com.mcmoddev.modernmetals.init.Items.class); - //MinecraftForge.EVENT_BUS.register(com.mcmoddev.modernmetals.init.Blocks.class); } @EventHandler public static void init(final FMLInitializationEvent event) { - ModernMetals.logger.fatal("FMLInitializationEvent"); + zone.moddev.mc.modernmetals.worldgen.ModernMetalsWorldgenProvider.enqueue(); proxy.init(event); } @EventHandler public static void postInit(final FMLPostInitializationEvent event) { - ModernMetals.logger.fatal("FMLPostInitializationEvent"); proxy.postInit(event); } } diff --git a/src/main/java/zone/moddev/mc/modernmetals/client/ModernMetalsConfigScreen.java b/src/main/java/zone/moddev/mc/modernmetals/client/ModernMetalsConfigScreen.java new file mode 100644 index 00000000..3914de2b --- /dev/null +++ b/src/main/java/zone/moddev/mc/modernmetals/client/ModernMetalsConfigScreen.java @@ -0,0 +1,36 @@ +package zone.moddev.mc.modernmetals.client; + +import java.util.ArrayList; +import java.util.List; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.resources.I18n; +import net.minecraftforge.common.config.ConfigElement; +import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.fml.client.config.GuiConfig; +import net.minecraftforge.fml.client.config.IConfigElement; +import zone.moddev.mc.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.content.ContentPolicy; +import zone.moddev.mc.modernmetals.util.MMeConfig; + +/** Shared configuration screen for the Forge and OreSpawn mod lists. */ +public final class ModernMetalsConfigScreen extends GuiConfig { + public ModernMetalsConfigScreen(final GuiScreen parent) { + super(parent, elements(), ModernMetals.MODID, false, true, + I18n.format("config.modernmetals.title"), + I18n.format(ContentPolicy.inheritsBaseMetals() + ? "config.modernmetals.inherited_mode" : "config.modernmetals.description")); + } + + private static List elements() { + final Configuration config = MMeConfig.getConfiguration(); + final List elements = new ArrayList<>( + new ConfigElement(config.getCategory("General")).getChildElements()); + if (ContentPolicy.inheritsBaseMetals()) { + elements.removeIf(element -> "contentMode".equals(element.getName())); + } + for (final String category : MMeConfig.MATERIAL_CATEGORIES) { + elements.add(new ConfigElement(config.getCategory(category))); + } + return elements; + } +} diff --git a/src/main/java/zone/moddev/mc/modernmetals/client/ModernMetalsGuiFactory.java b/src/main/java/zone/moddev/mc/modernmetals/client/ModernMetalsGuiFactory.java new file mode 100644 index 00000000..ecf8054c --- /dev/null +++ b/src/main/java/zone/moddev/mc/modernmetals/client/ModernMetalsGuiFactory.java @@ -0,0 +1,32 @@ +package zone.moddev.mc.modernmetals.client; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; +import net.minecraftforge.fml.client.IModGuiFactory; + +import java.util.Collections; +import java.util.Set; + +/** Opens the existing configuration screen from Forge's Mods list. */ +public final class ModernMetalsGuiFactory implements IModGuiFactory { + + @Override + public void initialize(final Minecraft minecraftInstance) { + // The screen uses the configuration already loaded by Modern Metals. + } + + @Override + public boolean hasConfigGui() { + return true; + } + + @Override + public GuiScreen createConfigGui(final GuiScreen parentScreen) { + return new ModernMetalsConfigScreen(parentScreen); + } + + @Override + public Set runtimeGuiCategories() { + return Collections.emptySet(); + } +} diff --git a/src/main/java/zone/moddev/mc/modernmetals/compat/LegacyNamespaceTransformer.java b/src/main/java/zone/moddev/mc/modernmetals/compat/LegacyNamespaceTransformer.java new file mode 100644 index 00000000..0c3635d6 --- /dev/null +++ b/src/main/java/zone/moddev/mc/modernmetals/compat/LegacyNamespaceTransformer.java @@ -0,0 +1,89 @@ +package zone.moddev.mc.modernmetals.compat; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import net.minecraft.launchwrapper.IClassTransformer; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.commons.Remapper; +import org.objectweb.asm.commons.RemappingClassAdapter; + +/** Relinks existing MMD add-ons to the same classes and registries as Modern Metals. */ +public final class LegacyNamespaceTransformer implements IClassTransformer { + + private static final String OLD = "com/mcmoddev/modernmetals/"; + private static final String CURRENT = "zone/moddev/mc/modernmetals/"; + private static final Set EXPORTS = loadExports(); + + @Override + public byte[] transform(final String name, final String transformedName, final byte[] bytes) { + if (bytes == null || name == null || name.startsWith("zone.moddev.mc.modernmetals.") + || !(contains(bytes, OLD) || contains(bytes, OLD.replace('/', '.')))) { + return bytes; + } + + final ClassWriter output = new ClassWriter(0); + final Remapper names = new Remapper() { + @Override + public String map(final String internalName) { + return currentName(internalName); + } + + @Override + public Object mapValue(final Object value) { + if (value instanceof String) { + final String text = (String) value; + final String internal = text.replace('.', '/'); + final String mapped = currentName(internal); + if (mapped.equals(internal)) return value; + return text.indexOf('/') < 0 ? mapped.replace('/', '.') : mapped; + } + return super.mapValue(value); + } + }; + + new ClassReader(bytes).accept(new RemappingClassAdapter(output, names), 0); + return output.toByteArray(); + } + + private static String currentName(final String name) { + if (!name.startsWith(OLD)) return name; + + final String suffix = name.substring(OLD.length()); + final int nested = suffix.indexOf('$'); + final String owner = nested < 0 ? suffix : suffix.substring(0, nested); + return EXPORTS.contains(owner) ? CURRENT + suffix : name; + } + + private static Set loadExports() { + final Set result = new HashSet<>(); + final InputStream stream = LegacyNamespaceTransformer.class.getClassLoader() + .getResourceAsStream("META-INF/modernmetals-legacy-api.list"); + if (stream == null) throw new IllegalStateException("Missing Modern Metals API name list"); + + try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { + String line; + while ((line = reader.readLine()) != null) { + if (!line.isEmpty() && !line.startsWith("#")) result.add(line); + } + } catch (final IOException failure) { + throw new IllegalStateException("Cannot read Modern Metals API names", failure); + } + return Collections.unmodifiableSet(result); + } + + private static boolean contains(final byte[] bytes, final String text) { + for (int offset = 0; offset <= bytes.length - text.length(); offset++) { + int index = 0; + while (index < text.length() && bytes[offset + index] == text.charAt(index)) index++; + if (index == text.length()) return true; + } + return false; + } +} diff --git a/src/main/java/zone/moddev/mc/modernmetals/compat/ModernMetalsLoadingPlugin.java b/src/main/java/zone/moddev/mc/modernmetals/compat/ModernMetalsLoadingPlugin.java new file mode 100644 index 00000000..45021ae0 --- /dev/null +++ b/src/main/java/zone/moddev/mc/modernmetals/compat/ModernMetalsLoadingPlugin.java @@ -0,0 +1,19 @@ +package zone.moddev.mc.modernmetals.compat; + +import java.util.Map; +import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin; + +/** Relinks old add-on names without installing a second Base Metals transformer. */ +@IFMLLoadingPlugin.Name("ModernMetals") +@IFMLLoadingPlugin.MCVersion("1.12.2") +@IFMLLoadingPlugin.SortingIndex(1002) +@IFMLLoadingPlugin.TransformerExclusions("zone.moddev.mc.modernmetals.compat.") +public final class ModernMetalsLoadingPlugin implements IFMLLoadingPlugin { + @Override public String[] getASMTransformerClass() { + return new String[] { "zone.moddev.mc.modernmetals.compat.LegacyNamespaceTransformer" }; + } + @Override public String getModContainerClass() { return null; } + @Override public String getSetupClass() { return null; } + @Override public void injectData(final Map data) { } + @Override public String getAccessTransformerClass() { return null; } +} diff --git a/src/main/java/zone/moddev/mc/modernmetals/content/ContentModeNetwork.java b/src/main/java/zone/moddev/mc/modernmetals/content/ContentModeNetwork.java new file mode 100644 index 00000000..bbe36aec --- /dev/null +++ b/src/main/java/zone/moddev/mc/modernmetals/content/ContentModeNetwork.java @@ -0,0 +1,64 @@ +package zone.moddev.mc.modernmetals.content; + +import java.util.Set; + +import net.minecraft.network.NetworkManager; +import net.minecraft.network.play.server.SPacketDisconnect; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.util.text.TextComponentTranslation; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.network.FMLNetworkEvent.CustomPacketRegistrationEvent; +import net.minecraftforge.fml.common.network.NetworkRegistry; + +/** Advertise the active recipe mode in Forge's login channel registration. */ +public final class ContentModeNetwork { + private static final String HIGH = "ModernMetals|High"; + private static final String LOW = "ModernMetals|Low"; + + private ContentModeNetwork() {} + + public static void register() { + NetworkRegistry.INSTANCE.newEventDrivenChannel(ContentPolicy.active().lowFantasy() ? LOW : HIGH); + MinecraftForge.EVENT_BUS.register(new ContentModeNetwork()); + } + + @SubscribeEvent + public void checkMode(final CustomPacketRegistrationEvent event) { + final Set channels = event.getRegistrations(); + // Forge includes FML|HS in its login registration, not ordinary channel updates. + if (!"REGISTER".equals(event.getOperation()) || !channels.contains("FML|HS")) return; + + final boolean localLow = ContentPolicy.active().lowFantasy(); + final boolean remoteLow = channels.contains(LOW); + final boolean remoteHigh = channels.contains(HIGH); + final boolean server = event.getSide().isServer(); + final ITextComponent reason; + if (remoteLow == remoteHigh) { + // A client with no mode channel may also lack the translation key. + reason = server + ? new TextComponentString("Modern Metals could not check the Fantasy Level. " + + "Use the same Modern Metals build on the server and client.") + : new TextComponentTranslation("config.modernmetals.connection.protocol"); + } else if (remoteLow == localLow) { + return; + } else { + final boolean serverLow = server ? localLow : remoteLow; + reason = new TextComponentTranslation("config.modernmetals.connection.mismatch", + modeLabel(serverLow), modeLabel(!serverLow)); + } + + final NetworkManager manager = event.getManager(); + manager.channel().config().setAutoRead(false); + if (server) { + manager.sendPacket(new SPacketDisconnect(reason), future -> manager.closeChannel(reason)); + } else { + manager.closeChannel(reason); + } + } + + private static ITextComponent modeLabel(final boolean low) { + return new TextComponentTranslation("config.modernmetals.content_mode." + (low ? "low_fantasy" : "high_fantasy")); + } +} diff --git a/src/main/java/zone/moddev/mc/modernmetals/content/ContentPolicy.java b/src/main/java/zone/moddev/mc/modernmetals/content/ContentPolicy.java new file mode 100644 index 00000000..b32c1a18 --- /dev/null +++ b/src/main/java/zone/moddev/mc/modernmetals/content/ContentPolicy.java @@ -0,0 +1,79 @@ +package zone.moddev.mc.modernmetals.content; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.ModContainer; +import net.minecraftforge.fml.common.versioning.DefaultArtifactVersion; +import zone.moddev.mc.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.util.MMeConfig; + +/** Restricts obtainability, while retaining every registered item and saved stack. */ +public final class ContentPolicy { + private static final Set TOOLS = names("axe","crackhammer","hoe","pickaxe","scythe","shears","shovel","sword","arrow","bolt"); + private static final Set PROTECTION = names("boots","chestplate","helmet","leggings","horse_armor","horsearmor","shield"); + private static final Set FULL_TOOLS = names("galvanizedsteel","stainlesssteel","titanium"); + private static final Set ARMOR = names("aluminum","aluminumbrass","galvanizedsteel","stainlesssteel","titanium"); + private static final Set GEARS = names("aluminum","aluminumbrass","galvanizedsteel","stainlesssteel","titanium"); + private static final Set STRUCTURAL_FORMS = names("bars","bookshelf","button","door","double_slab","doubleslab","fence","fence_gate","flower_pot","ladder","lever","pressure_plate","pressureplate","slab","stairs","trapdoor","tripwire_hook","wall"); + private static final Set STRUCTURAL_METALS = names("aluminum","aluminumbrass","galvanizedsteel","nichrome","stainlesssteel","tantalum","titanium","tungsten","zirconium"); + private static boolean initialized; + private static ContentPolicy active = forMode("high_fantasy"); + private final boolean low; + private ContentPolicy(final boolean low) { this.low=low; } + public static ContentPolicy forMode(final String mode) { + return new ContentPolicy(mode!=null && "low_fantasy".equals(mode.trim().toLowerCase(Locale.ROOT))); + } + public static ContentPolicy active() { return active; } + public boolean lowFantasy() { return low; } + /** Base Metals owns the mode when its startup configuration API is available. */ + public static boolean inheritsBaseMetals() { + final ModContainer mod = Loader.instance().getIndexedModList().get("basemetals"); + return mod != null && new DefaultArtifactVersion(mod.getVersion()) + .compareTo(new DefaultArtifactVersion("2.6.1.112021")) >= 0; + } + + public static void initialize() { + if (initialized) return; + final boolean inherited = inheritsBaseMetals(); + active = forMode(inherited ? BaseMetalsMode.read() : MMeConfig.configuredContentMode()); + initialized = true; + ModernMetals.logger.info("Modern Metals Fantasy Level %s (%s)", + active.low ? "low_fantasy" : "high_fantasy", inherited ? "Base Metals" : "Modern Metals"); + } + + // This class is linked only in a pack with the compatible Base Metals API. + private static final class BaseMetalsMode { + static String read() { + return com.mcmoddev.basemetals.util.BMeConfig.getActiveContentMode().serializedName(); + } + } + + public boolean allows(final String material,final String form) { + if(!low || material==null || form==null) return true; + if(TOOLS.contains(form)) return FULL_TOOLS.contains(material); + if(PROTECTION.contains(form)) return ARMOR.contains(material); + if ("bow".equals(form) || "crossbow".equals(form) || "fishing_rod".equals(form) + || "fishingrod".equals(form)) return false; + if("gear".equals(form)) return GEARS.contains(material); + if("anvil".equals(form)) return "stainlesssteel".equals(material) || "galvanizedsteel".equals(material); + if(STRUCTURAL_FORMS.contains(form)) return STRUCTURAL_METALS.contains(material); + return true; + } + public boolean allows(final ItemStack stack) { + if(!low || stack==null || stack.isEmpty()) return true; + final ResourceLocation id=stack.getItem().getRegistryName(); + if(id==null || !ModernMetals.MODID.equals(id.getNamespace())) return true; + final String path=id.getPath().startsWith("double_") ? id.getPath().substring(7) : id.getPath(); + final int split=path.indexOf('_'); + return split<0 || allows(path.substring(0,split),path.substring(split+1)); + } + private static Set names(final String... values) { + return Collections.unmodifiableSet(new HashSet<>(Arrays.asList(values))); + } +} diff --git a/src/main/java/com/mcmoddev/modernmetals/data/MaterialNames.java b/src/main/java/zone/moddev/mc/modernmetals/data/MaterialNames.java similarity index 97% rename from src/main/java/com/mcmoddev/modernmetals/data/MaterialNames.java rename to src/main/java/zone/moddev/mc/modernmetals/data/MaterialNames.java index ab7ce948..27083e9e 100644 --- a/src/main/java/com/mcmoddev/modernmetals/data/MaterialNames.java +++ b/src/main/java/zone/moddev/mc/modernmetals/data/MaterialNames.java @@ -1,4 +1,4 @@ -package com.mcmoddev.modernmetals.data; +package zone.moddev.mc.modernmetals.data; import com.mcmoddev.lib.data.SharedStrings; diff --git a/src/main/java/com/mcmoddev/modernmetals/data/TraitNames.java b/src/main/java/zone/moddev/mc/modernmetals/data/TraitNames.java similarity index 94% rename from src/main/java/com/mcmoddev/modernmetals/data/TraitNames.java rename to src/main/java/zone/moddev/mc/modernmetals/data/TraitNames.java index 301f6254..82ededc3 100644 --- a/src/main/java/com/mcmoddev/modernmetals/data/TraitNames.java +++ b/src/main/java/zone/moddev/mc/modernmetals/data/TraitNames.java @@ -1,4 +1,4 @@ -package com.mcmoddev.modernmetals.data; +package zone.moddev.mc.modernmetals.data; import com.mcmoddev.lib.data.SharedStrings; diff --git a/src/main/java/com/mcmoddev/modernmetals/init/Blocks.java b/src/main/java/zone/moddev/mc/modernmetals/init/Blocks.java similarity index 94% rename from src/main/java/com/mcmoddev/modernmetals/init/Blocks.java rename to src/main/java/zone/moddev/mc/modernmetals/init/Blocks.java index 7bae5bd1..370f793f 100644 --- a/src/main/java/com/mcmoddev/modernmetals/init/Blocks.java +++ b/src/main/java/zone/moddev/mc/modernmetals/init/Blocks.java @@ -1,4 +1,4 @@ -package com.mcmoddev.modernmetals.init; +package zone.moddev.mc.modernmetals.init; import java.util.Arrays; import java.util.List; @@ -7,8 +7,8 @@ import com.mcmoddev.lib.data.SharedStrings; import com.mcmoddev.lib.init.Materials; import com.mcmoddev.lib.material.MMDMaterial; -import com.mcmoddev.modernmetals.ModernMetals; -import com.mcmoddev.modernmetals.data.MaterialNames; +import zone.moddev.mc.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.data.MaterialNames; import net.minecraft.block.Block; import net.minecraftforge.event.RegistryEvent; diff --git a/src/main/java/com/mcmoddev/modernmetals/init/Fluids.java b/src/main/java/zone/moddev/mc/modernmetals/init/Fluids.java similarity index 66% rename from src/main/java/com/mcmoddev/modernmetals/init/Fluids.java rename to src/main/java/zone/moddev/mc/modernmetals/init/Fluids.java index 3cbfe03d..eae747fe 100644 --- a/src/main/java/com/mcmoddev/modernmetals/init/Fluids.java +++ b/src/main/java/zone/moddev/mc/modernmetals/init/Fluids.java @@ -1,14 +1,17 @@ -package com.mcmoddev.modernmetals.init; +package zone.moddev.mc.modernmetals.init; import java.util.Arrays; import java.util.List; import javax.annotation.Nonnull; +import com.mcmoddev.lib.block.InteractiveFluidBlock; import com.mcmoddev.lib.data.SharedStrings; +import com.mcmoddev.lib.material.MMDMaterial; import com.mcmoddev.lib.init.Materials; import com.mcmoddev.lib.util.Config.Options; -import com.mcmoddev.modernmetals.data.MaterialNames; +import zone.moddev.mc.modernmetals.data.MaterialNames; +import net.minecraft.util.DamageSource; /** * This class initializes all fluids in Modern Metals. @@ -34,9 +37,15 @@ public static void init() { materials.stream().filter(Materials::hasMaterial) .filter(Options::isFluidEnabled).forEach(materialName -> { - // if only this was easier... - addFluid(materialName, 2000, 10000, getTemperature(materialName), 10); - addFluidBlock(materialName); + final MMDMaterial material = Materials.getMaterialByName(materialName); + addFluid(material, 2000, 10000, getTemperature(materialName), 10); + material.setFluidBlockGetter(name -> new InteractiveFluidBlock(material.getFluid(), (world, entity) -> { + if (!world.isRemote) { + entity.attackEntityFrom(DamageSource.LAVA, 4.0F); + entity.setFire(4); + } + })); + addFluidBlock(material); }); } diff --git a/src/main/java/com/mcmoddev/modernmetals/init/ItemGroups.java b/src/main/java/zone/moddev/mc/modernmetals/init/ItemGroups.java similarity index 93% rename from src/main/java/com/mcmoddev/modernmetals/init/ItemGroups.java rename to src/main/java/zone/moddev/mc/modernmetals/init/ItemGroups.java index 9ca97f47..573ddbc0 100644 --- a/src/main/java/com/mcmoddev/modernmetals/init/ItemGroups.java +++ b/src/main/java/zone/moddev/mc/modernmetals/init/ItemGroups.java @@ -1,10 +1,10 @@ -package com.mcmoddev.modernmetals.init; +package zone.moddev.mc.modernmetals.init; import com.mcmoddev.lib.data.Names; import com.mcmoddev.lib.data.SharedStrings; import com.mcmoddev.lib.init.Materials; import com.mcmoddev.lib.material.MMDMaterial; -import com.mcmoddev.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.ModernMetals; /** * This class initializes all item groups in Modern Metals. diff --git a/src/main/java/com/mcmoddev/modernmetals/init/Items.java b/src/main/java/zone/moddev/mc/modernmetals/init/Items.java similarity index 97% rename from src/main/java/com/mcmoddev/modernmetals/init/Items.java rename to src/main/java/zone/moddev/mc/modernmetals/init/Items.java index 856a1342..59e5a901 100644 --- a/src/main/java/com/mcmoddev/modernmetals/init/Items.java +++ b/src/main/java/zone/moddev/mc/modernmetals/init/Items.java @@ -1,4 +1,4 @@ -package com.mcmoddev.modernmetals.init; +package zone.moddev.mc.modernmetals.init; import java.util.Arrays; import java.util.List; @@ -8,8 +8,8 @@ import com.mcmoddev.lib.init.Materials; import com.mcmoddev.lib.material.MMDMaterial; import com.mcmoddev.lib.util.Oredicts; -import com.mcmoddev.modernmetals.ModernMetals; -import com.mcmoddev.modernmetals.data.MaterialNames; +import zone.moddev.mc.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.data.MaterialNames; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; diff --git a/src/main/java/com/mcmoddev/modernmetals/init/Materials.java b/src/main/java/zone/moddev/mc/modernmetals/init/Materials.java similarity index 98% rename from src/main/java/com/mcmoddev/modernmetals/init/Materials.java rename to src/main/java/zone/moddev/mc/modernmetals/init/Materials.java index bf2858ab..88a9c35e 100644 --- a/src/main/java/com/mcmoddev/modernmetals/init/Materials.java +++ b/src/main/java/zone/moddev/mc/modernmetals/init/Materials.java @@ -1,4 +1,4 @@ -package com.mcmoddev.modernmetals.init; +package zone.moddev.mc.modernmetals.init; import java.util.Arrays; import java.util.List; @@ -8,7 +8,7 @@ import com.mcmoddev.lib.data.SharedStrings; import com.mcmoddev.lib.material.MMDMaterialType.MaterialType; import com.mcmoddev.lib.util.Config.Options; -import com.mcmoddev.modernmetals.data.MaterialNames; +import zone.moddev.mc.modernmetals.data.MaterialNames; /** * This class initializes all of the materials in Modern Metals. diff --git a/src/main/java/zone/moddev/mc/modernmetals/init/PolicyRecipe.java b/src/main/java/zone/moddev/mc/modernmetals/init/PolicyRecipe.java new file mode 100644 index 00000000..166e5f70 --- /dev/null +++ b/src/main/java/zone/moddev/mc/modernmetals/init/PolicyRecipe.java @@ -0,0 +1,66 @@ +package zone.moddev.mc.modernmetals.init; + +import zone.moddev.mc.modernmetals.content.ContentPolicy; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.util.NonNullList; +import net.minecraft.world.World; +import net.minecraftforge.registries.IForgeRegistryEntry; + +/** Disables restricted recipes without removing their saved registry names. */ +final class PolicyRecipe extends IForgeRegistryEntry.Impl implements IRecipe { + private final IRecipe delegate; + private final ContentPolicy policy; + private final boolean allowed; + + PolicyRecipe(final IRecipe delegate, final ContentPolicy policy) { + this.delegate = delegate; + + this.policy = policy; + this.allowed = policy.allows(delegate.getRecipeOutput()); + setRegistryName(delegate.getRegistryName()); + } + + @Override + public boolean matches(final InventoryCrafting inventory, final World world) { + return allowed && delegate.matches(inventory, world) && policy.allows(delegate.getCraftingResult(inventory)); + } + + @Override + public ItemStack getCraftingResult(final InventoryCrafting inventory) { + if (!allowed) return ItemStack.EMPTY; + final ItemStack result = delegate.getCraftingResult(inventory); + return policy.allows(result) ? result : ItemStack.EMPTY; + } + + @Override + public boolean canFit(final int width, final int height) { + return allowed && delegate.canFit(width, height); + } + + @Override + public ItemStack getRecipeOutput() { + return allowed ? delegate.getRecipeOutput() : ItemStack.EMPTY; + } + + @Override + public NonNullList getRemainingItems(final InventoryCrafting inventory) { + return delegate.getRemainingItems(inventory); + } + + @Override + public NonNullList getIngredients() { + return delegate.getIngredients(); + } + + @Override + public boolean isDynamic() { + return !allowed || delegate.isDynamic(); + } + + @Override + public String getGroup() { + return delegate.getGroup(); + } +} diff --git a/src/main/java/zone/moddev/mc/modernmetals/init/Recipes.java b/src/main/java/zone/moddev/mc/modernmetals/init/Recipes.java new file mode 100644 index 00000000..febf6624 --- /dev/null +++ b/src/main/java/zone/moddev/mc/modernmetals/init/Recipes.java @@ -0,0 +1,116 @@ +package zone.moddev.mc.modernmetals.init; + +import java.util.ArrayList; +import java.util.List; +import com.mcmoddev.lib.data.Names; +import com.mcmoddev.lib.data.SharedStrings; +import com.mcmoddev.lib.init.Materials; +import com.mcmoddev.lib.material.MMDMaterial; +import zone.moddev.mc.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.content.ContentPolicy; +import zone.moddev.mc.modernmetals.data.MaterialNames; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.FurnaceRecipes; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.EventPriority; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.registry.GameRegistry; + +/** + * + * @author Jasmine Iwanek + * + */ +@Mod.EventBusSubscriber(modid = ModernMetals.MODID) +public class Recipes extends com.mcmoddev.lib.init.Recipes { + + private Recipes() { + throw new IllegalAccessError(SharedStrings.NOT_INSTANTIABLE); + } + + /** + * + */ + public static void init() { + initModSpecificRecipes(); + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public static void registerRecipes(final RegistryEvent.Register event) { + initModSpecificRecipes(); + register(event); + registerBlendSmelting(); + final ContentPolicy policy = ContentPolicy.active(); + if (!policy.lowFantasy()) return; + + final List restricted = new ArrayList<>(); + for (final IRecipe recipe : event.getRegistry()) { + final String type = recipe.getClass().getName(); + final boolean sharedDynamic = recipe.getRecipeOutput().isEmpty() + && (type.startsWith("com.mcmoddev.lib.recipe.") || type.startsWith("zone.moddev.mc.mmdlib.recipe.")); + if (!policy.allows(recipe.getRecipeOutput()) || sharedDynamic) { + restricted.add(recipe); + } + } + for (final IRecipe recipe : restricted) { + event.getRegistry().register(new PolicyRecipe(recipe, policy)); + } + } + + private static void registerBlendSmelting() { + for (final MMDMaterial material : Materials.getMaterialsByMod(ModernMetals.MODID)) { + if (!material.hasItem(Names.BLEND) || !material.hasItem(Names.INGOT)) continue; + final ItemStack blend = material.getItemStack(Names.BLEND); + if (FurnaceRecipes.instance().getSmeltingResult(blend).isEmpty()) { + GameRegistry.addSmelting(blend, material.getItemStack(Names.INGOT), material.getOreSmeltXP()); + } + } + } + + private static void initModSpecificRecipes() { + if (Materials.hasMaterial(MaterialNames.ALUMINUM)) { + final MMDMaterial aluminum = Materials.getMaterialByName(MaterialNames.ALUMINUM); + + addAdditionalOredicts(aluminum, "Aluminium"); + addAdditionalOredicts(aluminum, "Bauxite"); + } + + if (Materials.hasMaterial(MaterialNames.ALUMINUM_BRASS)) { + final MMDMaterial aluminumBrass = Materials.getMaterialByName(MaterialNames.ALUMINUM_BRASS); + + addAdditionalOredicts(aluminumBrass, "AluminumBrass"); + addAdditionalOredicts(aluminumBrass, "Aluminiumbrass"); + addAdditionalOredicts(aluminumBrass, "AluminiumBrass"); + addAdditionalOredicts(aluminumBrass, "Alubrass"); + addAdditionalOredicts(aluminumBrass, "AluBrass"); + } + + if (Materials.hasMaterial(MaterialNames.CHROMIUM)) { + addAdditionalOredicts(MaterialNames.CHROMIUM, "Chrome"); + } + + if (Materials.hasMaterial(MaterialNames.GALVANIZED_STEEL)) { + final MMDMaterial galvanizedSteel = Materials.getMaterialByName(MaterialNames.GALVANIZED_STEEL); + + addAdditionalOredicts(galvanizedSteel, "GalvinizedSteel"); + } + + if (Materials.hasMaterial(MaterialNames.NICHROME)) { + final MMDMaterial nichrome = Materials.getMaterialByName(MaterialNames.NICHROME); + + addAdditionalOredicts(nichrome, "Nichrome"); + } + + if (Materials.hasMaterial(MaterialNames.STAINLESS_STEEL)) { + final MMDMaterial stainlessSteel = Materials.getMaterialByName(MaterialNames.STAINLESS_STEEL); + + addAdditionalOredicts(stainlessSteel, "StainlessSteel"); + } + + if (Materials.hasMaterial(MaterialNames.TUNGSTEN)) { + addAdditionalOredicts(MaterialNames.TUNGSTEN, "Wolfram"); + } + } +} diff --git a/src/main/java/zone/moddev/mc/modernmetals/init/VillagerTrades.java b/src/main/java/zone/moddev/mc/modernmetals/init/VillagerTrades.java new file mode 100644 index 00000000..ed00507e --- /dev/null +++ b/src/main/java/zone/moddev/mc/modernmetals/init/VillagerTrades.java @@ -0,0 +1,46 @@ +package zone.moddev.mc.modernmetals.init; + +import com.mcmoddev.lib.data.MaterialStats; +import com.mcmoddev.lib.data.Names; +import com.mcmoddev.lib.data.SharedStrings; +import com.mcmoddev.lib.init.Materials; +import com.mcmoddev.lib.material.MMDMaterial; +import com.mcmoddev.lib.util.VillagerTradeHelper; +import net.minecraft.item.ItemStack; +import zone.moddev.mc.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.content.ContentPolicy; + +/** + * + * @author Jasmine Iwanek + * + */ +public class VillagerTrades extends com.mcmoddev.lib.init.VillagerTrades { + private VillagerTrades() { + throw new IllegalAccessError(SharedStrings.NOT_INSTANTIABLE); + } + + /** + * + */ + public static void init() { + if (!ContentPolicy.active().lowFantasy()) { + registerCommonTrades(); + return; + } + // Keep smiths trading metal in Low Fantasy, without offering implausible equipment. + for (final MMDMaterial material : Materials.getMaterialsByMod(ModernMetals.MODID)) { + if (material.isEmpty() || material.isRare() || !material.hasItem(Names.INGOT)) continue; + final float value = material.getStat(MaterialStats.HARDNESS) + + material.getStat(MaterialStats.STRENGTH) + + material.getStat(MaterialStats.MAGICAFFINITY) + material.getToolHarvestLevel(); + final int price = emeraldPurchaseValue(value); + if (price > 64 || emeraldSaleValue(value) > 64) continue; + final ItemStack ingots = material.getItemStack(Names.INGOT, 12); + for (final int career : new int[] { ARMOR_SMITH_ID, WEAPON_SMITH_ID, TOOL_SMITH_ID }) { + VillagerTradeHelper.insertTrades(SMITH_RL, career, tradeLevel(value), + makePurchasePalette(price, ingots)); + } + } + } +} diff --git a/src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeConstructsArmory.java b/src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeConstructsArmory.java similarity index 95% rename from src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeConstructsArmory.java rename to src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeConstructsArmory.java index 913ebd67..5cf3f1d3 100644 --- a/src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeConstructsArmory.java +++ b/src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeConstructsArmory.java @@ -1,4 +1,4 @@ -package com.mcmoddev.modernmetals.integration.plugins; +package zone.moddev.mc.modernmetals.integration.plugins; import c4.conarm.common.armor.traits.ArmorTraits; import com.mcmoddev.lib.integration.IIntegration; @@ -8,8 +8,8 @@ import com.mcmoddev.lib.integration.plugins.tinkers.events.MaterialRegistrationEvent; import com.mcmoddev.lib.integration.plugins.tinkers.traits.MMDTraits; import com.mcmoddev.lib.util.Config; -import com.mcmoddev.modernmetals.ModernMetals; -import com.mcmoddev.modernmetals.data.MaterialNames; +import zone.moddev.mc.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.data.MaterialNames; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; diff --git a/src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeDenseOres.java b/src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeDenseOres.java similarity index 90% rename from src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeDenseOres.java rename to src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeDenseOres.java index 4956e573..66f3bedc 100644 --- a/src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeDenseOres.java +++ b/src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeDenseOres.java @@ -1,4 +1,4 @@ -package com.mcmoddev.modernmetals.integration.plugins; +package zone.moddev.mc.modernmetals.integration.plugins; import java.util.Arrays; import java.util.List; @@ -9,8 +9,8 @@ import com.mcmoddev.lib.material.MMDMaterial; import com.mcmoddev.lib.util.Config.Options; import com.mcmoddev.lib.util.Oredicts; -import com.mcmoddev.modernmetals.ModernMetals; -import com.mcmoddev.modernmetals.data.MaterialNames; +import zone.moddev.mc.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.data.MaterialNames; @MMDPlugin(addonId = ModernMetals.MODID, pluginId = MMeDenseOres.PLUGIN_MODID) public class MMeDenseOres extends com.mcmoddev.lib.integration.plugins.DenseOres implements IIntegration { diff --git a/src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeEnderIO.java b/src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeEnderIO.java similarity index 88% rename from src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeEnderIO.java rename to src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeEnderIO.java index 429d3b9d..9f3d8891 100644 --- a/src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeEnderIO.java +++ b/src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeEnderIO.java @@ -1,4 +1,4 @@ -package com.mcmoddev.modernmetals.integration.plugins; +package zone.moddev.mc.modernmetals.integration.plugins; import java.util.Arrays; import java.util.List; @@ -7,8 +7,8 @@ import com.mcmoddev.lib.integration.IIntegration; import com.mcmoddev.lib.integration.MMDPlugin; import com.mcmoddev.lib.util.Config.Options; -import com.mcmoddev.modernmetals.ModernMetals; -import com.mcmoddev.modernmetals.data.MaterialNames; +import zone.moddev.mc.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.data.MaterialNames; /** * diff --git a/src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeIC2.java b/src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeIC2.java similarity index 95% rename from src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeIC2.java rename to src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeIC2.java index 02c89d99..50b86927 100644 --- a/src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeIC2.java +++ b/src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeIC2.java @@ -1,4 +1,4 @@ -package com.mcmoddev.modernmetals.integration.plugins; +package zone.moddev.mc.modernmetals.integration.plugins; import java.util.Arrays; @@ -8,8 +8,8 @@ import com.mcmoddev.lib.integration.MMDPlugin; import com.mcmoddev.lib.material.MMDMaterial; import com.mcmoddev.lib.util.Config.Options; -import com.mcmoddev.modernmetals.ModernMetals; -import com.mcmoddev.modernmetals.data.MaterialNames; +import zone.moddev.mc.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.data.MaterialNames; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.RegistryEvent; diff --git a/src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeMekanism.java b/src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeMekanism.java similarity index 93% rename from src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeMekanism.java rename to src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeMekanism.java index 4577451c..420c2cc8 100644 --- a/src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeMekanism.java +++ b/src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeMekanism.java @@ -1,4 +1,4 @@ -package com.mcmoddev.modernmetals.integration.plugins; +package zone.moddev.mc.modernmetals.integration.plugins; import java.util.Arrays; import java.util.List; @@ -8,8 +8,8 @@ import com.mcmoddev.lib.integration.MMDPlugin; import com.mcmoddev.lib.integration.plugins.Mekanism; import com.mcmoddev.lib.util.Config.Options; -import com.mcmoddev.modernmetals.ModernMetals; -import com.mcmoddev.modernmetals.data.MaterialNames; +import zone.moddev.mc.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.data.MaterialNames; import net.minecraft.item.crafting.IRecipe; import net.minecraftforge.common.MinecraftForge; diff --git a/src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeThaumcraft.java b/src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeThaumcraft.java similarity index 80% rename from src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeThaumcraft.java rename to src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeThaumcraft.java index be4c5dbe..c669e075 100644 --- a/src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeThaumcraft.java +++ b/src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeThaumcraft.java @@ -1,9 +1,9 @@ -package com.mcmoddev.modernmetals.integration.plugins; +package zone.moddev.mc.modernmetals.integration.plugins; import com.mcmoddev.lib.integration.IIntegration; import com.mcmoddev.lib.integration.MMDPlugin; import com.mcmoddev.lib.util.Config.Options; -import com.mcmoddev.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.ModernMetals; @MMDPlugin(addonId = ModernMetals.MODID, pluginId = MMeThaumcraft.PLUGIN_MODID) public class MMeThaumcraft extends com.mcmoddev.lib.integration.plugins.Thaumcraft implements IIntegration { diff --git a/src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeThermalExpansion.java b/src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeThermalExpansion.java similarity index 79% rename from src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeThermalExpansion.java rename to src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeThermalExpansion.java index ffc0a422..3e4ca4ae 100644 --- a/src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeThermalExpansion.java +++ b/src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeThermalExpansion.java @@ -1,4 +1,4 @@ -package com.mcmoddev.modernmetals.integration.plugins; +package zone.moddev.mc.modernmetals.integration.plugins; import java.util.Arrays; import java.util.List; @@ -9,8 +9,8 @@ import com.mcmoddev.lib.integration.MMDPlugin; import com.mcmoddev.lib.material.MMDMaterial; import com.mcmoddev.lib.util.Config.Options; -import com.mcmoddev.modernmetals.ModernMetals; -import com.mcmoddev.modernmetals.data.MaterialNames; +import zone.moddev.mc.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.data.MaterialNames; import cofh.api.util.ThermalExpansionHelper; import net.minecraft.item.crafting.IRecipe; @@ -55,21 +55,21 @@ public void regShit(final RegistryEvent.Register event) { maybeAddMagmaticFuels(MaterialNames.PLUTONIUM, MaterialNames.URANIUM); - if ((hasMaterials(com.mcmoddev.modernmetals.data.MaterialNames.STEEL, MaterialNames.CHROMIUM, MaterialNames.STAINLESS_STEEL)) - && (materialsHaveItems(Arrays.asList(com.mcmoddev.modernmetals.data.MaterialNames.STEEL, MaterialNames.CHROMIUM, MaterialNames.STAINLESS_STEEL), Names.INGOT.toString()))) { - final MMDMaterial steel = Materials.getMaterialByName(com.mcmoddev.modernmetals.data.MaterialNames.STEEL); + if ((hasMaterials(zone.moddev.mc.modernmetals.data.MaterialNames.STEEL, MaterialNames.CHROMIUM, MaterialNames.STAINLESS_STEEL)) + && (materialsHaveItems(Arrays.asList(zone.moddev.mc.modernmetals.data.MaterialNames.STEEL, MaterialNames.CHROMIUM, MaterialNames.STAINLESS_STEEL), Names.INGOT.toString()))) { + final MMDMaterial steel = Materials.getMaterialByName(zone.moddev.mc.modernmetals.data.MaterialNames.STEEL); final MMDMaterial chromium = Materials.getMaterialByName(MaterialNames.CHROMIUM); final MMDMaterial stainlessSteel = Materials.getMaterialByName(MaterialNames.STAINLESS_STEEL); ThermalExpansionHelper.addSmelterRecipe(4000, steel.getItemStack(Names.INGOT, 1), chromium.getItemStack(Names.INGOT, 1), stainlessSteel.getItemStack(Names.INGOT, 2)); } - if ((hasMaterials(com.mcmoddev.modernmetals.data.MaterialNames.STEEL, com.mcmoddev.modernmetals.data.MaterialNames.ZINC, MaterialNames.GALVANIZED_STEEL)) - && (materialsHaveItems(Arrays.asList(com.mcmoddev.modernmetals.data.MaterialNames.STEEL, com.mcmoddev.modernmetals.data.MaterialNames.ZINC, MaterialNames.GALVANIZED_STEEL), Names.INGOT.toString()))) { - final MMDMaterial steel = Materials.getMaterialByName(com.mcmoddev.modernmetals.data.MaterialNames.STEEL); + if ((hasMaterials(zone.moddev.mc.modernmetals.data.MaterialNames.STEEL, zone.moddev.mc.modernmetals.data.MaterialNames.ZINC, MaterialNames.GALVANIZED_STEEL)) + && (materialsHaveItems(Arrays.asList(zone.moddev.mc.modernmetals.data.MaterialNames.STEEL, zone.moddev.mc.modernmetals.data.MaterialNames.ZINC, MaterialNames.GALVANIZED_STEEL), Names.INGOT.toString()))) { + final MMDMaterial steel = Materials.getMaterialByName(zone.moddev.mc.modernmetals.data.MaterialNames.STEEL); final MMDMaterial galvanizedSteel = Materials.getMaterialByName(MaterialNames.GALVANIZED_STEEL); final MMDMaterial zinc = Materials - .getMaterialByName(com.mcmoddev.modernmetals.data.MaterialNames.ZINC); + .getMaterialByName(zone.moddev.mc.modernmetals.data.MaterialNames.ZINC); ThermalExpansionHelper.addSmelterRecipe(4000, steel.getItemStack(Names.INGOT, 1), zinc.getItemStack(Names.INGOT, 1), galvanizedSteel.getItemStack(Names.INGOT, 2)); } diff --git a/src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeTinkersConstruct.java b/src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeTinkersConstruct.java similarity index 75% rename from src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeTinkersConstruct.java rename to src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeTinkersConstruct.java index 73f4e902..7001fdc4 100644 --- a/src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeTinkersConstruct.java +++ b/src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeTinkersConstruct.java @@ -1,8 +1,5 @@ -package com.mcmoddev.modernmetals.integration.plugins; +package zone.moddev.mc.modernmetals.integration.plugins; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; import java.util.Locale; import com.mcmoddev.lib.init.Materials; @@ -15,9 +12,10 @@ import com.mcmoddev.lib.integration.plugins.tinkers.events.TinkersAlloyRecipeEvent; import com.mcmoddev.lib.util.Config.Options; -import com.mcmoddev.modernmetals.ModernMetals; -import com.mcmoddev.modernmetals.data.MaterialNames; -import com.mcmoddev.modernmetals.data.TraitNames; +import zone.moddev.mc.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.content.ContentPolicy; +import zone.moddev.mc.modernmetals.data.MaterialNames; +import zone.moddev.mc.modernmetals.data.TraitNames; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fluids.FluidRegistry; @@ -25,6 +23,11 @@ import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.ModContainer; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import slimeknights.tconstruct.library.events.TinkerRegisterEvent; +import slimeknights.tconstruct.library.smeltery.CastingRecipe; +import slimeknights.tconstruct.library.smeltery.ICastingRecipe; +import slimeknights.tconstruct.library.tools.IToolPart; +import net.minecraft.item.ItemStack; /** * @@ -119,7 +122,7 @@ public void materialRegistration(MaterialRegistrationEvent ev) { private void registerMaterial(final boolean active, final String name, final boolean castable, final boolean craftable, MaterialRegistrationEvent ev, final Object... traits) { - if (active) { + if (active && Materials.getMaterialByName(name).getFluid() != null) { TinkersMaterial mat = new TinkersMaterial(Materials.getMaterialByName(name)) .setCastable(castable).setCraftable(craftable).setToolForge(true); int i = 0; @@ -145,38 +148,46 @@ private void registerMaterial(final boolean active, final String name, final boo private void registerMaterial(final boolean active, final String name, final boolean castable, final boolean craftable, MaterialRegistrationEvent ev) { - if (active) { - TinkersMaterial mat = new TinkersMaterial(Materials.getMaterialByName(name)) - .setCastable(castable).setCraftable(craftable).setToolForge(true).create(); - - ev.getRegistry().register(mat); - } + registerMaterial(active, name, castable, craftable, ev, new Object[0]); } private void registerAlloy(TinkersAlloyRecipeEvent ev, final String outputMaterialName, final int outputAmount, final Object[] recipe) { - final List materialNames = new ArrayList<>(); - materialNames.add(outputMaterialName); - Arrays.asList(recipe).stream() - .filter(elem -> elem instanceof String) - .forEach(elem -> materialNames.add((String)elem)); - if (!hasMaterials(materialNames)) { - return; - } - + if (FluidRegistry.getFluid(outputMaterialName) == null) return; final FluidStack[] rest = new FluidStack[recipe.length / 2]; for (int i = 0, j = 0; i < recipe.length; i += 2, j++) { rest[j] = FluidRegistry.getFluidStack((String)recipe[i], (int)recipe[i + 1]); + if (rest[j] == null) return; } ev.addAlloyRecipe(outputMaterialName, outputAmount, rest); } - private boolean hasMaterials(final List materialNames) { - for (final String name : materialNames) { - if (!Materials.hasMaterial(name)) { - return false; - } + @SubscribeEvent + public void tableCasting(final TinkerRegisterEvent.TableCastingRegisterEvent event) { + restrictCasting(event); + } + + @SubscribeEvent + public void basinCasting(final TinkerRegisterEvent.BasinCastingRegisterEvent event) { + restrictCasting(event); + } + + private static void restrictCasting(final TinkerRegisterEvent event) { + final ContentPolicy policy = ContentPolicy.active(); + if (!policy.lowFantasy() || !(event.getRecipe() instanceof CastingRecipe)) return; + final ItemStack output = ((CastingRecipe) event.getRecipe()).getResult(); + if (!policy.allows(output)) { + event.setCanceled(true); + return; + } + if (output.isEmpty() || !(output.getItem() instanceof IToolPart)) return; + final IToolPart part = (IToolPart) output.getItem(); + final String name = part.getMaterialID(output); + final boolean modernMaterial = Materials.getMaterialsByMod(ModernMetals.MODID).stream() + .anyMatch(material -> name.equals(material.getName())); + if (modernMaterial && (!policy.allows(name, "pickaxe") + || part.hasUseForStat("bow") || part.hasUseForStat("bowstring"))) { + event.setCanceled(true); } - return true; } @SubscribeEvent @@ -184,9 +195,9 @@ public void registerMyAlloys(TinkersAlloyRecipeEvent ev) { ModContainer oldActive = Loader.instance().activeModContainer(); ModContainer newActive = Loader.instance().getIndexedModList().get(ModernMetals.MODID); Loader.instance().setActiveModContainer(newActive); - registerAlloy(ev, MaterialNames.GALVANIZED_STEEL, 2, new Object[] { com.mcmoddev.modernmetals.data.MaterialNames.STEEL, 1, com.mcmoddev.modernmetals.data.MaterialNames.ZINC, 1 }); - registerAlloy(ev, MaterialNames.NICHROME, 2, new Object[] { com.mcmoddev.modernmetals.data.MaterialNames.NICKEL, 1, MaterialNames.CHROMIUM, 1 }); - registerAlloy(ev, MaterialNames.STAINLESS_STEEL, 2, new Object[] { com.mcmoddev.modernmetals.data.MaterialNames.STEEL, 1, MaterialNames.CHROMIUM, 1 }); + registerAlloy(ev, MaterialNames.GALVANIZED_STEEL, 2, new Object[] { zone.moddev.mc.modernmetals.data.MaterialNames.STEEL, 1, zone.moddev.mc.modernmetals.data.MaterialNames.ZINC, 1 }); + registerAlloy(ev, MaterialNames.NICHROME, 2, new Object[] { zone.moddev.mc.modernmetals.data.MaterialNames.NICKEL, 1, MaterialNames.CHROMIUM, 1 }); + registerAlloy(ev, MaterialNames.STAINLESS_STEEL, 2, new Object[] { zone.moddev.mc.modernmetals.data.MaterialNames.STEEL, 1, MaterialNames.CHROMIUM, 1 }); registerAlloy(ev, MaterialNames.TITANIUM, 2, new Object[] { MaterialNames.RUTILE, 1, MaterialNames.MAGNESIUM, 1 }); Loader.instance().setActiveModContainer(oldActive); } diff --git a/src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeVeinMiner.java b/src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeVeinMiner.java similarity index 89% rename from src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeVeinMiner.java rename to src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeVeinMiner.java index 9001c153..1f620bdd 100644 --- a/src/main/java/com/mcmoddev/modernmetals/integration/plugins/MMeVeinMiner.java +++ b/src/main/java/zone/moddev/mc/modernmetals/integration/plugins/MMeVeinMiner.java @@ -1,4 +1,4 @@ -package com.mcmoddev.modernmetals.integration.plugins; +package zone.moddev.mc.modernmetals.integration.plugins; import java.util.Arrays; import java.util.List; @@ -8,8 +8,8 @@ import com.mcmoddev.lib.integration.MMDPlugin; import com.mcmoddev.lib.integration.plugins.VeinMiner; import com.mcmoddev.lib.util.Config.Options; -import com.mcmoddev.modernmetals.ModernMetals; -import com.mcmoddev.modernmetals.data.MaterialNames; +import zone.moddev.mc.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.data.MaterialNames; /** * VeinMiner Integration Plugin. diff --git a/src/main/java/com/mcmoddev/modernmetals/proxy/ClientProxy.java b/src/main/java/zone/moddev/mc/modernmetals/proxy/ClientProxy.java similarity index 66% rename from src/main/java/com/mcmoddev/modernmetals/proxy/ClientProxy.java rename to src/main/java/zone/moddev/mc/modernmetals/proxy/ClientProxy.java index cd4468ae..5416d17b 100644 --- a/src/main/java/com/mcmoddev/modernmetals/proxy/ClientProxy.java +++ b/src/main/java/zone/moddev/mc/modernmetals/proxy/ClientProxy.java @@ -1,12 +1,16 @@ -package com.mcmoddev.modernmetals.proxy; +package zone.moddev.mc.modernmetals.proxy; import com.mcmoddev.lib.client.registrations.RegistrationHelper; import com.mcmoddev.lib.material.MMDMaterial; -import com.mcmoddev.modernmetals.init.Blocks; -import com.mcmoddev.modernmetals.init.Fluids; -import com.mcmoddev.modernmetals.init.Items; +import zone.moddev.mc.modernmetals.init.Blocks; +import zone.moddev.mc.modernmetals.init.Fluids; +import zone.moddev.mc.modernmetals.init.Items; import net.minecraftforge.client.event.ModelRegistryEvent; +import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import zone.moddev.mc.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.client.ModernMetalsConfigScreen; +import zone.moddev.mc.orespawn.api.client.WorldSettingsExtensionRegistry; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; @@ -27,6 +31,12 @@ public void preInit(final FMLPreInitializationEvent event) { MinecraftForge.EVENT_BUS.register(this); } + @Override + public void init(final FMLInitializationEvent event) { + super.init(event); + WorldSettingsExtensionRegistry.registerConfigScreen(ModernMetals.MODID, ModernMetalsConfigScreen::new); + } + /** * * @param event The Event. diff --git a/src/main/java/zone/moddev/mc/modernmetals/proxy/CommonProxy.java b/src/main/java/zone/moddev/mc/modernmetals/proxy/CommonProxy.java new file mode 100644 index 00000000..6504d0b4 --- /dev/null +++ b/src/main/java/zone/moddev/mc/modernmetals/proxy/CommonProxy.java @@ -0,0 +1,50 @@ +package zone.moddev.mc.modernmetals.proxy; + + +import zone.moddev.mc.modernmetals.content.ContentModeNetwork; +import zone.moddev.mc.modernmetals.data.MaterialNames; +import zone.moddev.mc.modernmetals.init.ItemGroups; +import zone.moddev.mc.modernmetals.init.VillagerTrades; +import zone.moddev.mc.modernmetals.util.MMeConfig; + +import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; +import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; + +/** + * Modern Metals Common Proxy. + * + * @author Jasmine Iwanek + * + */ +public class CommonProxy { + + /** + * + * @param event The Event. + */ + @SuppressWarnings("deprecation") + public void preInit(final FMLPreInitializationEvent event) { + + ContentModeNetwork.register(); + if (MMeConfig.villagerTradesEnabled()) { + VillagerTrades.init(); + } + } + + /** + * + * @param event The Event. + */ + public void init(final FMLInitializationEvent event) { + ItemGroups.setupIcons(MaterialNames.ALUMINUM); + } + + /** + * + * @param event The Event. + */ + public void postInit(FMLPostInitializationEvent event) { + MMeConfig.postInit(); + } +} diff --git a/src/main/java/com/mcmoddev/modernmetals/proxy/ServerProxy.java b/src/main/java/zone/moddev/mc/modernmetals/proxy/ServerProxy.java similarity index 77% rename from src/main/java/com/mcmoddev/modernmetals/proxy/ServerProxy.java rename to src/main/java/zone/moddev/mc/modernmetals/proxy/ServerProxy.java index a8052827..1e68b620 100644 --- a/src/main/java/com/mcmoddev/modernmetals/proxy/ServerProxy.java +++ b/src/main/java/zone/moddev/mc/modernmetals/proxy/ServerProxy.java @@ -1,4 +1,4 @@ -package com.mcmoddev.modernmetals.proxy; +package zone.moddev.mc.modernmetals.proxy; /** * Modern Metals Server Proxy. diff --git a/src/main/java/com/mcmoddev/modernmetals/util/EventHandler.java b/src/main/java/zone/moddev/mc/modernmetals/util/EventHandler.java similarity index 82% rename from src/main/java/com/mcmoddev/modernmetals/util/EventHandler.java rename to src/main/java/zone/moddev/mc/modernmetals/util/EventHandler.java index c7b7bc39..b9738deb 100644 --- a/src/main/java/com/mcmoddev/modernmetals/util/EventHandler.java +++ b/src/main/java/zone/moddev/mc/modernmetals/util/EventHandler.java @@ -1,69 +1,69 @@ -package com.mcmoddev.modernmetals.util; - -import com.mcmoddev.modernmetals.init.Blocks; -import com.mcmoddev.modernmetals.init.Fluids; -import com.mcmoddev.modernmetals.init.Items; -import com.mcmoddev.modernmetals.init.Materials; -import com.mcmoddev.lib.events.MMDLibRegisterBlocks; -import com.mcmoddev.lib.events.MMDLibRegisterFluids; -import com.mcmoddev.lib.events.MMDLibRegisterItems; -import com.mcmoddev.lib.events.MMDLibRegisterMaterials; - -import com.mcmoddev.modernmetals.ModernMetals; - -import net.minecraft.block.Block; -import net.minecraft.item.Item; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.common.Mod.EventBusSubscriber; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; - -@EventBusSubscriber(modid=ModernMetals.MODID) -public class EventHandler { - - @SubscribeEvent - public static void mmdlibRegisterMaterials(final MMDLibRegisterMaterials event) { - Materials.init(); - } - - @SubscribeEvent - public static void mmdlibRegisterBlocks(final MMDLibRegisterBlocks event) { - Blocks.init(); - } - - @SubscribeEvent - public static void mmdlibRegisterItems(final MMDLibRegisterItems event) { - Items.init(); - } - - @SubscribeEvent - public static void mmdlibRegisterFluids(final MMDLibRegisterFluids event) { - Fluids.init(); - } - - /** - * - * @param event The Event. - */ - @SubscribeEvent - public static void onRemapBlock(final RegistryEvent.MissingMappings event) { - for (final RegistryEvent.MissingMappings.Mapping mapping : event.getAllMappings()) { - if (mapping.key.getNamespace().equals(ModernMetals.MODID)) { - // dummy - } - } - } - - /** - * - * @param event The Event. - */ - @SubscribeEvent - public static void onRemapItem(final RegistryEvent.MissingMappings event) { - for (final RegistryEvent.MissingMappings.Mapping mapping : event.getAllMappings()) { - if (mapping.key.getNamespace().equals(ModernMetals.MODID)) { - // dummy - } - } - } - -} +package zone.moddev.mc.modernmetals.util; + +import zone.moddev.mc.modernmetals.init.Blocks; +import zone.moddev.mc.modernmetals.init.Fluids; +import zone.moddev.mc.modernmetals.init.Items; +import zone.moddev.mc.modernmetals.init.Materials; +import com.mcmoddev.lib.events.MMDLibRegisterBlocks; +import com.mcmoddev.lib.events.MMDLibRegisterFluids; +import com.mcmoddev.lib.events.MMDLibRegisterItems; +import com.mcmoddev.lib.events.MMDLibRegisterMaterials; + +import zone.moddev.mc.modernmetals.ModernMetals; + +import net.minecraft.block.Block; +import net.minecraft.item.Item; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +@EventBusSubscriber(modid=ModernMetals.MODID) +public class EventHandler { + + @SubscribeEvent + public static void mmdlibRegisterMaterials(final MMDLibRegisterMaterials event) { + Materials.init(); + } + + @SubscribeEvent + public static void mmdlibRegisterBlocks(final MMDLibRegisterBlocks event) { + Blocks.init(); + } + + @SubscribeEvent + public static void mmdlibRegisterItems(final MMDLibRegisterItems event) { + Items.init(); + } + + @SubscribeEvent + public static void mmdlibRegisterFluids(final MMDLibRegisterFluids event) { + Fluids.init(); + } + + /** + * + * @param event The Event. + */ + @SubscribeEvent + public static void onRemapBlock(final RegistryEvent.MissingMappings event) { + for (final RegistryEvent.MissingMappings.Mapping mapping : event.getAllMappings()) { + if (mapping.key.getNamespace().equals(ModernMetals.MODID)) { + // dummy + } + } + } + + /** + * + * @param event The Event. + */ + @SubscribeEvent + public static void onRemapItem(final RegistryEvent.MissingMappings event) { + for (final RegistryEvent.MissingMappings.Mapping mapping : event.getAllMappings()) { + if (mapping.key.getNamespace().equals(ModernMetals.MODID)) { + // dummy + } + } + } + +} diff --git a/src/main/java/com/mcmoddev/modernmetals/util/MMeConfig.java b/src/main/java/zone/moddev/mc/modernmetals/util/MMeConfig.java similarity index 54% rename from src/main/java/com/mcmoddev/modernmetals/util/MMeConfig.java rename to src/main/java/zone/moddev/mc/modernmetals/util/MMeConfig.java index 6a5c5680..925bbcc8 100644 --- a/src/main/java/com/mcmoddev/modernmetals/util/MMeConfig.java +++ b/src/main/java/zone/moddev/mc/modernmetals/util/MMeConfig.java @@ -1,15 +1,20 @@ -package com.mcmoddev.modernmetals.util; +package zone.moddev.mc.modernmetals.util; import com.mcmoddev.lib.registry.CrusherRecipeRegistry; import com.mcmoddev.lib.util.MaterialConfigOptions; -import com.mcmoddev.modernmetals.ModernMetals; -import com.mcmoddev.modernmetals.data.MaterialNames; +import zone.moddev.mc.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.data.MaterialNames; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.config.Configuration; import net.minecraftforge.fml.client.event.ConfigChangedEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import java.io.File; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import net.minecraftforge.common.config.Property; +import org.apache.commons.lang3.text.WordUtils; /** * @author Jasmine Iwanek @@ -17,7 +22,9 @@ */ public class MMeConfig extends com.mcmoddev.lib.util.Config { - private static Configuration configuration; + public static final List MATERIAL_CATEGORIES = Collections.unmodifiableList( + Arrays.asList("Metals", "Fluids", "Forced Traits")); + private static Configuration configuration; private static final String CONFIG_FILE = "config/ModernMetals.cfg"; private static final MaterialConfigOptions[] MATERIAL_CONFIG_OPTIONS = new MaterialConfigOptions[]{ @@ -63,13 +70,50 @@ public static void init() { MinecraftForge.EVENT_BUS.register(new MMeConfig()); } - configMaterialOptions(MATERIAL_CONFIG_OPTIONS, configuration); + final Property mode = configuration.get("General", "contentMode", "high_fantasy", + "Applies when a compatible Base Metals build is absent. Restart after changing.", + new String[] { "high_fantasy", "low_fantasy" }); + mode.setLanguageKey("config.modernmetals.content_mode").setRequiresMcRestart(true); + mode.setValidValuesDisplay(new String[] { + "config.modernmetals.content_mode.high_fantasy", "config.modernmetals.content_mode.low_fantasy" }); + configuration.get("General", "enableVillagerTrades", true) + .setLanguageKey("config.modernmetals.villager_trades").setRequiresMcRestart(true); + configMaterialOptions(MATERIAL_CONFIG_OPTIONS, configuration); + for (final String category : MATERIAL_CATEGORIES) { + configuration.getCategory(category).setRequiresMcRestart(true); + } + for (final MaterialConfigOptions material : MATERIAL_CONFIG_OPTIONS) { + final String name = material.getIdentifier(); + final String suffix = WordUtils.capitalizeFully(name); + decorate("Metals", "Enable" + suffix, name); + decorate("Fluids", "Enabled " + suffix, name); + decorate("Forced Traits", "Force" + suffix + "TraitRegistration", name); + } if (configuration.hasChanged()) { configuration.save(); } } + private static void decorate(final String category, final String key, final String material) { + final Property property = configuration.getCategory(category).get(key); + if (property != null) { + property.setLanguageKey("config.modernmetals.enable_" + material).setRequiresMcRestart(true); + } + } + + public static Configuration getConfiguration() { + return configuration; + } + + public static String configuredContentMode() { + return configuration.getCategory("General").get("contentMode").getString(); + } + + public static boolean villagerTradesEnabled() { + return configuration.getCategory("General").get("enableVillagerTrades").getBoolean(); + } + public static void postInit() { CrusherRecipeRegistry.getInstance().clearCache(); } diff --git a/src/main/java/zone/moddev/mc/modernmetals/worldgen/ModernMetalsWorldgenProvider.java b/src/main/java/zone/moddev/mc/modernmetals/worldgen/ModernMetalsWorldgenProvider.java new file mode 100644 index 00000000..90260f0a --- /dev/null +++ b/src/main/java/zone/moddev/mc/modernmetals/worldgen/ModernMetalsWorldgenProvider.java @@ -0,0 +1,85 @@ +package zone.moddev.mc.modernmetals.worldgen; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.function.Predicate; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.common.registry.ForgeRegistries; +import zone.moddev.mc.modernmetals.ModernMetals; +import zone.moddev.mc.orespawn.api.GeologyFamily; +import zone.moddev.mc.orespawn.api.OreDimensionSelector; +import zone.moddev.mc.orespawn.api.OrePattern; +import zone.moddev.mc.orespawn.api.OreSpawnApi; +import zone.moddev.mc.orespawn.api.WorldgenProvider; + +/** Native declarations only; OreSpawn resolves, bakes and executes generation. */ +public final class ModernMetalsWorldgenProvider { + private static final Ore[] ORES = { + new Ore("boron", 0, 31, 8D, 8, 8, true), + new Ore("thorium", 0, 31, 8D, 8, 4, true), + new Ore("beryllium", 0, 127, 20D, 5, 3, true), + new Ore("aluminum", 0, 95, 8D, 10, 8, true), + new Ore("cadmium", 0, 95, 8D, 4, 8, true), + new Ore("chromium", 0, 31, 3D, 2, 4, true), + new Ore("iridium", 0, 63, 5D, 6, 4, true), + new Ore("magnesium", 0, 95, 8D, 6, 4, true), + new Ore("manganese", 0, 63, 6D, 6, 4, true), + new Ore("osmium", 0, 95, 8D, 10, 4, true), + new Ore("plutonium", 0, 31, 4D, 2, 4, true), + new Ore("rutile", 0, 63, 6D, 6, 4, true), + new Ore("tantalum", 0, 63, 6D, 6, 4, true), + new Ore("tungsten", 0, 31, 6D, 4, 4, true), + new Ore("uranium", 0, 31, 6D, 2, 4, true), + new Ore("zirconium", 0, 63, 6D, 8, 4, true), + new Ore("titanium", 0, 63, 6D, 6, 4, false) + }; + private ModernMetalsWorldgenProvider() { } + public static void enqueue() { + build(ForgeRegistries.BLOCKS::containsKey).ifPresent(provider -> { + if (!OreSpawnApi.enqueue(provider)) throw new IllegalStateException("Modern Metals provider registered twice"); + }); + for (final Ore ore : ORES) { + final int minimum = ore.size - ore.variation; + if (minimum < 1 && ForgeRegistries.BLOCKS.containsKey(id("modernmetals", ore.name + "_ore"))) { + ModernMetals.logger.info("OreSpawn native quantity minimum for " + ore.name + + " is clamped from " + minimum + " to 1, matching the legacy importer"); + } + } + } + public static Optional build(final Predicate available) { + final List ores = new ArrayList<>(); + for (final Ore rule : ORES) { + final ResourceLocation block = id("modernmetals", rule.name + "_ore"); + if (!available.test(block)) continue; + final WorldgenProvider.OreDefinition.Builder ore = WorldgenProvider.OreDefinition + .builder(id("modernmetals", "legacy/" + rule.name + "_ore"), block) + .enabled(rule.enabled).nativeGeneration(false).retrogen(false) + .material(id("orespawn", rule.name)).output(block, 100D); + ore.dimensionSelector(OreDimensionSelector.ALL_EXCEPT_NETHER_AND_END, placement -> { + placement.yRange(rule.minY, rule.maxY).attempts(rule.frequency) + .quantityRange(Math.max(1, rule.size - rule.variation), Math.min(64, rule.size + rule.variation - 1)) + .pattern(OrePattern.DEFAULT).placementChannel(id("orespawn", "standard")) + .hostBlock(id("minecraft", "stone")).hostBlock(id("minecraft", "netherrack")) + .hostBlock(id("minecraft", "end_stone")); + for (final GeologyFamily family : GeologyFamily.values()) placement.hostFamily(family); + }); + ores.add(ore.build()); + } + if (ores.isEmpty()) return Optional.empty(); + final WorldgenProvider.Builder provider = WorldgenProvider.builder("modernmetals", 1); + ores.forEach(provider::ore); + return Optional.of(provider.build()); + } + private static ResourceLocation id(final String namespace, final String path) { return new ResourceLocation(namespace, path); } + private static final class Ore { + final String name; + final int minY, maxY, size, variation; + final double frequency; + final boolean enabled; + Ore(String name, int minY, int maxY, double frequency, int size, int variation, boolean enabled) { + this.name = name; this.minY = minY; this.maxY = maxY; this.frequency = frequency; + this.size = size; this.variation = variation; this.enabled = enabled; + } + } +} diff --git a/src/main/resources/META-INF/modernmetals-legacy-api.list b/src/main/resources/META-INF/modernmetals-legacy-api.list new file mode 100644 index 00000000..e7804639 --- /dev/null +++ b/src/main/resources/META-INF/modernmetals-legacy-api.list @@ -0,0 +1,24 @@ +data/MaterialNames +data/TraitNames +init/Blocks +init/Fluids +init/ItemGroups +init/Items +init/Materials +init/Recipes +init/VillagerTrades +integration/plugins/MMeConstructsArmory +integration/plugins/MMeDenseOres +integration/plugins/MMeEnderIO +integration/plugins/MMeIC2 +integration/plugins/MMeMekanism +integration/plugins/MMeThaumcraft +integration/plugins/MMeThermalExpansion +integration/plugins/MMeTinkersConstruct +integration/plugins/MMeVeinMiner +ModernMetals +proxy/ClientProxy +proxy/CommonProxy +proxy/ServerProxy +util/EventHandler +util/MMeConfig diff --git a/src/main/resources/assets/modernmetals/lang/de_DE.lang b/src/main/resources/assets/modernmetals/lang/de_DE.lang index 815157a6..1544ff4d 100644 --- a/src/main/resources/assets/modernmetals/lang/de_DE.lang +++ b/src/main/resources/assets/modernmetals/lang/de_DE.lang @@ -1313,4 +1313,40 @@ tile.modernmetals.zirconium_lever.name=Zirkonhebel tile.modernmetals.zirconium_pressure_plate.name=Zirkondruckplatte tile.modernmetals.zirconium_slab.name=Zirkonfliese tile.modernmetals.zirconium_stairs.name=Zirkontreppe -tile.modernmetals.zirconium_wall.name=Zirkonmauer \ No newline at end of file +tile.modernmetals.zirconium_wall.name=Zirkonmauer + +config.modernmetals.material.tooltip=Legt fest, ob die Blöcke, Gegenstände und Rezepte dieses Materials verfügbar sind. Ein Neustart ist nötig. +config.modernmetals.title=Modern Metals +config.modernmetals.description=Neustart erforderlich. Erze in OreSpawn einstellen. +config.modernmetals.content_mode=Fantasy-Stufe +config.modernmetals.content_mode.tooltip=Viel Fantasy behält alle Rezepte bei. Wenig Fantasy schränkt unrealistische Ausrüstung und Bauteile ein. Ein Neustart ist nötig. +high_fantasy=Viel Fantasy +low_fantasy=Wenig Fantasy +config.modernmetals.villager_trades=Dorfbewohnerhandel +config.modernmetals.villager_trades.tooltip=Schmiede handeln mit Barren und Ausrüstung aus Modern Metals. Ein Neustart ist nötig. +config.modernmetals.connection.mismatch=Der Server verwendet %s, dein Spiel verwendet %s. Gleiche die Fantasy-Stufe unter Mods > Modern Metals > Konfiguration an und starte das Spiel neu. +config.modernmetals.connection.protocol=Modern Metals konnte die Fantasy-Stufe nicht prüfen. Verwende auf dem Server und im Spiel denselben Build von Modern Metals. +config.modernmetals.enable_thorium=Thorium aktivieren +config.modernmetals.enable_boron=Bor aktivieren +config.modernmetals.enable_beryllium=Beryllium aktivieren +config.modernmetals.enable_cadmium=Cadmium aktivieren +config.modernmetals.enable_nichrome=Nickel-Chrom-Legierung aktivieren +config.modernmetals.enable_aluminum=Aluminium aktivieren +config.modernmetals.enable_aluminumbrass=Aluminiummessing aktivieren +config.modernmetals.enable_chromium=Chrom aktivieren +config.modernmetals.enable_galvanizedsteel=Verzinkter Stahl aktivieren +config.modernmetals.enable_iridium=Iridium aktivieren +config.modernmetals.enable_magnesium=Magnesium aktivieren +config.modernmetals.enable_manganese=Mangan aktivieren +config.modernmetals.enable_osmium=Osmium aktivieren +config.modernmetals.enable_plutonium=Plutonium aktivieren +config.modernmetals.enable_rutile=Rutil aktivieren +config.modernmetals.enable_stainlesssteel=Edelstahl aktivieren +config.modernmetals.enable_tantalum=Tantal aktivieren +config.modernmetals.enable_titanium=Titan aktivieren +config.modernmetals.enable_tungsten=Wolfram aktivieren +config.modernmetals.enable_uranium=Uran aktivieren +config.modernmetals.enable_zirconium=Zirkon aktivieren +config.modernmetals.content_mode.high_fantasy=Viel Fantasy +config.modernmetals.content_mode.low_fantasy=Wenig Fantasy +config.modernmetals.inherited_mode=Die Fantasiestufe wird in Base Metals eingestellt. Nach Änderungen das Spiel neu starten. diff --git a/src/main/resources/assets/modernmetals/lang/en_US.lang b/src/main/resources/assets/modernmetals/lang/en_US.lang index 5e6a7456..59070e88 100644 --- a/src/main/resources/assets/modernmetals/lang/en_US.lang +++ b/src/main/resources/assets/modernmetals/lang/en_US.lang @@ -1586,3 +1586,39 @@ gas.cleanGasTitanium=Clean Titanium Slurry gas.cleanGasTungsten=Clean Tungsten Slurry gas.cleanGasUranium=Clean Uranium Slurry gas.cleanGasZirconium=Clean Zirconium Slurry + +config.modernmetals.title=Modern Metals +config.modernmetals.description=Restart to apply changes. Edit ores in OreSpawn. +config.modernmetals.content_mode=Fantasy Level +config.modernmetals.content_mode.tooltip=High Fantasy keeps all recipes. Low Fantasy restricts unrealistic equipment and structures. Requires a game restart. +high_fantasy=High Fantasy +low_fantasy=Low Fantasy +config.modernmetals.enable_thorium=Enable Thorium +config.modernmetals.enable_boron=Enable Boron +config.modernmetals.enable_beryllium=Enable Beryllium +config.modernmetals.enable_cadmium=Enable Cadmium +config.modernmetals.enable_nichrome=Enable Nichrome +config.modernmetals.enable_aluminum=Enable Aluminum +config.modernmetals.enable_aluminumbrass=Enable Aluminum Brass +config.modernmetals.enable_chromium=Enable Chromium +config.modernmetals.enable_galvanizedsteel=Enable Galvanized Steel +config.modernmetals.enable_iridium=Enable Iridium +config.modernmetals.enable_magnesium=Enable Magnesium +config.modernmetals.enable_manganese=Enable Manganese +config.modernmetals.enable_osmium=Enable Osmium +config.modernmetals.enable_plutonium=Enable Plutonium +config.modernmetals.enable_rutile=Enable Rutile +config.modernmetals.enable_stainlesssteel=Enable Stainless Steel +config.modernmetals.enable_tantalum=Enable Tantalum +config.modernmetals.enable_titanium=Enable Titanium +config.modernmetals.enable_tungsten=Enable Tungsten +config.modernmetals.enable_uranium=Enable Uranium +config.modernmetals.enable_zirconium=Enable Zirconium +config.modernmetals.material.tooltip=Controls which blocks, items and recipes are available for this material. Requires a game restart. +config.modernmetals.villager_trades=Villager Trades +config.modernmetals.villager_trades.tooltip=Let blacksmiths trade Modern Metals ingots and equipment. Requires a game restart. +config.modernmetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in your mod settings and restart. +config.modernmetals.connection.protocol=Modern Metals could not check the Fantasy Level. Use the same Modern Metals build on the server and client. +config.modernmetals.content_mode.high_fantasy=High Fantasy +config.modernmetals.content_mode.low_fantasy=Low Fantasy +config.modernmetals.inherited_mode=Fantasy Level is set in Base Metals. Restart after changing settings. diff --git a/src/main/resources/assets/modernmetals/lang/en_au.lang b/src/main/resources/assets/modernmetals/lang/en_au.lang index 45a76929..aeaa5eda 100644 --- a/src/main/resources/assets/modernmetals/lang/en_au.lang +++ b/src/main/resources/assets/modernmetals/lang/en_au.lang @@ -1604,3 +1604,39 @@ gas.cleanGasPlatinum=Clean Platinum Slurry gas.cleanGasNickel=Clean Nickel Slurry gas.cleanGasStarsteel=Clean Star-Steel Slurry gas.cleanGasZinc=Clean Zinc Slurry + +config.modernmetals.title=Modern Metals +config.modernmetals.description=Restart to apply changes. Edit ores in OreSpawn. +config.modernmetals.content_mode=Fantasy Level +config.modernmetals.content_mode.tooltip=High Fantasy keeps all recipes. Low Fantasy restricts unrealistic equipment and structures. Requires a game restart. +high_fantasy=High Fantasy +low_fantasy=Low Fantasy +config.modernmetals.enable_thorium=Enable Thorium +config.modernmetals.enable_boron=Enable Boron +config.modernmetals.enable_beryllium=Enable Beryllium +config.modernmetals.enable_cadmium=Enable Cadmium +config.modernmetals.enable_nichrome=Enable Nichrome +config.modernmetals.enable_aluminum=Enable Aluminum +config.modernmetals.enable_aluminumbrass=Enable Aluminum Brass +config.modernmetals.enable_chromium=Enable Chromium +config.modernmetals.enable_galvanizedsteel=Enable Galvanized Steel +config.modernmetals.enable_iridium=Enable Iridium +config.modernmetals.enable_magnesium=Enable Magnesium +config.modernmetals.enable_manganese=Enable Manganese +config.modernmetals.enable_osmium=Enable Osmium +config.modernmetals.enable_plutonium=Enable Plutonium +config.modernmetals.enable_rutile=Enable Rutile +config.modernmetals.enable_stainlesssteel=Enable Stainless Steel +config.modernmetals.enable_tantalum=Enable Tantalum +config.modernmetals.enable_titanium=Enable Titanium +config.modernmetals.enable_tungsten=Enable Tungsten +config.modernmetals.enable_uranium=Enable Uranium +config.modernmetals.enable_zirconium=Enable Zirconium +config.modernmetals.material.tooltip=Controls which blocks, items and recipes are available for this material. Requires a game restart. +config.modernmetals.villager_trades=Villager Trades +config.modernmetals.villager_trades.tooltip=Let blacksmiths trade Modern Metals ingots and equipment. Requires a game restart. +config.modernmetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in your mod settings and restart. +config.modernmetals.connection.protocol=Modern Metals could not check the Fantasy Level. Use the same Modern Metals build on the server and client. +config.modernmetals.content_mode.high_fantasy=High Fantasy +config.modernmetals.content_mode.low_fantasy=Low Fantasy +config.modernmetals.inherited_mode=Fantasy Level is set in Base Metals. Restart after changing settings. diff --git a/src/main/resources/assets/modernmetals/lang/en_ca.lang b/src/main/resources/assets/modernmetals/lang/en_ca.lang index 45a76929..aeaa5eda 100644 --- a/src/main/resources/assets/modernmetals/lang/en_ca.lang +++ b/src/main/resources/assets/modernmetals/lang/en_ca.lang @@ -1604,3 +1604,39 @@ gas.cleanGasPlatinum=Clean Platinum Slurry gas.cleanGasNickel=Clean Nickel Slurry gas.cleanGasStarsteel=Clean Star-Steel Slurry gas.cleanGasZinc=Clean Zinc Slurry + +config.modernmetals.title=Modern Metals +config.modernmetals.description=Restart to apply changes. Edit ores in OreSpawn. +config.modernmetals.content_mode=Fantasy Level +config.modernmetals.content_mode.tooltip=High Fantasy keeps all recipes. Low Fantasy restricts unrealistic equipment and structures. Requires a game restart. +high_fantasy=High Fantasy +low_fantasy=Low Fantasy +config.modernmetals.enable_thorium=Enable Thorium +config.modernmetals.enable_boron=Enable Boron +config.modernmetals.enable_beryllium=Enable Beryllium +config.modernmetals.enable_cadmium=Enable Cadmium +config.modernmetals.enable_nichrome=Enable Nichrome +config.modernmetals.enable_aluminum=Enable Aluminum +config.modernmetals.enable_aluminumbrass=Enable Aluminum Brass +config.modernmetals.enable_chromium=Enable Chromium +config.modernmetals.enable_galvanizedsteel=Enable Galvanized Steel +config.modernmetals.enable_iridium=Enable Iridium +config.modernmetals.enable_magnesium=Enable Magnesium +config.modernmetals.enable_manganese=Enable Manganese +config.modernmetals.enable_osmium=Enable Osmium +config.modernmetals.enable_plutonium=Enable Plutonium +config.modernmetals.enable_rutile=Enable Rutile +config.modernmetals.enable_stainlesssteel=Enable Stainless Steel +config.modernmetals.enable_tantalum=Enable Tantalum +config.modernmetals.enable_titanium=Enable Titanium +config.modernmetals.enable_tungsten=Enable Tungsten +config.modernmetals.enable_uranium=Enable Uranium +config.modernmetals.enable_zirconium=Enable Zirconium +config.modernmetals.material.tooltip=Controls which blocks, items and recipes are available for this material. Requires a game restart. +config.modernmetals.villager_trades=Villager Trades +config.modernmetals.villager_trades.tooltip=Let blacksmiths trade Modern Metals ingots and equipment. Requires a game restart. +config.modernmetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in your mod settings and restart. +config.modernmetals.connection.protocol=Modern Metals could not check the Fantasy Level. Use the same Modern Metals build on the server and client. +config.modernmetals.content_mode.high_fantasy=High Fantasy +config.modernmetals.content_mode.low_fantasy=Low Fantasy +config.modernmetals.inherited_mode=Fantasy Level is set in Base Metals. Restart after changing settings. diff --git a/src/main/resources/assets/modernmetals/lang/en_gb.lang b/src/main/resources/assets/modernmetals/lang/en_gb.lang index 1618bbf8..8406d49c 100644 --- a/src/main/resources/assets/modernmetals/lang/en_gb.lang +++ b/src/main/resources/assets/modernmetals/lang/en_gb.lang @@ -1604,3 +1604,39 @@ gas.cleanGasPlatinum=Clean Platinum Slurry gas.cleanGasNickel=Clean Nickel Slurry gas.cleanGasStarsteel=Clean Star-Steel Slurry gas.cleanGasZinc=Clean Zinc Slurry + +config.modernmetals.title=Modern Metals +config.modernmetals.description=Restart to apply changes. Edit ores in OreSpawn. +config.modernmetals.content_mode=Fantasy Level +config.modernmetals.content_mode.tooltip=High Fantasy keeps all recipes. Low Fantasy restricts unrealistic equipment and structures. Requires a game restart. +high_fantasy=High Fantasy +low_fantasy=Low Fantasy +config.modernmetals.enable_thorium=Enable Thorium +config.modernmetals.enable_boron=Enable Boron +config.modernmetals.enable_beryllium=Enable Beryllium +config.modernmetals.enable_cadmium=Enable Cadmium +config.modernmetals.enable_nichrome=Enable Nichrome +config.modernmetals.enable_aluminum=Enable Aluminum +config.modernmetals.enable_aluminumbrass=Enable Aluminum Brass +config.modernmetals.enable_chromium=Enable Chromium +config.modernmetals.enable_galvanizedsteel=Enable Galvanized Steel +config.modernmetals.enable_iridium=Enable Iridium +config.modernmetals.enable_magnesium=Enable Magnesium +config.modernmetals.enable_manganese=Enable Manganese +config.modernmetals.enable_osmium=Enable Osmium +config.modernmetals.enable_plutonium=Enable Plutonium +config.modernmetals.enable_rutile=Enable Rutile +config.modernmetals.enable_stainlesssteel=Enable Stainless Steel +config.modernmetals.enable_tantalum=Enable Tantalum +config.modernmetals.enable_titanium=Enable Titanium +config.modernmetals.enable_tungsten=Enable Tungsten +config.modernmetals.enable_uranium=Enable Uranium +config.modernmetals.enable_zirconium=Enable Zirconium +config.modernmetals.material.tooltip=Controls which blocks, items and recipes are available for this material. Requires a game restart. +config.modernmetals.villager_trades=Villager Trades +config.modernmetals.villager_trades.tooltip=Let blacksmiths trade Modern Metals ingots and equipment. Requires a game restart. +config.modernmetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in your mod settings and restart. +config.modernmetals.connection.protocol=Modern Metals could not check the Fantasy Level. Use the same Modern Metals build on the server and client. +config.modernmetals.content_mode.high_fantasy=High Fantasy +config.modernmetals.content_mode.low_fantasy=Low Fantasy +config.modernmetals.inherited_mode=Fantasy Level is set in Base Metals. Restart after changing settings. diff --git a/src/main/resources/assets/modernmetals/lang/en_nz.lang b/src/main/resources/assets/modernmetals/lang/en_nz.lang index 45a76929..aeaa5eda 100644 --- a/src/main/resources/assets/modernmetals/lang/en_nz.lang +++ b/src/main/resources/assets/modernmetals/lang/en_nz.lang @@ -1604,3 +1604,39 @@ gas.cleanGasPlatinum=Clean Platinum Slurry gas.cleanGasNickel=Clean Nickel Slurry gas.cleanGasStarsteel=Clean Star-Steel Slurry gas.cleanGasZinc=Clean Zinc Slurry + +config.modernmetals.title=Modern Metals +config.modernmetals.description=Restart to apply changes. Edit ores in OreSpawn. +config.modernmetals.content_mode=Fantasy Level +config.modernmetals.content_mode.tooltip=High Fantasy keeps all recipes. Low Fantasy restricts unrealistic equipment and structures. Requires a game restart. +high_fantasy=High Fantasy +low_fantasy=Low Fantasy +config.modernmetals.enable_thorium=Enable Thorium +config.modernmetals.enable_boron=Enable Boron +config.modernmetals.enable_beryllium=Enable Beryllium +config.modernmetals.enable_cadmium=Enable Cadmium +config.modernmetals.enable_nichrome=Enable Nichrome +config.modernmetals.enable_aluminum=Enable Aluminum +config.modernmetals.enable_aluminumbrass=Enable Aluminum Brass +config.modernmetals.enable_chromium=Enable Chromium +config.modernmetals.enable_galvanizedsteel=Enable Galvanized Steel +config.modernmetals.enable_iridium=Enable Iridium +config.modernmetals.enable_magnesium=Enable Magnesium +config.modernmetals.enable_manganese=Enable Manganese +config.modernmetals.enable_osmium=Enable Osmium +config.modernmetals.enable_plutonium=Enable Plutonium +config.modernmetals.enable_rutile=Enable Rutile +config.modernmetals.enable_stainlesssteel=Enable Stainless Steel +config.modernmetals.enable_tantalum=Enable Tantalum +config.modernmetals.enable_titanium=Enable Titanium +config.modernmetals.enable_tungsten=Enable Tungsten +config.modernmetals.enable_uranium=Enable Uranium +config.modernmetals.enable_zirconium=Enable Zirconium +config.modernmetals.material.tooltip=Controls which blocks, items and recipes are available for this material. Requires a game restart. +config.modernmetals.villager_trades=Villager Trades +config.modernmetals.villager_trades.tooltip=Let blacksmiths trade Modern Metals ingots and equipment. Requires a game restart. +config.modernmetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in your mod settings and restart. +config.modernmetals.connection.protocol=Modern Metals could not check the Fantasy Level. Use the same Modern Metals build on the server and client. +config.modernmetals.content_mode.high_fantasy=High Fantasy +config.modernmetals.content_mode.low_fantasy=Low Fantasy +config.modernmetals.inherited_mode=Fantasy Level is set in Base Metals. Restart after changing settings. diff --git a/src/main/resources/assets/modernmetals/lang/en_pt.lang b/src/main/resources/assets/modernmetals/lang/en_pt.lang index 00e5cba2..72e6cda2 100644 --- a/src/main/resources/assets/modernmetals/lang/en_pt.lang +++ b/src/main/resources/assets/modernmetals/lang/en_pt.lang @@ -1604,3 +1604,39 @@ gas.cleanGasPlatinum=Clean Platinum Slurry gas.cleanGasNickel=Clean Nickel Slurry gas.cleanGasStarsteel=Clean Star-Steel Slurry gas.cleanGasZinc=Clean Zinc Slurry + +config.modernmetals.title=Modern Metals +config.modernmetals.description=Restart to apply changes. Edit ores in OreSpawn. +config.modernmetals.content_mode=Fantasy Level +config.modernmetals.content_mode.tooltip=High Fantasy keeps all recipes. Low Fantasy restricts unrealistic equipment and structures. Requires a game restart. +high_fantasy=High Fantasy +low_fantasy=Low Fantasy +config.modernmetals.enable_thorium=Enable Thorium +config.modernmetals.enable_boron=Enable Boron +config.modernmetals.enable_beryllium=Enable Beryllium +config.modernmetals.enable_cadmium=Enable Cadmium +config.modernmetals.enable_nichrome=Enable Nichrome +config.modernmetals.enable_aluminum=Enable Aluminum +config.modernmetals.enable_aluminumbrass=Enable Aluminum Brass +config.modernmetals.enable_chromium=Enable Chromium +config.modernmetals.enable_galvanizedsteel=Enable Galvanized Steel +config.modernmetals.enable_iridium=Enable Iridium +config.modernmetals.enable_magnesium=Enable Magnesium +config.modernmetals.enable_manganese=Enable Manganese +config.modernmetals.enable_osmium=Enable Osmium +config.modernmetals.enable_plutonium=Enable Plutonium +config.modernmetals.enable_rutile=Enable Rutile +config.modernmetals.enable_stainlesssteel=Enable Stainless Steel +config.modernmetals.enable_tantalum=Enable Tantalum +config.modernmetals.enable_titanium=Enable Titanium +config.modernmetals.enable_tungsten=Enable Tungsten +config.modernmetals.enable_uranium=Enable Uranium +config.modernmetals.enable_zirconium=Enable Zirconium +config.modernmetals.material.tooltip=Controls which blocks, items and recipes are available for this material. Requires a game restart. +config.modernmetals.villager_trades=Villager Trades +config.modernmetals.villager_trades.tooltip=Let blacksmiths trade Modern Metals ingots and equipment. Requires a game restart. +config.modernmetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in your mod settings and restart. +config.modernmetals.connection.protocol=Modern Metals could not check the Fantasy Level. Use the same Modern Metals build on the server and client. +config.modernmetals.content_mode.high_fantasy=High Fantasy +config.modernmetals.content_mode.low_fantasy=Low Fantasy +config.modernmetals.inherited_mode=Fantasy Level is set in Base Metals. Restart after changing settings. diff --git a/src/main/resources/assets/modernmetals/lang/ru_RU.lang b/src/main/resources/assets/modernmetals/lang/ru_RU.lang index 281225a1..9afd2809 100644 --- a/src/main/resources/assets/modernmetals/lang/ru_RU.lang +++ b/src/main/resources/assets/modernmetals/lang/ru_RU.lang @@ -1511,3 +1511,39 @@ tile.modernmetals.thorium_pressure_plate.name=Thorium Pressure Plate tile.modernmetals.thorium_slab.name=Thorium Slab tile.modernmetals.thorium_stairs.name=Thorium Stairs tile.modernmetals.thorium_wall.name=Thorium Wall + +config.modernmetals.material.tooltip=Включает блоки, предметы и рецепты этого материала. Требуется перезапуск игры. +config.modernmetals.title=Modern Metals +config.modernmetals.description=Для применения нужен перезапуск. Руды настраиваются в OreSpawn. +config.modernmetals.content_mode=Уровень фэнтези +config.modernmetals.content_mode.tooltip=Высокий уровень сохраняет все рецепты. Низкий ограничивает нереалистичное снаряжение и строительные блоки. Требуется перезапуск игры. +high_fantasy=Высокий уровень фэнтези +low_fantasy=Низкий уровень фэнтези +config.modernmetals.villager_trades=Торговля с жителями +config.modernmetals.villager_trades.tooltip=Кузнецы могут торговать слитками и снаряжением Modern Metals. Требуется перезапуск игры. +config.modernmetals.connection.mismatch=Уровень на сервере — %s, в вашей игре — %s. Выберите тот же уровень в меню «Моды > Modern Metals > Настройки» и перезапустите игру. +config.modernmetals.connection.protocol=Не удалось проверить уровень фэнтези Modern Metals. Установите одну и ту же сборку Modern Metals на клиенте и сервере. +config.modernmetals.enable_thorium=Включить торий +config.modernmetals.enable_boron=Включить бор +config.modernmetals.enable_beryllium=Включить бериллий +config.modernmetals.enable_cadmium=Включить кадмий +config.modernmetals.enable_nichrome=Включить нихром +config.modernmetals.enable_aluminum=Включить алюминий +config.modernmetals.enable_aluminumbrass=Включить алюминиевую латунь +config.modernmetals.enable_chromium=Включить хром +config.modernmetals.enable_galvanizedsteel=Включить оцинкованную сталь +config.modernmetals.enable_iridium=Включить иридий +config.modernmetals.enable_magnesium=Включить магний +config.modernmetals.enable_manganese=Включить марганец +config.modernmetals.enable_osmium=Включить осмий +config.modernmetals.enable_plutonium=Включить плутоний +config.modernmetals.enable_rutile=Включить рутил +config.modernmetals.enable_stainlesssteel=Включить нержавеющую сталь +config.modernmetals.enable_tantalum=Включить тантал +config.modernmetals.enable_titanium=Включить титан +config.modernmetals.enable_tungsten=Включить вольфрам +config.modernmetals.enable_uranium=Включить уран +config.modernmetals.enable_zirconium=Включить цирконий +config.modernmetals.content_mode.high_fantasy=Высокий уровень фэнтези +config.modernmetals.content_mode.low_fantasy=Низкий уровень фэнтези +config.modernmetals.inherited_mode=Уровень фэнтези задаётся в Base Metals. Перезапустите игру после изменений. diff --git a/src/main/resources/assets/modernmetals/lang/zh_CN.lang b/src/main/resources/assets/modernmetals/lang/zh_CN.lang index 57e1b4f6..be30efe2 100644 --- a/src/main/resources/assets/modernmetals/lang/zh_CN.lang +++ b/src/main/resources/assets/modernmetals/lang/zh_CN.lang @@ -1512,4 +1512,38 @@ tile.modernmetals.thorium_slab.name=钍台阶 tile.modernmetals.thorium_stairs.name=钍楼梯 tile.modernmetals.thorium_wall.name=钍墙 - +config.modernmetals.material.tooltip=控制是否启用此材料的方块、物品和配方。需要重启游戏。 +config.modernmetals.title=Modern Metals +config.modernmetals.description=重启游戏后应用更改。请在 OreSpawn 中设置矿石生成。 +config.modernmetals.content_mode=奇幻等级 +config.modernmetals.content_mode.tooltip=高奇幻保留全部配方。低奇幻限制不符合现实的装备和建筑部件。需要重启游戏。 +high_fantasy=高奇幻 +low_fantasy=低奇幻 +config.modernmetals.villager_trades=村民交易 +config.modernmetals.villager_trades.tooltip=允许铁匠交易 Modern Metals 的金属锭和装备。需要重启游戏。 +config.modernmetals.connection.mismatch=服务器使用%s,你的游戏使用%s。请在模组 > Modern Metals > 配置中选择与服务器一致的奇幻等级,然后重启游戏。 +config.modernmetals.connection.protocol=Modern Metals 无法核对奇幻等级。请在服务器和客户端使用相同构建版本的 Modern Metals。 +config.modernmetals.enable_thorium=启用钍 +config.modernmetals.enable_boron=启用硼 +config.modernmetals.enable_beryllium=启用铍 +config.modernmetals.enable_cadmium=启用镉 +config.modernmetals.enable_nichrome=启用镍铬合金 +config.modernmetals.enable_aluminum=启用铝 +config.modernmetals.enable_aluminumbrass=启用铝黄铜 +config.modernmetals.enable_chromium=启用铬 +config.modernmetals.enable_galvanizedsteel=启用镀锌钢 +config.modernmetals.enable_iridium=启用铱 +config.modernmetals.enable_magnesium=启用镁 +config.modernmetals.enable_manganese=启用锰 +config.modernmetals.enable_osmium=启用锇 +config.modernmetals.enable_plutonium=启用钚 +config.modernmetals.enable_rutile=启用金红石 +config.modernmetals.enable_stainlesssteel=启用不锈钢 +config.modernmetals.enable_tantalum=启用钽 +config.modernmetals.enable_titanium=启用钛 +config.modernmetals.enable_tungsten=启用钨 +config.modernmetals.enable_uranium=启用铀 +config.modernmetals.enable_zirconium=启用锆 +config.modernmetals.content_mode.high_fantasy=高奇幻 +config.modernmetals.content_mode.low_fantasy=低奇幻 +config.modernmetals.inherited_mode=幻想等级由 Base Metals 设置。更改设置后请重新启动游戏。 diff --git a/src/main/resources/assets/modernmetals/models/block/aluminum_ore.json b/src/main/resources/assets/modernmetals/models/block/aluminum_ore.json deleted file mode 100644 index 4616b535..00000000 --- a/src/main/resources/assets/modernmetals/models/block/aluminum_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/aluminum_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/aluminum_plate.json b/src/main/resources/assets/modernmetals/models/block/aluminum_plate.json index 47e435b1..ea91a282 100644 --- a/src/main/resources/assets/modernmetals/models/block/aluminum_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/aluminum_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/aluminum_plate", "side": "modernmetals:blocks/aluminum_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/aluminumbrass_ore.json b/src/main/resources/assets/modernmetals/models/block/aluminumbrass_ore.json deleted file mode 100644 index ed015015..00000000 --- a/src/main/resources/assets/modernmetals/models/block/aluminumbrass_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/aluminumbrass_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/aluminumbrass_plate.json b/src/main/resources/assets/modernmetals/models/block/aluminumbrass_plate.json index 681ab3c1..3dd5912a 100644 --- a/src/main/resources/assets/modernmetals/models/block/aluminumbrass_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/aluminumbrass_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/aluminumbrass_plate", "side": "modernmetals:blocks/aluminumbrass_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/beryllium_ore.json b/src/main/resources/assets/modernmetals/models/block/beryllium_ore.json deleted file mode 100644 index 6e531aa2..00000000 --- a/src/main/resources/assets/modernmetals/models/block/beryllium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/beryllium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/beryllium_plate.json b/src/main/resources/assets/modernmetals/models/block/beryllium_plate.json index 64fd0908..b0107a3f 100644 --- a/src/main/resources/assets/modernmetals/models/block/beryllium_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/beryllium_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/beryllium_plate", "side": "modernmetals:blocks/beryllium_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/boron_ore.json b/src/main/resources/assets/modernmetals/models/block/boron_ore.json deleted file mode 100644 index 13dfb423..00000000 --- a/src/main/resources/assets/modernmetals/models/block/boron_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/boron_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/boron_plate.json b/src/main/resources/assets/modernmetals/models/block/boron_plate.json index 52ef6b24..bf915982 100644 --- a/src/main/resources/assets/modernmetals/models/block/boron_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/boron_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/boron_plate", "side": "modernmetals:blocks/boron_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/cadmium_ore.json b/src/main/resources/assets/modernmetals/models/block/cadmium_ore.json deleted file mode 100644 index cf3636e0..00000000 --- a/src/main/resources/assets/modernmetals/models/block/cadmium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/cadmium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/cadmium_plate.json b/src/main/resources/assets/modernmetals/models/block/cadmium_plate.json index 773edbe1..2195e396 100644 --- a/src/main/resources/assets/modernmetals/models/block/cadmium_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/cadmium_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/cadmium_plate", "side": "modernmetals:blocks/cadmium_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/chromium_ore.json b/src/main/resources/assets/modernmetals/models/block/chromium_ore.json deleted file mode 100644 index f867a0b3..00000000 --- a/src/main/resources/assets/modernmetals/models/block/chromium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/chromium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/chromium_plate.json b/src/main/resources/assets/modernmetals/models/block/chromium_plate.json index 993dcf27..1f85aaf3 100644 --- a/src/main/resources/assets/modernmetals/models/block/chromium_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/chromium_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/chromium_plate", "side": "modernmetals:blocks/chromium_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/galvanizedsteel_ore.json b/src/main/resources/assets/modernmetals/models/block/galvanizedsteel_ore.json deleted file mode 100644 index f7e8487e..00000000 --- a/src/main/resources/assets/modernmetals/models/block/galvanizedsteel_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/galvanizedsteel_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/galvanizedsteel_plate.json b/src/main/resources/assets/modernmetals/models/block/galvanizedsteel_plate.json index 0e542f0c..76206966 100644 --- a/src/main/resources/assets/modernmetals/models/block/galvanizedsteel_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/galvanizedsteel_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/galvanizedsteel_plate", "side": "modernmetals:blocks/galvanizedsteel_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/iridium_ore.json b/src/main/resources/assets/modernmetals/models/block/iridium_ore.json deleted file mode 100644 index b3bd98cb..00000000 --- a/src/main/resources/assets/modernmetals/models/block/iridium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/iridium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/iridium_plate.json b/src/main/resources/assets/modernmetals/models/block/iridium_plate.json index 68582f0d..f9899b27 100644 --- a/src/main/resources/assets/modernmetals/models/block/iridium_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/iridium_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/iridium_plate", "side": "modernmetals:blocks/iridium_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/magnesium_ore.json b/src/main/resources/assets/modernmetals/models/block/magnesium_ore.json deleted file mode 100644 index 9f6fb257..00000000 --- a/src/main/resources/assets/modernmetals/models/block/magnesium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/magnesium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/magnesium_plate.json b/src/main/resources/assets/modernmetals/models/block/magnesium_plate.json index 09e617a1..daabb200 100644 --- a/src/main/resources/assets/modernmetals/models/block/magnesium_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/magnesium_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/magnesium_plate", "side": "modernmetals:blocks/magnesium_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/manganese_ore.json b/src/main/resources/assets/modernmetals/models/block/manganese_ore.json deleted file mode 100644 index 6c79d985..00000000 --- a/src/main/resources/assets/modernmetals/models/block/manganese_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/manganese_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/manganese_plate.json b/src/main/resources/assets/modernmetals/models/block/manganese_plate.json index 42c25245..821f8327 100644 --- a/src/main/resources/assets/modernmetals/models/block/manganese_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/manganese_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/manganese_plate", "side": "modernmetals:blocks/manganese_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/nichrome_ore.json b/src/main/resources/assets/modernmetals/models/block/nichrome_ore.json deleted file mode 100644 index 88f7cf51..00000000 --- a/src/main/resources/assets/modernmetals/models/block/nichrome_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/nichrome_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/nichrome_plate.json b/src/main/resources/assets/modernmetals/models/block/nichrome_plate.json index c5ec7e5e..1d07b3aa 100644 --- a/src/main/resources/assets/modernmetals/models/block/nichrome_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/nichrome_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/nichrome_plate", "side": "modernmetals:blocks/nichrome_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/osmium_ore.json b/src/main/resources/assets/modernmetals/models/block/osmium_ore.json deleted file mode 100644 index 9aabe0d0..00000000 --- a/src/main/resources/assets/modernmetals/models/block/osmium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/osmium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/osmium_plate.json b/src/main/resources/assets/modernmetals/models/block/osmium_plate.json index 6fc22243..131f1cee 100644 --- a/src/main/resources/assets/modernmetals/models/block/osmium_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/osmium_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/osmium_plate", "side": "modernmetals:blocks/osmium_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/plate.json b/src/main/resources/assets/modernmetals/models/block/plate.json new file mode 100644 index 00000000..1c963d8c --- /dev/null +++ b/src/main/resources/assets/modernmetals/models/block/plate.json @@ -0,0 +1,50 @@ +{ + "textures": { + "particle": "#top" + }, + "elements": [ + { "from": [ 0, 0, 15 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 16, 1 ], "texture": "#side", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 1 ], "texture": "#side", "cullface": "up" }, + "west": { "uv": [15, 0, 16, 16 ], "texture": "#side", "cullface": "west" }, + "east": { "uv": [15, 0, 16, 16 ], "texture": "#side", "cullface": "east" }, + "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom", "cullface": "north"}, + "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" } + } + } + ], + "display": { + "gui": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 0.625, 0.625, 0.625 ] + }, + "ground": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 3, 0], + "scale":[ 0.25, 0.25, 0.25 ] + }, + "fixed": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 0.5, 0.5, 0.5 ] + }, + "thirdperson_righthand": { + "rotation": [ 75, 45, 0 ], + "translation": [ 0, 2.5, 0], + "scale": [ 0.375, 0.375, 0.375 ] + }, + "firstperson_righthand": { + "rotation": [ 0, 45, 0 ], + "translation": [ 0, 0, 0 ], + "scale": [ 0.40, 0.40, 0.40 ] + }, + "firstperson_lefthand": { + "rotation": [ 0, 225, 0 ], + "translation": [ 0, 0, 0 ], + "scale": [ 0.40, 0.40, 0.40 ] + } + } +} diff --git a/src/main/resources/assets/modernmetals/models/block/plutonium_ore.json b/src/main/resources/assets/modernmetals/models/block/plutonium_ore.json deleted file mode 100644 index 2e4233ea..00000000 --- a/src/main/resources/assets/modernmetals/models/block/plutonium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/plutonium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/plutonium_plate.json b/src/main/resources/assets/modernmetals/models/block/plutonium_plate.json index c26563c7..80b64346 100644 --- a/src/main/resources/assets/modernmetals/models/block/plutonium_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/plutonium_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/plutonium_plate", "side": "modernmetals:blocks/plutonium_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/rutile_ore.json b/src/main/resources/assets/modernmetals/models/block/rutile_ore.json deleted file mode 100644 index 29f9be6c..00000000 --- a/src/main/resources/assets/modernmetals/models/block/rutile_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/rutile_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/rutile_plate.json b/src/main/resources/assets/modernmetals/models/block/rutile_plate.json index 5eaac81d..2d635302 100644 --- a/src/main/resources/assets/modernmetals/models/block/rutile_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/rutile_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/rutile_plate", "side": "modernmetals:blocks/rutile_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/stainlesssteel_ore.json b/src/main/resources/assets/modernmetals/models/block/stainlesssteel_ore.json deleted file mode 100644 index e757848f..00000000 --- a/src/main/resources/assets/modernmetals/models/block/stainlesssteel_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/stainlesssteel_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/stainlesssteel_plate.json b/src/main/resources/assets/modernmetals/models/block/stainlesssteel_plate.json index 5e00dfa1..22855f67 100644 --- a/src/main/resources/assets/modernmetals/models/block/stainlesssteel_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/stainlesssteel_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/stainlesssteel_plate", "side": "modernmetals:blocks/stainlesssteel_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/tantalum_ore.json b/src/main/resources/assets/modernmetals/models/block/tantalum_ore.json deleted file mode 100644 index 4aae5e70..00000000 --- a/src/main/resources/assets/modernmetals/models/block/tantalum_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/tantalum_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/tantalum_plate.json b/src/main/resources/assets/modernmetals/models/block/tantalum_plate.json index 8351801c..cad8623e 100644 --- a/src/main/resources/assets/modernmetals/models/block/tantalum_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/tantalum_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/tantalum_plate", "side": "modernmetals:blocks/tantalum_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/thorium_plate.json b/src/main/resources/assets/modernmetals/models/block/thorium_plate.json index 533e429d..73eb98c8 100644 --- a/src/main/resources/assets/modernmetals/models/block/thorium_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/thorium_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/thorium_plate", "side": "modernmetals:blocks/thorium_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/titanium_ore.json b/src/main/resources/assets/modernmetals/models/block/titanium_ore.json deleted file mode 100644 index ddfbdce7..00000000 --- a/src/main/resources/assets/modernmetals/models/block/titanium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/titanium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/titanium_plate.json b/src/main/resources/assets/modernmetals/models/block/titanium_plate.json index c701e591..6e71e038 100644 --- a/src/main/resources/assets/modernmetals/models/block/titanium_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/titanium_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/titanium_plate", "side": "modernmetals:blocks/titanium_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/tungsten_ore.json b/src/main/resources/assets/modernmetals/models/block/tungsten_ore.json deleted file mode 100644 index 369e7432..00000000 --- a/src/main/resources/assets/modernmetals/models/block/tungsten_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/tungsten_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/tungsten_plate.json b/src/main/resources/assets/modernmetals/models/block/tungsten_plate.json index fd968bed..245a0889 100644 --- a/src/main/resources/assets/modernmetals/models/block/tungsten_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/tungsten_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/tungsten_plate", "side": "modernmetals:blocks/tungsten_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/uranium_ore.json b/src/main/resources/assets/modernmetals/models/block/uranium_ore.json deleted file mode 100644 index b0dadbef..00000000 --- a/src/main/resources/assets/modernmetals/models/block/uranium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/uranium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/uranium_plate.json b/src/main/resources/assets/modernmetals/models/block/uranium_plate.json index 86a0730d..c85823cf 100644 --- a/src/main/resources/assets/modernmetals/models/block/uranium_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/uranium_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/uranium_plate", "side": "modernmetals:blocks/uranium_plate", diff --git a/src/main/resources/assets/modernmetals/models/block/zirconium_ore.json b/src/main/resources/assets/modernmetals/models/block/zirconium_ore.json deleted file mode 100644 index c5835215..00000000 --- a/src/main/resources/assets/modernmetals/models/block/zirconium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/zirconium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/zirconium_plate.json b/src/main/resources/assets/modernmetals/models/block/zirconium_plate.json index 2f4b4803..7e0b7856 100644 --- a/src/main/resources/assets/modernmetals/models/block/zirconium_plate.json +++ b/src/main/resources/assets/modernmetals/models/block/zirconium_plate.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:block/plate", + "parent": "modernmetals:block/plate", "textures": { "top": "modernmetals:blocks/zirconium_plate", "side": "modernmetals:blocks/zirconium_plate", diff --git a/src/main/resources/assets/modernmetals/models/item/aluminum_door.json b/src/main/resources/assets/modernmetals/models/item/aluminum_door.json index b36cbcc3..bba6d84c 100644 --- a/src/main/resources/assets/modernmetals/models/item/aluminum_door.json +++ b/src/main/resources/assets/modernmetals/models/item/aluminum_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/aluminum_door_lower", "top": "modernmetals:blocks/aluminum_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/aluminum_door_item.json b/src/main/resources/assets/modernmetals/models/item/aluminum_door_item.json index b36cbcc3..bba6d84c 100644 --- a/src/main/resources/assets/modernmetals/models/item/aluminum_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/aluminum_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/aluminum_door_lower", "top": "modernmetals:blocks/aluminum_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/aluminumbrass_door.json b/src/main/resources/assets/modernmetals/models/item/aluminumbrass_door.json index fd42e5e5..8a7485b0 100644 --- a/src/main/resources/assets/modernmetals/models/item/aluminumbrass_door.json +++ b/src/main/resources/assets/modernmetals/models/item/aluminumbrass_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/aluminumbrass_door_lower", "top": "modernmetals:blocks/aluminumbrass_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/aluminumbrass_door_item.json b/src/main/resources/assets/modernmetals/models/item/aluminumbrass_door_item.json index fd42e5e5..8a7485b0 100644 --- a/src/main/resources/assets/modernmetals/models/item/aluminumbrass_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/aluminumbrass_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/aluminumbrass_door_lower", "top": "modernmetals:blocks/aluminumbrass_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/beryllium_door.json b/src/main/resources/assets/modernmetals/models/item/beryllium_door.json index 397b8262..322575b2 100644 --- a/src/main/resources/assets/modernmetals/models/item/beryllium_door.json +++ b/src/main/resources/assets/modernmetals/models/item/beryllium_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/beryllium_door_lower", "top": "modernmetals:blocks/beryllium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/beryllium_door_item.json b/src/main/resources/assets/modernmetals/models/item/beryllium_door_item.json index 397b8262..322575b2 100644 --- a/src/main/resources/assets/modernmetals/models/item/beryllium_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/beryllium_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/beryllium_door_lower", "top": "modernmetals:blocks/beryllium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/boron_door.json b/src/main/resources/assets/modernmetals/models/item/boron_door.json index 2401e22a..b68d2d42 100644 --- a/src/main/resources/assets/modernmetals/models/item/boron_door.json +++ b/src/main/resources/assets/modernmetals/models/item/boron_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/boron_door_lower", "top": "modernmetals:blocks/boron_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/boron_door_item.json b/src/main/resources/assets/modernmetals/models/item/boron_door_item.json index 2401e22a..b68d2d42 100644 --- a/src/main/resources/assets/modernmetals/models/item/boron_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/boron_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/boron_door_lower", "top": "modernmetals:blocks/boron_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/cadmium_door.json b/src/main/resources/assets/modernmetals/models/item/cadmium_door.json index 3680748e..b52b105f 100644 --- a/src/main/resources/assets/modernmetals/models/item/cadmium_door.json +++ b/src/main/resources/assets/modernmetals/models/item/cadmium_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/cadmium_door_lower", "top": "modernmetals:blocks/cadmium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/cadmium_door_item.json b/src/main/resources/assets/modernmetals/models/item/cadmium_door_item.json index 3680748e..b52b105f 100644 --- a/src/main/resources/assets/modernmetals/models/item/cadmium_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/cadmium_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/cadmium_door_lower", "top": "modernmetals:blocks/cadmium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/chromium_door.json b/src/main/resources/assets/modernmetals/models/item/chromium_door.json index 419b4c2c..ed62953a 100644 --- a/src/main/resources/assets/modernmetals/models/item/chromium_door.json +++ b/src/main/resources/assets/modernmetals/models/item/chromium_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/chromium_door_lower", "top": "modernmetals:blocks/chromium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/chromium_door_item.json b/src/main/resources/assets/modernmetals/models/item/chromium_door_item.json index 419b4c2c..ed62953a 100644 --- a/src/main/resources/assets/modernmetals/models/item/chromium_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/chromium_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/chromium_door_lower", "top": "modernmetals:blocks/chromium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/door_item.json b/src/main/resources/assets/modernmetals/models/item/door_item.json new file mode 100644 index 00000000..006e7ec3 --- /dev/null +++ b/src/main/resources/assets/modernmetals/models/item/door_item.json @@ -0,0 +1,57 @@ +{ + "ambientocclusion": false, + "elements": [ + { "from": [ 0, 0, 4 ], + "to": [ 1, 8, 12 ], + "faces": { + "down": { "uv": [ 13, 0, 16, 16 ], "texture": "#bottom" }, + "north": { "uv": [ 3, 0, 0, 16 ], "texture": "#bottom" }, + "south": { "uv": [ 0, 0, 3, 16 ], "texture": "#bottom" }, + "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom" }, + "east": { "uv": [ 16, 0, 0, 16 ], "texture": "#bottom" } + } + }, + { "from": [ 0, 8, 4 ], + "to": [ 1, 16, 12 ], + "faces": { + "up": { "uv": [ 13, 0, 16, 16 ], "texture": "#bottom"}, + "north": { "uv": [ 3, 0, 0, 16 ], "texture": "#top" }, + "south": { "uv": [ 0, 0, 3, 16 ], "texture": "#top" }, + "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, + "east": { "uv": [ 16, 0, 0, 16 ], "texture": "#top" } + } + } + ], + "display": { + "gui": { + "rotation": [ 0, 90, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 0.9, 0.9, 0.9 ] + }, + "ground": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 3, 0], + "scale":[ 0.25, 0.25, 0.25 ] + }, + "fixed": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 0.5, 0.5, 0.5 ] + }, + "thirdperson_righthand": { + "rotation": [ 75, 45, 0 ], + "translation": [ 0, 2.5, 0], + "scale": [ 0.5, 0.5, 0.5 ] + }, + "firstperson_righthand": { + "rotation": [ 0, 45, 0 ], + "translation": [ 0, 0, 0 ], + "scale": [ 0.40, 0.40, 0.40 ] + }, + "firstperson_lefthand": { + "rotation": [ 0, 225, 0 ], + "translation": [ 0, 0, 0 ], + "scale": [ 0.40, 0.40, 0.40 ] + } + } +} diff --git a/src/main/resources/assets/modernmetals/models/item/galvanizedsteel_door.json b/src/main/resources/assets/modernmetals/models/item/galvanizedsteel_door.json index 98b2e3cc..79eca706 100644 --- a/src/main/resources/assets/modernmetals/models/item/galvanizedsteel_door.json +++ b/src/main/resources/assets/modernmetals/models/item/galvanizedsteel_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/galvanizedsteel_door_lower", "top": "modernmetals:blocks/galvanizedsteel_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/galvanizedsteel_door_item.json b/src/main/resources/assets/modernmetals/models/item/galvanizedsteel_door_item.json index 98b2e3cc..79eca706 100644 --- a/src/main/resources/assets/modernmetals/models/item/galvanizedsteel_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/galvanizedsteel_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/galvanizedsteel_door_lower", "top": "modernmetals:blocks/galvanizedsteel_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/iridium_door.json b/src/main/resources/assets/modernmetals/models/item/iridium_door.json index 8fa62811..a3825527 100644 --- a/src/main/resources/assets/modernmetals/models/item/iridium_door.json +++ b/src/main/resources/assets/modernmetals/models/item/iridium_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/iridium_door_lower", "top": "modernmetals:blocks/iridium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/iridium_door_item.json b/src/main/resources/assets/modernmetals/models/item/iridium_door_item.json index 8fa62811..a3825527 100644 --- a/src/main/resources/assets/modernmetals/models/item/iridium_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/iridium_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/iridium_door_lower", "top": "modernmetals:blocks/iridium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/magnesium_door.json b/src/main/resources/assets/modernmetals/models/item/magnesium_door.json index 1f738a53..a9ab4bee 100644 --- a/src/main/resources/assets/modernmetals/models/item/magnesium_door.json +++ b/src/main/resources/assets/modernmetals/models/item/magnesium_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/magnesium_door_lower", "top": "modernmetals:blocks/magnesium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/magnesium_door_item.json b/src/main/resources/assets/modernmetals/models/item/magnesium_door_item.json index 1f738a53..a9ab4bee 100644 --- a/src/main/resources/assets/modernmetals/models/item/magnesium_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/magnesium_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/magnesium_door_lower", "top": "modernmetals:blocks/magnesium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/manganese_door.json b/src/main/resources/assets/modernmetals/models/item/manganese_door.json index 9cf555dc..a045787f 100644 --- a/src/main/resources/assets/modernmetals/models/item/manganese_door.json +++ b/src/main/resources/assets/modernmetals/models/item/manganese_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/manganese_door_lower", "top": "modernmetals:blocks/manganese_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/manganese_door_item.json b/src/main/resources/assets/modernmetals/models/item/manganese_door_item.json index 9cf555dc..a045787f 100644 --- a/src/main/resources/assets/modernmetals/models/item/manganese_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/manganese_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/manganese_door_lower", "top": "modernmetals:blocks/manganese_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/nichrome_door.json b/src/main/resources/assets/modernmetals/models/item/nichrome_door.json index 05152464..86f7819f 100644 --- a/src/main/resources/assets/modernmetals/models/item/nichrome_door.json +++ b/src/main/resources/assets/modernmetals/models/item/nichrome_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/nichrome_door_lower", "top": "modernmetals:blocks/nichrome_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/nichrome_door_item.json b/src/main/resources/assets/modernmetals/models/item/nichrome_door_item.json index 05152464..86f7819f 100644 --- a/src/main/resources/assets/modernmetals/models/item/nichrome_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/nichrome_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/nichrome_door_lower", "top": "modernmetals:blocks/nichrome_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/osmium_door.json b/src/main/resources/assets/modernmetals/models/item/osmium_door.json index cfceccb3..bed87dbe 100644 --- a/src/main/resources/assets/modernmetals/models/item/osmium_door.json +++ b/src/main/resources/assets/modernmetals/models/item/osmium_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/osmium_door_lower", "top": "modernmetals:blocks/osmium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/osmium_door_item.json b/src/main/resources/assets/modernmetals/models/item/osmium_door_item.json index cfceccb3..bed87dbe 100644 --- a/src/main/resources/assets/modernmetals/models/item/osmium_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/osmium_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/osmium_door_lower", "top": "modernmetals:blocks/osmium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/plutonium_door.json b/src/main/resources/assets/modernmetals/models/item/plutonium_door.json index 83522295..7081ec04 100644 --- a/src/main/resources/assets/modernmetals/models/item/plutonium_door.json +++ b/src/main/resources/assets/modernmetals/models/item/plutonium_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/plutonium_door_lower", "top": "modernmetals:blocks/plutonium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/plutonium_door_item.json b/src/main/resources/assets/modernmetals/models/item/plutonium_door_item.json index 83522295..7081ec04 100644 --- a/src/main/resources/assets/modernmetals/models/item/plutonium_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/plutonium_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/plutonium_door_lower", "top": "modernmetals:blocks/plutonium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/rutile_door.json b/src/main/resources/assets/modernmetals/models/item/rutile_door.json index bba02b7f..03b73c40 100644 --- a/src/main/resources/assets/modernmetals/models/item/rutile_door.json +++ b/src/main/resources/assets/modernmetals/models/item/rutile_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/rutile_door_lower", "top": "modernmetals:blocks/rutile_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/rutile_door_item.json b/src/main/resources/assets/modernmetals/models/item/rutile_door_item.json index bba02b7f..03b73c40 100644 --- a/src/main/resources/assets/modernmetals/models/item/rutile_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/rutile_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/rutile_door_lower", "top": "modernmetals:blocks/rutile_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/silicon_block.json b/src/main/resources/assets/modernmetals/models/item/silicon_block.json deleted file mode 100644 index 1f0d9839..00000000 --- a/src/main/resources/assets/modernmetals/models/item/silicon_block.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "modernmetals:block/silicon_block" -} diff --git a/src/main/resources/assets/modernmetals/models/item/silicon_door.json b/src/main/resources/assets/modernmetals/models/item/silicon_door.json index 7097f25d..13ea83fd 100644 --- a/src/main/resources/assets/modernmetals/models/item/silicon_door.json +++ b/src/main/resources/assets/modernmetals/models/item/silicon_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/silicon_door_lower", "top": "modernmetals:blocks/silicon_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/silicon_door_item.json b/src/main/resources/assets/modernmetals/models/item/silicon_door_item.json index 7097f25d..13ea83fd 100644 --- a/src/main/resources/assets/modernmetals/models/item/silicon_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/silicon_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/silicon_door_lower", "top": "modernmetals:blocks/silicon_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/silicon_ore.json b/src/main/resources/assets/modernmetals/models/item/silicon_ore.json deleted file mode 100644 index 4363ce12..00000000 --- a/src/main/resources/assets/modernmetals/models/item/silicon_ore.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "modernmetals:block/silicon_ore" -} diff --git a/src/main/resources/assets/modernmetals/models/item/silicon_plate.json b/src/main/resources/assets/modernmetals/models/item/silicon_plate.json deleted file mode 100644 index 1c3a557c..00000000 --- a/src/main/resources/assets/modernmetals/models/item/silicon_plate.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "modernmetals:block/silicon_plate" -} diff --git a/src/main/resources/assets/modernmetals/models/item/silicon_trapdoor.json b/src/main/resources/assets/modernmetals/models/item/silicon_trapdoor.json deleted file mode 100644 index b8a79f9a..00000000 --- a/src/main/resources/assets/modernmetals/models/item/silicon_trapdoor.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "modernmetals:block/silicon_trapdoor_bottom" -} diff --git a/src/main/resources/assets/modernmetals/models/item/stainlesssteel_door.json b/src/main/resources/assets/modernmetals/models/item/stainlesssteel_door.json index b562dd1d..95e1c66c 100644 --- a/src/main/resources/assets/modernmetals/models/item/stainlesssteel_door.json +++ b/src/main/resources/assets/modernmetals/models/item/stainlesssteel_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/stainlesssteel_door_lower", "top": "modernmetals:blocks/stainlesssteel_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/stainlesssteel_door_item.json b/src/main/resources/assets/modernmetals/models/item/stainlesssteel_door_item.json index b562dd1d..95e1c66c 100644 --- a/src/main/resources/assets/modernmetals/models/item/stainlesssteel_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/stainlesssteel_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/stainlesssteel_door_lower", "top": "modernmetals:blocks/stainlesssteel_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/tantalum_door.json b/src/main/resources/assets/modernmetals/models/item/tantalum_door.json index 77fc67c5..c558e79a 100644 --- a/src/main/resources/assets/modernmetals/models/item/tantalum_door.json +++ b/src/main/resources/assets/modernmetals/models/item/tantalum_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/tantalum_door_lower", "top": "modernmetals:blocks/tantalum_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/tantalum_door_item.json b/src/main/resources/assets/modernmetals/models/item/tantalum_door_item.json index 77fc67c5..c558e79a 100644 --- a/src/main/resources/assets/modernmetals/models/item/tantalum_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/tantalum_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/tantalum_door_lower", "top": "modernmetals:blocks/tantalum_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/thorium_door.json b/src/main/resources/assets/modernmetals/models/item/thorium_door.json index 057c6d8f..8088d428 100644 --- a/src/main/resources/assets/modernmetals/models/item/thorium_door.json +++ b/src/main/resources/assets/modernmetals/models/item/thorium_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/thorium_door_lower", "top": "modernmetals:blocks/thorium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/thorium_door_item.json b/src/main/resources/assets/modernmetals/models/item/thorium_door_item.json index 057c6d8f..8088d428 100644 --- a/src/main/resources/assets/modernmetals/models/item/thorium_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/thorium_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/thorium_door_lower", "top": "modernmetals:blocks/thorium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/titanium_door.json b/src/main/resources/assets/modernmetals/models/item/titanium_door.json index 6321c7e9..e0ee37ae 100644 --- a/src/main/resources/assets/modernmetals/models/item/titanium_door.json +++ b/src/main/resources/assets/modernmetals/models/item/titanium_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/titanium_door_lower", "top": "modernmetals:blocks/titanium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/titanium_door_item.json b/src/main/resources/assets/modernmetals/models/item/titanium_door_item.json index 6321c7e9..e0ee37ae 100644 --- a/src/main/resources/assets/modernmetals/models/item/titanium_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/titanium_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/titanium_door_lower", "top": "modernmetals:blocks/titanium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/tungsten_door.json b/src/main/resources/assets/modernmetals/models/item/tungsten_door.json index 86ee3692..17bf0e85 100644 --- a/src/main/resources/assets/modernmetals/models/item/tungsten_door.json +++ b/src/main/resources/assets/modernmetals/models/item/tungsten_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/tungsten_door_lower", "top": "modernmetals:blocks/tungsten_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/tungsten_door_item.json b/src/main/resources/assets/modernmetals/models/item/tungsten_door_item.json index 86ee3692..17bf0e85 100644 --- a/src/main/resources/assets/modernmetals/models/item/tungsten_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/tungsten_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/tungsten_door_lower", "top": "modernmetals:blocks/tungsten_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/uranium_door.json b/src/main/resources/assets/modernmetals/models/item/uranium_door.json index 3d8fef1c..63046cc7 100644 --- a/src/main/resources/assets/modernmetals/models/item/uranium_door.json +++ b/src/main/resources/assets/modernmetals/models/item/uranium_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/uranium_door_lower", "top": "modernmetals:blocks/uranium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/uranium_door_item.json b/src/main/resources/assets/modernmetals/models/item/uranium_door_item.json index 3d8fef1c..63046cc7 100644 --- a/src/main/resources/assets/modernmetals/models/item/uranium_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/uranium_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/uranium_door_lower", "top": "modernmetals:blocks/uranium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/zirconium_door.json b/src/main/resources/assets/modernmetals/models/item/zirconium_door.json index c30fa5b8..96a577b6 100644 --- a/src/main/resources/assets/modernmetals/models/item/zirconium_door.json +++ b/src/main/resources/assets/modernmetals/models/item/zirconium_door.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/zirconium_door_lower", "top": "modernmetals:blocks/zirconium_door_upper" diff --git a/src/main/resources/assets/modernmetals/models/item/zirconium_door_item.json b/src/main/resources/assets/modernmetals/models/item/zirconium_door_item.json index c30fa5b8..96a577b6 100644 --- a/src/main/resources/assets/modernmetals/models/item/zirconium_door_item.json +++ b/src/main/resources/assets/modernmetals/models/item/zirconium_door_item.json @@ -1,5 +1,5 @@ { - "parent": "basemetals:item/door_item", + "parent": "modernmetals:item/door_item", "textures": { "bottom": "modernmetals:blocks/zirconium_door_lower", "top": "modernmetals:blocks/zirconium_door_upper" diff --git a/src/main/resources/assets/modernmetals/recipes/nichrome_blend_base.json b/src/main/resources/assets/modernmetals/recipes/nichrome_blend_base.json index 8681ca21..36e6d654 100644 --- a/src/main/resources/assets/modernmetals/recipes/nichrome_blend_base.json +++ b/src/main/resources/assets/modernmetals/recipes/nichrome_blend_base.json @@ -7,7 +7,7 @@ }, { "type": "forge:ore_dict", - "ore": "dustChrome" + "ore": "dustChromium" } ], "conditions": [ @@ -27,7 +27,7 @@ { "type": "mmdlib:enabled", "optionName": "material", - "optionValue": "Chrome" + "optionValue": "Chromium" }, { "type": "mmdlib:enabled", diff --git a/src/main/resources/assets/modernmetals/recipes/stainlesssteel_blend_base.json b/src/main/resources/assets/modernmetals/recipes/stainlesssteel_blend_base.json index 1d841105..a35478e5 100644 --- a/src/main/resources/assets/modernmetals/recipes/stainlesssteel_blend_base.json +++ b/src/main/resources/assets/modernmetals/recipes/stainlesssteel_blend_base.json @@ -7,7 +7,7 @@ }, { "type": "forge:ore_dict", - "ore": "dustChrome" + "ore": "dustChromium" } ], "conditions": [ @@ -27,7 +27,7 @@ { "type": "mmdlib:enabled", "optionName": "material", - "optionValue": "Chrome" + "optionValue": "Chromium" }, { "type": "mmdlib:enabled", diff --git a/src/main/resources/assets/modernmetals/textures/blocks/aluminum_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/aluminum_ore.png deleted file mode 100644 index 12193a9a..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/aluminum_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/aluminumbrass_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/aluminumbrass_ore.png deleted file mode 100644 index ddd4fd57..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/aluminumbrass_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/beryllium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/beryllium_ore.png deleted file mode 100644 index 2a81a533..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/beryllium_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/boron_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/boron_ore.png deleted file mode 100644 index ef64118e..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/boron_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/cadmium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/cadmium_ore.png deleted file mode 100644 index f75396f1..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/cadmium_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/chromium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/chromium_ore.png deleted file mode 100644 index 8072e574..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/chromium_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/galvanizedsteel_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/galvanizedsteel_ore.png deleted file mode 100644 index 458b14d8..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/galvanizedsteel_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/iridium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/iridium_ore.png deleted file mode 100644 index ab0f84af..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/iridium_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/magnesium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/magnesium_ore.png deleted file mode 100644 index 3ef80a04..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/magnesium_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/manganese_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/manganese_ore.png deleted file mode 100644 index c70dc999..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/manganese_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/nichrome_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/nichrome_ore.png deleted file mode 100644 index c555d6ae..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/nichrome_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/aluminum_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/aluminum_ore.png new file mode 100644 index 00000000..6cdc2b42 Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/aluminum_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/aluminumbrass_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/aluminumbrass_ore.png new file mode 100644 index 00000000..6d280430 Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/aluminumbrass_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/beryllium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/beryllium_ore.png new file mode 100644 index 00000000..a7accaa8 Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/beryllium_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/boron_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/boron_ore.png new file mode 100644 index 00000000..e6665f3f Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/boron_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/cadmium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/cadmium_ore.png new file mode 100644 index 00000000..b12af2d7 Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/cadmium_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/chromium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/chromium_ore.png new file mode 100644 index 00000000..5b5db264 Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/chromium_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/galvanizedsteel_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/galvanizedsteel_ore.png new file mode 100644 index 00000000..afbbc42b Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/galvanizedsteel_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/iridium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/iridium_ore.png new file mode 100644 index 00000000..f33bce70 Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/iridium_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/magnesium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/magnesium_ore.png new file mode 100644 index 00000000..bba78399 Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/magnesium_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/manganese_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/manganese_ore.png new file mode 100644 index 00000000..c15b0575 Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/manganese_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/nichrome_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/nichrome_ore.png new file mode 100644 index 00000000..726c1eac Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/nichrome_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/osmium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/osmium_ore.png new file mode 100644 index 00000000..cf803c4a Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/osmium_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/plutonium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/plutonium_ore.png new file mode 100644 index 00000000..ab038d65 Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/plutonium_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/rutile_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/rutile_ore.png new file mode 100644 index 00000000..72639290 Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/rutile_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/stainlesssteel_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/stainlesssteel_ore.png new file mode 100644 index 00000000..7683080d Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/stainlesssteel_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/tantalum_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/tantalum_ore.png new file mode 100644 index 00000000..1767a2ed Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/tantalum_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/titanium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/titanium_ore.png new file mode 100644 index 00000000..5ed04a22 Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/titanium_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/tungsten_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/tungsten_ore.png new file mode 100644 index 00000000..cbe271a9 Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/tungsten_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/uranium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/uranium_ore.png new file mode 100644 index 00000000..7fe6c81a Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/uranium_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/zirconium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/zirconium_ore.png new file mode 100644 index 00000000..96854591 Binary files /dev/null and b/src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/zirconium_ore.png differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/osmium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/osmium_ore.png deleted file mode 100644 index aba5cd7a..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/osmium_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/plutonium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/plutonium_ore.png deleted file mode 100644 index e635e2b4..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/plutonium_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/rutile_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/rutile_ore.png deleted file mode 100644 index 77a70899..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/rutile_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/stainlesssteel_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/stainlesssteel_ore.png deleted file mode 100644 index 76c2a6a7..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/stainlesssteel_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/tantalum_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/tantalum_ore.png deleted file mode 100644 index 060dd1c5..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/tantalum_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/titanium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/titanium_ore.png deleted file mode 100644 index a4a3e31b..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/titanium_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/tungsten_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/tungsten_ore.png deleted file mode 100644 index 78a89a97..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/tungsten_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/uranium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/uranium_ore.png deleted file mode 100644 index 342ea9ce..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/uranium_ore.png and /dev/null differ diff --git a/src/main/resources/assets/modernmetals/textures/blocks/zirconium_ore.png b/src/main/resources/assets/modernmetals/textures/blocks/zirconium_ore.png deleted file mode 100644 index a56eb87f..00000000 Binary files a/src/main/resources/assets/modernmetals/textures/blocks/zirconium_ore.png and /dev/null differ diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta index b0f2ba20..6361a04d 100644 --- a/src/main/resources/pack.mcmeta +++ b/src/main/resources/pack.mcmeta @@ -1,6 +1,6 @@ { "pack":{ - "pack_format":2, + "pack_format":3, "description":"Modern Metals" } -} \ No newline at end of file +} diff --git a/tools/validation/legacy112/audit_resources.py b/tools/validation/legacy112/audit_resources.py new file mode 100644 index 00000000..6904171f --- /dev/null +++ b/tools/validation/legacy112/audit_resources.py @@ -0,0 +1,30 @@ +"""Parse the JSON resources shipped to Minecraft.""" +import json +import sys +from pathlib import Path + +root = Path(sys.argv[1]) +files = sorted(set(root.rglob("*.json")) | set(root.rglob("*.mcmeta")) | {root / "mcmod.info"}) +for file in files: + try: + json.loads(file.read_text(encoding="utf-8-sig")) + except (OSError, ValueError) as exc: + raise SystemExit(f"{file}: {exc}") from exc + +assets = root / "assets/modernmetals" +assert json.loads((root / "pack.mcmeta").read_text(encoding="utf-8"))["pack"]["pack_format"] == 3 +for file in sorted((assets / "models").rglob("*.json")): + model = json.loads(file.read_text(encoding="utf-8")) + parent = model.get("parent", "") + assert not parent.startswith("basemetals:"), f"{file}: requires the optional Base Metals mod" + if parent.startswith("modernmetals:"): + model_path = parent.split(":", 1)[1] + assert (assets / "models" / (model_path + ".json")).is_file(), (file, parent) + +for locale in ("de_de", "en_us", "ru_ru", "zh_cn"): + lang = (assets / "lang" / (locale + ".lang")).read_text(encoding="utf-8-sig") + keys = {line.split("=", 1)[0] for line in lang.splitlines() if "=" in line and not line.startswith("#")} + assert {"config.modernmetals.title", "config.modernmetals.inherited_mode", + "config.modernmetals.content_mode", "config.modernmetals.content_mode.high_fantasy", + "config.modernmetals.content_mode.low_fantasy"} <= keys, locale +print(f"Verified {len(files)} packaged JSON resources") diff --git a/src/main/resources/assets/modernmetals/orespawn/modernmetals.json b/tools/validation/legacy112/fixtures/orespawn3-modernmetals.json similarity index 99% rename from src/main/resources/assets/modernmetals/orespawn/modernmetals.json rename to tools/validation/legacy112/fixtures/orespawn3-modernmetals.json index 3dfbb82a..1a5d8712 100644 --- a/src/main/resources/assets/modernmetals/orespawn/modernmetals.json +++ b/tools/validation/legacy112/fixtures/orespawn3-modernmetals.json @@ -370,4 +370,4 @@ ] } } -} \ No newline at end of file +} diff --git a/tools/validation/legacy112/run_packaged_suite.py b/tools/validation/legacy112/run_packaged_suite.py new file mode 100644 index 00000000..88ded9fa --- /dev/null +++ b/tools/validation/legacy112/run_packaged_suite.py @@ -0,0 +1,161 @@ +"""Run the packaged mod on disposable Minecraft 1.12.2 servers.""" + +import argparse +import hashlib +import json +from pathlib import Path +import shutil +import subprocess +from zipfile import ZipFile + +from jsonschema.validators import validator_for +from referencing import Registry, Resource + + +def dependency(spec, mirror): + group, name, version = spec["coordinate"].split(":") + jar = mirror / group.replace(".", "/") / name / version / f"{name}-{version}.jar" + assert digest(jar).upper() == spec["sha256"], jar + return jar + + +def digest(path): + return hashlib.sha256(path.read_bytes()).hexdigest() + + +def write_config(directory, mod, mode, boron_disabled=False): + text = f"general {{\n S:contentMode={mode}_fantasy\n}}\n" + if boron_disabled: + text += "metals {\n B:EnableBoron=false\n}\n" + (directory / f"config/{mod}.cfg").write_text(text, encoding="utf-8") + + +def run(java, directory, phase, flags): + report = directory / "modernmetals-review.json" + assert not report.exists(), report + console = directory / f"{phase}-console.log" + with console.open("w", encoding="utf-8") as log: + process = subprocess.run( + [str(java), "-Xmx1200M", "-Dfml.queryResult=confirm", *flags, "-jar", + "forge-1.12.2-14.23.5.2859-universal.jar", "nogui"], + cwd=directory, stdin=subprocess.DEVNULL, stdout=log, stderr=subprocess.STDOUT, + timeout=150, check=False, + ) + assert process.returncode == 0 and report.is_file(), console + report.rename(directory / f"{phase}-review.json") + return json.loads((directory / f"{phase}-review.json").read_text(encoding="utf-8")) + + +def prepare(template, target, installed): + shutil.copytree(template / "libraries", target / "libraries") + for filename in ("forge-1.12.2-14.23.5.2859-universal.jar", "minecraft_server.1.12.2.jar"): + shutil.copy2(template / filename, target) + (target / "eula.txt").write_text("eula=true\n", encoding="utf-8") + (target / "server.properties").write_text( + "online-mode=false\nserver-ip=127.0.0.1\nserver-port=0\nmax-tick-time=-1\n" + "level-seed=6713525\nview-distance=3\n", encoding="utf-8", + ) + for folder in ("config", "mods"): + (target / folder).mkdir() + for jar in installed: + shutil.copy2(jar, target / "mods") + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + for arg in ("java", "template", "output", "mirror"): + parser.add_argument(f"--{arg}", type=Path, required=True) + args = parser.parse_args() + args.output.mkdir(parents=True) + specs = json.loads(Path("gradle/dependencies.json").read_text(encoding="utf-8")) + jars = {spec["id"]: dependency(spec, args.mirror) for spec in specs} + mod = Path("build/libs/ModernMetals-2.5.1.112021.jar") + probe = Path("build/test-mods/modernmetals-probe-packaged.jar") + with ZipFile(jars["orespawn"]) as archive: + schemas = [json.loads(archive.read(name)) for name in archive.namelist() + if name.startswith("META-INF/orespawn/docs/schemas/") and name.endswith(".json")] + registry = Registry().with_resources((schema["$id"], Resource.from_contents(schema)) for schema in schemas) + schema = next(schema for schema in schemas if schema["$id"].endswith("/orespawn-provider.schema.json")) + validator = validator_for(schema)(schema, registry=registry) + + fresh_provider = None + for name, local_low, inherited, boron_disabled, integrations in [ + ("standalone-high", False, False, False, ()), + ("standalone-low", True, False, True, ()), + ("inherit-base-low", False, True, False, ()), + ("tinkers-high", False, False, False, ("mantle", "tconstruct")), + ("tinkers-low", True, False, False, ("mantle", "tconstruct")), + ("titanium-opt-in", False, False, False, ()), + ("os3-import", False, False, False, ()), + ]: + target = args.output / name + installed = [jars["mmdlib"], jars["orespawn"], mod, probe] + installed.extend(jars[integration] for integration in integrations) + if inherited: + installed.append(jars["basemetals"]) + prepare(args.template, target, installed) + if inherited: + write_config(target, "BaseMetals", "low") + write_config(target, "ModernMetals", "low" if local_low else "high", boron_disabled) + + rule_id = "modernmetals:legacy/titanium_ore" + if name == "titanium-opt-in": + fresh_provider["ores"][rule_id]["enabled"] = True + override = target / "config/modernmetals-orespawn.json" + override.write_text(json.dumps(fresh_provider), encoding="utf-8") + source_path = override + elif name == "os3-import": + legacy = target / "config/orespawn3/modernmetals.json" + legacy.parent.mkdir() + original = Path("tools/validation/legacy112/fixtures/orespawn3-modernmetals.json") + settings = json.loads(original.read_text(encoding="utf-8")) + settings["spawns"]["aluminum_ore"]["parameters"].update( + size=5, variation=0, frequency=2.75, minHeight=10, maxHeight=50) + settings["spawns"]["thorium_ore"]["enabled"] = False + legacy.write_text(json.dumps(settings), encoding="utf-8") + source_path = legacy + else: + source_path = None + original = digest(source_path) if source_path else None + + flags = [f"-Dreview.low={str(local_low or inherited).lower()}", + f"-Dreview.inherited={str(inherited).lower()}", + f"-Dreview.boronDisabled={str(boron_disabled).lower()}", + f"-Dreview.titanium={str(name == 'titanium-opt-in').lower()}"] + first = run(args.java, target, "first", flags) + provider = first["provider"] + if name == "standalone-high": + fresh_provider = provider + validator.validate(provider) + rules = provider["ores"] + assert len(rules) == (16 if boron_disabled else 17), rules.keys() + assert not rules[rule_id]["enabled"] + assert all(not rule["retrogen"] for rule in rules.values()) + profile = first["profile"] + assert not profile.get("terrain_dimensions") + assert profile["ores"].get(rule_id, {}).get("enabled", False) == (name == "titanium-opt-in") + selector = "orespawn:all_except_nether_end" + if name == "titanium-opt-in": + assert (profile["ores"][rule_id]["dimension_selectors"][selector] + == profile["ores"]["modernmetals:legacy/rutile_ore"]["dimension_selectors"][selector]) + if name == "os3-import": + aluminum = profile["ores"]["modernmetals:legacy/aluminum_ore"]["dimension_selectors"][selector] + assert (aluminum["frequency"], aluminum["min_y"], aluminum["max_y"]) == (2.75, 10, 49), aluminum + assert not profile["ores"]["modernmetals:legacy/thorium_ore"]["enabled"] + group = profile["ore_material_groups"]["orespawn:aluminum"] + assert {"oreAluminum", "oreAluminium"} <= set(group["ore_dictionary_entries"]) + if name == "os3-import": + # The 1.12 importer keeps the ambiguous legacy Bauxite alias for review. + assert any(key.startswith("orespawn:review/") and "oreBauxite" in item["ore_dictionary_entries"] + for key, item in profile["ore_material_groups"].items()) + else: + assert "oreBauxite" in group["ore_dictionary_entries"] + assert run(args.java, target, "reload", flags) == first, name + if source_path: + assert digest(source_path) == original, source_path + print(f"{name} passed fresh world and reload", flush=True) + print(f"Packaged game SHA-256 {digest(mod)}") + + +if __name__ == "__main__": + main() diff --git a/tools/validation/legacy112/runtime-probe/review/modern/ClientChecks.java b/tools/validation/legacy112/runtime-probe/review/modern/ClientChecks.java new file mode 100644 index 00000000..b567e0a9 --- /dev/null +++ b/tools/validation/legacy112/runtime-probe/review/modern/ClientChecks.java @@ -0,0 +1,97 @@ +package review.modern; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Collections; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiMainMenu; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.resources.I18n; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.client.FMLClientHandler; +import net.minecraftforge.fml.client.IModGuiFactory; +import net.minecraftforge.fml.client.config.GuiConfig; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import net.minecraftforge.fml.common.registry.ForgeRegistries; +import zone.moddev.mc.modernmetals.content.ContentPolicy; + +public final class ClientChecks { + public static void install() { + MinecraftForge.EVENT_BUS.register(new ClientChecks()); + } + + private GuiScreen menu; + private GuiConfig screen; + private int phase; + + @SubscribeEvent + public void check(final TickEvent.ClientTickEvent event) throws Exception { + if (event.phase != TickEvent.Phase.END || phase == 3) return; + final Minecraft minecraft = Minecraft.getMinecraft(); + if (phase == 0 && minecraft.currentScreen instanceof GuiMainMenu) { + menu = minecraft.currentScreen; + final IModGuiFactory factory = FMLClientHandler.instance() + .getGuiFactoryFor(Loader.instance().getIndexedModList().get("modernmetals")); + require(factory != null && factory.hasConfigGui(), "Forge's Mods factory is missing"); + screen = (GuiConfig) factory.createConfigGui(menu); + minecraft.displayGuiScreen(screen); + phase++; + } else if (phase == 1) { + verifyScreen(screen, menu); + final Class directoryType = Class.forName("zone.moddev.mc.orespawn.client.OreSpawnModsScreen"); + final Constructor constructor = directoryType.getDeclaredConstructor(GuiScreen.class); + constructor.setAccessible(true); + final GuiScreen directory = (GuiScreen) constructor.newInstance(menu); + final Field entries = directoryType.getDeclaredField("entries"); + entries.setAccessible(true); + for (final Object entry : (Iterable) entries.get(directory)) { + final Field modId = entry.getClass().getDeclaredField("modId"); + modId.setAccessible(true); + if ("modernmetals".equals(modId.get(entry))) { + minecraft.displayGuiScreen(directory); + final Method open = directoryType.getDeclaredMethod("open", entry.getClass()); + open.setAccessible(true); + open.invoke(directory, entry); + require(minecraft.currentScreen instanceof GuiConfig, "OreSpawn did not open the config"); + screen = (GuiConfig) minecraft.currentScreen; + menu = directory; + phase++; + return; + } + } + throw new IllegalStateException("Modern Metals is absent from OreSpawn's Mods list"); + } else if (phase == 2) { + verifyScreen(screen, menu); + for (final String path : new String[] { "aluminum_plate", "boron_ore", "titanium_ore" }) { + final ResourceLocation id = new ResourceLocation("modernmetals", path); + require(minecraft.getBlockRendererDispatcher().getBlockModelShapes().getModelForState( + ForgeRegistries.BLOCKS.getValue(id).getDefaultState()) + != minecraft.getRenderItem().getItemModelMesher().getModelManager().getMissingModel(), + "Missing block model " + id); + } + Files.write(Paths.get("modernmetals-client-pass.txt"), + Collections.singleton("Forge and OreSpawn screens and three baked block models passed."), + StandardCharsets.UTF_8); + phase++; + minecraft.shutdown(); + } + } + + private static void verifyScreen(final GuiConfig screen, final GuiScreen parent) { + require(screen.parentScreen == parent && screen.allRequireMcRestart, "Wrong config parent or restart policy"); + require(I18n.hasKey("config.modernmetals.title"), "Missing localized title"); + final boolean hasMode = screen.configElements.stream().anyMatch(element -> "contentMode".equals(element.getName())); + require(hasMode != ContentPolicy.inheritsBaseMetals(), "Fantasy selector belongs to the wrong mod"); + } + + private static void require(final boolean passes, final String message) { + if (!passes) throw new IllegalStateException(message); + } +} diff --git a/tools/validation/legacy112/runtime-probe/review/modern/ModernMetalsProbe.java b/tools/validation/legacy112/runtime-probe/review/modern/ModernMetalsProbe.java new file mode 100644 index 00000000..d99f3f7e --- /dev/null +++ b/tools/validation/legacy112/runtime-probe/review/modern/ModernMetalsProbe.java @@ -0,0 +1,164 @@ +package review.modern; + +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.mcmoddev.lib.registry.CrusherRecipeRegistry; +import com.mcmoddev.lib.registry.recipe.ICrusherRecipe; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; +import java.util.stream.Collectors; +import net.minecraft.block.Block; +import net.minecraft.entity.passive.EntityPig; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.FurnaceRecipes; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.WorldServer; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidUtil; +import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import net.minecraftforge.fml.common.event.FMLServerStartedEvent; +import net.minecraftforge.fml.common.registry.ForgeRegistries; +import net.minecraftforge.oredict.OreDictionary; +import zone.moddev.mc.modernmetals.content.ContentPolicy; +import zone.moddev.mc.modernmetals.worldgen.ModernMetalsWorldgenProvider; +import zone.moddev.mc.orespawn.api.OreSpawnApi; + +@Mod(modid = "modernmetalsreview", version = "1", dependencies = "required-after:modernmetals") +public final class ModernMetalsProbe { + @Mod.EventHandler + public void clientInit(final FMLInitializationEvent event) { + if (event.getSide().isClient() && Boolean.getBoolean("review.client")) { + ClientChecks.install(); + } + } + + @Mod.EventHandler + public void verify(final FMLServerStartedEvent event) throws Exception { + final WorldServer world = FMLCommonHandler.instance().getMinecraftServerInstance().getWorld(0); + final boolean low = Boolean.getBoolean("review.low"); + require(ContentPolicy.active().lowFantasy() == low, "Wrong active Fantasy Level"); + require(ContentPolicy.inheritsBaseMetals() == Boolean.getBoolean("review.inherited"), + "Wrong Fantasy Level owner"); + if (Boolean.getBoolean("review.historical")) { + final String[] expected = { "boron_ore", "titanium_ore", "aluminum_plate" }; + for (int x = 0; x < expected.length; x++) { + final Block saved = world.getBlockState(new BlockPos(x, 180, 0)).getBlock(); + require(id(expected[x]).equals(saved.getRegistryName()), "Legacy block did not survive: " + expected[x]); + } + } + + final List ores = ForgeRegistries.BLOCKS.getValuesCollection().stream() + .filter(block -> block.getRegistryName() != null + && block.getRegistryName().getNamespace().equals("modernmetals") + && block.getRegistryName().getPath().endsWith("_ore")) + .collect(Collectors.toList()); + for (final Block ore : ores) { + final ResourceLocation id = ore.getRegistryName(); + final String name = id.getPath().replaceFirst("_ore$", ""); + final ICrusherRecipe recipe = CrusherRecipeRegistry.getRecipeForInputItem(new ItemStack(ore)); + require(recipe != null && !recipe.getOutput().isEmpty() + && recipe.getOutput().getItem().getRegistryName().equals(id(name + "_powder")), + "Shared crusher cannot resolve " + id); + } + + final boolean disabled = Boolean.getBoolean("review.boronDisabled"); + require(ForgeRegistries.BLOCKS.containsKey(id("boron_ore")) != disabled, "Boron toggle failed"); + for (final String name : new String[] { "beryllium", "thorium", "titanium" }) { + final Fluid fluid = FluidRegistry.getFluid(name); + require(fluid != null && fluid.getBlock() != null, "Missing molten " + name); + require(!FluidUtil.getFilledBucket(new FluidStack(fluid, 1000)).isEmpty(), "Missing " + name + " bucket"); + } + + final Block molten = ForgeRegistries.BLOCKS.getValue(id("titanium")); + final EntityPig pig = new EntityPig(world); + final BlockPos position = world.getSpawnPoint().up(3); + pig.setPosition(position.getX() + 0.5, position.getY(), position.getZ() + 0.5); + final float health = pig.getHealth(); + molten.onEntityCollision(world, position, molten.getDefaultState(), pig); + require(pig.getHealth() < health && pig.isBurning(), "Molten metal contact did not damage the entity"); + + for (final String recipe : new String[] { "plutonium_pickaxe", "uranium_sword", "rutile_axe", + "plutonium_fishingrod", "plutonium_horsearmor", "plutonium_pressureplate" }) { + final IRecipe entry = ForgeRegistries.RECIPES.getValue(id(recipe)); + require(entry != null && entry.getRecipeOutput().isEmpty() == low, "Wrong policy for " + recipe); + } + final IRecipe titanium = ForgeRegistries.RECIPES.getValue(id("titanium_blend_base")); + require(titanium != null && titanium.getRecipeOutput().getItem() == item("titanium_blend"), + "Titanium blend recipe missing"); + require(FurnaceRecipes.instance().getSmeltingResult(new ItemStack(item("titanium_blend"))).getItem() + == item("titanium_ingot"), "Titanium blend cannot be smelted"); + if (ContentPolicy.inheritsBaseMetals()) { + for (final String material : new String[] { "stainlesssteel", "nichrome" }) { + final IRecipe recipe = ForgeRegistries.RECIPES.getValue(id(material + "_blend_base")); + require(recipe != null && recipe.getIngredients().stream() + .allMatch(ingredient -> ingredient.getMatchingStacks().length > 0), + "Missing alloy ingredients for " + material); + require(FurnaceRecipes.instance().getSmeltingResult(new ItemStack(item(material + "_blend"))).getItem() + == item(material + "_ingot"), "Cannot smelt " + material); + } + } + if (Loader.isModLoaded("tconstruct")) { + TinkersChecks.verify(low); + } + for (final String alias : new String[] { "oreAluminum", "oreAluminium", "oreBauxite", "oreChrome" }) { + final Item ore = item(alias.equals("oreChrome") ? "chromium_ore" : "aluminum_ore"); + require(OreDictionary.getOres(alias).stream().anyMatch(stack -> stack.getItem() == ore), + "Missing ore alias " + alias); + } + + require(OreSpawnApi.isOreTakeoverActive("modernmetals"), "OreSpawn takeover is inactive"); + final JsonObject profile = OreSpawnApi.getActiveProfile(world.getMinecraftServer()).get().toJson(); + final Block titaniumOre = ForgeRegistries.BLOCKS.getValue(id("titanium_ore")); + final Block rutileOre = ForgeRegistries.BLOCKS.getValue(id("rutile_ore")); + final BlockPos.MutableBlockPos sample = new BlockPos.MutableBlockPos(); + final int centerX = world.getSpawnPoint().getX(); + final int centerZ = world.getSpawnPoint().getZ(); + int titaniumBlocks = 0; + int rutileBlocks = 0; + for (int x = centerX - 32; x < centerX + 32; x++) { + for (int z = centerZ - 32; z < centerZ + 32; z++) { + for (int y = 0; y <= 63; y++) { + final Block block = world.getBlockState(sample.setPos(x, y, z)).getBlock(); + if (block == titaniumOre) titaniumBlocks++; + if (block == rutileOre) rutileBlocks++; + } + } + } + require((titaniumBlocks > 0) == Boolean.getBoolean("review.titanium"), "Wrong titanium ore placement"); + require(rutileBlocks > 0, "Rutile ore did not generate"); + final JsonObject report = new JsonObject(); + report.addProperty("ore_count", ores.size()); + report.addProperty("titanium_blocks", titaniumBlocks); + report.addProperty("rutile_blocks", rutileBlocks); + report.addProperty("low_fantasy", low); + report.add("profile", profile); + report.add("provider", ModernMetalsWorldgenProvider.build(ForgeRegistries.BLOCKS::containsKey).get().toJson()); + Files.write(Paths.get("modernmetals-review.json"), new GsonBuilder().setPrettyPrinting().create() + .toJson(report).getBytes(StandardCharsets.UTF_8)); + world.getMinecraftServer().initiateShutdown(); + } + + private static Item item(final String path) { + final Item item = ForgeRegistries.ITEMS.getValue(id(path)); + require(item != null, "Missing " + path); + return item; + } + + private static ResourceLocation id(final String path) { + return new ResourceLocation("modernmetals", path); + } + + private static void require(final boolean passes, final String message) { + if (!passes) throw new IllegalStateException(message); + } +} diff --git a/tools/validation/legacy112/runtime-probe/review/modern/TinkersChecks.java b/tools/validation/legacy112/runtime-probe/review/modern/TinkersChecks.java new file mode 100644 index 00000000..8ddd5954 --- /dev/null +++ b/tools/validation/legacy112/runtime-probe/review/modern/TinkersChecks.java @@ -0,0 +1,42 @@ +package review.modern; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fml.common.registry.ForgeRegistries; +import slimeknights.tconstruct.library.TinkerRegistry; +import slimeknights.tconstruct.library.materials.Material; +import slimeknights.tconstruct.library.smeltery.CastingRecipe; +import slimeknights.tconstruct.library.tools.IToolPart; + +final class TinkersChecks { + static void verify(final boolean low) { + final Fluid titanium = FluidRegistry.getFluid("titanium"); + final Material material = TinkerRegistry.getMaterial("titanium"); + require(material != Material.UNKNOWN && material.getFluid() == titanium, "Titanium tool material is missing"); + final ItemStack ingot = new ItemStack(ForgeRegistries.ITEMS.getValue( + new ResourceLocation("modernmetals", "titanium_ingot"))); + require(TinkerRegistry.getMelting(ingot) != null, "Titanium ingot cannot be melted"); + require(TinkerRegistry.getAlloys().stream().anyMatch(alloy -> + alloy.getResult().getFluid() == titanium && alloy.getFluids().size() == 2 + && alloy.getFluids().stream().anyMatch(fluid -> "rutile".equals(fluid.getFluid().getName())) + && alloy.getFluids().stream().anyMatch(fluid -> "magnesium".equals(fluid.getFluid().getName()))), + "Missing titanium smeltery alloy"); + require(TinkerRegistry.getAllTableCastingRecipes().stream().filter(CastingRecipe.class::isInstance) + .map(CastingRecipe.class::cast).map(CastingRecipe::getResult) + .anyMatch(stack -> ItemStack.areItemsEqual(stack, ingot)), "Titanium ingot cannot be cast"); + final boolean plutoniumParts = TinkerRegistry.getAllTableCastingRecipes().stream() + .filter(CastingRecipe.class::isInstance).map(CastingRecipe.class::cast) + .map(CastingRecipe::getResult) + .anyMatch(stack -> stack.getItem() instanceof IToolPart + && "plutonium".equals(((IToolPart) stack.getItem()).getMaterialID(stack))); + require(plutoniumParts != low, "Wrong Low Fantasy policy for plutonium tool parts"); + } + + private static void require(final boolean passes, final String message) { + if (!passes) throw new IllegalStateException(message); + } + + private TinkersChecks() { } +} diff --git a/tools/validation/requirements.txt b/tools/validation/requirements.txt new file mode 100644 index 00000000..ad5d466f --- /dev/null +++ b/tools/validation/requirements.txt @@ -0,0 +1,2 @@ +jsonschema==4.23.0 +PyYAML==6.0.3