diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a0d7cddda..13577d34e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,19 +1,19 @@ -name: Base Metals 1.10 CI +name: Base Metals 1.11 CI on: push: branches: - - master-1.10.2 + - master-1.11.2 - 'feature/**' pull_request: branches: - - master-1.10.2 + - master-1.11.2 permissions: contents: read concurrency: - group: basemetals-1.10-${{ github.workflow }}-${{ github.ref }} + group: basemetals-1.11-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: @@ -133,11 +133,11 @@ jobs: shell: bash run: | set -euo pipefail - runtime="$RUNNER_TEMP/forge-1.10.2-2511-runtime" + runtime="$RUNNER_TEMP/forge-1.11.2-2588-runtime" bash gradle/prepare-packaged-forge-runtime.sh "$runtime" "$JAVA_HOME_8_X64/bin/java" echo "runtime=$runtime" >> "$GITHUB_OUTPUT" - - name: Install world-audit tools + - name: Install Python for packaged runtime checks uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: '3.12' @@ -171,7 +171,7 @@ jobs: set -euo pipefail bundle="$RUNNER_TEMP/release-input" mkdir -p "$bundle" - cp build/libs/BaseMetals-2.5.1.110021{,-sources,-javadoc}.jar "$bundle/" + cp build/libs/BaseMetals-2.5.1.111021{,-sources,-javadoc}.jar "$bundle/" cp build/release/SHA256SUMS CHANGELOG.txt "$bundle/" ./gradlew verifyPreparedReleaseArtifacts verifyMavenCoordinates \ -PpreparedReleaseDir="$bundle" \ @@ -200,13 +200,13 @@ jobs: - name: Upload audited release candidate uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: - name: BaseMetals-1.10.2-${{ github.sha }} + name: BaseMetals-1.11.2-${{ github.sha }} if-no-files-found: error retention-days: 30 path: | - build/libs/BaseMetals-2.5.1.110021.jar - build/libs/BaseMetals-2.5.1.110021-sources.jar - build/libs/BaseMetals-2.5.1.110021-javadoc.jar + build/libs/BaseMetals-2.5.1.111021.jar + build/libs/BaseMetals-2.5.1.111021-sources.jar + build/libs/BaseMetals-2.5.1.111021-javadoc.jar build/release/SHA256SUMS CHANGELOG.txt @@ -214,7 +214,7 @@ jobs: if: failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: - name: BaseMetals-1.10.2-diagnostics-${{ github.sha }} + name: BaseMetals-1.11.2-diagnostics-${{ github.sha }} if-no-files-found: ignore retention-days: 14 path: | diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 28377a0b8..6f8b40a3c 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -3,11 +3,11 @@ name: CodeQL on: push: branches: - - master-1.10.2 + - master-1.11.2 - 'feature/**' pull_request: branches: - - master-1.10.2 + - master-1.11.2 schedule: - cron: '47 7 * * 4' diff --git a/.github/workflows/validate-gradle-build.yml b/.github/workflows/validate-gradle-build.yml index 81f7cd4ee..0b533e416 100644 --- a/.github/workflows/validate-gradle-build.yml +++ b/.github/workflows/validate-gradle-build.yml @@ -3,11 +3,11 @@ name: Validate Gradle Wrapper on: push: branches: - - master-1.10.2 + - master-1.11.2 - 'feature/**' pull_request: branches: - - master-1.10.2 + - master-1.11.2 permissions: contents: read diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 9ca7d0b6e..0f528961a 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,40 +1,24 @@ -2.5.1.110021 for 1.10.2 +2.5.1.111021 for 1.11.2 -- Require OreSpawn 4.1.2.110021 or a compatible newer 4.x release, with Forge - 12.18.3.2511 or later. Development uses the checksum-verified public release. -- Replace the old OreSpawn plugin and internal fallback generator with a native - OreSpawn provider. Keep the eleven ore rules and their historical distributions. -- Let OreSpawn import existing OS1 and OS3 configuration files, preserving custom - and disabled rules. Existing world profiles remain authoritative. -- Keep existing OreSpawn 4 provider settings when importing older files for the - first time, using the fix in the required OreSpawn release. -- Respect OreSpawn's Manage Vanilla Ores switch after importing old rules. - With it off, Minecraft places its own ores. With it on, the imported settings - replace the matching vanilla/default pass without generating the ores twice. - Existing terrain and saved settings are left alone. -- Retire the using_orespawn and fallback_orespawn switches. Ore generation is - now configured in OreSpawn, including when another mod places the ores. -- Keep door items, coal powder and liquid Mercury when upgrading from the original - Cyano release. Old item names continue to work after restarting, including items - stored in chunks that have not been opened yet. -- Leave Base Metals iron nuggets unchanged; Minecraft 1.10 has no vanilla equivalent. -- Support all eighteen Base Metal Golems from the unchanged 6.02.1 add-on, - including golems saved by the original Cyano release. -- Move Base Metals' Java packages and Maven group to zone.moddev.mc.basemetals. - Existing MMD add-ons keep using the same classes through a name adapter; - saved IDs, configuration names and the bundled library API are unchanged. -- Use the same Major.Minor.Patch.Target version format as the newer branches. -- Update to ForgeGradle 7 and Gradle 9.6.1 while keeping Java 8 game compatibility. - Eclipse launches now quote paths with spaces, use processed resources and leave - optional integration APIs and test mods off the normal runtime classpath. -- Pin and checksum the old integration dependencies, and add repeatable main, - sources and Javadoc jars with release-artifact checks. -- Add build, CodeQL and wrapper checks for master-1.10.2, with automated - Cyano/MMD save upgrades, OreSpawn configuration imports and vanilla takeover tests. -- Connect this target to the shared release action, using one verified bundle - for Maven, CurseForge and GitHub. Keep publication behind explicit confirmation. -- Normalize changed text files to LF and fix the stray import whitespace. -- Leave Windows folder metadata out of downloads and use UTF-8 for sources - and Javadocs on every platform. +This update brings the newer Base Metals features to 1.11.2. It requires +Forge 13.20.1.2588 or later and MMD OreSpawn 4.1.6.111021 or a compatible +newer 4.x version for 1.11.2. + +- Open the Base Metals settings from the Mods list or the cog in OreSpawn. +- High Fantasy keeps the usual recipes and is the default. Low Fantasy limits + what you can make without removing anything from your world or changing + where ores spawn. Use the same setting on the client and server. +- Molten metal now burns even in shallow flows. Mercury still causes nausea. +- OreSpawn handles all eleven Base Metals ore rules. It keeps existing + overrides when importing older settings and avoids adding a second set of + veins when you move an imported OreSpawn 1 world to a new instance. +- JEI shows Crack Hammer recipes, Base Metals rods use the 1.11.2 fishing + hook, and the material API still uses Minecraft's iron nugget. +- The Java packages and Maven group move to zone.moddev.mc.basemetals. + Existing add-ons can still use the old class names. Saved block and item + IDs and config names stay the same. +- The build now uses ForgeGradle 7 and Gradle 9.6.1. Minecraft still runs on + Java 8. Eclipse launches handle paths with spaces, and CI checks old-world + upgrades as well as the build and release files. 2.5.0 for 1.10.2 diff --git a/README.md b/README.md index 8a2c9aecc..1ccec0f43 100644 --- a/README.md +++ b/README.md @@ -1,161 +1,74 @@ -# Base Metals 1.10.2 +# Base Metals 1.11.2 -[![Build](https://github.com/MinecraftModDevelopmentMods/BaseMetals/actions/workflows/ci.yml/badge.svg?branch=master-1.10.2)](https://github.com/MinecraftModDevelopmentMods/BaseMetals/actions/workflows/ci.yml?query=branch%3Amaster-1.10.2) -[![CodeQL](https://github.com/MinecraftModDevelopmentMods/BaseMetals/actions/workflows/codeql-analysis.yml/badge.svg?branch=master-1.10.2)](https://github.com/MinecraftModDevelopmentMods/BaseMetals/actions/workflows/codeql-analysis.yml?query=branch%3Amaster-1.10.2) +[![Build](https://github.com/MinecraftModDevelopmentMods/BaseMetals/actions/workflows/ci.yml/badge.svg?branch=master-1.11.2)](https://github.com/MinecraftModDevelopmentMods/BaseMetals/actions/workflows/ci.yml?query=branch%3Amaster-1.11.2) +[![CodeQL](https://github.com/MinecraftModDevelopmentMods/BaseMetals/actions/workflows/codeql-analysis.yml/badge.svg?branch=master-1.11.2)](https://github.com/MinecraftModDevelopmentMods/BaseMetals/actions/workflows/codeql-analysis.yml?query=branch%3Amaster-1.11.2) -## Base Metals Mod +Base Metals adds metals like copper, tin, lead and silver, plus alloys such as +bronze and steel. There are a few fantasy metals too: look for Cold Iron and +Adamantine in the Nether, and Star Steel in the End. -This mod adds historically commonly used metals to Minecraft, specifically Silver, Copper, Tin, Lead, Zinc, Mercury, and Nickel. You will also find a number of metal alloys in this mod and a new tool: the Crack Hammer. +## Installing and updating -Fantasy metals have been added to the Nether and the End: Cold Iron, Mithril, Adamantine, and Star Steel +Install Forge `13.20.1.2588` or later and +[MMD OreSpawn `4.1.6.111021`](https://www.curseforge.com/minecraft/mc-mods/mmd-orespawn/files/9524249) +or a newer compatible 4.x release for Minecraft 1.11.2. Put the OreSpawn and +`BaseMetals-2.5.1.111021.jar` files in your `mods` folder. +If you're updating an existing world, back up the world and the `config` folder +first. Replace Base Metals and OreSpawn together, but keep your old OreSpawn +config files so their settings can be imported. OreSpawn now handles all Base +Metals ore placement, and the eleven default rules haven't changed. Check +[the ore generation guide](docs/ORE_GENERATION.md) before exploring new chunks, +especially if your pack changes where vanilla ores spawn. +## Using the Crack Hammer -## Metals and Alloys +Break an ore block with a Crack Hammer to get two piles of powder. Smelt the +powder into ingots, or mix different powders and smelt the blend to make an +alloy. You can also drop a crushable item and right-click the ground beneath +it with the hammer. If you use JEI, its Crack Hammer category shows what you +can crush. -### Natural Metals +## Making alloys -**Antimony**: +Mix three copper powders with one tin powder for bronze, or swap the tin for +zinc to make brass. Equal parts silver and gold make electrum. Two parts iron +to one part nickel make invar; eight parts iron to one part carbon make steel. +Mithril uses two parts silver to one part each of mercury and Cold Iron. -**Bismuth**: +## Choosing a Fantasy Level -**Copper**: Copper is soft, easy to work, and fairly abundant. It is needed to make bronze and brass metal alloys. +Open **Mods → Base Metals → Config** from the main menu, or use the Base Metals +cog under **Create World → OreSpawn → Mods**. Both edit `config/BaseMetals.cfg`. +Restart Minecraft or the server to apply changes. -**Lead**: Lead is a very soft metal that is best known for being very heavy and somewhat toxic. Lead tools are fragile, but can dish out a lot of damage when used as weapons. - -**Mercury**: This toxic liquid metal has many alchemical uses. The Mithril metal alloys requires mercury. - -**Nickel**: This metal is as soft as copper, but it has alchemical properties and forms the invar metal alloy when mixed with iron. - -**Platinum**: - -**Silver**: Silver is a soft, shiny metal that is valued for both is beauty and its alchemical uses. - -**Tin**: Tin is an extremely soft metal that is not useful by itself, but can be combined with copper to make bronze, a metal alloy nearly as strong as iron. - -**Zinc**: Like tin, zinc is worthless on its own, but can be used to make the metal ally brass. - - - -### Metal Alloys -*Metal alloys are made by crafting together the powdered forms of the required metals, and then smelting the resulting alloy blend in a furnace.* - -**Brass**: This alloy of copper and zinc (3:1 ratio) is soft, but has a beautiful golden color. - -**Bronze**: This alloy of copper and tin (3:1 ratio) is as hard as iron, but not quite as durable. - -**Electrum**: This alloy of silver and gold (1:1 ratio) can be enchanted like gold, but is slightly more durable. - -**Invar**: This alloy of iron and nickel (2:1 ratio) is harder than steel, but less durable. - -**Pewter**: - -**Steel**: This alloy of iron and carbon (8:1 ratio) is as hard as iron and much more durable. - - -### Fantasy Metals - -**Adamantine**: (found in the Nether): Adamantine is a rare magical metal that is as strong as diamond, maybe even stronger. Armor made from Adamantine grants resistance to damage and tools made from adamantine are extra effective against monsters that have more than 10 hearts of health. - -**Aquarium**: - -**Cold-Iron**: (found in the Nether): Cold-Iron is a magical metal that is as strong as iron. Tools made from Cold Iron are extra effective against denizens of the Nether and any creature that is immune to fire. - -**Mithril**: Mithril is an alloy of alloy of silver, mercury, and cold-iron (2:1:1 ratio). It is as strong as steel and Mithril weapons are extra effective against undead. - -**Star-Steel**: (found in the End): Armor made from Star Steel reduces the weight of the wearer, allowing the wearer to jump higher and fall slower. Star-Steel tools slowly repair themselves while held. - - - -## Crack Hammer - -Also known as a sledgehammer, this tool is designed for pulverizing rocks. Using this tool on ores will cause them to drop powdered metal instead of the standard ore block. Use can then use the powdered metals to make metal alloy mixes or just smelt the powder into ingots. You can crush items by dropping them on the ground and then right-clicking on the ground beneath the items. - - - -## Requirements - -Install Forge `12.18.3.2511` or later and -[MMD OreSpawn `4.1.2.110021`](https://www.curseforge.com/minecraft/mc-mods/mmd-orespawn/files/9276430) -or a newer compatible 4.x release for Minecraft 1.10.2. Base Metals no longer -includes its own fallback ore generator. - -OreSpawn handles ore placement and imports old OreSpawn configuration files. -The eleven ore defaults are unchanged. See [ore generation and upgrades](docs/ORE_GENERATION.md) -for configuration locations and advice for existing worlds. +**High Fantasy** keeps the usual recipes and is the default for older configs. +**Low Fantasy** limits what you can make from each material. For example, you +can still make an Adamantine pickaxe, but not an Adamantine bow. Items you +already have still work, and ore placement doesn't change. In multiplayer, +use the same Fantasy Level on the client and server. ## Building and running from source -This branch uses ForgeGradle 7 and the Gradle wrapper, like the newer branches. -Minecraft and the mod still run on Java 8. Gradle uses Java 17, while the initial -Minecraft setup also needs Java 25 for Mavenizer. - -Import the inner `BaseMetals` directory as an existing Gradle project. Use the -wrapper, then run `prepareEclipse` and choose `runClient` or `runServer`. -Optional integration mods are compile-time APIs, not ordinary launch dependencies. -See [the build guide](docs/BUILDING.md) for toolchains, checks and legacy-world tests. - -Source for this version lives on `master-1.10.2`. Releases use the shared -**Release Base Metals** action after the branch's build and compatibility checks -pass. Normal builds and tags do not publish anything. - - - -## Installing - -Install Forge and OreSpawn, then put `BaseMetals-2.5.1.110021.jar` in your -`mods` folder. Downloads are available on CurseForge and the repository's -Releases page once the version is published. - -## NEI - -The Crack Hammer recipes from this mod will appear in NEI if you have NEI installed. Hooray! - -## Upgrading an existing 1.10 world - -Back up your world before updating any mods. This build recognizes the original -Cyano names for door items, coal powder and liquid Mercury, including items in -chunks you visit later. Base Metals iron nuggets keep their existing identity. - -Mods that use Cyano's old Java API may need their own updates. Restoring saved -items cannot, by itself, repair those Java references. Base Metal Golems -`6.02.1`, with Extra Golems `6.02`, is supported by a small compatibility layer: -its eighteen golems use the existing Base Metals blocks and ingots. Neither -add-on needs changing, and neither is required when playing without golems. - -This release uses version `2.5.1.110021`. The final six digits identify Minecraft -1.10.2 on Forge, following the same version format as the newer branches. -The mod ID, saved block and item names, resources and configuration names remain -`basemetals`; moving the Java packages does not rename anything in your world. +Minecraft and the mod still run on Java 8. The Gradle wrapper uses Java 17, +and ForgeGradle's Minecraft setup needs Java 25 for Mavenizer. Import +`BaseMetals` as an existing Gradle project in Eclipse, run `prepareEclipse`, +then choose `runClient` or `runServer`. The normal launches don't load optional +integration mods or test mods. +See [the build guide](docs/BUILDING.md) for toolchains, checks and legacy-world +tests. The source for this version is on `master-1.11.2`. ## Mod API New integrations should use `zone.moddev.mc.basemetals.init` for materials, -blocks and items. Maven builds use -`zone.moddev.mc.basemetals:BaseMetals:2.5.1.110021`. Crack Hammer recipes still -use `com.mcmoddev.lib.registry.CrusherRecipeRegistry`; the bundled library API -has not moved. - -An early-loading adapter redirects compiled references to the former -`com.mcmoddev.basemetals` classes to their new names. They share the same mod -instance, material objects and registries, rather than registering a second -copy. This covers class references and literal reflection names, not arbitrary -class names assembled by an add-on at runtime. The Cyano compatibility layer -only supplies the block and ingot fields used by Base Metal Golems; it is not a -replacement for the complete Cyano API. - - -## Q&A - -Q: Why make this mod? - -A: Minecraft appears to have a pre-industrial fantasy setting, but the fantasy literature (and pre-industrial history) is full of references to silver and copper as well as gold. - - - -Q: What does the Crack Hammer do? - -A: When you break ores with the Crack Hammer, you get two piles of metal powders instead of a single block of ore. This is necessary to make metal alloys, which is done by combining the powders of the various components and then smelting the alloy mix. +blocks and items. The Maven coordinate is +`zone.moddev.mc.basemetals:BaseMetals:2.5.1.111021`. Crack Hammer recipes still +use `com.mcmoddev.lib.registry.CrusherRecipeRegistry`. + +Existing add-ons can still use the old `com.mcmoddev.basemetals` class names. +The adapter handles compiled references and literal class names used in +reflection, but not names an add-on assembles at runtime. Saved block and item +IDs still use `basemetals`. diff --git a/build.gradle b/build.gradle index a6aa42cb8..5d314c6e8 100644 --- a/build.gradle +++ b/build.gradle @@ -13,8 +13,8 @@ group = project.mod_group version = project.mod_version base.archivesName = 'BaseMetals' -if (!(project.version ==~ /\d+\.\d+\.\d+\.110021/)) { - throw new GradleException('Use Major.Minor.Patch.110021 for Minecraft 1.10.2 on Forge.') +if (!(project.version ==~ /\d+\.\d+\.\d+\.111021/)) { + throw new GradleException('Use Major.Minor.Patch.111021 for Minecraft 1.11.2 on Forge.') } // Gradle and Mavenizer use modern JDKs; the mod and game still use Java 8. @@ -57,10 +57,10 @@ def normalizeText = { details -> eof: FixCrLfFilter.AddAsisRemove.newInstance('asis')) } -def developmentOutput = layout.buildDirectory.dir('forge10-development/main') +def developmentOutput = layout.buildDirectory.dir('forge11-development/main') def prepareDevelopmentMod = tasks.register('prepareDevelopmentMod', Sync) { group = 'ide' - description = 'Merges production classes and processed resources for Forge 1.10 launches.' + description = 'Merges production classes and processed resources for Forge 1.11 launches.' dependsOn tasks.named('classes') from tasks.named('compileJava', JavaCompile).flatMap { it.destinationDirectory } from sourceSets.main.output.resourcesDir @@ -148,6 +148,8 @@ tasks.named('processResources', ProcessResources) { inputs.property 'version', project.version inputs.property 'mcversion', project.minecraft_version filesMatching('mcmod.info') { expand version: project.version, mcversion: project.minecraft_version } + // Pack format 3 looks up locale filenames in lowercase. + filesMatching('assets/basemetals/lang/*.lang') { name = name.toLowerCase(Locale.ROOT) } rename '(.+_at.cfg)', 'META-INF/$1' filesMatching(textPatterns, normalizeText) } diff --git a/docs/BUILDING.md b/docs/BUILDING.md index 088576b42..86fb53c2b 100644 --- a/docs/BUILDING.md +++ b/docs/BUILDING.md @@ -1,4 +1,4 @@ -# Building Base Metals 1.10.2 +# Building Base Metals 1.11.2 Use the inner `BaseMetals` directory as the project root. The Gradle wrapper is part of the project; there is no need to install Gradle separately. @@ -7,15 +7,15 @@ part of the project; there is no need to install Gradle separately. - Java 17 runs Gradle 9.6.1 and ForgeGradle 7.0.34. - Java 25 runs Forge's Minecraft Mavenizer during Minecraft setup. -- Java 8 compiles the mod and runs Minecraft 1.10.2. +- Java 8 compiles the mod and runs Minecraft 1.11.2. Ordinary development accepts compatible Java 8 installations. Release checks use Temurin 8u502-b07 and Gradle on Temurin 17.0.1+12. Do not change Eclipse's own runtime to Java 8: its Gradle and Minecraft runtimes are separate settings. -The compile and runtime target is Forge 12.18.3.2511 with stable-29 mappings. -OreSpawn 4.1.2.110021 is pinned through Curse Maven and verified against its -published SHA-256. Saved registry IDs and recipes have not changed. +The compile and runtime target is Forge 13.20.1.2588 with MCP stable 32 for 1.11 mappings. +OreSpawn 4.1.6.111021 is pinned through Curse Maven and verified against its +published SHA-256. The branch starts from the updated Base Metals 1.10.2 release. ## Eclipse @@ -29,7 +29,7 @@ cannot replace the mod version with a `${version}` placeholder. After changing textures or other resources, refresh Gradle or run `prepareEclipse` again. The launch tasks merge production classes and processed resources, so Minecraft -sees one mod root. Ordinary launches include the published OreSpawn 4.1.2.110021 +sees one mod root. Ordinary launches include the published OreSpawn 4.1.6.111021 release. Other integration APIs, JUnit and the migration probes are excluded. Keep personal worlds outside the development `run` directory. @@ -43,7 +43,7 @@ transformed copies cannot retain a valid signature for the original bytes. gradlew clean check build javadoc verifyReleaseArtifacts writeReleaseChecksums prepareEclipse ``` -The installable jar is `build/libs/BaseMetals-2.5.1.110021.jar`. Sources, +The installable jar is `build/libs/BaseMetals-2.5.1.111021.jar`. Sources, Javadocs are written alongside it; checksums are in `build/release/SHA256SUMS`. The mapped development jar is kept separately under `build/libs-dev`; it is not the jar to install in a normal Minecraft instance. Building never uploads anything. @@ -66,21 +66,26 @@ The older `legacyDependencyRepository` property still works for local setups. ## CI and releases -The target branch is `master-1.10.2`, matching OreSpawn's naming. CI runs on that +The target branch is `master-1.11.2`, matching OreSpawn's naming. CI runs on that branch and feature branches, with separate CodeQL and wrapper checks. It tests a cold Forge setup, an offline rebuild, Java 8 bytecode, Eclipse isolation and -byte-identical release jars. Public Cyano and MMD releases are used to create -temporary upgrade worlds; personal saves are never needed by CI. +byte-identical release jars. Public 1.11.2 releases are used to create temporary upgrade worlds; personal +saves are never needed by CI. To run the packaged suite locally, prepare a disposable Forge server with `gradle/prepare-packaged-forge-runtime.sh`, then run `packagedForgeRuntimeTest` -with `-PpackagedForgeRuntimeRoot=`. Python 3 needs `nbtlib` -2.0.4 and NumPy 2.2.6. On Windows, set `-PpythonExecutable=` if +with `-PpackagedForgeRuntimeRoot=`. On Windows, set +`-PpythonExecutable=` if `python3` is not available. The test destination must not already exist; keep a failed run before cleaning the build directory. +The packaged tests check that OreSpawn keeps existing overrides when importing +old configs, and that moving an OreSpawn 1 world without its converted config +does not duplicate its ore rules. They also exercise the vanilla-ore switch, +molten metal contact and the Modern Metals add-on. + The shared **Release Base Metals** workflow lives on the repository's default -branch. Version `2.5.1.110021` selects `master-1.10.2`; it requires successful +branch. Version `2.5.1.111021` selects `master-1.11.2`; it requires successful CI for the exact source commit and explicit publication confirmation. It builds one candidate, then publishes those same files to MMD Maven, CurseForge and GitHub, in that order. A tag alone only validates the candidate. @@ -94,21 +99,11 @@ without rebuilding the release. Do not run a publish task just to test a build. ## Save and add-on compatibility -Build the separate test mod with `migrationProbeJar`. It is written to -`build/test-mods`, never the release directory. The checks and their phased -first-load, reload and later-chunk procedure are described in -[the legacy test guide](../tools/validation/legacy110/README.md). - -Always test a disposable world copy. Base Metal Golems checks use the unchanged -6.02.1 add-on with Extra Golems 6.02, including golems saved by Cyano Base Metals. -Removing the add-ons from a live world can remove their entities; the no-add-on -test therefore uses a separate copy without those saved entities. - -The OreSpawn upgrade runner is `tools/validation/legacy110/run_orespawn_checks.py`. -It first saves a control world with the previous Base Metals and OreSpawn 3 jars, -then tests copies with the new jar and OreSpawn 4.1. It checks stock, custom and -disabled rules, OS1 imports, saved item data, reloads and chunks opened later. -Use `--help` for its input paths; its output must be a disposable directory. -Build the packaged probes with `packagedLaunchProbeJar packagedOreSpawnProbeJar`. -The ordinary probe jars use development mappings and are not interchangeable -with the packaged versions. +Use a disposable world copy when testing an upgrade. The packaged tests use the +previous public 1.11.2 Base Metals and OreSpawn 3 releases as their starting +point. The verification jars are under `build/test-mods`; don't install them in +a regular instance. + +For add-on development, use +`zone.moddev.mc.basemetals:BaseMetals:2.5.1.111021`. The public material and +recipe types under `com.mcmoddev.lib` are still bundled in Base Metals. diff --git a/docs/ORE_GENERATION.md b/docs/ORE_GENERATION.md index 7ed3645d5..59927ad6b 100644 --- a/docs/ORE_GENERATION.md +++ b/docs/ORE_GENERATION.md @@ -1,57 +1,38 @@ -# Ore generation in Minecraft 1.10.2 +# Ore generation in Minecraft 1.11.2 -Base Metals now requires MMD OreSpawn 4.1.2.110021 or a newer compatible 4.x +Base Metals now requires MMD OreSpawn 4.1.6.111021 or a newer compatible 4.x release. OreSpawn is the only ore-generation engine; Base Metals no longer ships its old OS3 plugin or fallback generator. This also raises the minimum -Forge version to 12.18.3.2511. +Forge version to 13.20.1.2588. ## Existing worlds Back up the world and its configuration folder before updating. Install the new Base Metals and OreSpawn jars together, removing the older jars first. -Keep the old configuration files in place: - -- OreSpawn 1: `config/orespawn/*.json` -- OreSpawn 3: `config/orespawn3/*.json`, together with `config/orespawn.cfg` - -OreSpawn imports those files without changing the originals. Custom ore -frequencies, sizes, heights, dimensions and disabled rules carry across. The -old exclusive maximum height becomes an inclusive maximum one block lower; -for example, `maxHeight: 96` becomes `max_y: 95`. - -Read `config/orespawn-upgrade-report.txt` after the first start. It lists what -was imported and anything that needs attention. Missing blocks and unsupported -custom settings cannot be guessed safely, so keep the report with your backup. - -An OS1 `+` dimension entry is imported for the dimensions installed at that -start. If you add another dimension mod later, review its ore rules yourself. - -The resulting provider override is `config/basemetals-orespawn.json`. Each -world stores its effective settings in -`/serverconfig/orespawn-worldgen.json`. Existing OS4 overrides and world -profiles take priority over the defaults supplied by Base Metals. Updating the -mod does not reset them or replace generated terrain. Retrogen stays off -unless the imported configuration explicitly enables it. - -OreSpawn's **Manage Vanilla Ores** switch controls imported vanilla-ore rules -as well as its newer vanilla defaults. When it is off, Minecraft generates its -own ores; imported vanilla rules stay saved but inactive. When it is on, the -imported frequency, height and vein settings are used without adding a second -vanilla/default pass. This switch does not disable Base Metals' own ore rules. -Changing it affects new generation, not ore already placed in existing chunks. - -Existing provider overrides are kept even when legacy files are imported for -the first time. OreSpawn records the retained file in its upgrade report. An -unfinished or invalid override is left for the normal loader to check, not -silently replaced by older settings. +Keep the old `config/orespawn/` or `config/orespawn3/` files and +`config/orespawn.cfg` in place. OreSpawn can import their rules without changing +the source files or replacing an existing Base Metals provider override. Check +`config/orespawn-upgrade-report.txt` before exploring new chunks. + +The Base Metals provider override is `config/basemetals-orespawn.json`. Each +world keeps its effective settings in +`/serverconfig/orespawn-worldgen.json`. Back up these files too if you +already use OreSpawn 4. Existing ores are not replaced by a change to the +defaults; review any imported retrogen setting separately. Copy the instance configuration folder as well as the world when moving an old save to another installation. A world alone cannot recover custom ore settings -that were stored outside it. +that were stored outside it. If an OreSpawn 1 world already has an imported rule +saved in its profile, OreSpawn keeps that rule instead of adding a second copy. + +OreSpawn's **Manage Vanilla Ores** switch also applies to imported vanilla ore +rules. With it off, Minecraft places its own ores and the imported settings stay +saved but inactive. With it on, the imported rules take over without a second +vanilla pass. Base Metals ores are unaffected by that switch. ## Changing ore placement -Use OreSpawn's ore editor, or edit its JSON files while Minecraft is stopped: +Use OreSpawn's editor, or edit its JSON files while Minecraft is stopped: - `config/orespawn-worldgen.json` holds defaults for new worlds. - `config/basemetals-orespawn.json` overrides the Base Metals provider. diff --git a/gradle.properties b/gradle.properties index 2246dc119..e66555652 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,14 +5,14 @@ org.gradle.caching=true org.gradle.parallel=false net.minecraftforge.gradle.merge-source-sets=false -minecraft_version=1.10.2 -forge_version=12.18.3.2511 +minecraft_version=1.11.2 +forge_version=13.20.1.2588 mappings_channel=stable -mappings_version=29-1.10.2 +mappings_version=32-1.11 mod_id=basemetals mod_group=zone.moddev.mc.basemetals -mod_version=2.5.1.110021 +mod_version=2.5.1.111021 mod_artifact=BaseMetals loader_name=forge loader_code=1 @@ -26,5 +26,5 @@ curseforge_project_id=240967 cf_requirements=mmd-orespawn orespawn_curse_project_id=245586 coreplugin=zone.moddev.mc.basemetals.compat.BaseMetalsLoadingPlugin -orespawn_version=4.1.2.110021 -orespawn_version_range=[4.1.2.110021,5.0.0) +orespawn_version=4.1.6.111021 +orespawn_version_range=[4.1.6.111021,5.0.0) diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 13942054f..43f164606 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -22,7 +22,7 @@ dependencies { testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.10.2' } -// Forge 1.10's mod scanner cannot read Java 11 multi-release entries. They are +// Forge 1.11'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 @@ -40,9 +40,9 @@ tasks.register('verifyReleaseDependencies') { doLast { def artifacts = configurations.legacyModArtifacts.resolvedConfiguration.resolvedArtifacts def orespawn = specs.find { it.id == 'orespawn' } - if (orespawn.coordinate != 'curse.maven:mmd-orespawn-245586:9276430' - || orespawn.sha256 != '4D4975421FEEBF17505056306D06B0344D7A4553B6275885D7C5C5065B0348A6') { - throw new GradleException('Use the verified OreSpawn 4.1.2.110021 release.') + if (orespawn.coordinate != 'curse.maven:mmd-orespawn-245586:9524249' + || orespawn.sha256 != '4246D1EB83FFFC325F04E3D3FE331D1404714F4A8D773ADE278A5D0EBEE5EDBC') { + throw new GradleException('Use the verified OreSpawn 4.1.6.111021 release.') } specs.each { spec -> def parts = spec.coordinate.split(':') @@ -58,6 +58,7 @@ tasks.register('verifyReleaseDependencies') { 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.getJarEntry('zone/moddev/mc/orespawn/api/client/WorldSettingsExtensionRegistry.class') == null || jar.manifest.mainAttributes.getValue('OreSpawn-API-Version') != '1') { throw new GradleException('Wrong OreSpawn identity or public API.') } diff --git a/gradle/dependencies.json b/gradle/dependencies.json index 39fca48f9..eccb68b4d 100644 --- a/gradle/dependencies.json +++ b/gradle/dependencies.json @@ -1,16 +1,13 @@ [ - {"id":"orespawn","coordinate":"curse.maven:mmd-orespawn-245586:9276430","sha256":"4D4975421FEEBF17505056306D06B0344D7A4553B6275885D7C5C5065B0348A6","repository":"https://www.cursemaven.com","runtime":true}, - {"id":"alt","coordinate":"curse.maven:additional-loot-tables-243157:2604973","sha256":"DFDEE18663A0CBC3A811E442C7B20F34F1765B1D36C6284CB3B8B8EAA3FC5620","repository":"https://www.cursemaven.com"}, - {"id":"mantle","coordinate":"slimeknights.mantle:Mantle:1.10.2-1.1.5.207","sha256":"520499E1329EA57DB3D7ABA671B30A0CC7DA60C02C97828CFAF57778B0923832","repository":"https://dvs1.progwml6.com/files/maven"}, - {"id":"tconstruct","coordinate":"slimeknights:TConstruct:1.10.2-2.6.5.11","sha256":"E33061BEFB4DA60B2EF79016A022C434149DDF1E573A01EFD2F202F03904E52D","repository":"https://dvs1.progwml6.com/files/maven"}, - {"id":"jei","coordinate":"mezz.jei:jei_1.10.2:3.14.7.420","sha256":"B29DC3077772543E765432CC2C91AAA657F2AC70E664707B3F1D9ACB2A02706A","repository":"https://dvs1.progwml6.com/files/maven"}, - {"id":"nei","coordinate":"codechicken:NotEnoughItems:1.10.2-2.1.3.220:universal","sha256":"C49BE9F4AE9ABD1CF397884D32F7F1DAD233C8ED4E74EA72F8B6656E8A8A1594","repository":"https://chickenbones.net/maven"}, - {"id":"ccl","coordinate":"codechicken:CodeChickenLib:1.10.2-2.5.9.320:universal","sha256":"E265A9B9F3E2ED4302CADAFDBC8520E90F12CF06BC60F267466AF8E6B752C8FC","repository":"https://chickenbones.net/maven"}, - {"id":"ccc","coordinate":"codechicken:CodeChickenCore:1.10.2-2.4.1.103:universal","sha256":"E2E4FDABAB58F76A25BCC9AE944639CA6265DA7BF81E62379CBED23851C2D479","repository":"https://chickenbones.net/maven"}, - {"id":"ic2","coordinate":"net.industrial-craft:industrialcraft-2:2.6.254-ex110","sha256":"CD51FB645C26FA96C6B22704EF168D00192A135F70BD97B1DA40CD5F80FA62A2","repository":"https://maven.ic2.player.to"}, - {"id":"cofh","coordinate":"cofh:CoFHCore:1.10.2-4.1.12.17:universal","sha256":"AD8924E7B142A98C03CF0C37DBD320DDBA553BA92487556C8D3D8F28D41409B3","repository":"https://maven.covers1624.net"}, - {"id":"mekanism","coordinate":"curse.maven:mekanism-268560:2475800","sha256":"E46A248BDA91F683812A10D1764CC95CA25A2BBBD24D945D1D4007DE54E79876","repository":"https://www.cursemaven.com"}, + {"id":"orespawn","coordinate":"curse.maven:mmd-orespawn-245586:9524249","sha256":"4246D1EB83FFFC325F04E3D3FE331D1404714F4A8D773ADE278A5D0EBEE5EDBC","repository":"https://www.cursemaven.com","runtime":true}, + {"id":"alt","coordinate":"curse.maven:additional-loot-tables-243157:2604961","sha256":"4CC6B59760DBCE28411B8F76F25F4F94AD6B1769F20917BDEF9FA6202ABB86C1","repository":"https://www.cursemaven.com"}, + {"id":"mantle","coordinate":"curse.maven:mantle-74924:2413993","sha256":"6C1C79BD8491106D65240D4DF139E2BEA7914BA2622FAE0662ADB3047D5EDF9D","repository":"https://www.cursemaven.com"}, + {"id":"tconstruct","coordinate":"curse.maven:tinkers-construct-74072:2451489","sha256":"2D7F4A08EDDA2881A432CD80FF26575CCEA593FCC8A597A435652C1A53B14CB8","repository":"https://www.cursemaven.com"}, + {"id":"jei","coordinate":"curse.maven:jei-238222:2461378","sha256":"370814660C9FEB9514C8F4A8B6F2DC74E5ACC665A4B11ED046AD68F1869A422F","repository":"https://www.cursemaven.com"}, + {"id":"ic2","coordinate":"curse.maven:industrial-craft-242638:2457397","sha256":"ACCFA9A503A4B194CFF9528EA521AB42E00A85620F13DDE268BE14C112305B98","repository":"https://www.cursemaven.com"}, + {"id":"cofh","coordinate":"curse.maven:cofh-core-69162:2469613","sha256":"7C3EC573F62AE6F3F98B34361123E9D706CFDF03419AE6242293515960391C11","repository":"https://www.cursemaven.com"}, + {"id":"mekanism","coordinate":"curse.maven:mekanism-268560:2475809","sha256":"AF013AB6843174E4E766EC98A576D60047EAEA372CD01F6BF5460678EFE86D19","repository":"https://www.cursemaven.com"}, {"id":"taiga","coordinate":"curse.maven:taiga-247661:2368038","sha256":"B835A38B80ED60E0F59426F82EE5EA2E681A2AE8DD877DB5DBCF7949B9C4B735","repository":"https://www.cursemaven.com"}, - {"id":"hwyla","coordinate":"curse.maven:hwyla-253449:2433252","sha256":"2FC66DBB0CD7A1B9395FB5AAC198CF29C69BE44DE12A771FC4E77D4106D2DDDF","repository":"https://www.cursemaven.com"}, - {"id":"veinminer","coordinate":"curse.maven:veinminer-67133:2528282","sha256":"C2F651221CFCE7049A0011426F3E712026ECE31CE61C6A47DEF68BD7C78EB10A","repository":"https://www.cursemaven.com"} + {"id":"hwyla","coordinate":"curse.maven:hwyla-253449:2496989","sha256":"4B6B22C4B79052841ABC7E84C2604CD8441ADADE07CD1262CC5B096DA68EC073","repository":"https://www.cursemaven.com"}, + {"id":"veinminer","coordinate":"curse.maven:veinminer-67133:2528292","sha256":"75B37AC8778261875A692D468ABAA3B1BD8AFF61D18B4EA900C26AA2C8528AD7","repository":"https://www.cursemaven.com"} ] diff --git a/gradle/ide/eclipse.gradle b/gradle/ide/eclipse.gradle index b12e788e9..a41673e76 100644 --- a/gradle/ide/eclipse.gradle +++ b/gradle/ide/eclipse.gradle @@ -15,6 +15,7 @@ eclipse { 'build/resources/main', 'tools/validation/legacy110', 'tools/validation/legacy110/migration-probe', 'tools/validation/legacy110/launch-probe', + 'tools/validation/legacy110/fantasy-probe', 'tools/validation/legacy110/orespawn-probe'] as Set classpath.entries.removeAll { it.kind == 'src' && managed.contains(it.path) } } @@ -88,7 +89,7 @@ tasks.register('isolateEclipseProductionRuns') { } 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(//, @@ -156,11 +157,11 @@ tasks.register('verifyEclipseProductionClasspath') { 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.10.2"') + || !text.contains('MC_VERSION" value="1.11.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('legacy110-probe')) { + || text.contains('junit-') || text.contains('legacy110-probe') || text.contains('fantasy-probe')) { throw new GradleException("Unsafe production launch: ${name}") } if (runtime.any { !text.contains(it.path.replace('\\', '/')) } diff --git a/gradle/prepare-packaged-forge-runtime.sh b/gradle/prepare-packaged-forge-runtime.sh index e5cefc939..577a08a49 100644 --- a/gradle/prepare-packaged-forge-runtime.sh +++ b/gradle/prepare-packaged-forge-runtime.sh @@ -7,8 +7,8 @@ if [[ $# -ne 2 ]]; then fi runtime="$1" java8="$2" -version=1.10.2-12.18.3.2511 -expected=664393C5A924B8F06CFB953903ABCF9FE5E99ECBE6AF8C7EA217339C766E519C +version=1.11.2-13.20.1.2588 +expected=00AEA3DDF1E78BBB4D5D05E8C22FB3E849DE09B47D828E57DAD373A16BB8A26F if [[ -e "$runtime" && -n "$(find "$runtime" -mindepth 1 -maxdepth 1 -print -quit)" ]]; then echo "Packaged Forge destination must be empty: $runtime" >&2 @@ -24,11 +24,11 @@ if [[ "$actual" != "$expected" ]]; then echo "Forge installer checksum mismatch: $actual" >&2 exit 1 fi -# The 1.10 installer writes to its working directory and ignores a destination argument. +# The legacy installer writes to its working directory. (cd "$runtime" && "$java8" -jar "forge-$version-installer.jar" --installServer) if [[ ! -f "$runtime/forge-$version-universal.jar" && -f "$runtime/forge-$version.jar" ]]; then cp "$runtime/forge-$version.jar" "$runtime/forge-$version-universal.jar" fi test -f "$runtime/forge-$version-universal.jar" -test -f "$runtime/minecraft_server.1.10.2.jar" +test -f "$runtime/minecraft_server.1.11.2.jar" test -d "$runtime/libraries" diff --git a/gradle/release/artifacts.gradle b/gradle/release/artifacts.gradle index 85c7ed54c..82711434d 100644 --- a/gradle/release/artifacts.gradle +++ b/gradle/release/artifacts.gradle @@ -19,7 +19,7 @@ tasks.register('verifyJava8Toolchain') { 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.10 requires Java 8.') + if (compiler.languageVersion.asInt() != 8) throw new GradleException('Minecraft 1.11 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')) { @@ -38,19 +38,19 @@ tasks.register('verifyReleaseConfiguration') { group = 'verification' dependsOn tasks.named('verifyJava8Toolchain') doLast { - if (project.group != 'zone.moddev.mc.basemetals' || project.version != '2.5.1.110021' - || project.minecraft_version != '1.10.2' || project.forge_version != '12.18.3.2511' - || project.mappings_channel != 'stable' || project.mappings_version != '29-1.10.2') { + if (project.group != 'zone.moddev.mc.basemetals' || project.version != '2.5.1.111021' + || project.minecraft_version != '1.11.2' || project.forge_version != '13.20.1.2588' + || project.mappings_channel != 'stable' || project.mappings_version != '32-1.11') { throw new GradleException('Base Metals target, mappings or Maven identity changed.') } String source = file('src/main/java/zone/moddev/mc/basemetals/BaseMetals.java').getText('UTF-8') if (!source.contains('VERSION = "' + project.version + '"') || !source.contains('MODID = "basemetals"')) { throw new GradleException('The mod identity differs from the build metadata.') } - if (project.orespawn_version != '4.1.2.110021' - || project.orespawn_version_range != '[4.1.2.110021,5.0.0)' + if (project.orespawn_version != '4.1.6.111021' + || project.orespawn_version_range != '[4.1.6.111021,5.0.0)' || !source.contains('required-after:orespawn@' + project.orespawn_version_range) - || !source.contains('required-after:Forge@[12.18.3.2511,)')) { + || !source.contains('required-after:forge@[13.20.1.2588,)')) { throw new GradleException('The OreSpawn or Forge runtime requirement changed.') } } @@ -113,11 +113,19 @@ def auditJars = { File directory -> throw new GradleException('Incorrect release manifest.') } def info = new JsonSlurper().parse(zip.getInputStream(zip.getEntry('mcmod.info')))[0] - if (info.modid != 'basemetals' || info.version != project.version || info.mcversion != '1.10.2') { + if (info.modid != 'basemetals' || info.version != project.version || info.mcversion != '1.11.2') { throw new GradleException('Incorrect processed mcmod.info.') } int classes = zip.entries().count { it.name.endsWith('.class') } - if (classes != 218 || zip.getEntry('cyano/basemetals/init/Blocks.class') == null + def fantasyClasses = [ + 'client/BaseMetalsConfigScreen', 'client/BaseMetalsGuiFactory', + 'content/ContentAcquisition', 'content/ContentMode', 'content/ContentModeNetwork', + 'content/ContentModeNetwork$RejectModList', + 'content/ContentPolicy', 'content/MaterialForm' + ] + if (classes != 218 || fantasyClasses.any { + zip.getEntry("zone/moddev/mc/basemetals/${it}.class") == null + } || zip.getEntry('cyano/basemetals/init/Blocks.class') == null || zip.getEntry('META-INF/basemetals-legacy-api.list') == null) { throw new GradleException('The compatibility-layer class inventory changed.') } @@ -171,7 +179,7 @@ tasks.register('verifyPreparedReleaseArtifacts') { 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.10.2')) { + if (!new File(directory, 'CHANGELOG.txt').getText('UTF-8').startsWith(project.version.toString() + ' for 1.11.2')) { throw new GradleException('The prepared changelog belongs to a different release.') } auditJars(directory) diff --git a/gradle/release/publishing.gradle b/gradle/release/publishing.gradle index 3b16bac92..c09f5e4c7 100644 --- a/gradle/release/publishing.gradle +++ b/gradle/release/publishing.gradle @@ -29,7 +29,7 @@ publishing { } pom { name = 'Base Metals' - description = 'Metals, alloys, equipment and Crack Hammer processing for Minecraft 1.10.2.' + description = 'Metals, alloys, equipment and Crack Hammer processing for Minecraft 1.11.2.' url = 'https://github.com/MinecraftModDevelopmentMods/BaseMetals' licenses { license { diff --git a/gradle/verification/legacy-runtime.gradle b/gradle/verification/legacy-runtime.gradle index 112f08b75..368a76789 100644 --- a/gradle/verification/legacy-runtime.gradle +++ b/gradle/verification/legacy-runtime.gradle @@ -18,6 +18,10 @@ sourceSets { java.srcDirs = ['tools/validation/legacy110/capture-probe'] compileClasspath = sourceSets.main.compileClasspath } + fantasyProbe { + java.srcDirs = ['tools/validation/legacy110/fantasy-probe'] + compileClasspath = sourceSets.main.output + sourceSets.main.compileClasspath + } } def captureJar = tasks.register('captureProbeJar', Jar) { @@ -79,11 +83,26 @@ tasks.register('migrationProbeJar', Jar) { } } +def fantasyProbe = tasks.register('fantasyProbeJar', Jar) { + group = 'verification' + archiveFileName = 'fantasy-probe.jar' + destinationDirectory = layout.buildDirectory.dir('test-mods') + from sourceSets.fantasyProbe.output +} +def packagedFantasyProbe = renamer.classes(fantasyProbe) { + map.from minecraft.dependency.toSrgFile + output = layout.buildDirectory.file('test-mods/fantasy-probe-packaged.jar') +} +tasks.register('packagedFantasyProbeJar') { + group = 'verification' + dependsOn packagedFantasyProbe +} + tasks.register('packagedForgeRuntimeTest', Exec) { group = 'verification' - description = 'Tests OS1/OS3 imports, overrides, reloads and the vanilla takeover switch.' - dependsOn 'verifyReleaseArtifacts', 'packagedLaunchProbeJar', 'packagedOreSpawnProbeJar', - 'migrationProbeJar', packagedCapture + description = 'Checks 1.11.2 save upgrades, OreSpawn imports, molten metals and Modern Metals on packaged Forge.' + dependsOn 'verifyReleaseArtifacts', 'packagedLaunchProbeJar', 'packagedOreSpawnProbeJar', 'packagedFantasyProbeJar', + packagedCapture doFirst { def runtime = providers.gradleProperty('packagedForgeRuntimeRoot') if (!runtime.isPresent()) throw new GradleException('Set packagedForgeRuntimeRoot to a prepared Forge server.') diff --git a/src/main/java/com/mcmoddev/lib/asm/ASMHooks.java b/src/main/java/com/mcmoddev/lib/asm/ASMHooks.java index da1032f23..22c85fcce 100644 --- a/src/main/java/com/mcmoddev/lib/asm/ASMHooks.java +++ b/src/main/java/com/mcmoddev/lib/asm/ASMHooks.java @@ -1,6 +1,5 @@ package com.mcmoddev.lib.asm; -import com.google.common.base.Optional; import com.mcmoddev.lib.common.item.IHorseArmor; import net.minecraft.entity.passive.EntityHorse; @@ -14,7 +13,7 @@ public class ASMHooks { - public static final DataParameter> ARMOR_STACK = EntityDataManager + public static final DataParameter ARMOR_STACK = EntityDataManager .createKey(EntityHorse.class, DataSerializers.OPTIONAL_ITEM_STACK); private ASMHooks() { @@ -22,11 +21,11 @@ private ASMHooks() { } public static void onInitHorse(final EntityHorse entity) { - entity.getDataManager().register(ASMHooks.ARMOR_STACK, Optional.absent()); + entity.getDataManager().register(ASMHooks.ARMOR_STACK, ItemStack.EMPTY); } public static void setHorseArmorStack(final EntityHorse entity, final ItemStack stack) { - entity.getDataManager().set(ASMHooks.ARMOR_STACK, Optional.fromNullable(stack)); + entity.getDataManager().set(ASMHooks.ARMOR_STACK, stack == null ? ItemStack.EMPTY : stack); } /** @@ -37,8 +36,8 @@ public static void setHorseArmorStack(final EntityHorse entity, final ItemStack */ @SideOnly(Side.CLIENT) public static String getTextureName(final HorseArmorType type, final EntityHorse entity) { - final ItemStack stack = entity.getDataManager().get(ASMHooks.ARMOR_STACK).orNull(); - if ((stack != null) && (stack.getItem() instanceof IHorseArmor)) { + final ItemStack stack = entity.getDataManager().get(ASMHooks.ARMOR_STACK); + if (!stack.isEmpty() && (stack.getItem() instanceof IHorseArmor)) { return ((IHorseArmor) stack.getItem()).getHorseArmorTexture(entity, stack); } return type.getTextureName(); diff --git a/src/main/java/com/mcmoddev/lib/asm/ASMPlugin.java b/src/main/java/com/mcmoddev/lib/asm/ASMPlugin.java index 1cd2dbf67..7e26f217a 100644 --- a/src/main/java/com/mcmoddev/lib/asm/ASMPlugin.java +++ b/src/main/java/com/mcmoddev/lib/asm/ASMPlugin.java @@ -14,7 +14,7 @@ import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin.SortingIndex; @Name("BaseMetals") -@MCVersion("1.10.2") +@MCVersion("1.11.2") @SortingIndex(1001) public class ASMPlugin implements IFMLLoadingPlugin { diff --git a/src/main/java/com/mcmoddev/lib/block/BlockMMDAnvil.java b/src/main/java/com/mcmoddev/lib/block/BlockMMDAnvil.java index eee691f5e..d0b7a5057 100644 --- a/src/main/java/com/mcmoddev/lib/block/BlockMMDAnvil.java +++ b/src/main/java/com/mcmoddev/lib/block/BlockMMDAnvil.java @@ -9,7 +9,6 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Container; -import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; @@ -50,8 +49,7 @@ public MMDMaterial getMMDMaterial() { @Override public boolean onBlockActivated(final World worldIn, final BlockPos pos, final IBlockState state, final EntityPlayer playerIn, final EnumHand hand, - final ItemStack itemStack, final EnumFacing facing, final float hitX, final float hitY, - final float hitZ) { + final EnumFacing facing, final float hitX, final float hitY, final float hitZ) { if (!worldIn.isRemote) { playerIn.displayGui(new BlockMMDAnvil.MMDAnvil(worldIn, pos, this.material)); } diff --git a/src/main/java/com/mcmoddev/lib/block/BlockMMDBlock.java b/src/main/java/com/mcmoddev/lib/block/BlockMMDBlock.java index e015f9e4c..5c653baaa 100644 --- a/src/main/java/com/mcmoddev/lib/block/BlockMMDBlock.java +++ b/src/main/java/com/mcmoddev/lib/block/BlockMMDBlock.java @@ -77,15 +77,6 @@ public boolean isNormalCube(final IBlockState bs) { return true; } - /** - * @deprecated - */ - @Override - @Deprecated - public boolean isFullyOpaque(final IBlockState bs) { - return true; - } - /** * @deprecated */ diff --git a/src/main/java/com/mcmoddev/lib/block/BlockMMDDoor.java b/src/main/java/com/mcmoddev/lib/block/BlockMMDDoor.java index 3ddfa99e6..b85368072 100644 --- a/src/main/java/com/mcmoddev/lib/block/BlockMMDDoor.java +++ b/src/main/java/com/mcmoddev/lib/block/BlockMMDDoor.java @@ -67,8 +67,7 @@ public Item getItemDropped(final IBlockState state, final Random rand, final int @Override public boolean onBlockActivated(final World worldIn, final BlockPos pos, final IBlockState state, final EntityPlayer playerIn, final EnumHand hand, - final ItemStack heldItem, final EnumFacing facing, final float hitX, final float hitY, - final float hitZ) { + final EnumFacing facing, final float hitX, final float hitY, final float hitZ) { if ((this.material.getToolHarvestLevel() > 1) || (this.material.getType().equals(MaterialType.METAL))) { return false; diff --git a/src/main/java/com/mcmoddev/lib/block/BlockMMDPlate.java b/src/main/java/com/mcmoddev/lib/block/BlockMMDPlate.java index 832a61e50..17f704aca 100644 --- a/src/main/java/com/mcmoddev/lib/block/BlockMMDPlate.java +++ b/src/main/java/com/mcmoddev/lib/block/BlockMMDPlate.java @@ -247,8 +247,8 @@ public AxisAlignedBB getBoundingBox(final IBlockState bs, final IBlockAccess wor @Deprecated public void addCollisionBoxToList(final IBlockState state, final World worldIn, final BlockPos pos, final AxisAlignedBB entityBox, - final List collidingBoxes, @Nullable final Entity entityIn) { -// final EnumFacing orientation = worldIn.getBlockState(pos).getValue(FACING); + final List collidingBoxes, @Nullable final Entity entityIn, + final boolean isActualState) { final EnumFacing orientation = state.getValue(FACING); addCollisionBoxToList(pos, entityBox, collidingBoxes, BOXES[orientation.ordinal()]); } diff --git a/src/main/java/com/mcmoddev/lib/block/BlockMMDTrapDoor.java b/src/main/java/com/mcmoddev/lib/block/BlockMMDTrapDoor.java index 95a2e3e48..793352031 100644 --- a/src/main/java/com/mcmoddev/lib/block/BlockMMDTrapDoor.java +++ b/src/main/java/com/mcmoddev/lib/block/BlockMMDTrapDoor.java @@ -9,7 +9,6 @@ import net.minecraft.block.BlockTrapDoor; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; @@ -41,8 +40,7 @@ public BlockMMDTrapDoor(final MMDMaterial material) { @Override public boolean onBlockActivated(final World worldIn, final BlockPos pos, final IBlockState state, final EntityPlayer playerIn, final EnumHand hand, - final ItemStack heldItem, final EnumFacing facing, final float hitX, final float hitY, - final float hitZ) { + final EnumFacing facing, final float hitX, final float hitY, final float hitZ) { if ((this.material.getToolHarvestLevel() > 1) || (this.material.getType().equals(MaterialType.METAL))) { return false; diff --git a/src/main/java/com/mcmoddev/lib/block/BlockMMDWall.java b/src/main/java/com/mcmoddev/lib/block/BlockMMDWall.java index 1e8d6c5d2..d79d75f49 100644 --- a/src/main/java/com/mcmoddev/lib/block/BlockMMDWall.java +++ b/src/main/java/com/mcmoddev/lib/block/BlockMMDWall.java @@ -1,7 +1,5 @@ package com.mcmoddev.lib.block; -import java.util.List; - import com.mcmoddev.lib.data.Names; import com.mcmoddev.lib.material.IMMDObject; import com.mcmoddev.lib.material.MMDMaterial; @@ -10,6 +8,7 @@ import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraftforge.fml.relauncher.Side; @@ -42,7 +41,7 @@ public BlockMMDWall(final MMDMaterial material) { @Override @SideOnly(Side.CLIENT) public void getSubBlocks(final Item itemIn, final CreativeTabs tab, - final List list) { + final NonNullList list) { list.add(new ItemStack(itemIn)); } diff --git a/src/main/java/com/mcmoddev/lib/block/BlockMoltenFluid.java b/src/main/java/com/mcmoddev/lib/block/BlockMoltenFluid.java index 05a4bd093..7f827a218 100644 --- a/src/main/java/com/mcmoddev/lib/block/BlockMoltenFluid.java +++ b/src/main/java/com/mcmoddev/lib/block/BlockMoltenFluid.java @@ -3,6 +3,12 @@ import javax.annotation.Nonnull; import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.DamageSource; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; import net.minecraftforge.fluids.Fluid; /** @@ -20,4 +26,18 @@ public class BlockMoltenFluid extends net.minecraftforge.fluids.BlockFluidClassi public BlockMoltenFluid(@Nonnull final Fluid fluid) { super(fluid, Material.LAVA); } + + @Override + public void onEntityCollidedWithBlock(final World world, final BlockPos pos, + final IBlockState state, final Entity entity) { + super.onEntityCollidedWithBlock(world, pos, state, entity); + if (world.isRemote || !(entity instanceof EntityLivingBase) || entity.isImmuneToFire()) return; + if (entity.getEntityBoundingBox().minY >= pos.getY() + getFluidHeightForRender(world, pos)) return; + + // Vanilla shrinks the lava contact bounds and handles damage once the entity is deeper. + if (!entity.isInLava()) { + entity.attackEntityFrom(DamageSource.LAVA, 4.0F); + entity.setFire(15); + } + } } diff --git a/src/main/java/com/mcmoddev/lib/block/InteractiveFluidBlock.java b/src/main/java/com/mcmoddev/lib/block/InteractiveFluidBlock.java index 07df384d5..d8002b500 100644 --- a/src/main/java/com/mcmoddev/lib/block/InteractiveFluidBlock.java +++ b/src/main/java/com/mcmoddev/lib/block/InteractiveFluidBlock.java @@ -123,7 +123,7 @@ public int getFireSpreadSpeed(final IBlockAccess world, final BlockPos pos, @Deprecated @Override public AxisAlignedBB getCollisionBoundingBox(final IBlockState blockState, - final World worldIn, final BlockPos pos) { + final IBlockAccess worldIn, final BlockPos pos) { return NULL_AABB; } } diff --git a/src/main/java/com/mcmoddev/lib/entity/EntityHelpers.java b/src/main/java/com/mcmoddev/lib/entity/EntityHelpers.java index 99a1f62dd..cf9d69135 100644 --- a/src/main/java/com/mcmoddev/lib/entity/EntityHelpers.java +++ b/src/main/java/com/mcmoddev/lib/entity/EntityHelpers.java @@ -29,7 +29,7 @@ public static NBTTagCompound writeToNBTItemStack(final NBTTagCompound compound, * @return */ public static ItemStack readFromNBTItemStack(final NBTTagCompound compound) { - return ItemStack.loadItemStackFromNBT(compound.getCompoundTag("itemstack")); + return new ItemStack(compound.getCompoundTag("itemstack")); } } diff --git a/src/main/java/com/mcmoddev/lib/entity/projectile/EntityFishHook.java b/src/main/java/com/mcmoddev/lib/entity/projectile/EntityFishHook.java deleted file mode 100644 index c449eb042..000000000 --- a/src/main/java/com/mcmoddev/lib/entity/projectile/EntityFishHook.java +++ /dev/null @@ -1,489 +0,0 @@ -package com.mcmoddev.lib.entity.projectile; - -import java.util.List; - -import com.mcmoddev.lib.item.ItemFishingRod; - -import net.minecraft.block.Block; -import net.minecraft.block.material.Material; -import net.minecraft.enchantment.EnchantmentHelper; -import net.minecraft.entity.Entity; -import net.minecraft.entity.item.EntityItem; -import net.minecraft.entity.item.EntityXPOrb; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; -import net.minecraft.init.SoundEvents; -import net.minecraft.item.ItemStack; -import net.minecraft.network.datasync.DataParameter; -import net.minecraft.network.datasync.DataSerializers; -import net.minecraft.network.datasync.EntityDataManager; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.World; -import net.minecraft.world.WorldServer; -import net.minecraft.world.storage.loot.LootContext; -import net.minecraft.world.storage.loot.LootTableList; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -/** - * - * @author Jasmine Iwanek - * - */ -public class EntityFishHook extends net.minecraft.entity.projectile.EntityFishHook { - - private static final DataParameter DATA_HOOKED_ENTITY = EntityDataManager - .createKey(EntityFishHook.class, DataSerializers.VARINT); - private Block inTile; - private boolean inGround; - private int ticksInGround; - private int ticksInAir; - private int ticksCatchable; - private int ticksCaughtDelay; - private int ticksCatchableDelay; - private float fishApproachAngle; - private int fishPosRotationIncrements; - private double fishX; - private double fishY; - private double fishZ; - private double fishYaw; - private double fishPitch; - @SideOnly(Side.CLIENT) - private double clientMotionX; - @SideOnly(Side.CLIENT) - private double clientMotionY; - @SideOnly(Side.CLIENT) - private double clientMotionZ; - - /** - * - * @param worldIn - * The World - */ - public EntityFishHook(final World worldIn) { - super(worldIn); - } - - /** - * - * @param worldIn - * The World - * @param x - * X - * @param y - * Y - * @param z - * Z - * @param anglerIn - * The bobber - */ - @SideOnly(Side.CLIENT) - public EntityFishHook(final World worldIn, final double x, final double y, final double z, - final EntityPlayer anglerIn) { - super(worldIn, x, y, z, anglerIn); - } - - /** - * - * @param worldIn - * The World - * @param fishingPlayer - * The player - */ - public EntityFishHook(final World worldIn, final EntityPlayer fishingPlayer) { - super(worldIn, fishingPlayer); - } - - // Do we need to override this? - @Override - protected void entityInit() { - this.getDataManager().register(DATA_HOOKED_ENTITY, Integer.valueOf(0)); - } - - // Do we need to override this? - @Override - public void notifyDataManagerChange(final DataParameter key) { - if (DATA_HOOKED_ENTITY.equals(key)) { - final int i = (this.getDataManager().get(DATA_HOOKED_ENTITY)).intValue(); - - if ((i > 0) && (this.caughtEntity != null)) { - this.caughtEntity = null; - } - } - - super.notifyDataManagerChange(key); - } - - /** - * Called to update the entity's position/logic. - */ - @Override - public void onUpdate() { - // super.onUpdate(); - - if (!this.world.isRemote) { - this.setFlag(6, this.isGlowing()); - } - - this.onEntityUpdate(); - - if (this.world.isRemote) { - final int i = (this.getDataManager().get(DATA_HOOKED_ENTITY)).intValue(); - - if ((i > 0) && (this.caughtEntity == null)) { - this.caughtEntity = this.world.getEntityByID(i - 1); - } - } else { - final ItemStack itemstack = this.angler.getHeldItemMainhand(); - - // We had to change this due to hardcoding - if (this.angler.isDead || !this.angler.isEntityAlive() || (itemstack == null) - || !(itemstack.getItem() instanceof ItemFishingRod) - || (this.getDistanceSqToEntity(this.angler) > 1024.0D)) { - this.setDead(); - this.angler.fishEntity = null; - return; - } - } - - if (this.caughtEntity != null) { - if (!this.caughtEntity.isDead) { - this.posX = this.caughtEntity.posX; - final double d17 = this.caughtEntity.height; - this.posY = this.caughtEntity.getEntityBoundingBox().minY + (d17 * 0.8D); - this.posZ = this.caughtEntity.posZ; - return; - } - - this.caughtEntity = null; - } - - if (this.fishPosRotationIncrements > 0) { - final double d3 = this.posX - + ((this.fishX - this.posX) / this.fishPosRotationIncrements); - final double d4 = this.posY - + ((this.fishY - this.posY) / this.fishPosRotationIncrements); - final double d6 = this.posZ - + ((this.fishZ - this.posZ) / this.fishPosRotationIncrements); - final double d8 = MathHelper.wrapDegrees(this.fishYaw - this.rotationYaw); - this.rotationYaw = (float) (this.rotationYaw + (d8 / this.fishPosRotationIncrements)); - this.rotationPitch = (float) (this.rotationPitch - + ((this.fishPitch - this.rotationPitch) / this.fishPosRotationIncrements)); - --this.fishPosRotationIncrements; - this.setPosition(d3, d4, d6); - this.setRotation(this.rotationYaw, this.rotationPitch); - } else { - if (this.inGround) { - // TODO: Differs - if (this.world.getBlockState(new BlockPos(this.posX, this.posY, this.posZ)) - .getBlock() == this.inTile) { - ++this.ticksInGround; - - if (this.ticksInGround == 1200) { - this.setDead(); - } - - return; - } - - this.inGround = false; - this.motionX *= this.rand.nextFloat() * 0.2F; - this.motionY *= this.rand.nextFloat() * 0.2F; - this.motionZ *= this.rand.nextFloat() * 0.2F; - this.ticksInGround = 0; - this.ticksInAir = 0; - } else { - ++this.ticksInAir; - } - - if (!this.world.isRemote) { - Vec3d vec3d1 = new Vec3d(this.posX, this.posY, this.posZ); - Vec3d vec3d = new Vec3d(this.posX + this.motionX, this.posY + this.motionY, - this.posZ + this.motionZ); - RayTraceResult raytraceresult = this.world.rayTraceBlocks(vec3d1, vec3d); - vec3d1 = new Vec3d(this.posX, this.posY, this.posZ); - vec3d = new Vec3d(this.posX + this.motionX, this.posY + this.motionY, - this.posZ + this.motionZ); - - if (raytraceresult != null) { - vec3d = new Vec3d(raytraceresult.hitVec.xCoord, raytraceresult.hitVec.yCoord, - raytraceresult.hitVec.zCoord); - } - - Entity entity = null; - final List list = this.world.getEntitiesWithinAABBExcludingEntity(this, - this.getEntityBoundingBox() - .addCoord(this.motionX, this.motionY, this.motionZ) - .expandXyz(1.0D)); - double d0 = 0.0D; - - for (int j = 0; j < list.size(); ++j) { - final Entity entity1 = list.get(j); - - if (entity1.canBeCollidedWith() - && ((entity1 != this.angler) || (this.ticksInAir >= 5))) { - final AxisAlignedBB axisalignedbb1 = entity1.getEntityBoundingBox() - .expandXyz(0.30000001192092896D); - final RayTraceResult raytraceresult1 = axisalignedbb1 - .calculateIntercept(vec3d1, vec3d); - - if (raytraceresult1 != null) { - final double d1 = vec3d1.squareDistanceTo(raytraceresult1.hitVec); - - if ((d1 < d0) || (d0 == 0.0D)) { - entity = entity1; - d0 = d1; - } - } - } - } - - if (entity != null) { - raytraceresult = new RayTraceResult(entity); - } - - if (raytraceresult != null) { - if (raytraceresult.entityHit != null) { - this.caughtEntity = raytraceresult.entityHit; - this.getDataManager().set(DATA_HOOKED_ENTITY, - Integer.valueOf(this.caughtEntity.getEntityId() + 1)); - } else { - this.inGround = true; - } - } - } - - if (!this.inGround) { - this.move(this.motionX, this.motionY, this.motionZ); - final float f2 = MathHelper - .sqrt((this.motionX * this.motionX) + (this.motionZ * this.motionZ)); - this.rotationYaw = (float) (MathHelper.atan2(this.motionX, this.motionZ) - * (180D / Math.PI)); - - for (this.rotationPitch = (float) (MathHelper.atan2(this.motionY, f2) - * (180D / Math.PI)); (this.rotationPitch - - this.prevRotationPitch) < -180.0F; this.prevRotationPitch -= 360.0F) { - ; - } - - while ((this.rotationPitch - this.prevRotationPitch) >= 180.0F) { - this.prevRotationPitch += 360.0F; - } - - while ((this.rotationYaw - this.prevRotationYaw) < -180.0F) { - this.prevRotationYaw -= 360.0F; - } - - while ((this.rotationYaw - this.prevRotationYaw) >= 180.0F) { - this.prevRotationYaw += 360.0F; - } - - this.rotationPitch = this.prevRotationPitch - + ((this.rotationPitch - this.prevRotationPitch) * 0.2F); - this.rotationYaw = this.prevRotationYaw - + ((this.rotationYaw - this.prevRotationYaw) * 0.2F); - float f3 = 0.92F; - - if (this.onGround || this.isCollidedHorizontally) { - f3 = 0.5F; - } - - // final int k = 5; - double d5 = 0.0D; - - for (int l = 0; l < 5; ++l) { - final AxisAlignedBB axisalignedbb = this.getEntityBoundingBox(); - final double d9 = axisalignedbb.maxY - axisalignedbb.minY; - final double d10 = axisalignedbb.minY + ((d9 * l) / 5.0D); - final double d11 = axisalignedbb.minY + ((d9 * (l + 1)) / 5.0D); - final AxisAlignedBB axisalignedbb2 = new AxisAlignedBB(axisalignedbb.minX, d10, - axisalignedbb.minZ, axisalignedbb.maxX, d11, axisalignedbb.maxZ); - - if (this.world.isAABBInMaterial(axisalignedbb2, Material.WATER)) { - d5 += 0.2D; - } - } - - if (!this.world.isRemote && (d5 > 0.0D)) { - final WorldServer worldserver = (WorldServer) this.world; - int i1 = 1; - final BlockPos blockpos = (new BlockPos(this)).up(); - - if ((this.rand.nextFloat() < 0.25F) && this.world.isRainingAt(blockpos)) { - i1 = 2; - } - - if ((this.rand.nextFloat() < 0.5F) && !this.world.canSeeSky(blockpos)) { - --i1; - } - - if (this.ticksCatchable > 0) { - --this.ticksCatchable; - - if (this.ticksCatchable <= 0) { - this.ticksCaughtDelay = 0; - this.ticksCatchableDelay = 0; - } - } else if (this.ticksCatchableDelay > 0) { - this.ticksCatchableDelay -= i1; - - if (this.ticksCatchableDelay <= 0) { - this.motionY -= 0.20000000298023224D; - this.playSound(SoundEvents.ENTITY_BOBBER_SPLASH, 0.25F, 1.0F - + ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F)); - final float f6 = MathHelper.floor(this.getEntityBoundingBox().minY); - worldserver.spawnParticle(EnumParticleTypes.WATER_BUBBLE, this.posX, - f6 + 1.0F, this.posZ, (int) (1.0F + (this.width * 20.0F)), - this.width, 0.0D, this.width, 0.20000000298023224D, new int[0]); - worldserver.spawnParticle(EnumParticleTypes.WATER_WAKE, this.posX, - f6 + 1.0F, this.posZ, (int) (1.0F + (this.width * 20.0F)), - this.width, 0.0D, this.width, 0.20000000298023224D, new int[0]); - this.ticksCatchable = MathHelper.getInt(this.rand, 10, 30); - } else { - this.fishApproachAngle = (float) (this.fishApproachAngle - + (this.rand.nextGaussian() * 4.0D)); - final float f5 = this.fishApproachAngle * 0.017453292F; - final float f8 = MathHelper.sin(f5); - final float f10 = MathHelper.cos(f5); - final double d13 = this.posX + f8 * this.ticksCatchableDelay * 0.1F; - final double d15 = MathHelper.floor(this.getEntityBoundingBox().minY) - + 1.0F; - final double d16 = this.posZ + f10 * this.ticksCatchableDelay * 0.1F; - final Block block1 = worldserver - .getBlockState( - new BlockPos((int) d13, (int) d15 - 1, (int) d16)) - .getBlock(); - - if ((block1 == Blocks.WATER) || (block1 == Blocks.FLOWING_WATER)) { - if (this.rand.nextFloat() < 0.15F) { - worldserver.spawnParticle(EnumParticleTypes.WATER_BUBBLE, d13, - d15 - 0.10000000149011612D, d16, 1, f8, 0.1D, f10, 0.0D, - new int[0]); - } - - final float f = f8 * 0.04F; - final float f1 = f10 * 0.04F; - worldserver.spawnParticle(EnumParticleTypes.WATER_WAKE, d13, d15, - d16, 0, f1, 0.01D, (-f), 1.0D, new int[0]); - worldserver.spawnParticle(EnumParticleTypes.WATER_WAKE, d13, d15, - d16, 0, (-f1), 0.01D, f, 1.0D, new int[0]); - } - } - } else if (this.ticksCaughtDelay > 0) { - this.ticksCaughtDelay -= i1; - float f4 = 0.15F; - - if (this.ticksCaughtDelay < 20) { - f4 = (float) (f4 + ((20 - this.ticksCaughtDelay) * 0.05D)); - } else if (this.ticksCaughtDelay < 40) { - f4 = (float) (f4 + ((40 - this.ticksCaughtDelay) * 0.02D)); - } else if (this.ticksCaughtDelay < 60) { - f4 = (float) (f4 + ((60 - this.ticksCaughtDelay) * 0.01D)); - } - - if (this.rand.nextFloat() < f4) { - final float f7 = MathHelper.nextFloat(this.rand, 0.0F, 360.0F) - * 0.017453292F; - final float f9 = MathHelper.nextFloat(this.rand, 25.0F, 60.0F); - final double d12 = this.posX + MathHelper.sin(f7) * f9 * 0.1F; - final double d14 = MathHelper.floor(this.getEntityBoundingBox().minY) - + 1.0F; - final double d2 = this.posZ + MathHelper.cos(f7) * f9 * 0.1F; - final Block block = worldserver - .getBlockState(new BlockPos((int) d12, (int) d14 - 1, (int) d2)) - .getBlock(); - - if ((block == Blocks.WATER) || (block == Blocks.FLOWING_WATER)) { - worldserver.spawnParticle(EnumParticleTypes.WATER_SPLASH, d12, d14, - d2, 2 + this.rand.nextInt(2), 0.10000000149011612D, 0.0D, - 0.10000000149011612D, 0.0D, new int[0]); - } - } - - if (this.ticksCaughtDelay <= 0) { - this.fishApproachAngle = MathHelper.nextFloat(this.rand, 0.0F, 360.0F); - this.ticksCatchableDelay = MathHelper.getInt(this.rand, 20, 80); - } - } else { - this.ticksCaughtDelay = MathHelper.getInt(this.rand, 100, 900); - this.ticksCaughtDelay -= EnchantmentHelper.getLureModifier(this.angler) * 20 - * 5; - } - - if (this.ticksCatchable > 0) { - this.motionY -= this.rand.nextFloat() * this.rand.nextFloat() - * this.rand.nextFloat() * 0.2D; - } - } - - final double d7 = (d5 * 2.0D) - 1.0D; - this.motionY += 0.03999999910593033D * d7; - - if (d5 > 0.0D) { - f3 = (float) (f3 * 0.9D); - this.motionY *= 0.8D; - } - - this.motionX *= f3; - this.motionY *= f3; - this.motionZ *= f3; - this.setPosition(this.posX, this.posY, this.posZ); - } - } - } - - // Do we need to override this? - @Override - public int handleHookRetraction() { - if (this.world.isRemote) { - return 0; - } else { - int i = 0; - - if (this.caughtEntity != null) { - this.bringInHookedEntity(); - this.world.setEntityState(this, (byte) 31); - i = this.caughtEntity instanceof EntityItem ? 3 : 5; - } else if (this.ticksCatchable > 0) { - final LootContext.Builder lootcontext$builder = new LootContext.Builder( - (WorldServer) this.world); - lootcontext$builder.withLuck(EnchantmentHelper.getLuckOfSeaModifier(this.angler) - + this.angler.getLuck()); - - for (final ItemStack itemstack : this.world.getLootTableManager() - .getLootTableFromLocation(LootTableList.GAMEPLAY_FISHING) - .generateLootForPools(this.rand, lootcontext$builder.build())) { - final EntityItem entityitem = new EntityItem(this.world, this.posX, this.posY, - this.posZ, itemstack); - final double d0 = this.angler.posX - this.posX; - final double d1 = this.angler.posY - this.posY; - final double d2 = this.angler.posZ - this.posZ; - final double d3 = MathHelper.sqrt((d0 * d0) + (d1 * d1) + (d2 * d2)); - // final double d4 = 0.1D; - entityitem.motionX = d0 * 0.1D; - entityitem.motionY = (d1 * 0.1D) + (MathHelper.sqrt(d3) * 0.08D); - entityitem.motionZ = d2 * 0.1D; - this.world.spawnEntity(entityitem); - this.angler.world.spawnEntity(new EntityXPOrb(this.angler.world, - this.angler.posX, this.angler.posY + 0.5D, this.angler.posZ + 0.5D, - this.rand.nextInt(6) + 1)); - } - - i = 1; - } - - if (this.inGround) { - i = 2; - } - - this.setDead(); - this.angler.fishEntity = null; - return i; - } - } -} diff --git a/src/main/java/com/mcmoddev/lib/init/Fluids.java b/src/main/java/com/mcmoddev/lib/init/Fluids.java index 50e6c57fd..18996f661 100644 --- a/src/main/java/com/mcmoddev/lib/init/Fluids.java +++ b/src/main/java/com/mcmoddev/lib/init/Fluids.java @@ -9,12 +9,12 @@ import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import zone.moddev.mc.basemetals.data.MaterialNames; +import com.mcmoddev.lib.block.BlockMoltenFluid; import com.mcmoddev.lib.block.InteractiveFluidBlock; import com.mcmoddev.lib.data.SharedStrings; import com.mcmoddev.lib.fluids.CustomFluid; import com.mcmoddev.lib.material.MMDMaterial; -import net.minecraft.block.material.Material; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.MobEffects; @@ -109,7 +109,7 @@ protected static BlockFluidClassic addFluidBlock(@Nonnull final MMDMaterial mate } if (!name.equals(MaterialNames.MERCURY)) { - block = new BlockFluidClassic(material.getFluid(), Material.LAVA); + block = new BlockMoltenFluid(material.getFluid()); } else { block = new InteractiveFluidBlock(getFluidByName(name), false, (final World w, final EntityLivingBase e) -> { diff --git a/src/main/java/com/mcmoddev/lib/init/MMDCreativeTab.java b/src/main/java/com/mcmoddev/lib/init/MMDCreativeTab.java index 26035bf40..7a6851e84 100644 --- a/src/main/java/com/mcmoddev/lib/init/MMDCreativeTab.java +++ b/src/main/java/com/mcmoddev/lib/init/MMDCreativeTab.java @@ -1,7 +1,6 @@ package com.mcmoddev.lib.init; import java.util.Comparator; -import java.util.List; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -11,6 +10,7 @@ import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -65,7 +65,7 @@ public MMDCreativeTab(@Nonnull final String unlocalizedName, @Nonnull final bool public MMDCreativeTab(@Nonnull final String unlocalizedName, @Nonnull final boolean searchable, @Nullable final ItemStack iconItem) { super(unlocalizedName); - if (iconItem == null) { + if (iconItem == null || iconItem.isEmpty()) { this.iconItem = new ItemStack(net.minecraft.init.Items.IRON_PICKAXE); } else { this.iconItem = iconItem; @@ -84,7 +84,7 @@ public boolean hasSearchBar() { @Override @SideOnly(Side.CLIENT) - public void displayAllRelevantItems(@Nonnull final List itemList) { + public void displayAllRelevantItems(@Nonnull final NonNullList itemList) { super.displayAllRelevantItems(itemList); if (this.comparator != null) { itemList.sort(this.comparator); @@ -93,8 +93,8 @@ public void displayAllRelevantItems(@Nonnull final List itemList) { @Override @SideOnly(Side.CLIENT) - public Item getTabIconItem() { - return this.iconItem.getItem(); + public ItemStack getTabIconItem() { + return this.iconItem; } public void setSortingAlgorithm(@Nonnull final Comparator comparator) { diff --git a/src/main/java/com/mcmoddev/lib/init/VillagerTrades.java b/src/main/java/com/mcmoddev/lib/init/VillagerTrades.java index f0e45b86c..eca95f3e5 100644 --- a/src/main/java/com/mcmoddev/lib/init/VillagerTrades.java +++ b/src/main/java/com/mcmoddev/lib/init/VillagerTrades.java @@ -16,6 +16,7 @@ import com.mcmoddev.lib.data.SharedStrings; import com.mcmoddev.lib.material.MMDMaterial; +import net.minecraft.entity.IMerchant; import net.minecraft.entity.passive.EntityVillager.ITradeList; import net.minecraft.entity.passive.EntityVillager.ListEnchantedItemForEmeralds; import net.minecraft.entity.passive.EntityVillager.PriceInfo; @@ -89,7 +90,7 @@ protected static void registerCommonTrades() { for (final Names name : Arrays.asList(Names.HELMET, Names.CHESTPLATE, Names.LEGGINGS, Names.BOOTS)) { - if (material.hasItem(name)) { + if (canTrade(material, name)) { final ItemStack itemStack = material.getItemStack(name); final ITradeList[] armorTrades = makeTradePalette(makePurchasePalette( emeraldPurch + (int) (material.getStat(MaterialStats.HARDNESS) / 2), @@ -112,7 +113,7 @@ protected static void registerCommonTrades() { } } } - if (material.hasItem(Names.CRACKHAMMER)) { + if (canTrade(material, Names.CRACKHAMMER)) { final ItemStack itemStack = material.getItemStack(Names.CRACKHAMMER); final ITradeList[] hammerTrades = makeTradePalette( makePurchasePalette(emeraldPurch, itemStack)); @@ -128,7 +129,7 @@ protected static void registerCommonTrades() { // enchantedHammerTrades); } } - if (material.hasItem(Names.SWORD)) { + if (canTrade(material, Names.SWORD)) { final ItemStack itemStack = material.getItemStack(Names.SWORD); final ITradeList[] swordTrades = makeTradePalette(makePurchasePalette( (emeraldPurch + (int) (material.getBaseAttackDamage() / 2)) - 1, @@ -153,7 +154,7 @@ protected static void registerCommonTrades() { } } for (final Names name : Arrays.asList(Names.AXE, Names.HOE, Names.SHOVEL)) { - if (material.hasItem(name)) { + if (canTrade(material, name)) { final ItemStack itemStack = material.getItemStack(name); final ITradeList[] toolTrades = makeTradePalette( makePurchasePalette(emeraldPurch, itemStack)); @@ -161,7 +162,7 @@ protected static void registerCommonTrades() { toolTrades); } } - if (material.hasItem(Names.PICKAXE)) { + if (canTrade(material, Names.PICKAXE)) { final ItemStack itemStack = material.getItemStack(Names.PICKAXE); final ITradeList[] pickaxeTrades = makeTradePalette( makePurchasePalette(emeraldPurch, itemStack)); @@ -178,7 +179,7 @@ protected static void registerCommonTrades() { // enchantedPickaxeTrades); } } - if (material.hasItem(Names.INGOT)) { + if (canTrade(material, Names.INGOT)) { final ItemStack itemStack = material.getItemStack(Names.INGOT, 12); if ((!itemStack.getItem().equals(net.minecraft.init.Items.EMERALD)) && (!itemStack.getItem().equals(net.minecraft.init.Items.DIAMOND))) { @@ -198,6 +199,11 @@ protected static void registerCommonTrades() { commitTrades(tradesTable); } + private static boolean canTrade(final MMDMaterial material, final Names form) { + return material.hasItem(form) && zone.moddev.mc.basemetals.content.ContentAcquisition + .allowsIntegrationOutput(material.getItemStack(form)); + } + protected static void registerModSpecificTrades() { } @@ -336,7 +342,7 @@ protected static ITradeList[] makeSalePalette(@Nonnull final int emeraldValue, @Nonnull final ItemStack... itemStacks) { final ITradeList[] trades = new ITradeList[itemStacks.length]; for (int i = 0; i < itemStacks.length; i++) { - trades[i] = new SimpleTrade(itemStacks[i], fluctuation(itemStacks[i].stackSize), + trades[i] = new SimpleTrade(itemStacks[i], fluctuation(itemStacks[i].getCount()), new ItemStack(net.minecraft.init.Items.EMERALD, emeraldValue, 0), 0); } return trades; @@ -400,10 +406,10 @@ public MultiTradeGenerator(@Nonnull final int tradeCount, * a psuedorandom number generator instance */ @Override - public void modifyMerchantRecipeList(final MerchantRecipeList recipeList, + public void addMerchantRecipe(final IMerchant merchant, final MerchantRecipeList recipeList, final Random random) { for (int n = 0; n < this.numberOfTrades; n++) { - this.trades[random.nextInt(this.trades.length)].modifyMerchantRecipeList(recipeList, + this.trades[random.nextInt(this.trades.length)].addMerchantRecipe(merchant, recipeList, random); } } @@ -535,7 +541,7 @@ public String toString() { * a psuedorandom number generator instance */ @Override - public void modifyMerchantRecipeList(@Nonnull final MerchantRecipeList recipeList, + public void addMerchantRecipe(final IMerchant merchant, @Nonnull final MerchantRecipeList recipeList, @Nonnull final Random random) { int numTrades = -1; if (this.maxTrades > 0) { @@ -549,18 +555,18 @@ public void modifyMerchantRecipeList(@Nonnull final MerchantRecipeList recipeLis } final ItemStack in1 = this.input1.copy(); if (this.maxInputMarkup1 > 0) { - in1.stackSize = in1.stackSize + random.nextInt(this.maxInputMarkup1); + in1.setCount(in1.getCount() + random.nextInt(this.maxInputMarkup1)); } - ItemStack in2 = null; - if ((this.input2 != null) && (this.input2.getItem() != null)) { + ItemStack in2 = ItemStack.EMPTY; + if (this.input2 != null && !this.input2.isEmpty()) { in2 = this.input2.copy(); if (this.maxInputMarkup2 > 0) { - in2.stackSize = in2.stackSize + random.nextInt(this.maxInputMarkup2); + in2.setCount(in2.getCount() + random.nextInt(this.maxInputMarkup2)); } } final ItemStack out = this.output.copy(); if (this.maxOutputMarkup > 0) { - out.stackSize = out.stackSize + random.nextInt(this.maxOutputMarkup); + out.setCount(out.getCount() + random.nextInt(this.maxOutputMarkup)); } if (numTrades > 0) { diff --git a/src/main/java/com/mcmoddev/lib/integration/plugins/IC2Base.java b/src/main/java/com/mcmoddev/lib/integration/plugins/IC2Base.java index de482345a..b78997170 100644 --- a/src/main/java/com/mcmoddev/lib/integration/plugins/IC2Base.java +++ b/src/main/java/com/mcmoddev/lib/integration/plugins/IC2Base.java @@ -15,6 +15,7 @@ import ic2.api.recipe.IRecipeInput; import ic2.api.recipe.Recipes; import net.minecraft.item.ItemStack; +import zone.moddev.mc.basemetals.content.ContentAcquisition; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.fml.common.registry.GameRegistry; @@ -51,8 +52,12 @@ private void addForgeHammerRecipe(@Nonnull final MMDMaterial material) { Recipes.inputFactory.forOreDict("craftingToolForgeHammer"), Recipes.inputFactory.forOreDict(Oredicts.PLATE + material.getCapitalizedName())); - Recipes.advRecipes.addShapelessRecipe(casing, inputsCasing.toArray()); - Recipes.advRecipes.addShapelessRecipe(plate, inputsPlate.toArray()); + if (ContentAcquisition.allowsIntegrationOutput(casing)) { + Recipes.advRecipes.addShapelessRecipe(casing, inputsCasing.toArray()); + } + if (ContentAcquisition.allowsIntegrationOutput(plate)) { + Recipes.advRecipes.addShapelessRecipe(plate, inputsPlate.toArray()); + } } protected void registerVanillaRecipes(@Nonnull final String materialName) { @@ -74,7 +79,8 @@ protected void addMaceratorRecipes(@Nonnull final MMDMaterial material) { final IRecipeInput inputOre = Recipes.inputFactory.forOreDict(Oredicts.ORE + oreDictName); final IRecipeInput inputDensePlate = Recipes.inputFactory .forOreDict(Oredicts.PLATE_DENSE + oreDictName); - if (material.hasItem(Names.CRUSHED)) { + if (material.hasItem(Names.CRUSHED) + && ContentAcquisition.allowsIntegrationOutput(material.getItemStack(Names.CRUSHED))) { Recipes.macerator.addRecipe(inputOre, null, false, material.getItemStack(Names.CRUSHED, 2)); } @@ -87,7 +93,9 @@ protected void addMaceratorRecipes(@Nonnull final MMDMaterial material) { protected void addMaceratorRecipe(@Nonnull final String oreDict, @Nonnull final ItemStack output) { final IRecipeInput input = Recipes.inputFactory.forOreDict(oreDict); - Recipes.macerator.addRecipe(input, null, false, output); + if (ContentAcquisition.allowsIntegrationOutput(output)) { + Recipes.macerator.addRecipe(input, null, false, output); + } } protected void addOreWashingPlantRecipes(@Nonnull final String materialName) { @@ -100,7 +108,8 @@ protected void addOreWashingPlantRecipes(@Nonnull final MMDMaterial material) { .forOreDict(Oredicts.CRUSHED + oreDictName); final NBTTagCompound metadata = new NBTTagCompound(); metadata.setInteger("amount", 1000); - if ((material.hasItem(Names.CRUSHED_PURIFIED))) { + if (material.hasItem(Names.CRUSHED_PURIFIED) + && ContentAcquisition.allowsIntegrationOutput(material.getItemStack(Names.CRUSHED_PURIFIED))) { if (material.hasItem(Names.SMALLPOWDER)) { Recipes.oreWashing.addRecipe(inputOre, metadata, false, material.getItemStack(Names.CRUSHED_PURIFIED), @@ -158,15 +167,15 @@ protected void addMetalFormerRecipes(@Nonnull final MMDMaterial material) { final ItemStack outputCasing = material.getItemStack(Names.CASING, 2); final ItemStack outputFence = material.getBlockItemStack(Names.FENCE, 1); - if (material.hasBlock(Names.PLATE)) { + if (material.hasBlock(Names.PLATE) && ContentAcquisition.allowsIntegrationOutput(outputPlate)) { Recipes.metalformerRolling.addRecipe(inputIngot, null, false, outputPlate); } - if (material.hasItem(Names.CASING)) { + if (material.hasItem(Names.CASING) && ContentAcquisition.allowsIntegrationOutput(outputCasing)) { Recipes.metalformerRolling.addRecipe(inputPlate, null, false, outputCasing); } - if (material.hasBlock(Names.FENCE)) { + if (material.hasBlock(Names.FENCE) && ContentAcquisition.allowsIntegrationOutput(outputFence)) { Recipes.metalformerExtruding.addRecipe(inputCasing, null, false, outputFence); } } @@ -180,7 +189,8 @@ protected void addCompressorRecipes(@Nonnull final MMDMaterial material) { final IRecipeInput inputIngot = Recipes.inputFactory .forOreDict(Oredicts.PLATE + oreDictName, 9); final ItemStack outputDensePlate = material.getItemStack(Names.DENSE_PLATE); - if ((material.hasItem(Names.DENSE_PLATE)) && (material.hasItem(Names.PLATE))) { + if (material.hasItem(Names.DENSE_PLATE) && material.hasItem(Names.PLATE) + && ContentAcquisition.allowsIntegrationOutput(outputDensePlate)) { Recipes.compressor.addRecipe(inputIngot, null, false, outputDensePlate); } } diff --git a/src/main/java/com/mcmoddev/lib/integration/plugins/MekanismBase.java b/src/main/java/com/mcmoddev/lib/integration/plugins/MekanismBase.java index ea2a5f743..0e61020c8 100644 --- a/src/main/java/com/mcmoddev/lib/integration/plugins/MekanismBase.java +++ b/src/main/java/com/mcmoddev/lib/integration/plugins/MekanismBase.java @@ -12,6 +12,7 @@ import mekanism.api.gas.GasRegistry; import mekanism.api.gas.GasStack; import net.minecraft.item.ItemStack; +import zone.moddev.mc.basemetals.content.ContentAcquisition; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; @@ -154,6 +155,10 @@ protected static void addOreMultiplicationRecipes(@Nonnull final MMDMaterial mat protected static void addMetallurgicInfuserRecipe(@Nonnull final String infuse, @Nonnull final int amount, @Nonnull final ItemStack inputItem, @Nonnull final ItemStack outputItem) { + if (!ContentAcquisition.allowsIntegrationOutput(outputItem)) { + return; + } + final NBTTagCompound recipeTag = new NBTTagCompound(); // TODO: Check @@ -167,6 +172,10 @@ protected static void addMetallurgicInfuserRecipe(@Nonnull final String infuse, protected static void addCrusherRecipe(@Nonnull final ItemStack inputItem, @Nonnull final ItemStack outputItem) { + if (!ContentAcquisition.allowsIntegrationOutput(outputItem)) { + return; + } + final NBTTagCompound recipeTag = new NBTTagCompound(); recipeTag.setTag(INPUT, inputItem.writeToNBT(new NBTTagCompound())); @@ -177,6 +186,10 @@ protected static void addCrusherRecipe(@Nonnull final ItemStack inputItem, protected static void addEnrichmentChamberRecipe(@Nonnull final ItemStack inputItem, @Nonnull final ItemStack outputItem) { + if (!ContentAcquisition.allowsIntegrationOutput(outputItem)) { + return; + } + final NBTTagCompound recipeTag = new NBTTagCompound(); recipeTag.setTag(INPUT, inputItem.writeToNBT(new NBTTagCompound())); @@ -187,6 +200,10 @@ protected static void addEnrichmentChamberRecipe(@Nonnull final ItemStack inputI protected static void addPurificationChamberRecipe(@Nonnull final ItemStack inputItem, @Nonnull final ItemStack outputItem) { + if (!ContentAcquisition.allowsIntegrationOutput(outputItem)) { + return; + } + final GasStack inputGasStack = new GasStack(GasRegistry.getGas("oxygen"), 1000); final NBTTagCompound recipeTag = new NBTTagCompound(); @@ -199,6 +216,10 @@ protected static void addPurificationChamberRecipe(@Nonnull final ItemStack inpu protected static void addChemicalInjectionChamberRecipe(@Nonnull final ItemStack inputItem, @Nonnull final ItemStack outputItem) { + if (!ContentAcquisition.allowsIntegrationOutput(outputItem)) { + return; + } + final GasStack inputGasStack = new GasStack(GasRegistry.getGas("hydrogenChloride"), 1000); final NBTTagCompound recipeTag = new NBTTagCompound(); @@ -212,6 +233,10 @@ protected static void addChemicalInjectionChamberRecipe(@Nonnull final ItemStack // 5x, Slurry to Crystal protected static void addChemicalCrystallizerRecipe(@Nonnull final String inputGas, @Nonnull final int inputGasQty, @Nonnull final ItemStack outputItem) { + if (!ContentAcquisition.allowsIntegrationOutput(outputItem)) { + return; + } + final GasStack inputGasStack = new GasStack(GasRegistry.getGas(inputGas), inputGasQty); final NBTTagCompound recipeTag = new NBTTagCompound(); @@ -260,6 +285,10 @@ protected static void addPRCRecipe(@Nonnull final ItemStack inputItem, @Nonnull final int inputGasQty, @Nonnull final ItemStack outputItem, @Nonnull final String outputGas, @Nonnull final int outputGasQty, final int extraEnergy, final int ticks) { + if (!ContentAcquisition.allowsIntegrationOutput(outputItem)) { + return; + } + final GasStack inputGasStack = new GasStack(GasRegistry.getGas(inputGas), inputGasQty); final GasStack outputGasStack = new GasStack(GasRegistry.getGas(outputGas), outputGasQty); final NBTTagCompound recipeTag = new NBTTagCompound(); @@ -283,6 +312,10 @@ protected static void addPRCRecipe(@Nonnull final ItemStack inputItem, protected static void addOsmiumCompressorRecipe(@Nonnull final ItemStack inputItem, @Nonnull final ItemStack outputItem) { + if (!ContentAcquisition.allowsIntegrationOutput(outputItem)) { + return; + } + final NBTTagCompound recipeTag = new NBTTagCompound(); // TODO: Check @@ -294,6 +327,10 @@ protected static void addOsmiumCompressorRecipe(@Nonnull final ItemStack inputIt protected static void addCombinerRecipe(@Nonnull final ItemStack inputItem, @Nonnull final ItemStack outputItem) { + if (!ContentAcquisition.allowsIntegrationOutput(outputItem)) { + return; + } + final NBTTagCompound recipeTag = new NBTTagCompound(); // TODO: Check @@ -336,6 +373,10 @@ protected static void addChemicalInfuserRecipe(@Nonnull final String leftInputGa protected static void addPrecisionSawmillRecipe(@Nonnull final ItemStack inputItem, @Nonnull final ItemStack outputItem) { + if (!ContentAcquisition.allowsIntegrationOutput(outputItem)) { + return; + } + final NBTTagCompound recipeTag = new NBTTagCompound(); // TODO: Check @@ -348,6 +389,11 @@ protected static void addPrecisionSawmillRecipe(@Nonnull final ItemStack inputIt protected static void addPrecisionSawmillRecipe(@Nonnull final ItemStack inputItem, @Nonnull final ItemStack primaryOutput, @Nonnull final ItemStack secondaryOutput, @Nonnull final double chance) { + if (!ContentAcquisition.allowsIntegrationOutput(primaryOutput) + || !ContentAcquisition.allowsIntegrationOutput(secondaryOutput)) { + return; + } + final NBTTagCompound recipeTag = new NBTTagCompound(); // TODO: Check diff --git a/src/main/java/com/mcmoddev/lib/integration/plugins/ThermalExpansionBase.java b/src/main/java/com/mcmoddev/lib/integration/plugins/ThermalExpansionBase.java index 7b49c7788..ad041325b 100755 --- a/src/main/java/com/mcmoddev/lib/integration/plugins/ThermalExpansionBase.java +++ b/src/main/java/com/mcmoddev/lib/integration/plugins/ThermalExpansionBase.java @@ -1,249 +1,256 @@ -package com.mcmoddev.lib.integration.plugins; - -import javax.annotation.Nonnull; - -import com.mcmoddev.lib.data.Names; -import com.mcmoddev.lib.init.Materials; -import com.mcmoddev.lib.integration.IIntegration; -import com.mcmoddev.lib.material.MMDMaterial; -import com.mcmoddev.lib.util.ConfigBase.Options; - -import cofh.api.util.ThermalExpansionHelper; -import net.minecraft.item.ItemStack; -//import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.fluids.FluidRegistry; -import net.minecraftforge.fluids.FluidStack; -//import net.minecraftforge.fml.common.event.FMLInterModComms; - -// Parts of this are based on code from older versions of CoFHLib -// Other parts are lifted from the "ThermalExpansionHelper" of the 1.7 versions -// of CoFHLib - they were efficient and did the integration in the simplest -// manner. Why they've been removed, I don't know. - -public class ThermalExpansionBase implements IIntegration { - - public static final String PLUGIN_MODID = "thermalexpansion"; - // private static final String INPUT = "input"; - // private static final String OUTPUT = "output"; - // private static final String ENERGY = "energy"; - - @Override - public void init() { - if (!Options.isModEnabled(PLUGIN_MODID)) { - return; - } - } - - protected static void addPulverizerRecipe(@Nonnull final int energy, - @Nonnull final ItemStack input, @Nonnull final ItemStack output) { - if ((input == null) || (output == null)) { - return; - } - if ((input.getItem() == null) || (output.getItem() == null)) { - return; - } - - ThermalExpansionHelper.addPulverizerRecipe(energy, input, output); - } - - protected static void addCompactorPressRecipe(@Nonnull final int energy, - @Nonnull final ItemStack input, @Nonnull final ItemStack output) { - if ((input == null) || (output == null)) { - return; - } - if ((input.getItem() == null) || (output.getItem() == null)) { - return; - } - - ThermalExpansionHelper.addCompactorPressRecipe(energy, input, output); - /* - final NBTTagCompound toSend = new NBTTagCompound(); - - toSend.setInteger(ENERGY, energy); - toSend.setTag(INPUT, new NBTTagCompound()); - toSend.setTag(OUTPUT, new NBTTagCompound()); - input.writeToNBT(toSend.getCompoundTag(INPUT)); - output.writeToNBT(toSend.getCompoundTag(OUTPUT)); - FMLInterModComms.sendMessage(PLUGIN_MODID, "addcompactorpressrecipe", toSend); - */ - } - - protected static void addCompactorStorageRecipe(@Nonnull final int energy, - @Nonnull final ItemStack input, @Nonnull final ItemStack output) { - if ((input == null) || (output == null)) { - return; - } - if ((input.getItem() == null) || (output.getItem() == null)) { - return; - } - - ThermalExpansionHelper.addCompactorStorageRecipe(energy, input, output); - /* - final NBTTagCompound toSend = new NBTTagCompound(); - - toSend.setInteger(ENERGY, energy); - toSend.setTag(INPUT, new NBTTagCompound()); - toSend.setTag(OUTPUT, new NBTTagCompound()); - input.writeToNBT(toSend.getCompoundTag(INPUT)); - output.writeToNBT(toSend.getCompoundTag(OUTPUT)); - FMLInterModComms.sendMessage(PLUGIN_MODID, "addcompactorstoragerecipe", toSend); - */ - } - - protected static void addPulverizer(@Nonnull final String materialName) { - addPulverizer(Materials.getMaterialByName(materialName)); - } - - protected static void addPulverizer(@Nonnull final MMDMaterial material) { - if (material.isEmpty() || !material.hasItem(Names.POWDER)) { - return; - } - - /* - * default energy in TE for Ore -> Dust is 4000RF default energy in TE for Ingot -> Dust is - * 2000RF - */ - final int ENERGY_ORE = 4000; - final int ENERGY_INGOT = 2000; - final ItemStack inputOre = material.getBlockItemStack(Names.ORE); - final ItemStack inputIngot = material.getItemStack(Names.INGOT); - final ItemStack outputDust = material.getItemStack(Names.POWDER); - - if (material.hasItem(Names.POWDER)) { - if (material.hasBlock(Names.ORE)) { - addPulverizerRecipe(ENERGY_ORE, inputOre, outputDust); - } - if (material.hasItem(Names.INGOT)) { - addPulverizerRecipe(ENERGY_INGOT, inputIngot, outputDust); - } - } - } - - protected static void addFurnace(@Nonnull final String materialName) { - addFurnace(Materials.getMaterialByName(materialName)); - } - - protected static void addFurnace(@Nonnull final MMDMaterial material) { - if (material.isEmpty()) { - return; - } - - /* - * Ore -> Ingot default, according to TE source, is 2000 dust -> Ingot default, according to - * same, is DEFAULT * 14 / 20 - at the 2000RF default, this is 1400 - */ - final int ENERGY_ORE = 2000; - final int ENERGY_DUST = 1400; - ItemStack ore; - if (material.hasBlock(Names.ORE)) { - ore = material.getBlockItemStack(Names.ORE, 1); - } else if (material.hasItem(Names.BLEND)) { - ore = material.getItemStack(Names.BLEND, 1); - } else { - return; - } - - if (material.hasItem(Names.INGOT)) { - final ItemStack ingot = material.getItemStack(Names.INGOT, 1); - ThermalExpansionHelper.addFurnaceRecipe(ENERGY_ORE, ore, ingot); - if (material.hasItem(Names.POWDER)) { - final ItemStack dust = material.getItemStack(Names.POWDER, 1); - ThermalExpansionHelper.addFurnaceRecipe(ENERGY_DUST, dust, ingot); - } - } - } - - protected static void addCrucible(@Nonnull final String materialName) { - addCrucible(Materials.getMaterialByName(materialName)); - } - - protected static void addCrucible(@Nonnull final MMDMaterial material) { - if (material.isEmpty()) { - return; - } - - /* - * Default power, according to TE source, is 8000 This is used for Pyrotheum, Cryotheum, - * Aerotheum, Petrotheum and Redstone. Redstone Block is 72000 Glowstone and Ender Pearl are - * 20000 Glowstone block is 80000 Cobblestone/Stone/Obsidian is 320000 - */ - final int ENERGY_QTY = 8000; - - final String materialName = material.getName(); - final ItemStack ingot = material.getItemStack(Names.INGOT); - final ItemStack dust = material.getItemStack(Names.POWDER); - final FluidStack oreFluid = FluidRegistry.getFluidStack(materialName, 288); - final FluidStack baseFluid = FluidRegistry.getFluidStack(materialName, 144); - final FluidStack nuggetFluid = FluidRegistry.getFluidStack(materialName, 16); - - if (material.hasBlock(Names.ORE)) { - final ItemStack ore = material.getBlockItemStack(Names.ORE); - ThermalExpansionHelper.addCrucibleRecipe(ENERGY_QTY, ore, oreFluid); - } - - if (material.hasItem(Names.INGOT)) { - ThermalExpansionHelper.addCrucibleRecipe(ENERGY_QTY, ingot, baseFluid); - } - - if (material.hasItem(Names.POWDER)) { - ThermalExpansionHelper.addCrucibleRecipe(ENERGY_QTY, dust, baseFluid); - } - - if (material.hasBlock(Names.PLATE)) { - ThermalExpansionHelper.addCrucibleRecipe(ENERGY_QTY, - material.getBlockItemStack(Names.PLATE), - baseFluid); - } - - if (material.hasItem(Names.NUGGET)) { - ThermalExpansionHelper.addCrucibleRecipe(ENERGY_QTY, - material.getItemStack(Names.NUGGET), nuggetFluid); - } - } - - protected static void addPlatePress(@Nonnull final String materialName) { - addPlatePress(Materials.getMaterialByName(materialName)); - } - - protected static void addPlatePress(@Nonnull final MMDMaterial material) { - if (material.isEmpty()) { - return; - } - if (material.hasItem(Names.PLATE) && material.hasItem(Names.INGOT)) { - - /* - * Compactors default is 4000RF per operation - */ - final int ENERGY_QTY = 4000; - addCompactorPressRecipe(ENERGY_QTY, material.getItemStack(Names.INGOT), - material.getBlockItemStack(Names.PLATE)); - } - } - - protected static void addPressStorage(@Nonnull final String materialName) { - addPressStorage(Materials.getMaterialByName(materialName)); - } - - protected static void addPressStorage(@Nonnull final MMDMaterial material) { - if (material.isEmpty()) { - return; - } - /* - * Compactors default is 4000RF per operation - */ - final int ENERGY_QTY = 4000; - final ItemStack ingotStack = material.getItemStack(Names.INGOT); - final ItemStack ingotsStack = material.getItemStack(Names.INGOT, 9); - final ItemStack nuggetsStack = material.getItemStack(Names.NUGGET, 9); - final ItemStack blockStack = material.getBlockItemStack(Names.BLOCK, 1); - - if (material.hasItem(Names.INGOT)) { - if (material.hasBlock(Names.BLOCK)) { - addCompactorStorageRecipe(ENERGY_QTY, ingotsStack, blockStack); - } - if (material.hasItem(Names.NUGGET)) { - addCompactorStorageRecipe(ENERGY_QTY, nuggetsStack, ingotStack); - } - } - } -} +package com.mcmoddev.lib.integration.plugins; + +import javax.annotation.Nonnull; + +import com.mcmoddev.lib.data.Names; +import com.mcmoddev.lib.init.Materials; +import com.mcmoddev.lib.integration.IIntegration; +import com.mcmoddev.lib.material.MMDMaterial; +import com.mcmoddev.lib.util.ConfigBase.Options; + +import cofh.api.util.ThermalExpansionHelper; +import net.minecraft.item.ItemStack; +import zone.moddev.mc.basemetals.content.ContentAcquisition; +//import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; +//import net.minecraftforge.fml.common.event.FMLInterModComms; + +// Parts of this are based on code from older versions of CoFHLib +// Other parts are lifted from the "ThermalExpansionHelper" of the 1.7 versions +// of CoFHLib - they were efficient and did the integration in the simplest +// manner. Why they've been removed, I don't know. + +public class ThermalExpansionBase implements IIntegration { + + public static final String PLUGIN_MODID = "thermalexpansion"; + // private static final String INPUT = "input"; + // private static final String OUTPUT = "output"; + // private static final String ENERGY = "energy"; + + @Override + public void init() { + if (!Options.isModEnabled(PLUGIN_MODID)) { + return; + } + } + + protected static void addPulverizerRecipe(@Nonnull final int energy, + @Nonnull final ItemStack input, @Nonnull final ItemStack output) { + if ((input == null) || (output == null)) { + return; + } + if ((input.getItem() == null) || (output.getItem() == null)) { + return; + } + + if (ContentAcquisition.allowsIntegrationOutput(output)) { + ThermalExpansionHelper.addPulverizerRecipe(energy, input, output); + } + } + + protected static void addCompactorPressRecipe(@Nonnull final int energy, + @Nonnull final ItemStack input, @Nonnull final ItemStack output) { + if ((input == null) || (output == null)) { + return; + } + if ((input.getItem() == null) || (output.getItem() == null)) { + return; + } + + if (ContentAcquisition.allowsIntegrationOutput(output)) { + ThermalExpansionHelper.addCompactorPressRecipe(energy, input, output); + } + /* + final NBTTagCompound toSend = new NBTTagCompound(); + + toSend.setInteger(ENERGY, energy); + toSend.setTag(INPUT, new NBTTagCompound()); + toSend.setTag(OUTPUT, new NBTTagCompound()); + input.writeToNBT(toSend.getCompoundTag(INPUT)); + output.writeToNBT(toSend.getCompoundTag(OUTPUT)); + FMLInterModComms.sendMessage(PLUGIN_MODID, "addcompactorpressrecipe", toSend); + */ + } + + protected static void addCompactorStorageRecipe(@Nonnull final int energy, + @Nonnull final ItemStack input, @Nonnull final ItemStack output) { + if ((input == null) || (output == null)) { + return; + } + if ((input.getItem() == null) || (output.getItem() == null)) { + return; + } + + if (ContentAcquisition.allowsIntegrationOutput(output)) { + ThermalExpansionHelper.addCompactorStorageRecipe(energy, input, output); + } + /* + final NBTTagCompound toSend = new NBTTagCompound(); + + toSend.setInteger(ENERGY, energy); + toSend.setTag(INPUT, new NBTTagCompound()); + toSend.setTag(OUTPUT, new NBTTagCompound()); + input.writeToNBT(toSend.getCompoundTag(INPUT)); + output.writeToNBT(toSend.getCompoundTag(OUTPUT)); + FMLInterModComms.sendMessage(PLUGIN_MODID, "addcompactorstoragerecipe", toSend); + */ + } + + protected static void addPulverizer(@Nonnull final String materialName) { + addPulverizer(Materials.getMaterialByName(materialName)); + } + + protected static void addPulverizer(@Nonnull final MMDMaterial material) { + if (material.isEmpty() || !material.hasItem(Names.POWDER)) { + return; + } + + /* + * default energy in TE for Ore -> Dust is 4000RF default energy in TE for Ingot -> Dust is + * 2000RF + */ + final int ENERGY_ORE = 4000; + final int ENERGY_INGOT = 2000; + final ItemStack inputOre = material.getBlockItemStack(Names.ORE); + final ItemStack inputIngot = material.getItemStack(Names.INGOT); + final ItemStack outputDust = material.getItemStack(Names.POWDER); + + if (material.hasItem(Names.POWDER)) { + if (material.hasBlock(Names.ORE)) { + addPulverizerRecipe(ENERGY_ORE, inputOre, outputDust); + } + if (material.hasItem(Names.INGOT)) { + addPulverizerRecipe(ENERGY_INGOT, inputIngot, outputDust); + } + } + } + + protected static void addFurnace(@Nonnull final String materialName) { + addFurnace(Materials.getMaterialByName(materialName)); + } + + protected static void addFurnace(@Nonnull final MMDMaterial material) { + if (material.isEmpty()) { + return; + } + + /* + * Ore -> Ingot default, according to TE source, is 2000 dust -> Ingot default, according to + * same, is DEFAULT * 14 / 20 - at the 2000RF default, this is 1400 + */ + final int ENERGY_ORE = 2000; + final int ENERGY_DUST = 1400; + ItemStack ore; + if (material.hasBlock(Names.ORE)) { + ore = material.getBlockItemStack(Names.ORE, 1); + } else if (material.hasItem(Names.BLEND)) { + ore = material.getItemStack(Names.BLEND, 1); + } else { + return; + } + + if (material.hasItem(Names.INGOT)) { + final ItemStack ingot = material.getItemStack(Names.INGOT, 1); + ThermalExpansionHelper.addFurnaceRecipe(ENERGY_ORE, ore, ingot); + if (material.hasItem(Names.POWDER)) { + final ItemStack dust = material.getItemStack(Names.POWDER, 1); + ThermalExpansionHelper.addFurnaceRecipe(ENERGY_DUST, dust, ingot); + } + } + } + + protected static void addCrucible(@Nonnull final String materialName) { + addCrucible(Materials.getMaterialByName(materialName)); + } + + protected static void addCrucible(@Nonnull final MMDMaterial material) { + if (material.isEmpty()) { + return; + } + + /* + * Default power, according to TE source, is 8000 This is used for Pyrotheum, Cryotheum, + * Aerotheum, Petrotheum and Redstone. Redstone Block is 72000 Glowstone and Ender Pearl are + * 20000 Glowstone block is 80000 Cobblestone/Stone/Obsidian is 320000 + */ + final int ENERGY_QTY = 8000; + + final String materialName = material.getName(); + final ItemStack ingot = material.getItemStack(Names.INGOT); + final ItemStack dust = material.getItemStack(Names.POWDER); + final FluidStack oreFluid = FluidRegistry.getFluidStack(materialName, 288); + final FluidStack baseFluid = FluidRegistry.getFluidStack(materialName, 144); + final FluidStack nuggetFluid = FluidRegistry.getFluidStack(materialName, 16); + + if (material.hasBlock(Names.ORE)) { + final ItemStack ore = material.getBlockItemStack(Names.ORE); + ThermalExpansionHelper.addCrucibleRecipe(ENERGY_QTY, ore, oreFluid); + } + + if (material.hasItem(Names.INGOT)) { + ThermalExpansionHelper.addCrucibleRecipe(ENERGY_QTY, ingot, baseFluid); + } + + if (material.hasItem(Names.POWDER)) { + ThermalExpansionHelper.addCrucibleRecipe(ENERGY_QTY, dust, baseFluid); + } + + if (material.hasBlock(Names.PLATE)) { + ThermalExpansionHelper.addCrucibleRecipe(ENERGY_QTY, + material.getBlockItemStack(Names.PLATE), + baseFluid); + } + + if (material.hasItem(Names.NUGGET)) { + ThermalExpansionHelper.addCrucibleRecipe(ENERGY_QTY, + material.getItemStack(Names.NUGGET), nuggetFluid); + } + } + + protected static void addPlatePress(@Nonnull final String materialName) { + addPlatePress(Materials.getMaterialByName(materialName)); + } + + protected static void addPlatePress(@Nonnull final MMDMaterial material) { + if (material.isEmpty()) { + return; + } + if (material.hasItem(Names.PLATE) && material.hasItem(Names.INGOT)) { + + /* + * Compactors default is 4000RF per operation + */ + final int ENERGY_QTY = 4000; + addCompactorPressRecipe(ENERGY_QTY, material.getItemStack(Names.INGOT), + material.getBlockItemStack(Names.PLATE)); + } + } + + protected static void addPressStorage(@Nonnull final String materialName) { + addPressStorage(Materials.getMaterialByName(materialName)); + } + + protected static void addPressStorage(@Nonnull final MMDMaterial material) { + if (material.isEmpty()) { + return; + } + /* + * Compactors default is 4000RF per operation + */ + final int ENERGY_QTY = 4000; + final ItemStack ingotStack = material.getItemStack(Names.INGOT); + final ItemStack ingotsStack = material.getItemStack(Names.INGOT, 9); + final ItemStack nuggetsStack = material.getItemStack(Names.NUGGET, 9); + final ItemStack blockStack = material.getBlockItemStack(Names.BLOCK, 1); + + if (material.hasItem(Names.INGOT)) { + if (material.hasBlock(Names.BLOCK)) { + addCompactorStorageRecipe(ENERGY_QTY, ingotsStack, blockStack); + } + if (material.hasItem(Names.NUGGET)) { + addCompactorStorageRecipe(ENERGY_QTY, nuggetsStack, ingotStack); + } + } + } +} diff --git a/src/main/java/com/mcmoddev/lib/integration/plugins/tinkers/TinkersConstructRegistry.java b/src/main/java/com/mcmoddev/lib/integration/plugins/tinkers/TinkersConstructRegistry.java index f7725bb9c..95fe69e11 100755 --- a/src/main/java/com/mcmoddev/lib/integration/plugins/tinkers/TinkersConstructRegistry.java +++ b/src/main/java/com/mcmoddev/lib/integration/plugins/tinkers/TinkersConstructRegistry.java @@ -17,6 +17,8 @@ import net.minecraft.block.Block; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import zone.moddev.mc.basemetals.content.ContentAcquisition; +import zone.moddev.mc.basemetals.content.ContentPolicy; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; @@ -200,13 +202,19 @@ private TCCode register(@Nonnull final TCMaterial mat) { this.registerFluid(mmdMaterial, mat.getAmountPer()); - TinkerRegistry.addMaterialStats(tcmat, mat.getHeadStats()); - TinkerRegistry.addMaterialStats(tcmat, mat.getHandleStats()); - TinkerRegistry.addMaterialStats(tcmat, mat.getExtraStats()); - TinkerRegistry.addMaterialStats(tcmat, mat.getBowStats()); - TinkerRegistry.addMaterialStats(tcmat, mat.getBowStringStats()); - TinkerRegistry.addMaterialStats(tcmat, mat.getArrowShaftStats()); - TinkerRegistry.addMaterialStats(tcmat, mat.getFletchingStats()); + final boolean restricted = ContentAcquisition.restrictsIntegration(); + if (!restricted || ContentPolicy.active().allowsToolParts(mmdMaterial.getName())) { + TinkerRegistry.addMaterialStats(tcmat, mat.getHeadStats()); + TinkerRegistry.addMaterialStats(tcmat, mat.getHandleStats()); + TinkerRegistry.addMaterialStats(tcmat, mat.getExtraStats()); + } + + if (!restricted) { + TinkerRegistry.addMaterialStats(tcmat, mat.getBowStats()); + TinkerRegistry.addMaterialStats(tcmat, mat.getBowStringStats()); + TinkerRegistry.addMaterialStats(tcmat, mat.getArrowShaftStats()); + TinkerRegistry.addMaterialStats(tcmat, mat.getFletchingStats()); + } tcmat.setFluid(fluid).setCraftable(mat.getCraftable()).setCastable(mat.getCastable()) .addItem(matRepItem, 1, Material.VALUE_Ingot); @@ -388,8 +396,10 @@ public TCCode registerBasin(@Nonnull final Block block, @Nonnull final Fluid sou if (sourceQty == 0) { return TCCode.FAILURE_PARAMETER_ERROR; } - TinkerRegistry.registerBasinCasting(new ItemStack(block), null, source, - sourceQty); + final ItemStack output = new ItemStack(block); + if (ContentAcquisition.allowsIntegrationOutput(output)) { + TinkerRegistry.registerBasinCasting(output, null, source, sourceQty); + } return TCCode.SUCCESS; } @@ -409,8 +419,10 @@ public TCCode registerCasting(@Nonnull final Item output, @Nonnull final Fluid s if (sourceQty == 0) { return TCCode.FAILURE_PARAMETER_ERROR; } - TinkerRegistry.registerTableCasting(new ItemStack(output), null, source, - sourceQty); + final ItemStack stack = new ItemStack(output); + if (ContentAcquisition.allowsIntegrationOutput(stack)) { + TinkerRegistry.registerTableCasting(stack, null, source, sourceQty); + } return TCCode.SUCCESS; } diff --git a/src/main/java/com/mcmoddev/lib/integration/plugins/tinkers/traits/TraitReactive.java b/src/main/java/com/mcmoddev/lib/integration/plugins/tinkers/traits/TraitReactive.java index ae6f5fd77..ae40e45fc 100755 --- a/src/main/java/com/mcmoddev/lib/integration/plugins/tinkers/traits/TraitReactive.java +++ b/src/main/java/com/mcmoddev/lib/integration/plugins/tinkers/traits/TraitReactive.java @@ -1,41 +1,41 @@ -package com.mcmoddev.lib.integration.plugins.tinkers.traits; - -import javax.annotation.Nonnull; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.util.DamageSource; -import net.minecraft.util.text.TextFormatting; -import net.minecraft.world.World; -import slimeknights.tconstruct.library.traits.AbstractTrait; -import slimeknights.tconstruct.library.utils.ToolHelper; - -public class TraitReactive extends AbstractTrait { - - public TraitReactive() { - super("mmd-reactive", TextFormatting.BLACK); - } - - @Override - public void onUpdate(@Nonnull final ItemStack tool, @Nonnull final World world, - @Nonnull final Entity entity, @Nonnull final int itemSlot, - @Nonnull final boolean isSelected) { - if (!world.isRemote && (entity instanceof EntityPlayer) && entity.isWet() - && (((EntityPlayer) entity).getActiveItemStack() == tool)) { - ToolHelper.damageTool(tool, 5, (EntityLivingBase) entity); - } - } - - @Override - public void onHit(@Nonnull final ItemStack tool, @Nonnull final EntityLivingBase player, - @Nonnull final EntityLivingBase target, @Nonnull final float damage, - @Nonnull final boolean isCritical) { - if (target.canBreatheUnderwater()) { - // do extra damage - final DamageSource extraDamage = DamageSource.onFire; - target.attackEntityFrom(extraDamage, isCritical ? 8f : 4f); - } - } -} +package com.mcmoddev.lib.integration.plugins.tinkers.traits; + +import javax.annotation.Nonnull; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.DamageSource; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.world.World; +import slimeknights.tconstruct.library.traits.AbstractTrait; +import slimeknights.tconstruct.library.utils.ToolHelper; + +public class TraitReactive extends AbstractTrait { + + public TraitReactive() { + super("mmd-reactive", TextFormatting.BLACK); + } + + @Override + public void onUpdate(@Nonnull final ItemStack tool, @Nonnull final World world, + @Nonnull final Entity entity, @Nonnull final int itemSlot, + @Nonnull final boolean isSelected) { + if (!world.isRemote && (entity instanceof EntityPlayer) && entity.isWet() + && (((EntityPlayer) entity).getActiveItemStack() == tool)) { + ToolHelper.damageTool(tool, 5, (EntityLivingBase) entity); + } + } + + @Override + public void onHit(@Nonnull final ItemStack tool, @Nonnull final EntityLivingBase player, + @Nonnull final EntityLivingBase target, @Nonnull final float damage, + @Nonnull final boolean isCritical) { + if (target.canBreatheUnderwater()) { + // do extra damage + final DamageSource extraDamage = DamageSource.ON_FIRE; + target.attackEntityFrom(extraDamage, isCritical ? 8f : 4f); + } + } +} diff --git a/src/main/java/com/mcmoddev/lib/item/ItemBow.java b/src/main/java/com/mcmoddev/lib/item/ItemBow.java index a38bf4c47..21f3af4d9 100644 --- a/src/main/java/com/mcmoddev/lib/item/ItemBow.java +++ b/src/main/java/com/mcmoddev/lib/item/ItemBow.java @@ -111,9 +111,9 @@ public void onPlayerStoppedUsing(final ItemStack stack, final World worldIn, (1.0F / ((itemRand.nextFloat() * 0.4F) + 1.2F)) + (f * 0.5F)); if (!flag1) { - --itemStack.stackSize; + itemStack.shrink(1); - if (itemStack.stackSize == 0) { + if (itemStack.getCount() == 0) { entityPlayer.inventory.deleteStack(itemStack); } } @@ -154,8 +154,9 @@ protected boolean isArrow(@Nullable final ItemStack stack) { * Called when the equipped item is right clicked. */ @Override - public ActionResult onItemRightClick(final ItemStack itemStackIn, - final World worldIn, final EntityPlayer playerIn, final EnumHand handIn) { + public ActionResult onItemRightClick(final World worldIn, + final EntityPlayer playerIn, final EnumHand handIn) { + final ItemStack itemStackIn = playerIn.getHeldItem(handIn); // Check for specific Arrows final boolean flag = this.myFindAmmo(playerIn) != null; diff --git a/src/main/java/com/mcmoddev/lib/item/ItemCrossbow.java b/src/main/java/com/mcmoddev/lib/item/ItemCrossbow.java index 6143c2d8b..ea8001c2d 100644 --- a/src/main/java/com/mcmoddev/lib/item/ItemCrossbow.java +++ b/src/main/java/com/mcmoddev/lib/item/ItemCrossbow.java @@ -113,9 +113,9 @@ public void onPlayerStoppedUsing(final ItemStack stack, final World worldIn, (1.0F / ((itemRand.nextFloat() * 0.4F) + 1.2F)) + (f * 0.5F)); if (!flag1) { - --itemStack.stackSize; + itemStack.shrink(1); - if (itemStack.stackSize == 0) { + if (itemStack.getCount() == 0) { entityPlayer.inventory.deleteStack(itemStack); } } @@ -166,8 +166,9 @@ protected boolean isBolt(@Nullable final ItemStack stack) { * Called when the equipped item is right clicked. */ @Override - public ActionResult onItemRightClick(final ItemStack itemStackIn, - final World worldIn, final EntityPlayer playerIn, final EnumHand handIn) { + public ActionResult onItemRightClick(final World worldIn, + final EntityPlayer playerIn, final EnumHand handIn) { + final ItemStack itemStackIn = playerIn.getHeldItem(handIn); final boolean flag = this.myFindAmmo(playerIn) != null; if (!playerIn.capabilities.isCreativeMode && !flag) { diff --git a/src/main/java/com/mcmoddev/lib/item/ItemFishingRod.java b/src/main/java/com/mcmoddev/lib/item/ItemFishingRod.java deleted file mode 100644 index 555b729f7..000000000 --- a/src/main/java/com/mcmoddev/lib/item/ItemFishingRod.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.mcmoddev.lib.item; - -import com.mcmoddev.lib.entity.projectile.EntityFishHook; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; -import net.minecraft.item.ItemStack; -import net.minecraft.stats.StatList; -import net.minecraft.util.ActionResult; -import net.minecraft.util.EnumActionResult; -import net.minecraft.util.EnumHand; -import net.minecraft.util.SoundCategory; -import net.minecraft.world.World; - -/** - * - * @author Jasmine Iwanek - * - */ -public class ItemFishingRod extends net.minecraft.item.ItemFishingRod { - - @Override - public ActionResult onItemRightClick(final ItemStack itemStack, final World worldIn, - final EntityPlayer playerIn, final EnumHand hand) { - if (playerIn.fishEntity != null) { - final int i = playerIn.fishEntity.handleHookRetraction(); - itemStack.damageItem(i, playerIn); - playerIn.swingArm(hand); - } else { - worldIn.playSound((EntityPlayer) null, playerIn.posX, playerIn.posY, playerIn.posZ, - SoundEvents.ENTITY_BOBBER_THROW, SoundCategory.NEUTRAL, 0.5F, - 0.4F / ((itemRand.nextFloat() * 0.4F) + 0.8F)); - - if (!worldIn.isRemote) { - // Changed from MC EntityFishHook to BMe EntityFishHook - final EntityFishHook entityfishhook = new EntityFishHook(worldIn, playerIn); - - worldIn.spawnEntity(entityfishhook); - } - - playerIn.swingArm(hand); - playerIn.addStat(StatList.getObjectUseStats(this)); - } - - return new ActionResult<>(EnumActionResult.SUCCESS, itemStack); - } -} diff --git a/src/main/java/com/mcmoddev/lib/item/ItemMMDArmor.java b/src/main/java/com/mcmoddev/lib/item/ItemMMDArmor.java index 93d3d180c..3d72d52df 100644 --- a/src/main/java/com/mcmoddev/lib/item/ItemMMDArmor.java +++ b/src/main/java/com/mcmoddev/lib/item/ItemMMDArmor.java @@ -60,7 +60,7 @@ public void onArmorTick(final World w, final EntityPlayer player, final ItemStac playerUpdateTimestampMap.get(player).set(w.getTotalWorldTime() + UPDATE_INTERVAL); final int updateCount = playerUpdateCountMap.get(player).getAndIncrement(); for (int i = 0; i < 4; i++) { - final ItemStack armorItemStack = player.inventory.armorInventory[i]; + final ItemStack armorItemStack = player.inventory.armorInventory.get(i); if ((armorItemStack != null) && (armorItemStack.getItem() instanceof ItemMMDArmor)) { MMDToolEffects.extraEffectsOnArmorUpdate(w, player, this.mmdMaterial, diff --git a/src/main/java/com/mcmoddev/lib/item/ItemMMDCrackHammer.java b/src/main/java/com/mcmoddev/lib/item/ItemMMDCrackHammer.java index 51f7d087f..279d49090 100644 --- a/src/main/java/com/mcmoddev/lib/item/ItemMMDCrackHammer.java +++ b/src/main/java/com/mcmoddev/lib/item/ItemMMDCrackHammer.java @@ -81,8 +81,8 @@ public boolean onBlockDestroyed(final ItemStack tool, final World world, final ItemStack output = recipe.getOutput().copy(); world.setBlockToAir(coord); if (output != null) { - final int num = output.stackSize; - output.stackSize = 1; + final int num = output.getCount(); + output.setCount(1); for (int i = 0; i < num; i++) { world.spawnEntity(new EntityItem(world, coord.getX() + 0.5, coord.getY() + 0.5, coord.getZ() + 0.5, output.copy())); @@ -94,9 +94,10 @@ public boolean onBlockDestroyed(final ItemStack tool, final World world, } @Override - public EnumActionResult onItemUse(final ItemStack item, final EntityPlayer player, + public EnumActionResult onItemUse(final EntityPlayer player, final World w, final BlockPos coord, final EnumHand hand, final EnumFacing facing, final float partialX, final float partialY, final float partialZ) { + final ItemStack item = player.getHeldItem(hand); if (facing != EnumFacing.UP) { return EnumActionResult.PASS; } @@ -105,7 +106,7 @@ public EnumActionResult onItemUse(final ItemStack item, final EntityPlayer playe final List entities = w.getEntitiesWithinAABB(EntityItem.class, boundingBox); boolean success = false; for (final EntityItem target : entities) { - final ItemStack targetItem = target.getEntityItem(); + final ItemStack targetItem = target.getItem(); if (targetItem != null) { final ICrusherRecipe recipe = CrusherRecipeRegistry.getInstance() .getRecipeForInputItem(targetItem); @@ -122,16 +123,16 @@ public EnumActionResult onItemUse(final ItemStack item, final EntityPlayer playe // crush the item (server side only) if (!w.isRemote) { final ItemStack output = recipe.getOutput().copy(); - final int count = output.stackSize; + final int count = output.getCount(); int toolDamage; if (Options.crackHammerFullStack()) { - output.stackSize = targetItem.stackSize; - if (item.isItemDamaged() && (item.getItemDamage() < output.stackSize)) { - output.stackSize = item.getItemDamage(); + output.setCount(targetItem.getCount()); + if (item.isItemDamaged() && (item.getItemDamage() < output.getCount())) { + output.setCount(item.getItemDamage()); } - toolDamage = output.stackSize; + toolDamage = output.getCount(); } else { - output.stackSize = 1; + output.setCount(1); toolDamage = 1; } final double x = target.posX; @@ -139,11 +140,11 @@ public EnumActionResult onItemUse(final ItemStack item, final EntityPlayer playe final double z = target.posZ; if (Options.crackHammerFullStack()) { - targetItem.stackSize -= output.stackSize; + targetItem.shrink(output.getCount()); } else { - targetItem.stackSize--; + targetItem.shrink(1); } - if (targetItem.stackSize <= 0) { + if (targetItem.getCount() <= 0) { w.removeEntity(target); } for (int i = 0; i < count; i++) { @@ -214,6 +215,11 @@ public boolean getIsRepairable(final ItemStack intputItem, final ItemStack repai */ @Override @Deprecated + public int getHarvestLevel(final ItemStack stack, final String typeRequested, + final EntityPlayer player, final IBlockState state) { + return getHarvestLevel(stack, typeRequested); + } + public int getHarvestLevel(final ItemStack stack, final String typeRequested) { if ((typeRequested != null) && this.toolTypes.contains(typeRequested)) { if (Options.strongHammers()) { diff --git a/src/main/java/com/mcmoddev/lib/item/ItemMMDFishingRod.java b/src/main/java/com/mcmoddev/lib/item/ItemMMDFishingRod.java index cea9bd1dd..ec73d5c56 100644 --- a/src/main/java/com/mcmoddev/lib/item/ItemMMDFishingRod.java +++ b/src/main/java/com/mcmoddev/lib/item/ItemMMDFishingRod.java @@ -16,7 +16,7 @@ * @author Jasmine Iwanek * */ -public class ItemMMDFishingRod extends ItemFishingRod implements IMMDObject { +public class ItemMMDFishingRod extends net.minecraft.item.ItemFishingRod implements IMMDObject { private final MMDMaterial material; diff --git a/src/main/java/com/mcmoddev/lib/item/ItemMMDHoe.java b/src/main/java/com/mcmoddev/lib/item/ItemMMDHoe.java index b2d7ff47b..2f7d0dbd5 100644 --- a/src/main/java/com/mcmoddev/lib/item/ItemMMDHoe.java +++ b/src/main/java/com/mcmoddev/lib/item/ItemMMDHoe.java @@ -50,6 +50,11 @@ public boolean getIsRepairable(final ItemStack intputItem, final ItemStack repai */ @Override @Deprecated + public int getHarvestLevel(final ItemStack stack, final String typeRequested, + final EntityPlayer player, final IBlockState state) { + return getHarvestLevel(stack, typeRequested); + } + public int getHarvestLevel(final ItemStack stack, final String typeRequested) { if ((typeRequested != null) && this.toolTypes.contains(typeRequested)) { return this.material.getToolHarvestLevel(); diff --git a/src/main/java/com/mcmoddev/lib/item/ItemMMDSickle.java b/src/main/java/com/mcmoddev/lib/item/ItemMMDSickle.java index f9a10a617..5cc1285b9 100644 --- a/src/main/java/com/mcmoddev/lib/item/ItemMMDSickle.java +++ b/src/main/java/com/mcmoddev/lib/item/ItemMMDSickle.java @@ -137,7 +137,7 @@ private void breakBlock(final ItemStack tool, final World world, final EntityPla // tool should be, mostly, equal to what the player is holding... Maybe literal // equality is needed, dunno - if ((tool.stackSize == 0) && tool.equals(player.getHeldItemMainhand())) { + if ((tool.getCount() == 0) && tool.equals(player.getHeldItemMainhand())) { ForgeEventFactory.onPlayerDestroyItem(player, tool, EnumHand.MAIN_HAND); player.setHeldItem(EnumHand.MAIN_HAND, null); } @@ -180,7 +180,7 @@ private ImmutableList getEffectedBlocks(final BlockPos pos, final Worl final EntityPlayer player, final ItemStack stack, final int range) { BaseMetals.logger.debug("Entered getEffectedBlocks"); - if ((stack.stackSize == 0) || !(stack.getItem() instanceof ItemMMDSickle)) { + if ((stack.getCount() == 0) || !(stack.getItem() instanceof ItemMMDSickle)) { BaseMetals.logger.debug("Early out because tool-stack is empty"); return ImmutableList.of(); } diff --git a/src/main/java/com/mcmoddev/lib/jei/BaseMetalsJEIPlugin.java b/src/main/java/com/mcmoddev/lib/jei/BaseMetalsJEIPlugin.java index b05569bb4..c9c26d51d 100644 --- a/src/main/java/com/mcmoddev/lib/jei/BaseMetalsJEIPlugin.java +++ b/src/main/java/com/mcmoddev/lib/jei/BaseMetalsJEIPlugin.java @@ -1,7 +1,5 @@ package com.mcmoddev.lib.jei; -import java.util.stream.Collectors; - import zone.moddev.mc.basemetals.BaseMetals; import com.mcmoddev.lib.registry.CrusherRecipeRegistry; import com.mcmoddev.lib.registry.recipe.ICrusherRecipe; @@ -10,6 +8,7 @@ import mezz.jei.api.IGuiHelper; import mezz.jei.api.IModRegistry; import mezz.jei.api.JEIPlugin; +import mezz.jei.api.recipe.IRecipeCategoryRegistration; /** * @@ -24,15 +23,15 @@ public final class BaseMetalsJEIPlugin extends BlankModPlugin { public static final String RECIPE_UID = JEI_UID + ".crackhammer"; @Override - public void register(final IModRegistry registry) { + public void registerCategories(final IRecipeCategoryRegistration registry) { final IGuiHelper guiHelper = registry.getJeiHelpers().getGuiHelper(); registry.addRecipeCategories(new ICrusherRecipeCategory(guiHelper)); - registry.addRecipeHandlers(new CrusherRecipeHandler()); - - registry.addRecipes(CrusherRecipeRegistry.getInstance().getAllRecipes().stream() - .map((final ICrusherRecipe in) -> new ICrusherRecipeWrapper(in)) - .collect(Collectors.toList())); + } + @Override + public void register(final IModRegistry registry) { + registry.handleRecipes(ICrusherRecipe.class, ICrusherRecipeWrapper::new, RECIPE_UID); + registry.addRecipes(CrusherRecipeRegistry.getInstance().getAllRecipes(), RECIPE_UID); } } diff --git a/src/main/java/com/mcmoddev/lib/jei/CrusherRecipeHandler.java b/src/main/java/com/mcmoddev/lib/jei/CrusherRecipeHandler.java deleted file mode 100644 index c1163201c..000000000 --- a/src/main/java/com/mcmoddev/lib/jei/CrusherRecipeHandler.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.mcmoddev.lib.jei; - -import javax.annotation.Nonnull; - -import mezz.jei.api.recipe.IRecipeHandler; -import mezz.jei.api.recipe.IRecipeWrapper; - -/** - * - * @author DrCyano - * @author Daniel Hazelton - * - */ -public class CrusherRecipeHandler implements IRecipeHandler { - - @Override - public Class getRecipeClass() { - return ICrusherRecipeWrapper.class; - } - - @Nonnull - @Override - public String getRecipeCategoryUid(@Nonnull final ICrusherRecipeWrapper recipe) { - return BaseMetalsJEIPlugin.RECIPE_UID; - } - - @Override - public String getRecipeCategoryUid() { - return BaseMetalsJEIPlugin.JEI_UID; - } - - @Override - public IRecipeWrapper getRecipeWrapper(final ICrusherRecipeWrapper recipe) { - return recipe; - } - - @Override - public boolean isRecipeValid(final ICrusherRecipeWrapper recipe) { - return true; - } -} diff --git a/src/main/java/com/mcmoddev/lib/jei/ICrusherRecipeCategory.java b/src/main/java/com/mcmoddev/lib/jei/ICrusherRecipeCategory.java index 5b355c993..c324d84c5 100644 --- a/src/main/java/com/mcmoddev/lib/jei/ICrusherRecipeCategory.java +++ b/src/main/java/com/mcmoddev/lib/jei/ICrusherRecipeCategory.java @@ -52,6 +52,11 @@ public String getTitle() { return new TextComponentTranslation(String.format(this.getUid())).getFormattedText(); } + @Override + public String getModName() { + return "Base Metals"; + } + @Override public IDrawable getBackground() { return this.background; @@ -80,7 +85,7 @@ public void setRecipe(final IRecipeLayout recipeLayout, // load the output and input bits final List> inputs = ingredients.getInputs(ItemStack.class); - final List outputs = ingredients.getOutputs(ItemStack.class); + final List> outputs = ingredients.getOutputs(ItemStack.class); // setup the data guiItemStacks.set(0, inputs.get(0)); diff --git a/src/main/java/com/mcmoddev/lib/nei/CrusherRecipeHandler.java b/src/main/java/com/mcmoddev/lib/nei/CrusherRecipeHandler.java deleted file mode 100644 index bc46eb498..000000000 --- a/src/main/java/com/mcmoddev/lib/nei/CrusherRecipeHandler.java +++ /dev/null @@ -1,216 +0,0 @@ -package com.mcmoddev.lib.nei; - -import java.awt.Rectangle; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import org.lwjgl.opengl.GL11; - -import zone.moddev.mc.basemetals.BaseMetals; -import com.mcmoddev.lib.registry.CrusherRecipeRegistry; -import com.mcmoddev.lib.registry.recipe.ICrusherRecipe; - -import codechicken.nei.api.stack.PositionedStack; -import codechicken.nei.recipe.TemplateRecipeHandler; -import net.minecraft.client.gui.inventory.GuiContainer; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; -import net.minecraft.inventory.Container; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; -//import net.minecraft.util.text.translation.I18n; -import net.minecraft.util.text.TextComponentTranslation; - -/** - * - * @author Jasmine Iwanek - * - */ -public class CrusherRecipeHandler extends TemplateRecipeHandler { - - private static final String CRUSHER = "crusher"; - - @Override - public String getOverlayIdentifier() { - return CRUSHER; - } - - @Override - public String getGuiTexture() { - return BaseMetals.MODID + ":textures/gui/nei/nei_crusher.png"; - } - - @Override - public void loadUsageRecipes(final ItemStack ingredient) { - final ICrusherRecipe recipe = CrusherRecipeRegistry.getInstance() - .getRecipeForInputItem(ingredient); - if (recipe == null) { - return; - } - this.arecipes.add(new CrusherPair(ingredient.copy(), recipe.getOutput())); - } - - @Override - public void loadCraftingRecipes(final ItemStack result) { - final List recipes = CrusherRecipeRegistry.getInstance() - .getRecipesForOutputItem(result); - if (recipes == null) { - return; // no crusher recipes - } - for (final ICrusherRecipe r : recipes) { - this.arecipes.addAll(r.getValidInputs().stream() - .map(input -> new CrusherPair(input.copy(), r.getOutput().copy())) - .collect(Collectors.toList())); - } - } - - @Override - public void loadUsageRecipes(final String inputId, final Object... ingredients) { - if (inputId.equals(CRUSHER) && (this.getClass() == CrusherRecipeHandler.class)) { - this.loadCraftingRecipes("smelting"); - } else { - super.loadUsageRecipes(inputId, ingredients); - } - } - - @Override - public void loadCraftingRecipes(final String outputId, final Object... results) { - if (outputId.equals(CRUSHER) && (this.getClass() == CrusherRecipeHandler.class)) { // we - // don't - // want - // overstep - // subclasses - // add all crusher recipes - final Collection recipes = CrusherRecipeRegistry.getInstance() - .getAllRecipes(); - if (recipes == null) { - return; - } - for (final ICrusherRecipe r : recipes) { - if (r == null) { - continue; - } - this.arecipes.addAll(r.getValidInputs().stream() - .map(input -> new CrusherPair(input.copy(), r.getOutput().copy())) - .collect(Collectors.toList())); - } - } else { - super.loadCraftingRecipes(outputId, results); - } - } - - @Override - public TemplateRecipeHandler newInstance() { - return super.newInstance(); - } - - @Override - public String getRecipeName() { - // TODO: Finish this - final String key = BaseMetals.MODID + ".crusher"; - // if (I18n.canTranslate(key)) { - return new TextComponentTranslation(String.format(key)).getFormattedText(); - // } else { - // return "Crusher"; - // } - } - - @Override - public void loadTransferRects() { - this.transferRects.add(new RecipeTransferRect(new Rectangle(95, 23, 18, 18), CRUSHER)); - } - - @Override - public Class getGuiClass() { - return GuiCrusher.class; - } - - /** - * - * @author Jasmine Iwanek - * - */ - public static class GuiCrusher extends GuiContainer { - - ResourceLocation guiDisplayImage = new ResourceLocation( - BaseMetals.MODID + ":textures/gui/nei/nei_crusher.png"); - - /** - * - * @param container - * Container - */ - public GuiCrusher(final Container container) { - super(container); - } - - @Override - protected void drawGuiContainerBackgroundLayer(final float f, final int i, final int j) { - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - final int x = (this.width - this.xSize) / 2; - final int y = (this.height - this.ySize) / 2; - this.mc.renderEngine.bindTexture(this.guiDisplayImage); - this.drawTexturedModalRect(x, y, 0, 0, 176, 76); // x, y, textureOffsetX, - // textureOffsetY, width, height) - } - } - - /** - * - * @author Jasmine Iwanek - * - */ - public static class ContainerCrusher extends Container { - - @Override - public boolean canInteractWith(final EntityPlayer playerIn) { - return true; - } - } - - /** - * - * @author Jasmine Iwanek - * - */ - public class CrusherPair extends CachedRecipe { - - PositionedStack ingred; - PositionedStack result; - - /** - * - * @param ingred - * ItemStack - * @param result - * ItemStack - */ - public CrusherPair(ItemStack ingred, ItemStack result) { - if ((ingred == null) || (result == null)) { - BaseMetals.logger.warn("Added null item to NEI GUI: " + ingred + " -> " + result); - if (ingred == null) { - ingred = new ItemStack(Blocks.AIR); - } - if (result == null) { - result = new ItemStack(Blocks.AIR); - } - } - ingred.stackSize = 1; - this.ingred = new PositionedStack(ingred, 65, 23); - this.result = new PositionedStack(result, 123, 23); - } - - @Override - public List getIngredients() { - return this.getCycledIngredients(CrusherRecipeHandler.this.cycleticks / 48, - Collections.singletonList(this.ingred)); - } - - @Override - public PositionedStack getResult() { - return this.result; - } - } -} diff --git a/src/main/java/com/mcmoddev/lib/nei/NEIBaseMetalsConfig.java b/src/main/java/com/mcmoddev/lib/nei/NEIBaseMetalsConfig.java deleted file mode 100644 index f6d20dd55..000000000 --- a/src/main/java/com/mcmoddev/lib/nei/NEIBaseMetalsConfig.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.mcmoddev.lib.nei; - -import zone.moddev.mc.basemetals.BaseMetals; - -import codechicken.nei.api.IConfigureNEI; - -/** - * - * @author Jasmine Iwanek - * - */ -public class NEIBaseMetalsConfig implements IConfigureNEI { - - // see https://www.youtube.com/watch?v=8CtcExhsplg for a tutorial - - // NEI is supposed to automatically detect classes with the name NEI*Config - @Override - public String getName() { - return "PowerAdvantage NEI Plugin"; - } - - @Override - public String getVersion() { - return BaseMetals.VERSION; - } - - @Override - public void loadConfig() { - final CrusherRecipeHandler crusherHandler = new CrusherRecipeHandler(); - codechicken.nei.api.API.registerRecipeHandler(crusherHandler); - codechicken.nei.api.API.registerUsageHandler(crusherHandler); - } -} diff --git a/src/main/java/com/mcmoddev/lib/recipe/RepairRecipeBase.java b/src/main/java/com/mcmoddev/lib/recipe/RepairRecipeBase.java index 2f2840ea0..4b3295175 100644 --- a/src/main/java/com/mcmoddev/lib/recipe/RepairRecipeBase.java +++ b/src/main/java/com/mcmoddev/lib/recipe/RepairRecipeBase.java @@ -1,8 +1,5 @@ package com.mcmoddev.lib.recipe; -import java.util.ArrayList; -import java.util.List; - import com.mcmoddev.lib.data.Names; import com.mcmoddev.lib.material.MMDMaterial; import com.mcmoddev.lib.util.Oredicts; @@ -10,6 +7,7 @@ import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; import net.minecraft.world.World; import net.minecraftforge.oredict.OreDictionary; import net.minecraftforge.oredict.ShapelessOreRecipe; @@ -20,7 +18,7 @@ public abstract class RepairRecipeBase extends ShapelessOreRecipe { private final ItemStack baseItem; private final String materialName; private final String itemName; - private final List repairMaterials; + private final NonNullList repairMaterials; /** * @@ -59,22 +57,16 @@ public RepairRecipeBase(final MMDMaterial material, final String itemName, this.itemName = itemName; } - private boolean repairMaterialsDoesntContain(final ItemStack itemStack) { - return !this.repairMaterials.contains(itemStack); - } - @Override public boolean matches(final InventoryCrafting inv, final World worldIn) { - // make sure we have all the materials that can be used for repair, not just what was - // available when we were initialized. - OreDictionary.getOres(Oredicts.PLATE + this.materialName).stream() - .filter(this::repairMaterialsDoesntContain).forEach(this.repairMaterials::add); - boolean matched = false; boolean repairMatched = false; for (int i = 0; i < inv.getSizeInventory(); i++) { final ItemStack item = inv.getStackInSlot(i); + if (item.isEmpty()) { + continue; + } if (!repairMatched) { repairMatched = OreDictionary.containsMatch(false, this.repairMaterials, item); } @@ -89,7 +81,7 @@ public boolean matches(final InventoryCrafting inv, final World worldIn) { private ItemStack findBaseItem(final InventoryCrafting inv) { for (int i = 0; i < inv.getSizeInventory(); i++) { final ItemStack a = inv.getStackInSlot(i); - if (a != null) { + if (!a.isEmpty()) { final ItemStack comp = new ItemStack(a.getItem(), 1, a.getMetadata()); if (OreDictionary.itemMatches(this.baseItem, comp, false)) { return a; @@ -133,8 +125,8 @@ public ItemStack getRecipeOutput() { * @return */ @Override - public ArrayList getInput() { - final ArrayList inputs = new ArrayList<>(); + public NonNullList getInput() { + final NonNullList inputs = NonNullList.create(); inputs.add(this.baseItem); inputs.addAll(OreDictionary.getOres(Oredicts.PLATE + this.materialName)); return inputs; diff --git a/src/main/java/com/mcmoddev/lib/recipe/ShieldUpgradeRecipe.java b/src/main/java/com/mcmoddev/lib/recipe/ShieldUpgradeRecipe.java index 49051a646..4d2675337 100755 --- a/src/main/java/com/mcmoddev/lib/recipe/ShieldUpgradeRecipe.java +++ b/src/main/java/com/mcmoddev/lib/recipe/ShieldUpgradeRecipe.java @@ -9,6 +9,8 @@ import java.util.Map.Entry; import zone.moddev.mc.basemetals.BaseMetals; +import zone.moddev.mc.basemetals.content.ContentMode; +import zone.moddev.mc.basemetals.content.ContentPolicy; import com.mcmoddev.lib.data.MaterialStats; import com.mcmoddev.lib.data.Names; import com.mcmoddev.lib.init.Materials; @@ -53,16 +55,22 @@ public boolean matches(final InventoryCrafting inv, final World worldIn) { for (int i = 0; i < inv.getSizeInventory(); i++) { final ItemStack curItem = inv.getStackInSlot(i); - if (curItem != null) { + if (!curItem.isEmpty()) { final ItemStack comp = new ItemStack(curItem.getItem(), 1, curItem.getItemDamage()); if (OreDictionary.itemMatches(base, comp, false)) { matches[0] = true; - } else if (OreDictionary.containsMatch(false, upgradeMats, comp)) { + } else if (upgradeMats.stream().anyMatch(plate -> OreDictionary.itemMatches(plate, comp, false))) { matches[1] = true; } } } - return matches[0] ? matches[1] : false; + if (!matches[0] || !matches[1]) { + return false; + } + + // The plate determines the output, so the crafting list cannot filter this recipe. + return ContentPolicy.active().mode() == ContentMode.HIGH_FANTASY + || !getCraftingResult(inv).isEmpty(); } @Override @@ -82,7 +90,7 @@ public ItemStack getCraftingResult(final InventoryCrafting inv) { } } - ItemStack plateMatched = null; + ItemStack plateMatched = ItemStack.EMPTY; Map enchants = Collections.emptyMap(); final ItemStack matcher = new ItemStack( Materials.getMaterialByName(this.materialName).getItem(Names.SHIELD), 1, 0); @@ -90,10 +98,10 @@ public ItemStack getCraftingResult(final InventoryCrafting inv) { for (int i = 0; i < inv.getSizeInventory(); i++) { final ItemStack curItem = inv.getStackInSlot(i); - if (curItem != null) { + if (!curItem.isEmpty()) { final ItemStack comp = new ItemStack(curItem.getItem(), 1, curItem.getMetadata()); for (final Entry> ent : plates.entrySet()) { - if (OreDictionary.containsMatch(false, ent.getValue(), comp)) { + if (ent.getValue().stream().anyMatch(plate -> OreDictionary.itemMatches(plate, comp, false))) { plateMatched = new ItemStack( Materials.getMaterialByName(ent.getKey().toLowerCase()) .getItem(Names.SHIELD), @@ -106,6 +114,10 @@ public ItemStack getCraftingResult(final InventoryCrafting inv) { } } + if (plateMatched.isEmpty() || !ContentPolicy.active().allows(plateMatched)) { + return ItemStack.EMPTY; + } + BaseMetals.logger.debug("Adding %d enchantments to output item", enchants.size()); EnchantmentHelper.setEnchantments(enchants, plateMatched); return plateMatched; @@ -115,7 +127,7 @@ private MMDMaterial getUpgradeMat(final InventoryCrafting inv) { for (int i = 0; i < inv.getSizeInventory(); i++) { final ItemStack curItem = inv.getStackInSlot(i); - if (curItem != null) { + if (!curItem.isEmpty()) { for (final MMDMaterial e : Materials.getAllMaterials()) { if (OreDictionary.containsMatch(false, OreDictionary.getOres(Oredicts.PLATE + e.getName()), curItem)) { @@ -133,7 +145,7 @@ private ItemStack findBaseItem(final InventoryCrafting inv) { for (int i = 0; i < inv.getSizeInventory(); i++) { final ItemStack a = inv.getStackInSlot(i); - if (a != null) { + if (!a.isEmpty()) { final ItemStack comp = new ItemStack(a.getItem(), 1, a.getMetadata()); if (OreDictionary.itemMatches(input, comp, false)) { return a; diff --git a/src/main/java/com/mcmoddev/lib/registry/CrusherRecipeRegistry.java b/src/main/java/com/mcmoddev/lib/registry/CrusherRecipeRegistry.java index c1ac58537..dcd321d11 100644 --- a/src/main/java/com/mcmoddev/lib/registry/CrusherRecipeRegistry.java +++ b/src/main/java/com/mcmoddev/lib/registry/CrusherRecipeRegistry.java @@ -9,6 +9,7 @@ import java.util.Map; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Predicate; import zone.moddev.mc.basemetals.BaseMetals; import com.mcmoddev.lib.registry.recipe.ArbitraryCrusherRecipe; @@ -41,6 +42,7 @@ public class CrusherRecipeRegistry { private final List recipes = new ArrayList<>(); + private Predicate outputFilter; private final Map recipeByInputCache = new HashMap<>(); private final Map> recipeByOutputCache = new HashMap<>(); @@ -154,7 +156,22 @@ public void clearCache() { * An implementation of the ICrusherRecipe interface. */ public void addRecipe(final ICrusherRecipe crusherRecipe) { - this.recipes.add(crusherRecipe); + if (this.outputFilter == null || this.outputFilter.test(crusherRecipe.getOutput())) { + this.recipes.add(crusherRecipe); + } + } + + /** Applies an output rule only during the caller's startup registration. */ + public void registerWithOutputFilter(final Runnable register, + final Predicate filter) { + final Predicate previous = this.outputFilter; + this.outputFilter = previous == null ? filter : previous.and(filter); + try { + register.run(); + } finally { + this.outputFilter = previous; + clearCache(); + } } /** @@ -181,7 +198,7 @@ public List getRecipesForOutputItem(final ItemStack output) { for (final String s : Options.disabledRecipes()) { final List ores = OreDictionary.getOres(s); for (final ItemStack input : r.getValidInputs()) { - if (OreDictionary.containsMatch(false, ores, input)) { + if (ores.stream().anyMatch(ore -> OreDictionary.itemMatches(ore, input, false))) { this.recipeByInputCache.put(hashKey, null); return new ArrayList<>(); } @@ -231,7 +248,7 @@ public ICrusherRecipe getRecipeForInputItem(final ItemStack input) { if (r.isValidInput(input)) { for (final String s : Options.disabledRecipes()) { final List ores = OreDictionary.getOres(s); - if (OreDictionary.containsMatch(false, ores, input)) { + if (ores.stream().anyMatch(ore -> OreDictionary.itemMatches(ore, input, false))) { this.recipeByInputCache.put(hashKey, null); return null; } diff --git a/src/main/java/com/mcmoddev/lib/util/ConfigBase.java b/src/main/java/com/mcmoddev/lib/util/ConfigBase.java index 20418a025..97eee281f 100644 --- a/src/main/java/com/mcmoddev/lib/util/ConfigBase.java +++ b/src/main/java/com/mcmoddev/lib/util/ConfigBase.java @@ -94,7 +94,7 @@ private static void addIngotRecipes(final Set dictionary) { }).forEach(entry -> { final String ingotX = Oredicts.INGOT.concat(entry.substring(4)); final ItemStack dustX = OreDictionary.getOres(entry).get(0).copy(); - dustX.stackSize = 2; + dustX.setCount(2); BaseMetals.logger.info("Automatically adding custom crusher recipe '{}' -> {}", ingotX, dustX); CrusherRecipeRegistry.addNewCrusherRecipe(ingotX, dustX); @@ -114,7 +114,7 @@ private static void addOreRecipes(final Set dictionary) { }).forEach(entry -> { final String oreX = Oredicts.ORE.concat(entry.substring(4)); final ItemStack dustX = OreDictionary.getOres(entry).get(0).copy(); - dustX.stackSize = 2; + dustX.setCount(2); BaseMetals.logger.info("Automatically adding custom crusher recipe '{}' -> {}", oreX, dustX); CrusherRecipeRegistry.addNewCrusherRecipe(oreX, dustX); diff --git a/src/main/java/com/mcmoddev/lib/util/ItemStackHelper.java b/src/main/java/com/mcmoddev/lib/util/ItemStackHelper.java index 37195a01a..a03688ff0 100644 --- a/src/main/java/com/mcmoddev/lib/util/ItemStackHelper.java +++ b/src/main/java/com/mcmoddev/lib/util/ItemStackHelper.java @@ -2,35 +2,29 @@ import javax.annotation.Nullable; -import net.minecraft.init.Blocks; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; public class ItemStackHelper { - public static final ItemStack EMPTY = new ItemStack((Item)null); + public static final ItemStack EMPTY = ItemStack.EMPTY; public boolean isEmpty(@Nullable final ItemStack itemStack) { - if (itemStack == null) { - return true; - } - final Item item = getItemRaw(itemStack); - return itemStack == EMPTY ? true : (item != null && item != Item.getItemFromBlock(Blocks.AIR) ? (itemStack.stackSize <= 0 ? true : itemStack.getItemDamage() < -32768 || itemStack.getItemDamage() > 65535) : true); + return itemStack == null || itemStack.isEmpty(); } public int getCount(@Nullable final ItemStack itemStack) { - return ((this.isEmpty(itemStack)) || (itemStack == null)) ? 0 : itemStack.stackSize; + return ((this.isEmpty(itemStack)) || (itemStack == null)) ? 0 : itemStack.getCount(); } public void setCount(@Nullable final ItemStack itemStack, final int size) { if (itemStack != null) { - itemStack.stackSize = size; + itemStack.setCount(size); } } public void grow(@Nullable final ItemStack itemStack, final int quantity) { if (itemStack != null) { - this.setCount(itemStack, itemStack.stackSize + quantity); + this.setCount(itemStack, itemStack.getCount() + quantity); } } @@ -38,16 +32,4 @@ public void shrink(@Nullable final ItemStack itemStack, final int quantity) { this.grow(itemStack, -quantity); } - /** - * Internal call to get the actual item, not the delegate. - * In all other methods, FML replaces calls to this.item with the item delegate. - */ - private Item getItemRaw(@Nullable final ItemStack itemStack) { - if (itemStack != null) { - return itemStack.getItem(); - // TODO: Either AT or Reflect this instead - // return itemStack.item; - } - return null; - } } diff --git a/src/main/java/zone/moddev/mc/basemetals/BaseMetals.java b/src/main/java/zone/moddev/mc/basemetals/BaseMetals.java index c97891541..176a1f1e8 100644 --- a/src/main/java/zone/moddev/mc/basemetals/BaseMetals.java +++ b/src/main/java/zone/moddev/mc/basemetals/BaseMetals.java @@ -34,8 +34,9 @@ modid = BaseMetals.MODID, name = BaseMetals.NAME, version = BaseMetals.VERSION, - dependencies = "required-after:Forge@[12.18.3.2511,);required-after:orespawn@[4.1.2.110021,5.0.0);after:tconstruct;after:ic2;after:taiga;before:buildingbricks", - acceptedMinecraftVersions = "[1.10.2]", + dependencies = "required-after:forge@[13.20.1.2588,);required-after:orespawn@[4.1.6.111021,5.0.0);after:tconstruct;after:ic2;after:taiga;before:buildingbricks", + guiFactory = "zone.moddev.mc.basemetals.client.BaseMetalsGuiFactory", + acceptedMinecraftVersions = "[1.11.2]", certificateFingerprint = "", updateJSON = BaseMetals.UPDATEJSON) public class BaseMetals { @@ -50,9 +51,9 @@ public class BaseMetals { protected static final String NAME = "Base Metals"; /** - * Major.Minor.Patch.Target, where 110021 means Minecraft 1.10.2 on Forge. + * Major.Minor.Patch.Target, where 111021 means Minecraft 1.11.2 on Forge. */ - public static final String VERSION = "2.5.1.110021"; + public static final String VERSION = "2.5.1.111021"; protected static final String UPDATEJSON = SharedStrings.UPDATE_JSON_URL + "BaseMetals/master/update.json"; diff --git a/src/main/java/zone/moddev/mc/basemetals/client/BaseMetalsConfigScreen.java b/src/main/java/zone/moddev/mc/basemetals/client/BaseMetalsConfigScreen.java new file mode 100644 index 000000000..0ca081dfd --- /dev/null +++ b/src/main/java/zone/moddev/mc/basemetals/client/BaseMetalsConfigScreen.java @@ -0,0 +1,35 @@ +package zone.moddev.mc.basemetals.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 net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import zone.moddev.mc.basemetals.BaseMetals; +import zone.moddev.mc.basemetals.util.Config; + +@SideOnly(Side.CLIENT) +public final class BaseMetalsConfigScreen extends GuiConfig { + public BaseMetalsConfigScreen(final GuiScreen parent) { + super(parent, categories(), BaseMetals.MODID, false, true, + I18n.format("config.basemetals.title"), I18n.format("config.basemetals.restart_guidance")); + } + + private static List categories() { + final Configuration config = Config.getConfiguration(); + final List elements = new ArrayList<>(); + + for (final String category : new String[] { "General", "Metals", "Vanilla", + "Tools and Items", "Fluids", "Mod Integration", "Crack Hammer Recipes" }) { + elements.add(new ConfigElement(config.getCategory(category))); + } + + return elements; + } +} diff --git a/src/main/java/zone/moddev/mc/basemetals/client/BaseMetalsGuiFactory.java b/src/main/java/zone/moddev/mc/basemetals/client/BaseMetalsGuiFactory.java new file mode 100644 index 000000000..28e94705e --- /dev/null +++ b/src/main/java/zone/moddev/mc/basemetals/client/BaseMetalsGuiFactory.java @@ -0,0 +1,42 @@ +package zone.moddev.mc.basemetals.client; + +import java.util.Collections; +import java.util.Set; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; +import net.minecraftforge.fml.client.IModGuiFactory; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public final class BaseMetalsGuiFactory implements IModGuiFactory { + @Override + public void initialize(final Minecraft minecraft) { + } + + @Override + public Class mainConfigGuiClass() { + return BaseMetalsConfigScreen.class; + } + + @Override + public boolean hasConfigGui() { + return true; + } + + @Override + public GuiScreen createConfigGui(final GuiScreen parent) { + return new BaseMetalsConfigScreen(parent); + } + + @Override + public Set runtimeGuiCategories() { + return Collections.emptySet(); + } + + @Override + public RuntimeOptionGuiHandler getHandlerFor(final RuntimeOptionCategoryElement category) { + return null; + } +} diff --git a/src/main/java/zone/moddev/mc/basemetals/compat/BaseMetalsLoadingPlugin.java b/src/main/java/zone/moddev/mc/basemetals/compat/BaseMetalsLoadingPlugin.java index 3ca76f20a..f516d7eba 100644 --- a/src/main/java/zone/moddev/mc/basemetals/compat/BaseMetalsLoadingPlugin.java +++ b/src/main/java/zone/moddev/mc/basemetals/compat/BaseMetalsLoadingPlugin.java @@ -5,7 +5,7 @@ /** Keeps the existing horse-armour hooks and installs the old API name adapter. */ @IFMLLoadingPlugin.Name("BaseMetals") -@IFMLLoadingPlugin.MCVersion("1.10.2") +@IFMLLoadingPlugin.MCVersion("1.11.2") @IFMLLoadingPlugin.SortingIndex(1001) @IFMLLoadingPlugin.TransformerExclusions("zone.moddev.mc.basemetals.compat.") public final class BaseMetalsLoadingPlugin extends ASMPlugin { diff --git a/src/main/java/zone/moddev/mc/basemetals/content/ContentAcquisition.java b/src/main/java/zone/moddev/mc/basemetals/content/ContentAcquisition.java new file mode 100644 index 000000000..803590365 --- /dev/null +++ b/src/main/java/zone/moddev/mc/basemetals/content/ContentAcquisition.java @@ -0,0 +1,57 @@ +package zone.moddev.mc.basemetals.content; + +import java.util.Collections; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.mcmoddev.lib.registry.CrusherRecipeRegistry; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.item.crafting.FurnaceRecipes; +import net.minecraft.item.crafting.IRecipe; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.ModContainer; +import zone.moddev.mc.basemetals.BaseMetals; + +/** Filters only the recipes added by Base Metals, leaving earlier mod and pack recipes alone. */ +public final class ContentAcquisition { + private ContentAcquisition() { + } + + /** Shared integration helpers must not apply Base Metals' mode to another mod's recipes. */ + public static boolean restrictsIntegration() { + if (ContentPolicy.active().mode() == ContentMode.HIGH_FANTASY) { + return false; + } + + final ModContainer owner = Loader.instance().activeModContainer(); + return owner != null && BaseMetals.MODID.equals(owner.getModId()); + } + + public static boolean allowsIntegrationOutput(final ItemStack output) { + return !restrictsIntegration() || ContentPolicy.active().allows(output); + } + + public static void registerRecipes(final Runnable register) { + final ContentPolicy policy = ContentPolicy.active(); + if (policy.mode() == ContentMode.HIGH_FANTASY) { + register.run(); + return; + } + + final List crafting = CraftingManager.getInstance().getRecipeList(); + final Map smelting = FurnaceRecipes.instance().getSmeltingList(); + final Set previousCrafting = Collections.newSetFromMap(new IdentityHashMap<>()); + final Set previousSmelting = Collections.newSetFromMap(new IdentityHashMap<>()); + previousCrafting.addAll(crafting); + previousSmelting.addAll(smelting.keySet()); + + CrusherRecipeRegistry.getInstance().registerWithOutputFilter(register, policy::allows); + crafting.removeIf(recipe -> !previousCrafting.contains(recipe) + && !policy.allows(recipe.getRecipeOutput())); + smelting.entrySet().removeIf(recipe -> !previousSmelting.contains(recipe.getKey()) + && !policy.allows(recipe.getValue())); + } +} diff --git a/src/main/java/zone/moddev/mc/basemetals/content/ContentMode.java b/src/main/java/zone/moddev/mc/basemetals/content/ContentMode.java new file mode 100644 index 000000000..e2f99d18b --- /dev/null +++ b/src/main/java/zone/moddev/mc/basemetals/content/ContentMode.java @@ -0,0 +1,63 @@ +package zone.moddev.mc.basemetals.content; + +import java.util.Locale; + +/** Content modes, with names shared by the config file and network messages. */ +public enum ContentMode { + HIGH_FANTASY("high_fantasy"), + LOW_FANTASY("low_fantasy"); + + private final String serializedName; + + ContentMode(final String serializedName) { + this.serializedName = serializedName; + } + + public String serializedName() { + return serializedName; + } + + public String translationKey() { + return "config.basemetals.content_mode." + serializedName; + } + + public static ContentMode fromSerializedName(final String value) { + if (value != null) { + final String normalized = value.trim().toLowerCase(Locale.ROOT); + + for (final ContentMode mode : values()) { + if (mode.serializedName.equals(normalized)) { + return mode; + } + } + } + + return HIGH_FANTASY; + } + + public static boolean isValidSerializedName(final String value) { + if (value == null) { + return false; + } + + for (final ContentMode mode : values()) { + if (mode.serializedName.equals(value.trim().toLowerCase(Locale.ROOT))) { + return true; + } + } + + return false; + } + + public static String[] serializedNames() { + final ContentMode[] modes = values(); + final String[] names = new String[modes.length]; + + for (int i = 0; i < modes.length; i++) { + names[i] = modes[i].serializedName; + } + + return names; + } + +} diff --git a/src/main/java/zone/moddev/mc/basemetals/content/ContentModeNetwork.java b/src/main/java/zone/moddev/mc/basemetals/content/ContentModeNetwork.java new file mode 100644 index 000000000..f4e3c20e0 --- /dev/null +++ b/src/main/java/zone/moddev/mc/basemetals/content/ContentModeNetwork.java @@ -0,0 +1,109 @@ +package zone.moddev.mc.basemetals.content; + +import java.util.Set; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.PacketBuffer; +import net.minecraft.network.play.client.CPacketCustomPayload; +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 = "BaseMetals|High"; + private static final String LOW = "BaseMetals|Low"; + private static final String HANDSHAKE = "FML|HS"; + private static final String REJECTION_HANDLER = "basemetals:fantasy_level"; + private static final int FORGE_MOD_LIST = 2; + + private ContentModeNetwork() {} + + public static void register() { + NetworkRegistry.INSTANCE.newEventDrivenChannel(ContentPolicy.active().mode() == ContentMode.LOW_FANTASY ? 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(HANDSHAKE)) { + return; + } + + final boolean localLow = ContentPolicy.active().mode() == ContentMode.LOW_FANTASY; + 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("Base Metals could not check the Fantasy Level. " + + "Use the same Base Metals build on the server and client.") + : new TextComponentTranslation("config.basemetals.connection.protocol"); + } else if (!server || remoteLow == localLow) { + return; + } else { + reason = new TextComponentTranslation("config.basemetals.connection.mismatch", + modeLabel(localLow), modeLabel(remoteLow)); + } + + final NetworkManager manager = event.getManager(); + if (server) { + if (manager.channel().pipeline().get(REJECTION_HANDLER) == null) { + manager.channel().pipeline().addBefore("fml:packet_handler", REJECTION_HANDLER, + new RejectModList(manager, reason)); + } + } else { + // An older server cannot reject a missing Fantasy Level itself. + manager.channel().eventLoop().execute(() -> { + if (manager.isChannelOpen()) { + manager.closeChannel(reason); + } + }); + } + } + + private static ITextComponent modeLabel(final boolean low) { + return new TextComponentTranslation(low ? ContentMode.LOW_FANTASY.translationKey() : ContentMode.HIGH_FANTASY.translationKey()); + } + + private static final class RejectModList extends ChannelInboundHandlerAdapter { + private final NetworkManager manager; + private final ITextComponent reason; + + RejectModList(final NetworkManager manager, final ITextComponent reason) { + this.manager = manager; + this.reason = reason; + } + + @Override + public void channelRead(final ChannelHandlerContext context, final Object message) { + if (message instanceof CPacketCustomPayload) { + final CPacketCustomPayload packet = (CPacketCustomPayload) message; + final PacketBuffer data = packet.getBufferData(); + + // Forge 1.11 sends its mod list after registration and ClientHello. + // Reject it here so the client finishes writing before we close the connection. + if (HANDSHAKE.equals(packet.getChannelName()) && data.isReadable() + && data.getUnsignedByte(data.readerIndex()) == FORGE_MOD_LIST) { + data.release(); + context.channel().config().setAutoRead(false); + manager.sendPacket(new SPacketDisconnect(reason), future -> manager.closeChannel(reason)); + return; + } + } + + context.fireChannelRead(message); + } + } +} diff --git a/src/main/java/zone/moddev/mc/basemetals/content/ContentPolicy.java b/src/main/java/zone/moddev/mc/basemetals/content/ContentPolicy.java new file mode 100644 index 000000000..7b6f5e08a --- /dev/null +++ b/src/main/java/zone/moddev/mc/basemetals/content/ContentPolicy.java @@ -0,0 +1,233 @@ +package zone.moddev.mc.basemetals.content; + +import zone.moddev.mc.basemetals.BaseMetals; +import zone.moddev.mc.basemetals.data.MaterialNames; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; + +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Locale; +import java.util.Set; + +/** Defines which material forms can be made in each content mode. */ +public final class ContentPolicy { + private static final ContentPolicy HIGH = new ContentPolicy(ContentMode.HIGH_FANTASY); + private static final ContentPolicy LOW = new ContentPolicy(ContentMode.LOW_FANTASY); + private static final Set MATERIALS = set( + MaterialNames.ADAMANTINE, MaterialNames.ANTIMONY, MaterialNames.AQUARIUM, + MaterialNames.BISMUTH, MaterialNames.BRASS, MaterialNames.BRONZE, + MaterialNames.CHARCOAL, MaterialNames.COAL, MaterialNames.COLDIRON, + MaterialNames.COPPER, MaterialNames.CUPRONICKEL, MaterialNames.DIAMOND, + MaterialNames.ELECTRUM, MaterialNames.EMERALD, MaterialNames.ENDER, + MaterialNames.GOLD, MaterialNames.INVAR, MaterialNames.IRON, + MaterialNames.LAPIS, MaterialNames.LEAD, MaterialNames.MERCURY, + MaterialNames.MITHRIL, MaterialNames.NICKEL, MaterialNames.OBSIDIAN, + MaterialNames.PEWTER, MaterialNames.PLATINUM, MaterialNames.PRISMARINE, + MaterialNames.QUARTZ, MaterialNames.REDSTONE, MaterialNames.SILVER, + MaterialNames.STARSTEEL, MaterialNames.STEEL, MaterialNames.STONE, + MaterialNames.TIN, MaterialNames.WOOD, MaterialNames.ZINC); + + private static final Set FULL_TOOLS = set(MaterialNames.ADAMANTINE, + MaterialNames.AQUARIUM, MaterialNames.BRONZE, MaterialNames.COLDIRON, + MaterialNames.COPPER, MaterialNames.CUPRONICKEL, MaterialNames.INVAR, + MaterialNames.MITHRIL, MaterialNames.NICKEL, MaterialNames.STARSTEEL, + MaterialNames.STEEL, MaterialNames.IRON); + + private static final Set ARMOR = set(MaterialNames.ADAMANTINE, + MaterialNames.AQUARIUM, MaterialNames.BRASS, MaterialNames.BRONZE, + MaterialNames.COLDIRON, MaterialNames.COPPER, MaterialNames.CUPRONICKEL, + MaterialNames.ELECTRUM, MaterialNames.INVAR, MaterialNames.MITHRIL, + MaterialNames.NICKEL, MaterialNames.PLATINUM, MaterialNames.SILVER, + MaterialNames.STARSTEEL, MaterialNames.STEEL); + private static final Set PROTECTIVE = union(ARMOR, + set(MaterialNames.IRON, MaterialNames.GOLD, MaterialNames.DIAMOND)); + + private static final Set AMMUNITION = union(FULL_TOOLS, + set(MaterialNames.SILVER, MaterialNames.OBSIDIAN, MaterialNames.DIAMOND)); + + private static final Set GEARS = set(MaterialNames.ADAMANTINE, + MaterialNames.AQUARIUM, MaterialNames.BRASS, MaterialNames.BRONZE, + MaterialNames.COLDIRON, MaterialNames.COPPER, MaterialNames.CUPRONICKEL, + MaterialNames.INVAR, MaterialNames.MITHRIL, MaterialNames.NICKEL, + MaterialNames.STARSTEEL, MaterialNames.STEEL, MaterialNames.IRON, + MaterialNames.GOLD, MaterialNames.WOOD); + + private static final Set TOOLS = Collections.unmodifiableSet( + new LinkedHashSet<>(Arrays.asList(MaterialForm.AXE, MaterialForm.CRACKHAMMER, + MaterialForm.HOE, MaterialForm.PICKAXE, MaterialForm.SCYTHE, + MaterialForm.SHEARS, MaterialForm.SHOVEL, MaterialForm.SWORD))); + private static final Set ARMOR_FORMS = Collections.unmodifiableSet( + new LinkedHashSet<>(Arrays.asList(MaterialForm.BOOTS, MaterialForm.CHESTPLATE, + MaterialForm.HELMET, MaterialForm.LEGGINGS, MaterialForm.HORSE_ARMOR, + MaterialForm.SHIELD))); + private static final Set BUILDING_FORMS = Collections.unmodifiableSet( + new LinkedHashSet<>(Arrays.asList(MaterialForm.ANVIL, MaterialForm.BARS, + MaterialForm.BLOCK, MaterialForm.BOOKSHELF, MaterialForm.BUTTON, + MaterialForm.DOOR, MaterialForm.DOUBLE_SLAB, MaterialForm.FENCE, + MaterialForm.FENCE_GATE, MaterialForm.FLOWER_POT, MaterialForm.LADDER, + MaterialForm.LEVER, MaterialForm.PLATE, MaterialForm.PRESSURE_PLATE, + MaterialForm.SLAB, MaterialForm.STAIRS, MaterialForm.TRAPDOOR, + MaterialForm.TRIPWIRE_HOOK, MaterialForm.WALL))); + + private final ContentMode mode; + + private ContentPolicy(final ContentMode mode) { + this.mode = mode; + } + + public static ContentPolicy forMode(final ContentMode mode) { + return mode == ContentMode.LOW_FANTASY ? LOW : HIGH; + } + + public static ContentPolicy active() { + return forMode(zone.moddev.mc.basemetals.util.Config.getActiveContentMode()); + } + + public ContentMode mode() { + return mode; + } + + public boolean allowsToolParts(final String material) { + return TOOLS.stream().anyMatch(form -> allows(material, form)); + } + + public boolean allows(final String material, final MaterialForm form) { + final String name = normalize(material); + + if (mode == ContentMode.HIGH_FANTASY || material == null || form == null) { + return true; + } + + if (form == MaterialForm.OTHER) { + return !MaterialNames.MERCURY.equals(name); + } + + if (form == MaterialForm.BOW || form == MaterialForm.CROSSBOW + || form == MaterialForm.FISHING_ROD) { + return false; + } + + if (TOOLS.contains(form)) { + return allowsTool(name, form); + } + + if (ARMOR_FORMS.contains(form)) { + return PROTECTIVE.contains(name); + } + + if (form == MaterialForm.ARROW || form == MaterialForm.BOLT) { + return AMMUNITION.contains(name); + } + + if (form == MaterialForm.GEAR) { + return GEARS.contains(name); + } + + if (form == MaterialForm.ANVIL) { + return MaterialNames.STONE.equals(name) || MaterialNames.STEEL.equals(name) + || MaterialNames.ADAMANTINE.equals(name); + } + + if (MaterialNames.MERCURY.equals(name)) { + return form == MaterialForm.ORE || form == MaterialForm.POWDER + || form == MaterialForm.SMALLPOWDER || form == MaterialForm.FLUID + || form == MaterialForm.INGOT; + } + + if (BUILDING_FORMS.contains(form)) { + return true; + } + + return true; + } + + public boolean allows(final ItemStack stack) { + if (stack == null || stack.isEmpty()) { + return true; + } + + return allows(stack.getItem().getRegistryName()); + } + + public boolean allows(final ResourceLocation id) { + if (id == null || !BaseMetals.MODID.equals(id.getResourceDomain())) { + return true; + } + + final String material = materialFromPath(id.getResourcePath()); + + if (material == null) { + return true; + } + + MaterialForm form = MaterialForm.fromRegistryPath(id.getResourcePath()); + + if (form == MaterialForm.OTHER && id.getResourcePath().equals(material)) { + form = MaterialForm.FLUID; + } + + return allows(material, form); + } + + + public static String materialFromPath(final String registryPath) { + if (registryPath == null) { + return null; + } + + final String path = registryPath.toLowerCase(Locale.ROOT); + + for (final String material : MATERIALS) { + if (path.equals(material) || path.startsWith(material + "_") + || path.startsWith("double_" + material + "_")) { + return material; + } + } + + return null; + } + + private boolean allowsTool(final String material, final MaterialForm form) { + if (FULL_TOOLS.contains(material)) { + return true; + } + + if (MaterialNames.SILVER.equals(material)) { + return form == MaterialForm.SWORD; + } + + if (MaterialNames.OBSIDIAN.equals(material)) { + return form == MaterialForm.AXE || form == MaterialForm.SWORD + || form == MaterialForm.SCYTHE; + } + + if (MaterialNames.DIAMOND.equals(material)) { + return form == MaterialForm.CRACKHAMMER || form == MaterialForm.SCYTHE + || form == MaterialForm.SHEARS; + } + + if (MaterialNames.STONE.equals(material)) { + return form == MaterialForm.CRACKHAMMER || form == MaterialForm.SCYTHE; + } + + return MaterialNames.WOOD.equals(material) && form == MaterialForm.CRACKHAMMER; + } + + private static String normalize(final String material) { + return material == null ? "" : material.trim().toLowerCase(Locale.ROOT); + } + + private static Set set(final String... values) { + return Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(values))); + } + + private static Set union(final Set first, final Set second) { + final Set values = new LinkedHashSet<>(first); + + values.addAll(second); + + return Collections.unmodifiableSet(values); + } +} diff --git a/src/main/java/zone/moddev/mc/basemetals/content/MaterialForm.java b/src/main/java/zone/moddev/mc/basemetals/content/MaterialForm.java new file mode 100644 index 000000000..c2209cbfb --- /dev/null +++ b/src/main/java/zone/moddev/mc/basemetals/content/MaterialForm.java @@ -0,0 +1,98 @@ +package zone.moddev.mc.basemetals.content; + +import java.util.Locale; + +/** Item and block forms used to decide which recipes a content mode permits. */ +public enum MaterialForm { + ARROW, + AXE, + BLEND, + BOOTS, + BOLT, + BOW, + CHESTPLATE, + CRACKHAMMER, + CROSSBOW, + FISHING_ROD, + GEAR, + HELMET, + HOE, + HORSE_ARMOR, + INGOT, + LEGGINGS, + NUGGET, + PICKAXE, + POWDER, + ROD, + SCYTHE, + SHEARS, + SHIELD, + SHOVEL, + SMALLBLEND, + SMALLPOWDER, + SWORD, + CASING, + CLUMP, + CRUSHED, + CRUSHED_PURIFIED, + CRYSTAL, + DENSE_PLATE, + DIRTY_POWDER, + SHARD, + ANVIL, + BARS, + BLOCK, + BOOKSHELF, + BUTTON, + DOOR, + DOUBLE_SLAB, + FENCE, + FENCE_GATE, + FLOWER_POT, + LADDER, + LEVER, + PLATE, + PRESSURE_PLATE, + SLAB, + STAIRS, + TRAPDOOR, + TRIPWIRE_HOOK, + WALL, + ORE, + FLUID, + OTHER; + + /** Finds the form from the suffix of a Base Metals or MMDLib registry name. */ + public static MaterialForm fromRegistryPath(final String registryPath) { + if (registryPath == null) { + return OTHER; + } + + final String path = registryPath.toLowerCase(Locale.ROOT); + MaterialForm match = OTHER; + int longestMatch = -1; + + for (final MaterialForm form : values()) { + if (form == OTHER || form == FLUID) { + continue; + } + + final String suffix = registrySuffix(form); + + if (path.endsWith("_" + suffix) && suffix.length() > longestMatch) { + match = form; + longestMatch = suffix.length(); + } + } + + return match; + } + + private static String registrySuffix(final MaterialForm form) { + if (form == DIRTY_POWDER) { + return "powder_dirty"; + } + + return form.name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/zone/moddev/mc/basemetals/init/Items.java b/src/main/java/zone/moddev/mc/basemetals/init/Items.java index 88f90cff7..83b4e9a38 100644 --- a/src/main/java/zone/moddev/mc/basemetals/init/Items.java +++ b/src/main/java/zone/moddev/mc/basemetals/init/Items.java @@ -293,7 +293,7 @@ private static void addIronBits() { iron.addNewItem(Names.HELMET, net.minecraft.init.Items.IRON_HELMET); iron.addNewItem(Names.LEGGINGS, net.minecraft.init.Items.IRON_LEGGINGS); iron.addNewItem(Names.INGOT, net.minecraft.init.Items.IRON_INGOT); - // iron.addNewItem(Names.NUGGET, net.minecraft.init.Items.field_191525_da); // Items.IRON_NUGGET + iron.addNewItem(Names.NUGGET, net.minecraft.init.Items.field_191525_da); // Vanilla iron nugget. iron.addNewItem(Names.SHEARS, net.minecraft.init.Items.SHEARS); if (Materials.hasMaterial(MaterialNames.IRON)) { diff --git a/src/main/java/zone/moddev/mc/basemetals/init/Recipes.java b/src/main/java/zone/moddev/mc/basemetals/init/Recipes.java index c1652b47a..82ee7e9c6 100644 --- a/src/main/java/zone/moddev/mc/basemetals/init/Recipes.java +++ b/src/main/java/zone/moddev/mc/basemetals/init/Recipes.java @@ -12,7 +12,6 @@ import net.minecraft.item.ItemStack; import net.minecraftforge.common.ForgeModContainer; import net.minecraftforge.fluids.FluidRegistry; -import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.UniversalBucket; import net.minecraftforge.fml.common.registry.GameRegistry; import net.minecraftforge.oredict.OreDictionary; @@ -48,22 +47,6 @@ protected static void initVanillaRecipes() { } } - // Iron items - if (Materials.hasMaterial(MaterialNames.IRON)) { - final MMDMaterial iron = com.mcmoddev.lib.init.Materials - .getMaterialByName(MaterialNames.IRON); - final String oreDictName = iron.getCapitalizedName(); - - if (iron.hasItem(Names.NUGGET)) { - GameRegistry.addRecipe(new ShapelessOreRecipe(iron.getItemStack(Names.NUGGET, 9), - Oredicts.INGOT + oreDictName)); - } - if (iron.hasItem(Names.INGOT)) { - GameRegistry.addRecipe(new ShapedOreRecipe(iron.getItemStack(Names.INGOT), "xxx", "xxx", - "xxx", 'x', Oredicts.NUGGET + oreDictName)); - } - } - coalCharcoalHelper(MaterialNames.CHARCOAL); coalCharcoalHelper(MaterialNames.COAL); } @@ -153,9 +136,8 @@ private static void initModSpecificRecipes() { if (FluidRegistry.isUniversalBucketEnabled()) { final UniversalBucket universalBucket = ForgeModContainer .getInstance().universalBucket; - final ItemStack bucketMercury = new ItemStack(universalBucket, 1, 0); - universalBucket.fill(bucketMercury, - new FluidStack(mercury.getFluid(), universalBucket.getCapacity()), true); + final ItemStack bucketMercury = UniversalBucket.getFilledBucket(universalBucket, + mercury.getFluid()); GameRegistry.addRecipe(new ShapelessOreRecipe(bucketMercury, net.minecraft.init.Items.BUCKET, Oredicts.INGOT_MERCURY, Oredicts.INGOT_MERCURY, Oredicts.INGOT_MERCURY, Oredicts.INGOT_MERCURY, diff --git a/src/main/java/zone/moddev/mc/basemetals/items/MMDToolEffects.java b/src/main/java/zone/moddev/mc/basemetals/items/MMDToolEffects.java index 5d1bdeb25..2ece2116e 100644 --- a/src/main/java/zone/moddev/mc/basemetals/items/MMDToolEffects.java +++ b/src/main/java/zone/moddev/mc/basemetals/items/MMDToolEffects.java @@ -82,12 +82,12 @@ public static void extraEffectsOnAttack(final MMDMaterial material, final ItemSt final String materialName = material.getName(); if (materialName.equals(MaterialNames.COLDIRON)) { if (target.isImmuneToFire()) { - final DamageSource extraDamage = DamageSource.generic; + final DamageSource extraDamage = DamageSource.GENERIC; target.attackEntityFrom(extraDamage, 3f); } } else if (materialName.equals(MaterialNames.ADAMANTINE)) { if (target.getMaxHealth() > 20f) { - final DamageSource extraDamage = DamageSource.generic; + final DamageSource extraDamage = DamageSource.GENERIC; target.attackEntityFrom(extraDamage, 4f); } } else if (materialName.equals(MaterialNames.MITHRIL)) { @@ -101,7 +101,7 @@ public static void extraEffectsOnAttack(final MMDMaterial material, final ItemSt } } else if ((materialName.equals(MaterialNames.AQUARIUM)) && (target.canBreatheUnderwater())) { - final DamageSource extraDamage = DamageSource.generic; + final DamageSource extraDamage = DamageSource.GENERIC; target.attackEntityFrom(extraDamage, 4f); } } @@ -310,7 +310,7 @@ private static boolean isHolding(final EntityPlayer player, final String materia final MMDMaterial material = Materials.getMaterialByName(materialName); final ItemStack heldItemStack = player.getHeldItemMainhand(); final Item heldItem = heldItemStack.getItem(); - if (((heldItemStack.stackSize >= 1) && (heldItem == material.getItem(itemName)))) { + if (((heldItemStack.getCount() >= 1) && (heldItem == material.getItem(itemName)))) { return true; } } diff --git a/src/main/java/zone/moddev/mc/basemetals/proxy/ClientProxy.java b/src/main/java/zone/moddev/mc/basemetals/proxy/ClientProxy.java index 7a9de9d3f..3814103e0 100644 --- a/src/main/java/zone/moddev/mc/basemetals/proxy/ClientProxy.java +++ b/src/main/java/zone/moddev/mc/basemetals/proxy/ClientProxy.java @@ -1,6 +1,8 @@ package zone.moddev.mc.basemetals.proxy; import zone.moddev.mc.basemetals.BaseMetals; +import zone.moddev.mc.basemetals.client.BaseMetalsConfigScreen; +import zone.moddev.mc.orespawn.api.client.WorldSettingsExtensionRegistry; import com.mcmoddev.lib.client.registrations.RegistrationHelper; import com.mcmoddev.lib.client.renderer.RenderCustomArrow; import com.mcmoddev.lib.client.renderer.RenderCustomBolt; @@ -65,6 +67,8 @@ public void preInit(final FMLPreInitializationEvent event) { @Override public void init(final FMLInitializationEvent event) { super.init(event); + WorldSettingsExtensionRegistry.registerConfigScreen(BaseMetals.MODID, BaseMetalsConfigScreen::new); + if (Loader.isModLoaded("waila")) { com.mcmoddev.lib.waila.Waila.init(); } diff --git a/src/main/java/zone/moddev/mc/basemetals/proxy/CommonProxy.java b/src/main/java/zone/moddev/mc/basemetals/proxy/CommonProxy.java index 1ebff500c..0996f7402 100644 --- a/src/main/java/zone/moddev/mc/basemetals/proxy/CommonProxy.java +++ b/src/main/java/zone/moddev/mc/basemetals/proxy/CommonProxy.java @@ -4,6 +4,8 @@ import java.util.Map; import zone.moddev.mc.basemetals.BaseMetals; +import zone.moddev.mc.basemetals.content.ContentAcquisition; +import zone.moddev.mc.basemetals.content.ContentModeNetwork; import zone.moddev.mc.basemetals.data.MaterialNames; import zone.moddev.mc.basemetals.init.Achievements; import zone.moddev.mc.basemetals.init.Blocks; @@ -49,6 +51,7 @@ public boolean allsGood() { public void preInit(final FMLPreInitializationEvent event) { Config.init(); + ContentModeNetwork.register(); com.mcmoddev.lib.init.Materials.init(); Materials.init(); @@ -118,8 +121,10 @@ public void onIdMapping() { public void init(final FMLInitializationEvent event) { this.allsGood = false; BaseMetalsWorldgenProvider.enqueue(); - com.mcmoddev.lib.init.Recipes.init(); - Recipes.init(); + ContentAcquisition.registerRecipes(() -> { + com.mcmoddev.lib.init.Recipes.init(); + Recipes.init(); + }); Achievements.init(); FuelRegistry.register(); diff --git a/src/main/java/zone/moddev/mc/basemetals/util/Config.java b/src/main/java/zone/moddev/mc/basemetals/util/Config.java index 808b8b8b9..8725d5997 100644 --- a/src/main/java/zone/moddev/mc/basemetals/util/Config.java +++ b/src/main/java/zone/moddev/mc/basemetals/util/Config.java @@ -3,6 +3,7 @@ import java.io.File; import zone.moddev.mc.basemetals.BaseMetals; +import zone.moddev.mc.basemetals.content.ContentMode; import zone.moddev.mc.basemetals.data.MaterialNames; import com.mcmoddev.lib.data.ConfigKeys; import com.mcmoddev.lib.integration.plugins.DenseOresBase; @@ -30,6 +31,7 @@ public class Config extends ConfigBase { private static Configuration configuration; + private static ContentMode activeContentMode = ContentMode.HIGH_FANTASY; private static final String CONFIG_FILE = "config/BaseMetals.cfg"; private static final String GENERAL_CAT = "General"; private static final String INTEGRATION_CAT = "Mod Integration"; @@ -39,14 +41,22 @@ public class Config extends ConfigBase { private static final String TOOLS_CAT = "Tools and Items"; private static final String FLUIDS_CAT = "Fluids"; + public static Configuration getConfiguration() { + return configuration; + } + + public static ContentMode getActiveContentMode() { + return activeContentMode; + } + /** * * @param event */ @SubscribeEvent public void onConfigChange(final ConfigChangedEvent.OnConfigChangedEvent event) { - if (event.getModID().equals(BaseMetals.MODID)) { - init(); + if (BaseMetals.MODID.equals(event.getModID()) && configuration.hasChanged()) { + configuration.save(); } } @@ -57,6 +67,22 @@ public static void init() { if (configuration == null) { configuration = new Configuration(new File(CONFIG_FILE)); MinecraftForge.EVENT_BUS.register(new Config()); + + final Property mode = configuration.get(GENERAL_CAT, "contentMode", "high_fantasy", + "High Fantasy keeps the full recipe set. Low Fantasy limits what each material can make. " + + "Existing items and ore generation are unchanged. Restart to apply."); + mode.setLanguageKey("config.basemetals.option.content_mode"); + mode.setValidValues(ContentMode.serializedNames()); + mode.setRequiresMcRestart(true); + + final String configured = mode.getString(); + activeContentMode = ContentMode.fromSerializedName(configured); + if (!ContentMode.isValidSerializedName(configured)) { + BaseMetals.logger.warn("Unknown Fantasy Level '%s'; using High Fantasy.", configured); + } + if (!activeContentMode.serializedName().equals(configured)) { + mode.set(activeContentMode.serializedName()); + } } // GENERAL @@ -364,6 +390,14 @@ public static void init() { manageUserHammerRecipes(userRecipeCat.values()); + configuration.getCategory(GENERAL_CAT).setLanguageKey("config.basemetals.category.general"); + configuration.getCategory(MATERIALS_CAT).setLanguageKey("config.basemetals.category.metals"); + configuration.getCategory(VANILLA_CAT).setLanguageKey("config.basemetals.category.vanilla"); + configuration.getCategory(FLUIDS_CAT).setLanguageKey("config.basemetals.category.fluids"); + configuration.getCategory(TOOLS_CAT).setLanguageKey(TOOLS_CAT); + configuration.getCategory(INTEGRATION_CAT).setLanguageKey(INTEGRATION_CAT); + configuration.getCategory(HAMMER_RECIPES_CAT).setLanguageKey(HAMMER_RECIPES_CAT); + if (configuration.hasChanged()) { configuration.save(); } diff --git a/src/main/java/zone/moddev/mc/basemetals/util/EventHandler.java b/src/main/java/zone/moddev/mc/basemetals/util/EventHandler.java index 96e1add3f..2750c9582 100644 --- a/src/main/java/zone/moddev/mc/basemetals/util/EventHandler.java +++ b/src/main/java/zone/moddev/mc/basemetals/util/EventHandler.java @@ -53,7 +53,7 @@ public void attackEvent(final LivingAttackEvent event) { if ((damage > 0.0F) && (activeItemStack.getItem() instanceof ItemMMDShield)) { final int i = 1 + MathHelper.floor(damage); activeItemStack.damageItem(i, player); - if (activeItemStack.stackSize <= 0) { + if (activeItemStack.getCount() <= 0) { final EnumHand enumhand = player.getActiveHand(); ForgeEventFactory.onPlayerDestroyItem(player, activeItemStack, enumhand); if (enumhand == EnumHand.MAIN_HAND) { @@ -156,8 +156,8 @@ public void handleAnvilEvent(final AnvilUpdateEvent event) { final ItemStack left = event.getLeft(); final ItemStack right = event.getRight(); - if ((left == null) || (right == null) || (left.stackSize != 1) - || (right.stackSize != 1)) { + if ((left == null) || (right == null) || (left.getCount() != 1) + || (right.getCount() != 1)) { return; } diff --git a/src/main/resources/assets/basemetals/lang/de_DE.lang b/src/main/resources/assets/basemetals/lang/de_DE.lang index c75f9a312..b3e62d058 100644 --- a/src/main/resources/assets/basemetals/lang/de_DE.lang +++ b/src/main/resources/assets/basemetals/lang/de_DE.lang @@ -1,1818 +1,1832 @@ -basemetals.crackhammer=Zerkleinerte Blöcke / Gegenstände - -#Creative Tabs -itemGroup.basemetals.blocks=Base Metals Blöcke -itemGroup.basemetals.combat=Base Metals Combat -itemGroup.basemetals.items=Base Metals Gegenstände -itemGroup.basemetals.tools=Base Metals Werkzeuge - -#ToolTips -tooltip.adamantine.tool=+%d Schaden gegen zähe Feinde -tooltip.adamantine.armor=Volle Rüstung: Schadensreduktion - -tooltip.aquarium.tool=+%d Schaden gegen aquatische Feinde -tooltip.aquarium.armor=Volle Rüstung: Unterwasseratmung - -tooltip.coldiron.tool=+%d Schaden gegen feurige Feinde -tooltip.coldiron.armor=Volle Rüstung: Feuerimmunität - -tooltip.mithril.tool=Blendet Wither und Untote -tooltip.mithril.armor=Volle Rüstung: Immunität gegen Gift & Wither - -tooltip.starsteel.tool=Repariert 1 Schaden alle %d Sekunden -tooltip.starsteel.armor=Volle Rüstung: Gewichtsreduktion - -#Achievements - #Achievement Name -achievement.aquarium_maker=Aquarium -achievement.angel_of_death=Todesengel -achievement.brass_maker=Messing -achievement.bronze_maker=Bronze -achievement.blocktastic=Blocktastisch! -achievement.cupronickel_maker=Kupfernickel -achievement.demon_slayer=Dämonenschlächter -achievement.electrum_maker=Elektron -achievement.geologist=Geologe -achievement.invar_maker=Invar -achievement.juggernaut=Juggernaut -achievement.metallurgy=Metallurgy -achievement.mithril_maker=Mithril -achievement.moon_boots=Moon Walker -achievement.scuba_diver=SCUBA Diver -achievement.steel_maker=Stahl -achievement.this_is_new=Das ist neu ... - #Acheviement Desc -achievement.aquarium_maker.desc=Kombiniere Kupferpulver, Zinkpulver und Prismarinkristalle, um Aquarium herzustellen -achievement.angel_of_death.desc=Trage eine vollständige Mithrilrüstung und führe ein Mithrilschwert -achievement.brass_maker.desc=Kombiniere Kupferpulver und Zinkpulver, um Messing herzustellen -achievement.bronze_maker.desc=Kombiniere Kupferpulver und Zinnpulver, um Bronze herzustellen -achievement.blocktastic.desc=Platziere einen Metallblock, der weder Eisen noch Gold ist -achievement.cupronickel_maker.desc=Kombiniere Kupferpulver und Nickelpulver, um Kupfernickel herzustellen -achievement.demon_slayer.desc=Trage eine vollständige Kalteisenrüstung und führe ein Kalteisenschwert -achievement.electrum_maker.desc=Kombiniere Silberpulver und Goldpulver, um Elektron herzustellen -achievement.geologist.desc=Stelle einen Hammer aus einem Metallblock her -achievement.invar_maker.desc=Kombiniere Eisenpulver und Nickelpulver, um Invar herzustellen -achievement.juggernaut.desc=Trage eine vollständige Adamantrüstung -achievement.metallurgy.desc=Stelle ein beliebiges Gemisch her -achievement.mithril_maker.desc=Kombiniere Silverpulver, Kalteisenpulver und Quecksilberpulver, um Mithril herzustellen -achievement.moon_boots.desc=Trage ein Paar Sternenstahlstiefel -achievement.scuba_diver.desc=Trage eine vollständige Aquariumrüstung und tauche im Wasser -achievement.steel_maker.desc=Kombiniere Eisenpulver mit Holzkohlepulver, um Stahl herzustellen -achievement.this_is_new.desc=Schmelze ein neues Metall des Base Metals Mod - -#axts -item.basemetals.adamantine_axe.name=Adamantaxt -item.basemetals.aquarium_axe.name=Aquariumaxt -item.basemetals.antimony_axe.name=Antimonaxt -item.basemetals.bismuth_axe.name=Bismuthaxt -item.basemetals.brass_axe.name=Messingaxt -item.basemetals.bronze_axe.name=Bronzeaxt -item.basemetals.coldiron_axe.name=Kalteisenaxt -item.basemetals.copper_axe.name=Kupferaxt -item.basemetals.cupronickel_axe.name=Kupfernickelaxt -item.basemetals.electrum_axe.name=Elektronaxt -item.basemetals.emerald_axe.name=Smaragdaxt -item.basemetals.invar_axe.name=Invaraxt -item.basemetals.lead_axe.name=Bleiaxt -item.basemetals.mithril_axe.name=Mithrilaxt -item.basemetals.nickel_axe.name=Nickelaxt -item.basemetals.obsidian_axe.name=Obsdidianaxt -item.basemetals.pewter_axe.name=Hartzinnaxt -item.basemetals.platinum_axe.name=Platinaxt -item.basemetals.quartz_axe.name=Quartzaxt -item.basemetals.silver_axe.name=Silberaxt -item.basemetals.starsteel_axe.name=Sternenstahlaxt -item.basemetals.steel_axe.name=Stahlaxt -item.basemetals.tin_axe.name=Zinnaxt -item.basemetals.zinc_axe.name=Zinkaxt - -#swords -item.basemetals.adamantine_sword.name=Adamantschwert -item.basemetals.aquarium_sword.name=Aquariumschwert -item.basemetals.antimony_sword.name=Antimonschwert -item.basemetals.bismuth_sword.name=Bismuthschwert -item.basemetals.brass_sword.name=Messingschwert -item.basemetals.bronze_sword.name=Bronzeschwert -item.basemetals.coldiron_sword.name=Kalteisenschwert -item.basemetals.copper_sword.name=Kupferschwert -item.basemetals.cupronickel_sword.name=Kupfernickelschwert -item.basemetals.electrum_sword.name=Elektronschwert -item.basemetals.emerald_sword.name=Smaragdschwert -item.basemetals.invar_sword.name=Invarschwert -item.basemetals.lead_sword.name=Bleischwert -item.basemetals.mithril_sword.name=Mithrilschwert -item.basemetals.obsidian_sword.name=Obsidianschwert -item.basemetals.nickel_sword.name=Nickelschwert -item.basemetals.quartz_sword.name=Quartzschwert -item.basemetals.pewter_sword.name=Hartzinnschwert -item.basemetals.platinum_sword.name=Platinschwert -item.basemetals.silver_sword.name=Silberschwert -item.basemetals.starsteel_sword.name=Sternenstahlschwert -item.basemetals.steel_sword.name=Stahlschwert -item.basemetals.tin_sword.name=Zinnschwert -item.basemetals.zinc_sword.name=Zinkschwert - -#spitzhackes -item.basemetals.adamantine_pickaxe.name=Adamantspitzhacke -item.basemetals.aquarium_pickaxe.name=Aquariumspitzhacke -item.basemetals.antimony_pickaxe.name=Antimonspitzhacke -item.basemetals.bismuth_pickaxe.name=Bismuthspitzhacke -item.basemetals.brass_pickaxe.name=Messingspitzhacke -item.basemetals.bronze_pickaxe.name=Bronzespitzhacke -item.basemetals.coldiron_pickaxe.name=Kalteisenspitzhacke -item.basemetals.copper_pickaxe.name=Kupferspitzhacke -item.basemetals.cupronickel_pickaxe.name=Kupfernickelspitzhacke -item.basemetals.electrum_pickaxe.name=Elektronspitzhacke -item.basemetals.emerald_pickaxe.name=Smaragdspitzhacke -item.basemetals.invar_pickaxe.name=Invarspitzhacke -item.basemetals.lead_pickaxe.name=Bleispitzhacke -item.basemetals.mithril_pickaxe.name=Mithrilspitzhacke -item.basemetals.nickel_pickaxe.name=Nickelspitzhacke -item.basemetals.obsidian_pickaxe.name=Obsidianspitzhacke -item.basemetals.pewter_pickaxe.name=Hartzinnspitzhacke -item.basemetals.platinum_pickaxe.name=Platinspitzhacke -item.basemetals.quartz_pickaxe.name=Quartzspitzhacke -item.basemetals.silver_pickaxe.name=Silberspitzhacke -item.basemetals.starsteel_pickaxe.name=Sternenstahlspitzhacke -item.basemetals.steel_pickaxe.name=Stahlspitzhacke -item.basemetals.tin_pickaxe.name=Zinnspitzhacke -item.basemetals.zinc_pickaxe.name=Zinkspitzhacke - -#schaufels -item.basemetals.adamantine_shovel.name=Adamantschaufel -item.basemetals.aquarium_shovel.name=Aquariumschaufel -item.basemetals.antimony_shovel.name=Antimonschaufel -item.basemetals.bismuth_shovel.name=Bismuthschaufel -item.basemetals.brass_shovel.name=Messingschaufel -item.basemetals.bronze_shovel.name=Bronzeschaufel -item.basemetals.coldiron_shovel.name=Kalteisenschaufel -item.basemetals.copper_shovel.name=Kupferschaufel -item.basemetals.cupronickel_shovel.name=Kupfernickelschaufel -item.basemetals.electrum_shovel.name=Elektronschaufel -item.basemetals.emerald_shovel.name=Smaragdschaufel -item.basemetals.invar_shovel.name=Invarschaufel -item.basemetals.lead_shovel.name=Bleischaufel -item.basemetals.mithril_shovel.name=Mithrilschaufel -item.basemetals.nickel_shovel.name=Nickelschaufel -item.basemetals.obsidian_shovel.name=Obsidianschaufel -item.basemetals.pewter_shovel.name=Hartzinnschaufel -item.basemetals.platinum_shovel.name=Platinschaufel -item.basemetals.quartz_shovel.name=Quartzschaufel -item.basemetals.silver_shovel.name=Silberschaufel -item.basemetals.starsteel_shovel.name=Sternenstahlschaufel -item.basemetals.steel_shovel.name=Stahlschaufel -item.basemetals.tin_shovel.name=Zinnschaufel -item.basemetals.zinc_shovel.name=Zinkschaufel - -#hackes -item.basemetals.adamantine_hoe.name=Adamanthacke -item.basemetals.aquarium_hoe.name=Aquariumhacke -item.basemetals.antimony_hoe.name=Antimonhacke -item.basemetals.bismuth_hoe.name=Bismuthhacke -item.basemetals.brass_hoe.name=Messinghacke -item.basemetals.bronze_hoe.name=Bronzehacke -item.basemetals.coldiron_hoe.name=Kalteisenhacke -item.basemetals.copper_hoe.name=Kupferhacke -item.basemetals.cupronickel_hoe.name=Kupfernickelhacke -item.basemetals.electrum_hoe.name=Elektronhacke -item.basemetals.emerald_hoe.name=Smaragdhacke -item.basemetals.invar_hoe.name=Invarhacke -item.basemetals.lead_hoe.name=Bleihacke -item.basemetals.mithril_hoe.name=Mithrilhacke -item.basemetals.nickel_hoe.name=Nickelhacke -item.basemetals.obsidian_hoe.name=Obsidianhacke -item.basemetals.pewter_hoe.name=Hartzinnhacke -item.basemetals.platinum_hoe.name=Platinhacke -item.basemetals.quartz_hoe.name=Quartzhacke -item.basemetals.silver_hoe.name=Silberhacke -item.basemetals.starsteel_hoe.name=Sternenstahlhacke -item.basemetals.steel_hoe.name=Stahlhacke -item.basemetals.tin_hoe.name=Zinnhacke -item.basemetals.zinc_hoe.name=Zinkhacke - -#Crackhammers -item.basemetals.adamantine_crackhammer.name=Adamantbruchhammer -item.basemetals.aquarium_crackhammer.name=Aquariumbruchhammer -item.basemetals.antimony_crackhammer.name=Antimonbruchhammer -item.basemetals.bismuth_crackhammer.name=Bismuthbruchhammer -item.basemetals.brass_crackhammer.name=Messingbruchhammer -item.basemetals.bronze_crackhammer.name=Bronzebruchhammer -item.basemetals.coldiron_crackhammer.name=Kalteisenbruchhammer -item.basemetals.copper_crackhammer.name=Kupferbruchhammer -item.basemetals.cupronickel_crackhammer.name=Kupfernickelbruchhammer -item.basemetals.diamond_crackhammer.name=Diamantbruchhammer -item.basemetals.electrum_crackhammer.name=Elektronbruchhammer -item.basemetals.emerald_crackhammer.name=Smaragdbruchhammer -item.basemetals.gold_crackhammer.name=Goldenbruchhammer -item.basemetals.invar_crackhammer.name=Invarbruchhammer -item.basemetals.iron_crackhammer.name=Eisenbruchhammer -item.basemetals.lead_crackhammer.name=Bleibruchhammer -item.basemetals.mithril_crackhammer.name=Mithrilbruchhammer -item.basemetals.obsidian_crackhammer.name=Obsidianbruchhammer -item.basemetals.platinum_crackhammer.name=Platinbruchhammer -item.basemetals.pewter_crackhammer.name=Hartzinnbruchhammer -item.basemetals.quartz_crackhammer.name=Quartzbruchhammer -item.basemetals.nickel_crackhammer.name=Nickelbruchhammer -item.basemetals.silver_crackhammer.name=Silberbruchhammer -item.basemetals.starsteel_crackhammer.name=Sternenstahlbruchhammer -item.basemetals.steel_crackhammer.name=Stahlbruchhammer -item.basemetals.stone_crackhammer.name=Stonebruchhammer -item.basemetals.tin_crackhammer.name=Zinnbruchhammer -item.basemetals.wood_crackhammer.name=Holzbruchhammer -item.basemetals.zinc_crackhammer.name=Zinkbruchhammer - -#schere -item.basemetals.adamantine_shears.name=Adamantschere -item.basemetals.aquarium_shears.name=Aquariumschere -item.basemetals.antimony_shears.name=Antimonschere -item.basemetals.bismuth_shears.name=Bismuthschere -item.basemetals.brass_shears.name=Messingschere -item.basemetals.bronze_shears.name=Bronzeschere -item.basemetals.coldiron_shears.name=Kalteisenschere -item.basemetals.copper_shears.name=Kupferschere -item.basemetals.cupronickel_shears.name=Kupfernickelschere -item.basemetals.diamond_shears.name=Diamantschere -item.basemetals.electrum_shears.name=Elektronschere -item.basemetals.emerald_shears.name=Smaragdschere -item.basemetals.gold_shears.name=Goldschere -item.basemetals.invar_shears.name=Invarschere -item.basemetals.lead_shears.name=Bleischere -item.basemetals.mithril_shears.name=Mithrilschere -item.basemetals.nickel_shears.name=Nickelschere -item.basemetals.obsidian_shears.name=Obsidianschere -item.basemetals.pewter_shears.name=Hartzinnschere -item.basemetals.platinum_shears.name=Platinschere -item.basemetals.quartz_shears.name=Quartzschere -item.basemetals.silver_shears.name=Silberschere -item.basemetals.starsteel_shears.name=Sternenstahlschere -item.basemetals.steel_shears.name=Stahlschere -item.basemetals.tin_shears.name=Zinnschere -item.basemetals.zinc_shears.name=Zinkschere - -#bogen -item.basemetals.adamantine_bow.name=Adamantbogen -item.basemetals.aquarium_bow.name=Aquariumbogen -item.basemetals.antimony_bow.name=Antimonbogen -item.basemetals.bismuth_bow.name=Bismuthbogen -item.basemetals.brass_bow.name=Messingbogen -item.basemetals.bronze_bow.name=Bronzebogen -item.basemetals.coldiron_bow.name=Kalteisenbogen -item.basemetals.copper_bow.name=Kupferbogen -item.basemetals.cupronickel_bow.name=Kupfernickelbogen -item.basemetals.diamond_bow.name=Diamantbogen -item.basemetals.electrum_bow.name=Elektronbogen -item.basemetals.emerald_bow.name=Smaragdbogen -item.basemetals.gold_bow.name=Goldbogen -item.basemetals.invar_bow.name=Invarbogen -item.basemetals.iron_bow.name=Eisenbogen -item.basemetals.lead_bow.name=Bleibogen -item.basemetals.mithril_bow.name=Mithrilbogen -item.basemetals.nickel_bow.name=Nickelbogen -item.basemetals.obsidian_bow.name=Obsidianbogen -item.basemetals.pewter_bow.name=Hartzinnbogen -item.basemetals.platinum_bow.name=Platinbogen -item.basemetals.quartz_bow.name=Quartzbogen -item.basemetals.silver_bow.name=Silberbogen -item.basemetals.starsteel_bow.name=Sternenstahlbogen -item.basemetals.steel_bow.name=Stahlbogen -item.basemetals.tin_bow.name=Zinnbogen -item.basemetals.zinc_bow.name=Zinkbogen - -#armbrust -item.basemetals.adamantine_crossbow.name=Adamantarmbrust -item.basemetals.aquarium_crossbow.name=Aquariumarmbrust -item.basemetals.antimony_crossbow.name=Antimonarmbrust -item.basemetals.bismuth_crossbow.name=Bismutharmbrust -item.basemetals.brass_crossbow.name=Messingarmbrust -item.basemetals.bronze_crossbow.name=Bronzearmbrust -item.basemetals.coldiron_crossbow.name=Kalteisenarmbrust -item.basemetals.copper_crossbow.name=Kupferarmbrust -item.basemetals.cupronickel_crossbow.name=Kupfernickelarmbrust -item.basemetals.diamond_crossbow.name=Diamantarmbrust -item.basemetals.electrum_crossbow.name=Elektronarmbrust -item.basemetals.emerald_crossbow.name=Smaragdarmbrust -item.basemetals.gold_crossbow.name=Goldarmbrust -item.basemetals.invar_crossbow.name=Invararmbrust -item.basemetals.iron_crossbow.name=Eisenarmbrust -item.basemetals.lead_crossbow.name=Bleiarmbrust -item.basemetals.mithril_crossbow.name=Mithrilarmbrust -item.basemetals.nickel_crossbow.name=Nickelarmbrust -item.basemetals.obsidian_crossbow.name=Obsidianarmbrust -item.basemetals.pewter_crossbow.name=Hartzinnarmbrust -item.basemetals.platinum_crossbow.name=Platinarmbrust -item.basemetals.quartz_crossbow.name=Quartzarmbrust -item.basemetals.silver_crossbow.name=Silberarmbrust -item.basemetals.starsteel_crossbow.name=Sternenstahlarmbrust -item.basemetals.steel_crossbow.name=Stahlarmbrust -item.basemetals.tin_crossbow.name=Zinnarmbrust -item.basemetals.zinc_crossbow.name=Zinkarmbrust - -#angels -item.basemetals.adamantine_fishing_rod.name=Adamantangel -item.basemetals.aquarium_fishing_rod.name=Aquariumangel -item.basemetals.antimony_fishing_rod.name=Antimonangel -item.basemetals.bismuth_fishing_rod.name=Bismuthangel -item.basemetals.brass_fishing_rod.name=Messingangel -item.basemetals.bronze_fishing_rod.name=Bronzeangel -item.basemetals.coldiron_fishing_rod.name=Kalteisenangel -item.basemetals.copper_fishing_rod.name=Kupferangel -item.basemetals.cupronickel_fishing_rod.name=Kupfernickelangel -item.basemetals.diamond_fishing_rod.name=Diamantangel -item.basemetals.electrum_fishing_rod.name=Elektronangel -item.basemetals.emerald_fishing_rod.name=Smaragdangel -item.basemetals.gold_fishing_rod.name=Goldangel -item.basemetals.invar_fishing_rod.name=Invarangel -item.basemetals.iron_fishing_rod.name=Eisenangel -item.basemetals.lead_fishing_rod.name=Bleiangel -item.basemetals.mithril_fishing_rod.name=Mithrilangel -item.basemetals.nickel_fishing_rod.name=Nickelangel -item.basemetals.obsidian_fishing_rod.name=Obsidianangel -item.basemetals.pewter_fishing_rod.name=Hartzinnangel -item.basemetals.platinum_fishing_rod.name=Platinangel -item.basemetals.quartz_fishing_rod.name=Quartzangel -item.basemetals.silver_fishing_rod.name=Silberangel -item.basemetals.starsteel_fishing_rod.name=Sternenstahlangel -item.basemetals.steel_fishing_rod.name=Stahlangel -item.basemetals.tin_fishing_rod.name=Zinnangel -item.basemetals.zinc_fishing_rod.name=Zinkangel - -#schilds -item.basemetals.adamantine_shield.name=Adamantschild -item.basemetals.aquarium_shield.name=Aquariumschild -item.basemetals.antimony_shield.name=Antimonschild -item.basemetals.bismuth_shield.name=Bismuthschild -item.basemetals.brass_shield.name=Messingschild -item.basemetals.bronze_shield.name=Bronzeschild -item.basemetals.coldiron_shield.name=Kalteisenschild -item.basemetals.copper_shield.name=Kupferschild -item.basemetals.cupronickel_shield.name=Kupfernickelschild -item.basemetals.diamond_shield.name=Diamantschild -item.basemetals.electrum_shield.name=Elektronschild -item.basemetals.emerald_shield.name=Smaragdschild -item.basemetals.gold_shield.name=Goldschild -item.basemetals.invar_shield.name=Invarschild -item.basemetals.iron_shield.name=Eisenschild -item.basemetals.lead_shield.name=Bleischild -item.basemetals.mithril_shield.name=Mithrilschild -item.basemetals.obsidian_shield.name=Obsidianschild -item.basemetals.nickel_shield.name=Nickelschild -item.basemetals.pewter_shield.name=Hartzinnschild -item.basemetals.platinum_shield.name=Platinschild -item.basemetals.quartz_shield.name=Quartzschild -item.basemetals.silver_shield.name=Silberschild -item.basemetals.starsteel_shield.name=Sternenstahlschild -item.basemetals.steel_shield.name=Stahlschild -item.basemetals.tin_shield.name=Zinnschild -item.basemetals.zinc_shield.name=Zinkschild - -#pfeil -item.basemetals.adamantine_arrow.name=Adamantpfeil -item.basemetals.aquarium_arrow.name=Aquariumpfeil -item.basemetals.antimony_arrow.name=Antimonpfeil -item.basemetals.bismuth_arrow.name=Bismuthpfeil -item.basemetals.brass_arrow.name=Messingpfeil -item.basemetals.bronze_arrow.name=Bronzepfeil -item.basemetals.coldiron_arrow.name=Kalteisenpfeil -item.basemetals.copper_arrow.name=Kupferpfeil -item.basemetals.cupronickel_arrow.name=Kupfernickelpfeil -item.basemetals.diamond_arrow.name=Diamantpfeil -item.basemetals.electrum_arrow.name=Elektronpfeil -item.basemetals.emerald_arrow.name=Smaragdpfeil -item.basemetals.gold_arrow.name=Goldpfeil -item.basemetals.invar_arrow.name=Invarpfeil -item.basemetals.iron_arrow.name=Eisenpfeil -item.basemetals.lead_arrow.name=Bleipfeil -item.basemetals.mithril_arrow.name=Mithrilpfeil -item.basemetals.nickel_arrow.name=Nickelpfeil -item.basemetals.obsidian_arrow.name=Obsidianpfeil -item.basemetals.pewter_arrow.name=Hartzinnpfeil -item.basemetals.platinum_arrow.name=Platinpfeil -item.basemetals.quartz_arrow.name=Quartzpfeil -item.basemetals.silver_arrow.name=Silberpfeil -item.basemetals.starsteel_arrow.name=Sternenstahlpfeil -item.basemetals.steel_arrow.name=Stahlpfeil -item.basemetals.tin_arrow.name=Zinnpfeil -item.basemetals.zinc_arrow.name=Zinkpfeil - -#bolzen -item.basemetals.adamantine_bolt.name=Adamantbolzen -item.basemetals.aquarium_bolt.name=Aquariumbolzen -item.basemetals.antimony_bolt.name=Antimonbolzen -item.basemetals.bismuth_bolt.name=Bismuthbolzen -item.basemetals.brass_bolt.name=Messingbolzen -item.basemetals.bronze_bolt.name=Bronzebolzen -item.basemetals.coldiron_bolt.name=Kalteisenbolzen -item.basemetals.copper_bolt.name=Kupferbolzen -item.basemetals.cupronickel_bolt.name=Kupfernickelbolzen -item.basemetals.diamond_bolt.name=Diamantbolzen -item.basemetals.electrum_bolt.name=Elektronbolzen -item.basemetals.emerald_bolt.name=Smaragdbolzen -item.basemetals.gold_bolt.name=Goldbolzen -item.basemetals.invar_bolt.name=Invarbolzen -item.basemetals.iron_bolt.name=Eisenbolzen -item.basemetals.lead_bolt.name=Bleibolzen -item.basemetals.mithril_bolt.name=Mithrilbolzen -item.basemetals.nickel_bolt.name=Nickelbolzen -item.basemetals.obsidian_bolt.name=Obsidianbolzen -item.basemetals.pewter_bolt.name=Hartzinnbolzen -item.basemetals.platinum_bolt.name=Platinbolzen -item.basemetals.quartz_bolt.name=Quartzbolzen -item.basemetals.silver_bolt.name=Silberbolzen -item.basemetals.starsteel_bolt.name=Sternenstahlbolzen -item.basemetals.steel_bolt.name=Stahlbolzen -item.basemetals.tin_bolt.name=Zinnbolzen -item.basemetals.zinc_bolt.name=Zinkbolzen - -#Armor Sets - #Adamant -item.basemetals.adamantine_boots.name=Adamantstiefel -item.basemetals.adamantine_chestplate.name=Adamantbrustpanzer -item.basemetals.adamantine_helmet.name=Adamanthelm -item.basemetals.adamantine_leggings.name=Adamantbeinpanzer - #Aquarium -item.basemetals.aquarium_boots.name=Aquariumstiefel -item.basemetals.aquarium_chestplate.name=Aquariumbrustpanzer -item.basemetals.aquarium_helmet.name=Aquariumhelm -item.basemetals.aquarium_leggings.name=Aquariumbeinpanzer - #Antimon -item.basemetals.antimony_boots.name=Antimonstiefel -item.basemetals.antimony_chestplate.name=Antimonbrustpanzer -item.basemetals.antimony_helmet.name=Antimonhelm -item.basemetals.antimony_leggings.name=Antimonbeinpanzer - #Bismuth -item.basemetals.bismuth_boots.name=Bismuthstiefel -item.basemetals.bismuth_chestplate.name=Bismuthbrustpanzer -item.basemetals.bismuth_helmet.name=Bismuthhelm -item.basemetals.bismuth_leggings.name=Bismuthbeinpanzer - #Messing -item.basemetals.brass_boots.name=Messingstiefel -item.basemetals.brass_chestplate.name=Messingbrustpanzer -item.basemetals.brass_helmet.name=Messinghelm -item.basemetals.brass_leggings.name=Messingbeinpanzer - #Bronze -item.basemetals.bronze_boots.name=Bronzestiefel -item.basemetals.bronze_chestplate.name=Bronzebrustpanzer -item.basemetals.bronze_helmet.name=Bronzehelm -item.basemetals.bronze_leggings.name=Bronzebeinpanzer - #Kalteisen -item.basemetals.coldiron_boots.name=Kalteisenstiefel -item.basemetals.coldiron_chestplate.name=Kalteisenbrustpanzer -item.basemetals.coldiron_helmet.name=Kalteisenhelm -item.basemetals.coldiron_leggings.name=Kalteisenbeinpanzer - #Kupfer -item.basemetals.copper_boots.name=Kupferstiefel -item.basemetals.copper_chestplate.name=Kupferbrustpanzer -item.basemetals.copper_helmet.name=Kupferhelm -item.basemetals.copper_leggings.name=Kupferbeinpanzer - #Kupfernickel -item.basemetals.cupronickel_boots.name=Kupfernickelstiefel -item.basemetals.cupronickel_chestplate.name=Kupfernickelbrustpanzer -item.basemetals.cupronickel_helmet.name=Kupfernickelhelm -item.basemetals.cupronickel_leggings.name=Kupfernickelbeinpanzer - #Elektron -item.basemetals.electrum_boots.name=Elektronstiefel -item.basemetals.electrum_chestplate.name=Elektronbrustpanzer -item.basemetals.electrum_helmet.name=Elektronhelm -item.basemetals.electrum_leggings.name=Elektronbeinpanzer - #Smaragd -item.basemetals.emerald_boots.name=Smaragdstiefel -item.basemetals.emerald_chestplate.name=Smaragdbrustpanzer -item.basemetals.emerald_helmet.name=Smaragdhelm -item.basemetals.emerald_leggings.name=Smaragdbeinpanzer - #Invar -item.basemetals.invar_boots.name=Invarstiefel -item.basemetals.invar_chestplate.name=Invarbrustpanzer -item.basemetals.invar_helmet.name=Invarhelm -item.basemetals.invar_leggings.name=Invarbeinpanzer - #Blei -item.basemetals.lead_boots.name=Bleistiefel -item.basemetals.lead_chestplate.name=Bleibrustpanzer -item.basemetals.lead_helmet.name=Bleihelm -item.basemetals.lead_leggings.name=Bleibeinpanzer - #Mithril -item.basemetals.mithril_boots.name=Mithrilstiefel -item.basemetals.mithril_chestplate.name=Mithrilbrustpanzer -item.basemetals.mithril_helmet.name=Mithrilhelm -item.basemetals.mithril_leggings.name=Mithrilbeinpanzer - #Nickel -item.basemetals.nickel_boots.name=Nickelstiefel -item.basemetals.nickel_chestplate.name=Nickelbrustpanzer -item.basemetals.nickel_helmet.name=Nickelhelm -item.basemetals.nickel_leggings.name=Nickelbeinpanzer - #Obsidian -item.basemetals.obsidian_boots.name=Obsidianstiefel -item.basemetals.obsidian_chestplate.name=Obsidianbrustpanzer -item.basemetals.obsidian_helmet.name=Obsidianhelm -item.basemetals.obsidian_leggings.name=Obsidianbeinpanzer - #Hartzinn -item.basemetals.pewter_boots.name=Hartzinnstiefel -item.basemetals.pewter_chestplate.name=Hartzinnbrustpanzer -item.basemetals.pewter_helmet.name=Hartzinnhelm -item.basemetals.pewter_leggings.name=Hartzinnbeinpanzer - #Platin -item.basemetals.platinum_boots.name=Platinstiefel -item.basemetals.platinum_chestplate.name=Platinbrustpanzer -item.basemetals.platinum_helmet.name=Platinhelm -item.basemetals.platinum_leggings.name=Platinbeinpanzer - #Quartz -item.basemetals.quartz_boots.name=Quartzstiefel -item.basemetals.quartz_chestplate.name=Quartzbrustpanzer -item.basemetals.quartz_helmet.name=Quartzhelm -item.basemetals.quartz_leggings.name=Quartzbeinpanzer - #Silber -item.basemetals.silver_boots.name=Silberstiefel -item.basemetals.silver_chestplate.name=Silberbrustpanzer -item.basemetals.silver_helmet.name=Silberhelm -item.basemetals.silver_leggings.name=Silberbeinpanzer - #Sternenstahl -item.basemetals.starsteel_boots.name=Sternenstahlstiefel -item.basemetals.starsteel_chestplate.name=Sternenstahlbrustpanzer -item.basemetals.starsteel_helmet.name=Sternenstahlhelm -item.basemetals.starsteel_leggings.name=Sternenstahlbeinpanzer - #Stahl -item.basemetals.steel_boots.name=Stahlstiefel -item.basemetals.steel_chestplate.name=Stahlbrustpanzer -item.basemetals.steel_helmet.name=Stahlhelm -item.basemetals.steel_leggings.name=Stahlbeinpanzer - #Zinn -item.basemetals.tin_boots.name=Zinnstiefel -item.basemetals.tin_chestplate.name=Zinnbrustpanzer -item.basemetals.tin_helmet.name=Zinnhelm -item.basemetals.tin_leggings.name=Zinnbeinpanzer - #Zink -item.basemetals.zinc_boots.name=Zinkstiefel -item.basemetals.zinc_chestplate.name=Zinkbrustpanzer -item.basemetals.zinc_helmet.name=Zinkhelm -item.basemetals.zinc_leggings.name=Zinkbeinpanzer - -#pferderüstung -item.basemetals.adamantine_horsearmor.name=Adamantpferderüstung -item.basemetals.aquarium_horsearmor.name=Aquariumpferderüstung -item.basemetals.antimony_horsearmor.name=Antimonpferderüstung -item.basemetals.bismuth_horsearmor.name=Bismuthpferderüstung -item.basemetals.brass_horsearmor.name=Messingpferderüstung -item.basemetals.bronze_horsearmor.name=Bronzepferderüstung -item.basemetals.coldiron_horsearmor.name=Kalteisenpferderüstung -item.basemetals.copper_horsearmor.name=Kupferpferderüstung -item.basemetals.cupronickel_horsearmor.name=Kupfernickelpferderüstung -item.basemetals.electrum_horsearmor.name=Elektronpferderüstung -item.basemetals.emerald_horsearmor.name=Smaragdpferderüstung -item.basemetals.invar_horsearmor.name=Invarpferderüstung -item.basemetals.lead_horsearmor.name=Bleipferderüstung -item.basemetals.mercury_horsearmor.name=Quecksilberpferderüstung -item.basemetals.mithril_horsearmor.name=Mithrilpferderüstung -item.basemetals.nickel_horsearmor.name=Nickelpferderüstung -item.basemetals.obsidian_horsearmor.name=Obsidianpferderüstung -item.basemetals.pewter_horsearmor.name=Hartzinnpferderüstung -item.basemetals.platinum_horsearmor.name=Platinpferderüstung -item.basemetals.quartz_horsearmor.name=Quartzpferderüstung -item.basemetals.silver_horsearmor.name=Silberpferderüstung -item.basemetals.starsteel_horsearmor.name=Sternenstahlpferderüstung -item.basemetals.steel_horsearmor.name=Stahlpferderüstung -item.basemetals.tin_horsearmor.name=Zinnpferderüstung -item.basemetals.zinc_horsearmor.name=Zinkpferderüstung - -#barren -item.basemetals.adamantine_ingot.name=Adamantbarren -item.basemetals.aquarium_ingot.name=Aquariumbarren -item.basemetals.antimony_ingot.name=Antimonbarren -item.basemetals.bismuth_ingot.name=Bismuthbarren -item.basemetals.brass_ingot.name=Messingbarren -item.basemetals.bronze_ingot.name=Bronzebarren -item.basemetals.coldiron_ingot.name=Kalteisenbarren -item.basemetals.copper_ingot.name=Kupferbarren -item.basemetals.cupronickel_ingot.name=Kupfernickelbarren -item.basemetals.electrum_ingot.name=Elektronbarren -item.basemetals.invar_ingot.name=Invarbarren -item.basemetals.lead_ingot.name=Bleibarren -item.basemetals.mercury_ingot.name=Flüssiges Quecksilber -item.basemetals.mithril_ingot.name=Mithrilbarren -item.basemetals.nickel_ingot.name=Nickelbarren -item.basemetals.obsidian_ingot.name=Obsidianbarren -item.basemetals.pewter_ingot.name=Hartzinnbarren -item.basemetals.platinum_ingot.name=Platinbarren -item.basemetals.redstone_ingot.name=Redstonebarren -item.basemetals.silver_ingot.name=Silberbarren -item.basemetals.starsteel_ingot.name=Sternenstahlbarren -item.basemetals.steel_ingot.name=Stahlbarren -item.basemetals.tin_ingot.name=Zinnbarren -item.basemetals.zinc_ingot.name=Zinkbarren - -#gitter - #Item -item.basemetals.adamantine_bars.name=Adamantgitter -item.basemetals.aquarium_bars.name=Aquariumgitter -item.basemetals.antimony_bars.name=Antimongitter -item.basemetals.bismuth_bars.name=Bismuthgitter -item.basemetals.brass_bars.name=Messinggitter -item.basemetals.bronze_bars.name=Bronzegitter -item.basemetals.coldiron_bars.name=Kalteisengitter -item.basemetals.copper_bars.name=Kupfergitter -item.basemetals.cupronickel_bars.name=Kupfernickelgitter -item.basemetals.diamond_bars.name=Diamantgitter -item.basemetals.electrum_bars.name=Elektrongitter -item.basemetals.emerald_bars.name=Smaragdgitter -item.basemetals.gold_bars.name=Goldgitter -item.basemetals.invar_bars.name=Invargitter -item.basemetals.lead_bars.name=Bleigitter -item.basemetals.mithril_bars.name=Mithrilgitter -item.basemetals.nickel_bars.name=Nickelgitter -item.basemetals.obsidian_bars.name=Obsidiangitter -item.basemetals.pewter_bars.name=Hartzinngitter -item.basemetals.platinum_bars.name=Platingitter -item.basemetals.quartz_bars.name=Quartzgitter -item.basemetals.silver_bars.name=Silbergitter -item.basemetals.starsteel_bars.name=Sternenstahlgitter -item.basemetals.steel_bars.name=Stahlgitter -item.basemetals.tin_bars.name=Zinngitter -item.basemetals.zinc_bars.name=Zinkgitter - #Tile -tile.basemetals.adamantine_bars.name=Adamantgitter -tile.basemetals.aquarium_bars.name=Aquariumgitter -tile.basemetals.antimony_bars.name=Antimongitter -tile.basemetals.bismuth_bars.name=Bismuthgitter -tile.basemetals.brass_bars.name=Messinggitter -tile.basemetals.bronze_bars.name=Bronzegitter -tile.basemetals.coldiron_bars.name=Kalteisengitter -tile.basemetals.copper_bars.name=Kupfergitter -tile.basemetals.cupronickel_bars.name=Kupfernickelgitter -tile.basemetals.diamond_bars.name=Diamantgitter -tile.basemetals.electrum_bars.name=Elektrongitter -tile.basemetals.emerald_bars.name=Smaragdgitter -tile.basemetals.gold_bars.name=Goldgitter -tile.basemetals.invar_bars.name=Invargitter -tile.basemetals.lead_bars.name=Bleigitter -tile.basemetals.mithril_bars.name=Mithrilgitter -tile.basemetals.nickel_bars.name=Nickelgitter -tile.basemetals.obsidian_bars.name=Obsidiangitter -tile.basemetals.pewter_bars.name=Hartzinngitter -tile.basemetals.platinum_bars.name=Platingitter -tile.basemetals.quartz_bars.name=Quartzgitter -tile.basemetals.silver_bars.name=Silbergitter -tile.basemetals.starsteel_bars.name=Sternenstahlgitter -tile.basemetals.steel_bars.name=Stahlgitter -tile.basemetals.tin_bars.name=Zinngitter -tile.basemetals.zinc_bars.name=Zinkgitter - -#nugget -item.basemetals.adamantine_nugget.name=Adamantnugget -item.basemetals.aquarium_nugget.name=Aquariumnugget -item.basemetals.antimony_nugget.name=Antimonnugget -item.basemetals.bismuth_nugget.name=Bismuthnugget -item.basemetals.brass_nugget.name=Messingnugget -item.basemetals.bronze_nugget.name=Bronzenugget -item.basemetals.charcoal_nugget.name=Charcoalnugget -item.basemetals.coal_nugget.name=Coalnugget -item.basemetals.coldiron_nugget.name=Kalteisennugget -item.basemetals.copper_nugget.name=Kupfernugget -item.basemetals.cupronickel_nugget.name=Kupfernickelnugget -item.basemetals.diamond_nugget.name=Diamant Fragment -item.basemetals.electrum_nugget.name=Elektronnugget -item.basemetals.emerald_nugget.name=Smaragd Fragment -item.basemetals.invar_nugget.name=Invarnugget -item.basemetals.iron_nugget.name=Eisennugget -item.basemetals.lead_nugget.name=Bleinugget -item.basemetals.mercury_nugget.name=Kleiner Tropfen flüssiges Quecksilber -item.basemetals.mithril_nugget.name=Mithrilnugget -item.basemetals.nickel_nugget.name=Nickelnugget -item.basemetals.obsidian_nugget.name=Obsidian Fragment -item.basemetals.pewter_nugget.name=Hartzinnnugget -item.basemetals.platinum_nugget.name=Platinnugget -item.basemetals.quartz_nugget.name=Quartz Fragment -item.basemetals.silver_nugget.name=Silbernugget -item.basemetals.starsteel_nugget.name=Sternenstahlnugget -item.basemetals.steel_nugget.name=Stahlnugget -item.basemetals.tin_nugget.name=Zinnnugget -item.basemetals.zinc_nugget.name=Zinknugget - -#Powdered -item.basemetals.adamantine_powder.name=Adamantpulver -item.basemetals.aquarium_powder.name=Aquariumpulver -item.basemetals.antimony_powder.name=Antimonpulver -item.basemetals.bismuth_powder.name=Bismuthpulver -item.basemetals.brass_powder.name=Messingpulver -item.basemetals.bronze_powder.name=Bronzepulver -item.basemetals.carbon_powder.name=Kohlenstoffpulver -item.basemetals.coal_powder.name=Kohlepulver -item.basemetals.charcoal_powder.name=Holzkohlepulver -item.basemetals.coldiron_powder.name=Kalteisenpulver -item.basemetals.copper_powder.name=Kupferpulver -item.basemetals.cupronickel_powder.name=Kupfernickelpulver -item.basemetals.diamond_powder.name=Diamantpulver -item.basemetals.electrum_powder.name=Elektronpulver -item.basemetals.emerald_powder.name=Smaragdpulver -item.basemetals.gold_powder.name=Goldpulver -item.basemetals.invar_powder.name=Invarpulver -item.basemetals.iron_powder.name=Eisenpulver -item.basemetals.lead_powder.name=Bleipulver -item.basemetals.mercury_powder.name=Quecksilberpulver -item.basemetals.mithril_powder.name=Mithrilpulver -item.basemetals.nickel_powder.name=Nickelpulver -item.basemetals.obsidian_powder.name=Obsidianpulver -item.basemetals.pewter_powder.name=Hartzinnpulver -item.basemetals.platinum_powder.name=Platinpulver -item.basemetals.quartz_powder.name=Quartzpulver -item.basemetals.silver_powder.name=Silberpulver -item.basemetals.starsteel_powder.name=Sternenstahlpulver -item.basemetals.steel_powder.name=Stahlpulver -item.basemetals.tin_powder.name=Zinnpulver -item.basemetals.wood_powder.name=Sägemehl -item.basemetals.zinc_powder.name=Zinkpulver - -#Small Powders -item.basemetals.adamantine_smallpowder.name=Kleiner Adamantpulverhaufen -item.basemetals.aquarium_smallpowder.name=Kleiner Aquariumpulverhaufen -item.basemetals.antimony_smallpowder.name=Kleiner Antimonpulverhaufen -item.basemetals.bismuth_smallpowder.name=Kleiner Bismuthpulverhaufen -item.basemetals.brass_smallpowder.name=Kleiner Messingpulverhaufen -item.basemetals.bronze_smallpowder.name=Kleiner Bronzepulverhaufen -item.basemetals.carbon_smallpowder.name=Kleiner Kohlenstoffpulverhaufen -item.basemetals.coal_smallpowder.name=Kleiner Kohlepulverhaufen -item.basemetals.charcoal_smallpowder.name=Kleiner Holzkohlepulverhaufen -item.basemetals.coldiron_smallpowder.name=Kleiner Kalteisenpulverhaufen -item.basemetals.copper_smallpowder.name=Kleiner Kupferpulverhaufen -item.basemetals.cupronickel_smallpowder.name=Kleiner Kupfernickelpulverhaufen -item.basemetals.diamond_smallpowder.name=Kleiner Diamantpulverhaufen -item.basemetals.electrum_smallpowder.name=Kleiner Elektronpulverhaufen -item.basemetals.emerald_smallpowder.name=Kleiner Smaragdpulverhaufen -item.basemetals.gold_smallpowder.name=Kleiner Goldpulverhaufen -item.basemetals.invar_smallpowder.name=Kleiner Invarpulverhaufen -item.basemetals.iron_smallpowder.name=Kleiner Eisenpulverhaufen -item.basemetals.lapis_smallpowder.name=Kleiner Lapispulverhaufen -item.basemetals.lead_smallpowder.name=Kleiner Bleipulverhaufen -item.basemetals.mercury_smallpowder.name=Kleiner Quecksilberpulverhaufen -item.basemetals.mithril_smallpowder.name=Kleiner Mithrilpulverhaufen -item.basemetals.nickel_smallpowder.name=Kleiner Nickelpulverhaufen -item.basemetals.obsidian_smallpowder.name=Kleiner Obsidianpulverhaufen -item.basemetals.pewter_smallpowder.name=Kleiner Hartzinnpulverhaufen -item.basemetals.platinum_smallpowder.name=Kleiner Platinpulverhaufen -item.basemetals.quartz_smallpowder.name=Kleiner Quartzpulverhaufen -item.basemetals.redstone_smallpowder.name=Kleiner Redstonepulverhaufen -item.basemetals.silver_smallpowder.name=Kleiner Silberpulverhaufen -item.basemetals.starsteel_smallpowder.name=Kleiner Sternenstahlpulverhaufen -item.basemetals.steel_smallpowder.name=Kleiner Stahlpulverhaufen -item.basemetals.tin_smallpowder.name=Kleiner Zinnpulverhaufen -item.basemetals.wood_powder.name=Kleiner Sägemehlhaufen -item.basemetals.zinc_smallpowder.name=Kleiner Zinkpulverhaufen - -#Zerkleinertes -item.basemetals.adamantine_crushed.name=Zerkleinertes Adamant -item.basemetals.aquarium_crushed.name=Zerkleinertes Aquarium -item.basemetals.antimony_crushed.name=Zerkleinertes Antimon -item.basemetals.bismuth_crushed.name=Zerkleinertes Bismuth -item.basemetals.brass_crushed.name=Zerkleinertes Messing -item.basemetals.bronze_crushed.name=Zerkleinerte Bronze -item.basemetals.coldiron_crushed.name=Zerkleinertes Kalteisen -item.basemetals.copper_crushed.name=Zerkleinertes Kupfer -item.basemetals.cupronickel_crushed.name=Zerkleinertes Kupfernickel -item.basemetals.electrum_crushed.name=Zerkleinertes Elektron -item.basemetals.gold_crushed.name=Zerkleinertes Gold -item.basemetals.invar_crushed.name=Zerkleinertes Invar -item.basemetals.iron_crushed.name=Zerkleinertes Eisen -item.basemetals.lead_crushed.name=Zerkleinertes Blei -item.basemetals.mithril_crushed.name=Zerkleinertes Mithril -item.basemetals.nickel_crushed.name=Zerkleinertes Nickel -item.basemetals.pewter_crushed.name=Zerkleinertes Hartzinn -item.basemetals.platinum_crushed.name=Zerkleinertes Platin -item.basemetals.silver_crushed.name=Zerkleinertes Silber -item.basemetals.starsteel_crushed.name=Zerkleinerter Sternenstahl -item.basemetals.steel_crushed.name=Zerkleinerter Stahl -item.basemetals.tin_crushed.name=Zerkleinertes Zinn -item.basemetals.zinc_crushed.name=Zerkleinertes Zink - -#Zerkleinertes Purified -item.basemetals.adamantine_crushed_purified.name=Gereinigtes, zerkleinertes Adamant -item.basemetals.aquarium_crushed_purified.name=Gereinigtes, zerkleinertes Aquarium -item.basemetals.antimony_crushed_purified.name=Gereinigtes, zerkleinertes Antimon -item.basemetals.bismuth_crushed_purified.name=Gereinigtes, zerkleinertes Bismuth -item.basemetals.brass_crushed_purified.name=Gereinigtes, zerkleinertes Messing -item.basemetals.bronze_crushed_purified.name=Gereinigte, zerkleinerte Bronze -item.basemetals.coldiron_crushed_purified.name=Gereinigtes, zerkleinertes Kalteisen -item.basemetals.copper_crushed_purified.name=Gereinigtes, zerkleinertes Kupfer -item.basemetals.cupronickel_crushed_purified.name=Gereinigtes, zerkleinertes Kupfernickel -item.basemetals.electrum_crushed_purified.name=Gereinigtes, zerkleinertes Elektron -item.basemetals.gold_crushed_purified.name=Gereinigtes, zerkleinertes Gold -item.basemetals.invar_crushed_purified.name=Gereinigtes, zerkleinertes Invar -item.basemetals.iron_crushed_purified.name=Gereinigtes, zerkleinertes Eisen -item.basemetals.lead_crushed_purified.name=Gereinigtes, zerkleinertes Blei -item.basemetals.mithril_crushed_purified.name=Gereinigtes, zerkleinertes Mithril -item.basemetals.nickel_crushed_purified.name=Gereinigtes, zerkleinertes Nickel -item.basemetals.pewter_crushed_purified.name=Gereinigtes, zerkleinertes Hartzinn -item.basemetals.platinum_crushed_purified.name=Gereinigtes, zerkleinertes Platin -item.basemetals.silver_crushed_purified.name=Gereinigtes, zerkleinertes Silber -item.basemetals.starsteel_crushed_purified.name=Gereinigter, zerkleinerter Sternenstahl -item.basemetals.steel_crushed_purified.name=Gereinigter, zerkleinerter Stahl -item.basemetals.tin_crushed_purified.name=Gereinigtes, zerkleinertes Zinn -item.basemetals.zinc_crushed_purified.name=Gereinigtes, zerkleinertes Zink - -#erzs - #Item -item.basemetals.adamantine_ore.name=Adamanterz -item.basemetals.aquarium_ore.name=Aquariumerz -item.basemetals.antimony_ore.name=Antimonerz -item.basemetals.bismuth_ore.name=Bismutherz -item.basemetals.coldiron_ore.name=Kalteisenerz -item.basemetals.copper_ore.name=Kupfererz -item.basemetals.lead_ore.name=Bleierz -item.basemetals.mercury_ore.name=Quecksilbererz -item.basemetals.nickel_ore.name=Nickelerz -item.basemetals.pewter_ore.name=Hartzinnerz -item.basemetals.platinum_ore.name=Platinerz -item.basemetals.silver_ore.name=Silbererz -item.basemetals.starsteel_ore.name=Sternenstahlerz -item.basemetals.tin_ore.name=Zinnerz -item.basemetals.zinc_ore.name=Zinkerz - #Tile -tile.basemetals.adamantine_ore.name=Adamanterz -tile.basemetals.aquarium_ore.name=Aquariumerz -tile.basemetals.antimony_ore.name=Antimonerz -tile.basemetals.bismuth_ore.name=Bismutherz -tile.basemetals.coldiron_ore.name=Kalteisenerz -tile.basemetals.copper_ore.name=Kupfererz -tile.basemetals.lead_ore.name=Bleierz -tile.basemetals.mercury_ore.name=Quecksilbererz -tile.basemetals.nickel_ore.name=Nickelerz -tile.basemetals.pewter_ore.name=Hartzinnerz -tile.basemetals.platinum_ore.name=Platinerz -tile.basemetals.silver_ore.name=Silbererz -tile.basemetals.starsteel_ore.name=Sternenstahlerz -tile.basemetals.tin_ore.name=Zinnerz -tile.basemetals.zinc_ore.name=Zinkerz - -#gemischs -item.basemetals.aquarium_blend.name=Aquariumgemisch -item.basemetals.brass_blend.name=Messinggemisch -item.basemetals.bronze_blend.name=Bronzegemisch -item.basemetals.cupronickel_blend.name=Kupfernickelgemisch -item.basemetals.electrum_blend.name=Elektrongemisch -item.basemetals.invar_blend.name=Invargemisch -item.basemetals.mithril_blend.name=Mithrilgemisch -item.basemetals.pewter_blend.name=Hartzinngemisch -item.basemetals.steel_blend.name=Stahlgemisch - -#Smallgemischs -item.basemetals.aquarium_smallblend.name=Kleiner Aquariumgemischhaufen -item.basemetals.brass_smallblend.name=Kleiner Messinggemischhaufen -item.basemetals.bronze_smallblend.name=Kleiner Bronzegemischhaufen -item.basemetals.cupronickel_smallblend.name=Kleiner Kupfernickelgemischhaufen -item.basemetals.electrum_smallblend.name=Kleiner Elektrongemischhaufen -item.basemetals.invar_smallblend.name=Kleiner Invargemischhaufen -item.basemetals.mithril_smallblend.name=Kleiner Mithrilgemischhaufen -item.basemetals.pewter_smallblend.name=Kleiner Hartzinngemischhaufen -item.basemetals.steel_smallblend.name=Kleiner Stahlgemischhaufen - -#Block Of... - #Item -item.basemetals.adamantine_block.name=Adamantblock -item.basemetals.aquarium_block.name=Aquariumblock -item.basemetals.antimony_block.name=Antimonblock -item.basemetals.bismuth_block.name=Bismuthblock -item.basemetals.brass_block.name=Messingblock -item.basemetals.bronze_block.name=Bronzeblock -item.basemetals.charcoal_block.name=Charcoalblock -item.basemetals.coldiron_block.name=Kalteisenblock -item.basemetals.copper_block.name=Kupferblock -item.basemetals.platinum_block.name=Platinblock -item.basemetals.nickel_block.name=Nickelblock -item.basemetals.electrum_block.name=Elektronblock -item.basemetals.invar_block.name=Invarblock -item.basemetals.lead_block.name=Bleiblock -item.basemetals.mithril_block.name=Mithrilblock -item.basemetals.nickel_block.name=Nickelblock -item.basemetals.pewter_block.name=Hartzinnblock -item.basemetals.cupronickel_block.name=Kupfernickelblock -item.basemetals.silver_block.name=Silberblock -item.basemetals.starsteel_block.name=Sternenstahlblock -item.basemetals.steel_block.name=Stahlblock -item.basemetals.tin_block.name=Zinnblock -item.basemetals.zinc_block.name=Zinkblock - #Tile -tile.basemetals.adamantine_block.name=Adamantblock -tile.basemetals.aquarium_block.name=Aquariumblock -tile.basemetals.antimony_block.name=Antimonblock -tile.basemetals.bismuth_block.name=Bismuthblock -tile.basemetals.brass_block.name=Messingblock -tile.basemetals.bronze_block.name=Bronzeblock -tile.basemetals.charcoal_block.name=Charcoalblock -tile.basemetals.coldiron_block.name=Kalteisenblock -tile.basemetals.copper_block.name=Kupferblock -tile.basemetals.cupronickel_block.name=Kupfernickelblock -tile.basemetals.electrum_block.name=Elektronblock -tile.basemetals.invar_block.name=Invarblock -tile.basemetals.lead_block.name=Bleiblock -tile.basemetals.mithril_block.name=Mithrilblock -tile.basemetals.nickel_block.name=Nickelblock -tile.basemetals.pewter_block.name=Hartzinnblock -tile.basemetals.platinum_block.name=Platinblock -tile.basemetals.silver_block.name=Silberblock -tile.basemetals.starsteel_block.name=Sternenstahlblock -tile.basemetals.steel_block.name=Stahlblock -tile.basemetals.tin_block.name=Zinnblock -tile.basemetals.zinc_block.name=Zinkblock - -#Fluids - #Fluid -fluid.basemetals.mercury=Flüssiges Quecksilber -fluid.basemetals.adamantine=Geschmolzenes Adamant -fluid.basemetals.antimony=Geschmolzenes Antimon -fluid.basemetals.aquarium=Geschmolzenes Aquarium -fluid.basemetals.bismuth=Geschmolzenes Bismuth -fluid.basemetals.brass=Geschmolzenes Messing -fluid.basemetals.bronze=Geschmolzenes Bronze -fluid.basemetals.coldiron=Geschmolzenes Kalteisen -fluid.basemetals.copper=Geschmolzenes Kupfer -fluid.basemetals.cupronickel=Geschmolzenes Kupfernickel -fluid.basemetals.electrum=Geschmolzenes Elektron -fluid.basemetals.ender=Geschmolzenes Ender -fluid.basemetals.invar=Geschmolzenes Invar -fluid.basemetals.lead=Geschmolzenes Blei -fluid.basemetals.mithril=Geschmolzenes Mithril -fluid.basemetals.nickel=Geschmolzenes Nickel -fluid.basemetals.pewter=Geschmolzenes Hartzinn -fluid.basemetals.platinum=Geschmolzenes Platin -fluid.basemetals.silver=Geschmolzenes Silber -fluid.basemetals.starsteel=Geschmolzenes Sternenstahl -fluid.basemetals.steel=Geschmolzenes Stahl -fluid.basemetals.tin=Geschmolzenes Zinn -fluid.basemetals.zinc=Geschmolzenes Zink - #Fluid.name -fluid.basemetals.mercury.name=Flüssiges Quecksilber -fluid.basemetals.adamantine.name=Geschmolzenes Adamant -fluid.basemetals.antimony.name=Geschmolzenes Antimon -fluid.basemetals.aquarium.name=Geschmolzenes Aquarium -fluid.basemetals.bismuth.name=Geschmolzenes Bismuth -fluid.basemetals.brass.name=Geschmolzenes Messing -fluid.basemetals.bronze.name=Geschmolzenes Bronze -fluid.basemetals.charcoal.name=Liquifacted Charcoal -fluid.basemetals.coal.name=Liquifacted Coal -fluid.basemetals.coldiron.name=Geschmolzenes Kalteisen -fluid.basemetals.copper.name=Geschmolzenes Kupfer -fluid.basemetals.cupronickel.name=Geschmolzenes Kupfernickel -fluid.basemetals.diamond.name=Geschmolzenes Diamant -fluid.basemetals.electrum.name=Geschmolzenes Elektron -fluid.basemetals.electrum.name=Geschmolzenes Smaragd -fluid.basemetals.invar.name=Geschmolzenes Invar -fluid.basemetals.lead.name=Geschmolzenes Blei -fluid.basemetals.mithril.name=Geschmolzenes Mithril -fluid.basemetals.nickel.name=Geschmolzenes Nickel -fluid.basemetals.pewter.name=Geschmolzenes Hartzinn -fluid.basemetals.platinum.name=Geschmolzenes Platin -fluid.basemetals.prismarine.name=Geschmolzenes Prismarin -fluid.basemetals.redstone.name=Geschmolzenes Redstone -fluid.basemetals.silver.name=Geschmolzenes Silber -fluid.basemetals.starsteel.name=Geschmolzenes Sternenstahl -fluid.basemetals.steel.name=Geschmolzenes Stahl -fluid.basemetals.tin.name=Geschmolzenes Zinn -fluid.basemetals.zinc.name=Geschmolzenes Zink - #Tile -tile.basemetals.mercury.name=Flüssiges Quecksilber -tile.basemetals.adamantine.name=Geschmolzenes Adamant -tile.basemetals.antimony.name=Geschmolzenes Antimon -tile.basemetals.aquarium.name=Geschmolzenes Aquarium -tile.basemetals.bismuth.name=Geschmolzenes Bismuth -tile.basemetals.brass.name=Geschmolzenes Messing -tile.basemetals.bronze.name=Geschmolzenes Bronze -tile.basemetals.charcoal.name=Liquifacted Charcoal -tile.basemetals.coal.name=Liquifacted Coal -tile.basemetals.coldiron.name=Geschmolzenes Kalteisen -tile.basemetals.copper.name=Geschmolzenes Kupfer -tile.basemetals.cupronickel.name=Geschmolzenes Kupfernickel -tile.basemetals.diamond.name=Geschmolzenes Diamant -tile.basemetals.electrum.name=Geschmolzenes Elektron -tile.basemetals.emerald.name=Geschmolzenes Smaragd -tile.basemetals.ender.name=Geschmolzenes Ender -tile.basemetals.gold.name=Geschmolzenes Gold -tile.basemetals.invar.name=Geschmolzenes Invar -tile.basemetals.iron.name=Geschmolzenes Eisen -tile.basemetals.lead.name=Geschmolzenes Blei -tile.basemetals.mithril.name=Geschmolzenes Mithril -tile.basemetals.nickel.name=Geschmolzenes Nickel -tile.basemetals.obsidian.name=Geschmolzenes Obsidian -tile.basemetals.pewter.name=Geschmolzenes Hartzinn -tile.basemetals.platinum.name=Geschmolzenes Platin -tile.basemetals.prismarine.name=Geschmolzenes Prismarin -tile.basemetals.redstone.name=Geschmolzenes Redstone -tile.basemetals.silver.name=Geschmolzenes Silber -tile.basemetals.starsteel.name=Geschmolzenes Sternenstahl -tile.basemetals.steel.name=Geschmolzenes Stahl -tile.basemetals.tin.name=Geschmolzenes Zinn -tile.basemetals.zinc.name=Geschmolzenes Zink - #Bucket -item.bucket.mercury=Eimer mit Quecksilber -item.bucket.adamantine=Eimer mit geschmolzenem Adamant -item.bucket.antimony=Eimer mit geschmolzenem Antimon -item.bucket.aquarium=Eimer mit geschmolzenem Aquarium -item.bucket.bismuth=Eimer mit geschmolzenem Bismuth -item.bucket.brass=Eimer mit geschmolzenem Messing -item.bucket.bronze=Eimer mit geschmolzenem Bronze -item.bucket.charcoal=Eimer mit verflüssigter Holzkohle -item.bucket.coal=Eimer mit verflüssigter Kohle -item.bucket.coldiron=Eimer mit geschmolzenem Kalteisen -item.bucket.copper=Eimer mit geschmolzenem Kupfer -item.bucket.cupronickel=Eimer mit geschmolzenem Kupfernickel -item.bucket.diamond=Eimer mit geschmolzenem Diamant -item.bucket.electrum=Eimer mit geschmolzenem Elektron -item.bucket.emerald=Eimer mit geschmolzenem Smaragd -item.bucket.ender=Eimer mit geschmolzenem Ender -item.bucket.invar=Eimer mit geschmolzenem Invar -item.bucket.lead=Eimer mit geschmolzenem Blei -item.bucket.mithril=Eimer mit geschmolzenem Mithril -item.bucket.nickel=Eimer mit geschmolzenem Nickel -item.bucket.pewter=Eimer mit geschmolzenem Hartzinn -item.bucket.platinum=Eimer mit geschmolzenem Platin -item.bucket.prismarine=Eimer mit geschmolzenem Prismarin -item.bucket.redstone=Eimer mit geschmolzenem Redstone -item.bucket.silver=Eimer mit geschmolzenem Silber -item.bucket.starsteel=Eimer mit geschmolzenem Sternenstahl -item.bucket.steel=Eimer mit geschmolzenem Stahl -item.bucket.tin=Eimer mit geschmolzenem Zinn -item.bucket.zinc=Eimer mit geschmolzenem Zink - Material -material.mercury.name=Quecksilber -material.adamantine.name=Adamant -material.antimony.name=Antimon -material.aquarium.name=Aquarium -material.bismuth.name=Bismuth -material.brass.name=Messing -material.bronze.name=Bronze -material.coldiron.name=Kalteisen -material.copper.name=Kupfer -material.cupronickel.name=Kupfernickel -material.electrum.name=Elektron -material.invar.name=Invar -material.lead.name=Blei -material.mithril.name=Mithril -material.nickel.name=Nickel -material.pewter.name=Hartzinn -material.platinum.name=Platin -material.silver.name=Silber -material.starsteel.name=Sternenstahl -material.steel.name=Stahl -material.tin.name=Zinn -material.zinc.name=Zink - -#türs - #Item -item.basemetals.adamantine_door.name=Adamanttür -item.basemetals.aquarium_door.name=Aquariumtür -item.basemetals.antimony_door.name=Antimontür -item.basemetals.bismuth_door.name=Bismuthtür -item.basemetals.brass_door.name=Messingtür -item.basemetals.bronze_door.name=Bronzetür -item.basemetals.coldiron_door.name=Kalteisentür -item.basemetals.copper_door.name=Kupfertür -item.basemetals.cupronickel_door.name=Kupfernickeltür -item.basemetals.diamond_door.name=Diamanttür -item.basemetals.electrum_door.name=Elektrontür -item.basemetals.emerald_door.name=Smaragdtür -item.basemetals.gold_door.name=Goldtür -item.basemetals.invar_door.name=Invartür -item.basemetals.lead_door.name=Bleitür -item.basemetals.mithril_door.name=Mithriltür -item.basemetals.nickel_door.name=Nickeltür -item.basemetals.obsidian_door.name=Obsidiantür -item.basemetals.pewter_door.name=Hartzinntür -item.basemetals.platinum_door.name=Platintür -item.basemetals.quartz_door.name=Quartztür -item.basemetals.silver_door.name=Silbertür -item.basemetals.starsteel_door.name=Sternenstahltür -item.basemetals.steel_door.name=Stahltür -item.basemetals.tin_door.name=Zinntür -item.basemetals.zinc_door.name=Zinktür - #Tile -tile.basemetals.adamantine_door.name=Adamanttür -tile.basemetals.aquarium_door.name=Aquariumtür -tile.basemetals.antimony_door.name=Antimontür -tile.basemetals.bismuth_door.name=Bismuthtür -tile.basemetals.brass_door.name=Messingtür -tile.basemetals.bronze_door.name=Bronzetür -tile.basemetals.coldiron_door.name=Kalteisentür -tile.basemetals.copper_door.name=Kupfertür -tile.basemetals.cupronickel_door.name=Kupfernickeltür -tile.basemetals.diamond_door.name=Diamanttür -tile.basemetals.electrum_door.name=Elektrontür -tile.basemetals.emerald_door.name=Smaragdtür -tile.basemetals.gold_door.name=Goldtür -tile.basemetals.invar_door.name=Invartür -tile.basemetals.lead_door.name=Bleitür -tile.basemetals.mithril_door.name=Mithriltür -tile.basemetals.nickel_door.name=Nickeltür -tile.basemetals.obsidian_door.name=Obsidiantür -tile.basemetals.pewter_door.name=Hartzinntür -tile.basemetals.platinum_door.name=Platintür -tile.basemetals.quartz_door.name=Quartztür -tile.basemetals.silver_door.name=Silbertür -tile.basemetals.starsteel_door.name=Sternenstahltür -tile.basemetals.steel_door.name=Stahltür -tile.basemetals.tin_door.name=Zinntür -tile.basemetals.zinc_door.name=Zinktür - -#falltürs - #Tiles -tile.basemetals.adamantine_trapdoor.name=Adamantfalltür -tile.basemetals.aquarium_trapdoor.name=Aquariumfalltür -tile.basemetals.antimony_trapdoor.name=Antimonfalltür -tile.basemetals.bismuth_trapdoor.name=Bismuthfalltür -tile.basemetals.brass_trapdoor.name=Messingfalltür -tile.basemetals.bronze_trapdoor.name=Bronzefalltür -tile.basemetals.coldiron_trapdoor.name=Kalteisenfalltür -tile.basemetals.copper_trapdoor.name=Kupferfalltür -tile.basemetals.cupronickel_trapdoor.name=Kupfernickelfalltür -tile.basemetals.diamond_trapdoor.name=Diamantfalltür -tile.basemetals.electrum_trapdoor.name=Elektronfalltür -tile.basemetals.emerald_trapdoor.name=Smaragdfalltür -tile.basemetals.gold_trapdoor.name=Goldfalltür -tile.basemetals.invar_trapdoor.name=Invarfalltür -tile.basemetals.lead_trapdoor.name=Bleifalltür -tile.basemetals.mithril_trapdoor.name=Mithrilfalltür -tile.basemetals.nickel_trapdoor.name=Nickelfalltür -tile.basemetals.obsidian_trapdoor.name=Obsidianfalltür -tile.basemetals.pewter_trapdoor.name=Hartzinnfalltür -tile.basemetals.platinum_trapdoor.name=Platinfalltür -tile.basemetals.quartz_trapdoor.name=Quartzfalltür -tile.basemetals.silver_trapdoor.name=Silberfalltür -tile.basemetals.starsteel_trapdoor.name=Sternenstahlfalltür -tile.basemetals.steel_trapdoor.name=Stahlfalltür -tile.basemetals.tin_trapdoor.name=Zinnfalltür -tile.basemetals.zinc_trapdoor.name=Zinkfalltür - #Items -item.basemetals.adamantine_trapdoor.name=Adamantfalltür -item.basemetals.aquarium_trapdoor.name=Aquariumfalltür -item.basemetals.antimony_trapdoor.name=Antimonfalltür -item.basemetals.bismuth_trapdoor.name=Bismuthfalltür -item.basemetals.brass_trapdoor.name=Messingfalltür -item.basemetals.bronze_trapdoor.name=Bronzefalltür -item.basemetals.coldiron_trapdoor.name=Kalteisenfalltür -item.basemetals.copper_trapdoor.name=Kupferfalltür -item.basemetals.cupronickel_trapdoor.name=Kupfernickelfalltür -item.basemetals.diamond_trapdoor.name=Diamantfalltür -item.basemetals.electrum_trapdoor.name=Elektronfalltür -item.basemetals.emerald_trapdoor.name=Smaragdfalltür -item.basemetals.gold_trapdoor.name=Goldfalltür -item.basemetals.invar_trapdoor.name=Invarfalltür -item.basemetals.lead_trapdoor.name=Bleifalltür -item.basemetals.mithril_trapdoor.name=Mithrilfalltür -item.basemetals.nickel_trapdoor.name=Nickelfalltür -item.basemetals.obsidian_trapdoor.name=Obsidianfalltür -item.basemetals.pewter_trapdoor.name=Hartzinnfalltür -item.basemetals.platinum_trapdoor.name=Platinfalltür -item.basemetals.quartz_trapdoor.name=Quartzfalltür -item.basemetals.silver_trapdoor.name=Silberfalltür -item.basemetals.starsteel_trapdoor.name=Sternenstahlfalltür -item.basemetals.steel_trapdoor.name=Stahlfalltür -item.basemetals.tin_trapdoor.name=Zinnfalltür - -#zahnrads -item.basemetals.adamantine_gear.name=Adamantzahnrad -item.basemetals.aquarium_gear.name=Aquariumzahnrad -item.basemetals.antimony_gear.name=Antimonzahnrad -item.basemetals.bismuth_gear.name=Bismuthzahnrad -item.basemetals.brass_gear.name=Messingzahnrad -item.basemetals.bronze_gear.name=Bronzezahnrad -item.basemetals.coldiron_gear.name=Kalteisenzahnrad -item.basemetals.copper_gear.name=Kupferzahnrad -item.basemetals.cupronickel_gear.name=Kupfernickelzahnrad -item.basemetals.diamond_gear.name=Diamantzahnrad -item.basemetals.electrum_gear.name=Elektronzahnrad -item.basemetals.emerald_gear.name=Smaragdzahnrad -item.basemetals.gold_gear.name=Goldzahnrad -item.basemetals.invar_gear.name=Invarzahnrad -item.basemetals.iron_gear.name=Eisenzahnrad -item.basemetals.lead_gear.name=Bleizahnrad -item.basemetals.mithril_gear.name=Mithrilzahnrad -item.basemetals.nickel_gear.name=Nickelzahnrad -item.basemetals.obsidian_gear.name=Obsidianzahnrad -item.basemetals.pewter_gear.name=Hartzinnzahnrad -item.basemetals.platinum_gear.name=Platinzahnrad -item.basemetals.quartz_gear.name=Quartzzahnrad -item.basemetals.silver_gear.name=Silberzahnrad -item.basemetals.starsteel_gear.name=Sternenstahlzahnrad -item.basemetals.steel_gear.name=Stahlzahnrad -item.basemetals.stone_gear.name=Stonezahnrad -item.basemetals.tin_gear.name=Zinnzahnrad -item.basemetals.wood_gear.name=Holzzahnrad -item.basemetals.zinc_gear.name=Zinkzahnrad - -#stanges -item.basemetals.adamantine_rod.name=Adamantstange -item.basemetals.aquarium_rod.name=Aquariumstange -item.basemetals.antimony_rod.name=Antimonstange -item.basemetals.bismuth_rod.name=Bismuthstange -item.basemetals.brass_rod.name=Messingstange -item.basemetals.bronze_rod.name=Bronzestange -item.basemetals.coldiron_rod.name=Kalteisenstange -item.basemetals.copper_rod.name=Kupferstange -item.basemetals.cupronickel_rod.name=Kupfernickelstange -item.basemetals.diamond_rod.name=Diamantstange -item.basemetals.electrum_rod.name=Elektronstange -item.basemetals.emerald_rod.name=Smaragdstange -item.basemetals.gold_rod.name=Goldstange -item.basemetals.invar_rod.name=Invarstange -item.basemetals.iron_rod.name=Eisenstange -item.basemetals.lead_rod.name=Bleistange -item.basemetals.mithril_rod.name=Mithrilstange -item.basemetals.nickel_rod.name=Nickelstange -item.basemetals.obsidian_rod.name=Obsidianstange -item.basemetals.pewter_rod.name=Hartzinnstange -item.basemetals.platinum_rod.name=Platinstange -item.basemetals.quartz_rod.name=Quartzstange -item.basemetals.silver_rod.name=Silberstange -item.basemetals.starsteel_rod.name=Sternenstahlstange -item.basemetals.steel_rod.name=Stahlstange -item.basemetals.stone_rod.name=Stonestange -item.basemetals.tin_rod.name=Zinnstange -item.basemetals.zinc_rod.name=Zinkstange - -#blechs - #Item -item.basemetals.adamantine_plate.name=Verdichtetes Adamantblech -item.basemetals.aquarium_plate.name=Verdichtetes Aquariumblech -item.basemetals.antimony_plate.name=Verdichtetes Antimonblech -item.basemetals.bismuth_plate.name=Verdichtetes Bismuthblech -item.basemetals.brass_plate.name=Verdichtetes Messingblech -item.basemetals.bronze_plate.name=Verdichtetes Bronzeblech -item.basemetals.coldiron_plate.name=Verdichtetes Kalteisenblech -item.basemetals.copper_plate.name=Verdichtetes Kupferblech -item.basemetals.cupronickel_plate.name=Verdichtetes Kupfernickelblech -item.basemetals.electrum_plate.name=Verdichtetes Elektronblech -item.basemetals.gold_plate.name=Verdichtetes Goldblech -item.basemetals.invar_plate.name=Verdichtetes Invarblech -item.basemetals.lead_plate.name=Verdichtetes Bleiblech -item.basemetals.mithril_plate.name=Verdichtetes Mithrilblech -item.basemetals.nickel_plate.name=Verdichtetes Nickelblech -item.basemetals.pewter_plate.name=Verdichtetes Hartzinnblech -item.basemetals.platinum_plate.name=Verdichtetes Platinblech -item.basemetals.silver_plate.name=Verdichtetes Silberblech -item.basemetals.starsteel_plate.name=Verdichtetes Sternenstahlblech -item.basemetals.steel_plate.name=Verdichtetes Stahlblech -item.basemetals.tin_plate.name=Verdichtetes Zinnblech -item.basemetals.zinc_plate.name=Verdichtetes Zinkblech -item.basemetals.iron_plate.name=Verdichtetes Eisenblech -item.basemetals.gold_plate.name=Verdichtetes Goldblech - #Tile -tile.basemetals.adamantine_plate.name=Verdichtetes Adamantblech -tile.basemetals.aquarium_plate.name=Verdichtetes Aquariumblech -tile.basemetals.antimony_plate.name=Verdichtetes Antimonblech -tile.basemetals.bismuth_plate.name=Verdichtetes Bismuthblech -tile.basemetals.brass_plate.name=Verdichtetes Messingblech -tile.basemetals.bronze_plate.name=Verdichtetes Bronzeblech -tile.basemetals.coldiron_plate.name=Verdichtetes Kalteisenblech -tile.basemetals.copper_plate.name=Verdichtetes Kupferblech -tile.basemetals.cupronickel_plate.name=Verdichtetes Kupfernickelblech -tile.basemetals.electrum_plate.name=Verdichtetes Elektronblech -tile.basemetals.gold_plate.name=Verdichtetes Goldblech -tile.basemetals.invar_plate.name=Verdichtetes Invarblech -tile.basemetals.lead_plate.name=Verdichtetes Bleiblech -tile.basemetals.mithril_plate.name=Verdichtetes Mithrilblech -tile.basemetals.nickel_plate.name=Verdichtetes Nickelblech -tile.basemetals.pewter_plate.name=Verdichtetes Hartzinnblech -tile.basemetals.platinum_plate.name=Verdichtetes Platinblech -tile.basemetals.silver_plate.name=Verdichtetes Silberblech -tile.basemetals.starsteel_plate.name=Verdichtetes Sternenstahlblech -tile.basemetals.steel_plate.name=Verdichtetes Stahlblech -tile.basemetals.tin_plate.name=Verdichtetes Zinnblech -tile.basemetals.zinc_plate.name=Verdichtetes Zinkblech -tile.basemetals.iron_plate.name=Verdichtetes Eisenblech -tile.basemetals.gold_plate.name=Verdichtetes Goldblech - -#Player Detectors (Pressureblechs) - #Items -item.basemetals.human_detector.name=Sicherheits-Druckplatte - #Tiles -tile.basemetals.human_detector.name=Sicherheits-Druckplatte - -#schalter - #Item -item.basemetals.adamantine_button.name=Adamantschalter -item.basemetals.aquarium_button.name=Aquariumschalter -item.basemetals.antimony_button.name=Antimonschalter -item.basemetals.bismuth_button.name=Bismuthschalter -item.basemetals.brass_button.name=Messingschalter -item.basemetals.bronze_button.name=Bronzeschalter -item.basemetals.coldiron_button.name=Kalteisenschalter -item.basemetals.copper_button.name=Kupferschalter -item.basemetals.cupronickel_button.name=Kupfernickelschalter -item.basemetals.diamond_button.name=Diamantschalter -item.basemetals.electrum_button.name=Elektronschalter -item.basemetals.emerald_button.name=Smaragdschalter -item.basemetals.gold_button.name=Goldschalter -item.basemetals.invar_button.name=Invarschalter -item.basemetals.lead_button.name=Bleischalter -item.basemetals.mithril_button.name=Mithrilschalter -item.basemetals.nickel_button.name=Nickelschalter -item.basemetals.obsidian_button.name=Obsidianschalter -item.basemetals.pewter_button.name=Hartzinnschalter -item.basemetals.platinum_button.name=Platinschalter -item.basemetals.quartz_button.name=Quartzschalter -item.basemetals.silver_button.name=Silberschalter -item.basemetals.starsteel_button.name=Sternenstahlschalter -item.basemetals.steel_button.name=Stahlschalter -item.basemetals.tin_button.name=Zinnschalter -item.basemetals.zinc_button.name=Zinkschalter -item.basemetals.iron_button.name=Eisenschalter -item.basemetals.gold_button.name=Goldschalter - #Tile -tile.basemetals.adamantine_button.name=Adamantschalter -tile.basemetals.aquarium_button.name=Aquariumschalter -tile.basemetals.antimony_button.name=Antimonschalter -tile.basemetals.bismuth_button.name=Bismuthschalter -tile.basemetals.brass_button.name=Messingschalter -tile.basemetals.bronze_button.name=Bronzeschalter -tile.basemetals.coldiron_button.name=Kalteisenschalter -tile.basemetals.copper_button.name=Kupferschalter -tile.basemetals.cupronickel_button.name=Kupfernickelschalter -tile.basemetals.diamond_button.name=Diamantschalter -tile.basemetals.electrum_button.name=Elektronschalter -tile.basemetals.emerald_button.name=Smaragdschalter -tile.basemetals.gold_button.name=Goldschalter -tile.basemetals.invar_button.name=Invarschalter -tile.basemetals.lead_button.name=Bleischalter -tile.basemetals.mithril_button.name=Mithrilschalter -tile.basemetals.nickel_button.name=Nickelschalter -tile.basemetals.obsidian_button.name=Obsidianschalter -tile.basemetals.pewter_button.name=Hartzinnschalter -tile.basemetals.platinum_button.name=Platinschalter -tile.basemetals.quartz_button.name=Quartzschalter -tile.basemetals.silver_button.name=Silberschalter -tile.basemetals.starsteel_button.name=Sternenstahlschalter -tile.basemetals.steel_button.name=Stahlschalter -tile.basemetals.tin_button.name=Zinnschalter -tile.basemetals.zinc_button.name=Zinkschalter -tile.basemetals.iron_button.name=Eisenschalter -tile.basemetals.gold_button.name=Goldschalter - -Pressureblech - #Item -item.basemetals.adamantine_pressure_plate.name=Adamantdruckplatte -item.basemetals.aquarium_pressure_plate.name=Aquariumdruckplatte -item.basemetals.antimony_pressure_plate.name=Antimondruckplatte -item.basemetals.bismuth_pressure_plate.name=Bismuthdruckplatte -item.basemetals.brass_pressure_plate.name=Messingdruckplatte -item.basemetals.bronze_pressure_plate.name=Bronzedruckplatte -item.basemetals.coldiron_pressure_plate.name=Kalteisendruckplatte -item.basemetals.copper_pressure_plate.name=Kupferdruckplatte -item.basemetals.cupronickel_pressure_plate.name=Kupfernickeldruckplatte -item.basemetals.diamond_pressure_plate.name=Diamantdruckplatte -item.basemetals.electrum_pressure_plate.name=Elektrondruckplatte -item.basemetals.emerald_pressure_plate.name=Smaragddruckplatte -item.basemetals.invar_pressure_plate.name=Invardruckplatte -item.basemetals.lead_pressure_plate.name=Bleidruckplatte -item.basemetals.mithril_pressure_plate.name=Mithrildruckplatte -item.basemetals.nickel_pressure_plate.name=Nickeldruckplatte -item.basemetals.obsidian_pressure_plate.name=Obsidiandruckplatte -item.basemetals.pewter_pressure_plate.name=Hartzinndruckplatte -item.basemetals.platinum_pressure_plate.name=Platindruckplatte -item.basemetals.quartz_pressure_plate.name=Quartzdruckplatte -item.basemetals.silver_pressure_plate.name=Silberdruckplatte -item.basemetals.starsteel_pressure_plate.name=Sternenstahldruckplatte -item.basemetals.steel_pressure_plate.name=Stahldruckplatte -item.basemetals.tin_pressure_plate.name=Zinndruckplatte -item.basemetals.zinc_pressure_plate.name=Zinkdruckplatte -item.basemetals.iron_pressure_plate.name=Eisendruckplatte -item.basemetals.gold_pressure_plate.name=Golddruckplatte - #Tile -tile.basemetals.adamantine_pressure_plate.name=Adamantdruckplatte -tile.basemetals.aquarium_pressure_plate.name=Aquariumdruckplatte -tile.basemetals.antimony_pressure_plate.name=Antimondruckplatte -tile.basemetals.bismuth_pressure_plate.name=Bismuthdruckplatte -tile.basemetals.brass_pressure_plate.name=Messingdruckplatte -tile.basemetals.bronze_pressure_plate.name=Bronzedruckplatte -tile.basemetals.coldiron_pressure_plate.name=Kalteisendruckplatte -tile.basemetals.copper_pressure_plate.name=Kupferdruckplatte -tile.basemetals.cupronickel_pressure_plate.name=Kupfernickeldruckplatte -tile.basemetals.diamond_pressure_plate.name=Diamantdruckplatte -tile.basemetals.electrum_pressure_plate.name=Elektrondruckplatte -tile.basemetals.emerald_pressure_plate.name=Smaragddruckplatte -tile.basemetals.invar_pressure_plate.name=Invardruckplatte -tile.basemetals.lead_pressure_plate.name=Bleidruckplatte -tile.basemetals.mithril_pressure_plate.name=Mithrildruckplatte -tile.basemetals.nickel_pressure_plate.name=Nickeldruckplatte -tile.basemetals.obsidian_pressure_plate.name=Obsidiandruckplatte -tile.basemetals.pewter_pressure_plate.name=Hartzinndruckplatte -tile.basemetals.platinum_pressure_plate.name=Platindruckplatte -tile.basemetals.quartz_pressure_plate.name=Quartzdruckplatte -tile.basemetals.silver_pressure_plate.name=Silberdruckplatte -tile.basemetals.starsteel_pressure_plate.name=Sternenstahldruckplatte -tile.basemetals.steel_pressure_plate.name=Stahldruckplatte -tile.basemetals.tin_pressure_plate.name=Zinndruckplatte -tile.basemetals.zinc_pressure_plate.name=Zinkdruckplatte -tile.basemetals.iron_pressure_plate.name=Eisendruckplatte -tile.basemetals.gold_pressure_plate.name=Golddruckplatte - -#Crystal -item.basemetals.adamantine_crystal.name=Adamantkristall -item.basemetals.aquarium_crystal.name=Aquariumkristall -item.basemetals.antimony_crystal.name= Antimonkristall -item.basemetals.bismuth_crystal.name= Bismuthkristall -item.basemetals.brass_crystal.name= Messingkristall -item.basemetals.bronze_crystal.name= Bronzekristall -item.basemetals.coldiron_crystal.name= Kalteisenkristall -item.basemetals.copper_crystal.name= Kupferkristall -item.basemetals.cupronickel_crystal.name= Kupfernickelkristall -item.basemetals.electrum_crystal.name= Elektronkristall -item.basemetals.invar_crystal.name= Invarkristall -item.basemetals.lead_crystal.name= Bleikristall -item.basemetals.mithril_crystal.name= Mithrilkristall -item.basemetals.nickel_crystal.name= Nickelkristall -item.basemetals.pewter_crystal.name= Hartzinnkristall -item.basemetals.platinum_crystal.name= Platinkristall -item.basemetals.silver_crystal.name= Silberkristall -item.basemetals.starsteel_crystal.name= Sternenstahlkristall -item.basemetals.steel_crystal.name= Stahlkristall -item.basemetals.tin_crystal.name= Zinnkristall -item.basemetals.zinc_crystal.name=Zinkkristall - -#Clump -item.basemetals.adamantine_clump.name= Adamantklumpen -item.basemetals.aquarium_clump.name= Aquariumklumpen -item.basemetals.antimony_clump.name= Antimonklumpen -item.basemetals.bismuth_clump.name= Bismuthklumpen -item.basemetals.brass_clump.name= Messingklumpen -item.basemetals.bronze_clump.name= Bronzeklumpen -item.basemetals.coldiron_clump.name= Kalteisenklumpen -item.basemetals.copper_clump.name= Kupferklumpen -item.basemetals.cupronickel_clump.name= Kupfernickelklumpen -item.basemetals.electrum_clump.name= Elektronklumpen -item.basemetals.invar_clump.name= Invarklumpen -item.basemetals.lead_clump.name= Bleiklumpen -item.basemetals.mithril_clump.name= Mithrilklumpen -item.basemetals.nickel_clump.name= Nickelklumpen -item.basemetals.pewter_clump.name= Hartzinnklumpen -item.basemetals.platinum_clump.name= Platinklumpen -item.basemetals.silver_clump.name= Silberklumpen -item.basemetals.starsteel_clump.name= Sternenstahlklumpen -item.basemetals.steel_clump.name= Stahlklumpen -item.basemetals.tin_clump.name= Zinnklumpen -item.basemetals.zinc_clump.name= Zinkklumpen - -#Shard -item.basemetals.adamantine_shard.name= Adamantsplitter -item.basemetals.aquarium_shard.name= Aquariumsplitter -item.basemetals.antimony_shard.name= Antimonsplitter -item.basemetals.bismuth_shard.name= Bismuthsplitter -item.basemetals.brass_shard.name= Messingsplitter -item.basemetals.bronze_shard.name= Bronzesplitter -item.basemetals.coldiron_shard.name= Kalteisensplitter -item.basemetals.copper_shard.name= Kupfersplitter -item.basemetals.cupronickel_shard.name= Kupfernickelsplitter -item.basemetals.electrum_shard.name= Elektronsplitter -item.basemetals.invar_shard.name= Invarsplitter -item.basemetals.lead_shard.name= Bleisplitter -item.basemetals.mithril_shard.name= Mithrilsplitter -item.basemetals.nickel_shard.name= Nickelsplitter -item.basemetals.pewter_shard.name= Hartzinnsplitter -item.basemetals.platinum_shard.name= Platinsplitter -item.basemetals.silver_shard.name= Silbersplitter -item.basemetals.starsteel_shard.name= Sternenstahlsplitter -item.basemetals.steel_shard.name= Stahlsplitter -item.basemetals.tin_shard.name= Zinnsplitter -item.basemetals.zinc_shard.name= Zinksplitter - -#Verunreinigtes -item.basemetals.adamantine_powder_dirty.name=Verunreinigtes Adamantpulver -item.basemetals.aquarium_powder_dirty.name=Verunreinigtes Aquariumpulver -item.basemetals.antimony_powder_dirty.name=Verunreinigtes Antimonpulver -item.basemetals.bismuth_powder_dirty.name=Verunreinigtes Bismuthpulver -item.basemetals.brass_powder_dirty.name=Verunreinigtes Messingpulver -item.basemetals.bronze_powder_dirty.name=Verunreinigtes Bronzepulver -item.basemetals.coldiron_powder_dirty.name=Verunreinigtes Kalteisenpulver -item.basemetals.copper_powder_dirty.name=Verunreinigtes Kupferpulver -item.basemetals.cupronickel_powder_dirty.name=Verunreinigtes Kupfernickelpulver -item.basemetals.electrum_powder_dirty.name=Verunreinigtes Elektronpulver -item.basemetals.gold_powder_dirty.name=Verunreinigtes Goldpulver -item.basemetals.invar_powder_dirty.name=Verunreinigtes Invarpulver -item.basemetals.iron_powder_dirty.name=Verunreinigtes Eisenpulver -item.basemetals.lead_powder_dirty.name=Verunreinigtes Bleipulver -item.basemetals.mithril_powder_dirty.name=Verunreinigtes Mithrilpulver -item.basemetals.nickel_powder_dirty.name=Verunreinigtes Nickelpulver -item.basemetals.pewter_powder_dirty.name=Verunreinigtes Hartzinnpulver -item.basemetals.platinum_powder_dirty.name=Verunreinigtes Platinpulver -item.basemetals.silver_powder_dirty.name=Verunreinigtes Silberpulver -item.basemetals.starsteel_powder_dirty.name=Verunreinigtes Sternenstahlpulver -item.basemetals.steel_powder_dirty.name=Verunreinigtes Stahlpulver -item.basemetals.tin_powder_dirty.name=Verunreinigtes Zinnpulver -item.basemetals.zinc_powder_dirty.name=Verunreinigtes Zinkpulver - -#Casing - #Item -item.basemetals.adamantine_casing.name=Adamantgehäuse -item.basemetals.aquarium_casing.name=Aquariumgehäuse -item.basemetals.antimony_casing.name=Antimongehäuse -item.basemetals.bismuth_casing.name=Bismuthgehäuse -item.basemetals.brass_casing.name=Messinggehäuse -item.basemetals.bronze_casing.name=Bronzegehäuse -item.basemetals.coldiron_casing.name=Kalteisengehäuse -item.basemetals.copper_casing.name=Kupfergehäuse -item.basemetals.cupronickel_casing.name=Kupfernickelgehäuse -item.basemetals.electrum_casing.name=Elektrongehäuse -item.basemetals.invar_casing.name=Invargehäuse -item.basemetals.lead_casing.name=Bleigehäuse -item.basemetals.mithril_casing.name=Mithrilgehäuse -item.basemetals.nickel_casing.name=Nickelgehäuse -item.basemetals.pewter_casing.name=Hartzinngehäuse -item.basemetals.platinum_casing.name=Platingehäuse -item.basemetals.silver_casing.name=Silbergehäuse -item.basemetals.starsteel_casing.name=Sternenstahlgehäuse -item.basemetals.steel_casing.name=Stahlgehäuse -item.basemetals.tin_casing.name=Zinngehäuse -item.basemetals.zinc_casing.name=Zinkgehäuse -item.basemetals.iron_casing.name=Eisengehäuse -item.basemetals.gold_casing.name=Goldgehäuse - -#Denseblech - #Item -item.basemetals.adamantine_dense_plate.name=Verdichtetes Adamantblech -item.basemetals.aquarium_dense_plate.name=Verdichtetes Aquariumblech -item.basemetals.antimony_dense_plate.name=Verdichtetes Antimonblech -item.basemetals.bismuth_dense_plate.name=Verdichtetes Bismuthblech -item.basemetals.brass_dense_plate.name=Verdichtetes Messingblech -item.basemetals.bronze_dense_plate.name=Verdichtetes Bronzeblech -item.basemetals.coldiron_dense_plate.name=Verdichtetes Kalteisenblech -item.basemetals.copper_dense_plate.name=Verdichtetes Kupferblech -item.basemetals.cupronickel_dense_plate.name=Verdichtetes Kupfernickelblech -item.basemetals.electrum_dense_plate.name=Verdichtetes Elektronblech -item.basemetals.invar_dense_plate.name=Verdichtetes Invarblech -item.basemetals.lead_dense_plate.name=Verdichtetes Bleiblech -item.basemetals.mithril_dense_plate.name=Verdichtetes Mithrilblech -item.basemetals.nickel_dense_plate.name=Verdichtetes Nickelblech -item.basemetals.pewter_dense_plate.name=Verdichtetes Hartzinnblech -item.basemetals.platinum_dense_plate.name=Verdichtetes Platinblech -item.basemetals.silver_dense_plate.name=Verdichtetes Silberblech -item.basemetals.starsteel_dense_plate.name=Verdichtetes Sternenstahlblech -item.basemetals.steel_dense_plate.name=Verdichtetes Stahlblech -item.basemetals.tin_dense_plate.name=Verdichtetes Zinnblech -item.basemetals.zinc_dense_plate.name=Verdichtetes Zinkblech -item.basemetals.iron_dense_plate.name=Verdichtetes Eisenblech -item.basemetals.gold_dense_plate.name=Verdichtetes Goldblech - #Tile -tile.basemetals.adamantine_dense_plate.name=Verdichtetes Adamantblech -tile.basemetals.aquarium_dense_plate.name=Verdichtetes Aquariumblech -tile.basemetals.antimony_dense_plate.name=Verdichtetes Antimonblech -tile.basemetals.bismuth_dense_plate.name=Verdichtetes Bismuthblech -tile.basemetals.brass_dense_plate.name=Verdichtetes Messingblech -tile.basemetals.bronze_dense_plate.name=Verdichtetes Bronzeblech -tile.basemetals.coldiron_dense_plate.name=Verdichtetes Kalteisenblech -tile.basemetals.copper_dense_plate.name=Verdichtetes Kupferblech -tile.basemetals.cupronickel_dense_plate.name=Verdichtetes Kupfernickelblech -tile.basemetals.electrum_dense_plate.name=Verdichtetes Elektronblech -tile.basemetals.invar_dense_dense_plate.name=Verdichtetes Invarblech -tile.basemetals.lead_dense_plate.name=Verdichtetes Verdichtetes Bleiblech -tile.basemetals.mithril_dense_plate.name=Verdichtetes Verdichtetes Mithrilblech -tile.basemetals.nickel_dense_plate.name=Verdichtetes Verdichtetes Nickelblech -tile.basemetals.pewter_dense_plate.name=Verdichtetes Verdichtetes Hartzinnblech -tile.basemetals.platinum_dense_plate.name=Verdichtetes Verdichtetes Platinblech -tile.basemetals.silver_dense_plate.name=Verdichtetes Verdichtetes Silberblech -tile.basemetals.starsteel_dense_plate.name=Verdichtetes Verdichtetes Sternenstahlblech -tile.basemetals.steel_dense_plate.name=Verdichtetes Verdichtetes Stahlblech -tile.basemetals.tin_dense_plate.name=Verdichtetes Verdichtetes Zinnblech -tile.basemetals.zinc_dense_plate.name=Verdichtetes Verdichtetes Zinkblech -tile.basemetals.iron_dense_plate.name=Verdichtetes Verdichtetes Eisenblech -tile.basemetals.gold_dense_plate.name=Verdichtetes Verdichtetes Goldblech - -#fliese - #Item -item.basemetals.adamantine_slab.name=Adamantfliese -item.basemetals.aquarium_slab.name=Aquariumfliese -item.basemetals.antimony_slab.name=Antimonfliese -item.basemetals.bismuth_slab.name=Bismuthfliese -item.basemetals.brass_slab.name=Messingfliese -item.basemetals.bronze_slab.name=Bronzefliese -item.basemetals.coldiron_slab.name=Kalteisenfliese -item.basemetals.copper_slab.name=Kupferfliese -item.basemetals.cupronickel_slab.name=Kupfernickelfliese -item.basemetals.diamond_slab.name=Diamantfliese -item.basemetals.electrum_slab.name=Elektronfliese -item.basemetals.emerald_slab.name=Smaragdfliese -item.basemetals.gold_slab.name=Goldfliese -item.basemetals.invar_slab.name=Invarfliese -item.basemetals.iron_slab.name=Eisenfliese -item.basemetals.lead_slab.name=Bleifliese -item.basemetals.mithril_slab.name=Mithrilfliese -item.basemetals.nickel_slab.name=Nickelfliese -item.basemetals.obsidian_slab.name=Obsidianfliese -item.basemetals.pewter_slab.name=Hartzinnfliese -item.basemetals.platinum_slab.name=Platinfliese -item.basemetals.silver_slab.name=Silberfliese -item.basemetals.starsteel_slab.name=Sternenstahlfliese -item.basemetals.steel_slab.name=Stahlfliese -item.basemetals.tin_slab.name=Zinnfliese -item.basemetals.zinc_slab.name=Zinkfliese - #Tile -tile.basemetals.adamantine_slab.name=Adamantfliese -tile.basemetals.aquarium_slab.name=Aquariumfliese -tile.basemetals.antimony_slab.name=Antimonfliese -tile.basemetals.bismuth_slab.name=Bismuthfliese -tile.basemetals.brass_slab.name=Messingfliese -tile.basemetals.bronze_slab.name=Bronzefliese -tile.basemetals.coldiron_slab.name=Kalteisenfliese -tile.basemetals.copper_slab.name=Kupferfliese -tile.basemetals.cupronickel_slab.name=Kupfernickelfliese -tile.basemetals.diamond_slab.name=Diamantfliese -tile.basemetals.electrum_slab.name=Elektronfliese -tile.basemetals.emerald_slab.name=Smaragdfliese -tile.basemetals.gold_slab.name=Goldfliese -tile.basemetals.invar_slab.name=Invarfliese -tile.basemetals.iron_slab.name=Eisenfliese -tile.basemetals.lead_slab.name=Bleifliese -tile.basemetals.mithril_slab.name=Mithrilfliese -tile.basemetals.nickel_slab.name=Nickelfliese -tile.basemetals.obsidian_slab.name=Obsidianfliese -tile.basemetals.pewter_slab.name=Hartzinnfliese -tile.basemetals.platinum_slab.name=Platinfliese -tile.basemetals.silver_slab.name=Silberfliese -tile.basemetals.starsteel_slab.name=Sternenstahlfliese -tile.basemetals.steel_slab.name=Stahlfliese -tile.basemetals.tin_slab.name=Zinnfliese -tile.basemetals.zinc_slab.name=Zinkfliese - -#hebel - #Item -item.basemetals.adamantine_lever.name=Adamanthebel -item.basemetals.aquarium_lever.name=Aquariumhebel -item.basemetals.antimony_lever.name=Antimonhebel -item.basemetals.bismuth_lever.name=Bismuthhebel -item.basemetals.brass_lever.name=Messinghebel -item.basemetals.bronze_lever.name=Bronzehebel -item.basemetals.coldiron_lever.name=Kalteisenhebel -item.basemetals.copper_lever.name=Kupferhebel -item.basemetals.cupronickel_lever.name=Kupfernickelhebel -item.basemetals.diamond_lever.name=Diamanthebel -item.basemetals.electrum_lever.name=Elektronhebel -item.basemetals.emerald_lever.name=Smaragdhebel -item.basemetals.gold_lever.name=Goldhebel -item.basemetals.invar_lever.name=Invarhebel -item.basemetals.iron_lever.name=Eisenhebel -item.basemetals.lead_lever.name=Bleihebel -item.basemetals.mithril_lever.name=Mithrilhebel -item.basemetals.nickel_lever.name=Nickelhebel -item.basemetals.obsidian_lever.name=Obsidianhebel -item.basemetals.pewter_lever.name=Hartzinnhebel -item.basemetals.platinum_lever.name=Platinhebel -item.basemetals.quartz_lever.name=Quartzhebel -item.basemetals.silver_lever.name=Silberhebel -item.basemetals.starsteel_lever.name=Sternenstahlhebel -item.basemetals.steel_lever.name=Stahlhebel -item.basemetals.tin_lever.name=Zinnhebel -item.basemetals.zinc_lever.name=Zinkhebel - #Tile -tile.basemetals.adamantine_lever.name=Adamanthebel -tile.basemetals.aquarium_lever.name=Aquariumhebel -tile.basemetals.antimony_lever.name=Antimonhebel -tile.basemetals.bismuth_lever.name=Bismuthhebel -tile.basemetals.brass_lever.name=Messinghebel -tile.basemetals.bronze_lever.name=Bronzehebel -tile.basemetals.coldiron_lever.name=Kalteisenhebel -tile.basemetals.copper_lever.name=Kupferhebel -tile.basemetals.cupronickel_lever.name=Kupfernickelhebel -tile.basemetals.diamond_lever.name=Diamanthebel -tile.basemetals.electrum_lever.name=Elektronhebel -tile.basemetals.emerald_lever.name=Smaragdhebel -tile.basemetals.gold_lever.name=Goldhebel -tile.basemetals.invar_lever.name=Invarhebel -tile.basemetals.iron_lever.name=Eisenhebel -tile.basemetals.lead_lever.name=Bleihebel -tile.basemetals.mithril_lever.name=Mithrilhebel -tile.basemetals.nickel_lever.name=Nickelhebel -tile.basemetals.obsidian_lever.name=Obsidianhebel -tile.basemetals.pewter_lever.name=Hartzinnhebel -tile.basemetals.platinum_lever.name=Platinhebel -tile.basemetals.quartz_lever.name=Quartzhebel -tile.basemetals.silver_lever.name=Silberhebel -tile.basemetals.starsteel_lever.name=Sternenstahlhebel -tile.basemetals.steel_lever.name=Stahlhebel -tile.basemetals.tin_lever.name=Zinnhebel -tile.basemetals.zinc_lever.name=Zinkhebel - -#Stair - #Item -item.basemetals.adamantine_stairs.name=Adamanttreppe -item.basemetals.aquarium_stairs.name=Aquariumtreppe -item.basemetals.antimony_stairs.name=Antimontreppe -item.basemetals.bismuth_stairs.name=Bismuthtreppe -item.basemetals.brass_stairs.name=Messingtreppe -item.basemetals.bronze_stairs.name=Bronzetreppe -item.basemetals.coldiron_stairs.name=Kalteisentreppe -item.basemetals.copper_stairs.name=Kupfertreppe -item.basemetals.cupronickel_stairs.name=Kupfernickeltreppe -item.basemetals.diamond_stairs.name=Diamanttreppe -item.basemetals.electrum_stairs.name=Elektrontreppe -item.basemetals.emerald_stairs.name=Smaragdtreppe -item.basemetals.gold_stairs.name=Goldtreppe -item.basemetals.invar_stairs.name=Invartreppe -item.basemetals.iron_stairs.name=Eisentreppe -item.basemetals.lead_stairs.name=Bleitreppe -item.basemetals.mithril_stairs.name=Mithriltreppe -item.basemetals.nickel_stairs.name=Nickeltreppe -item.basemetals.obsidian_stairs.name=Obsidiantreppe -item.basemetals.pewter_stairs.name=Hartzinntreppe -item.basemetals.platinum_stairs.name=Platintreppe -item.basemetals.silver_stairs.name=Silbertreppe -item.basemetals.starsteel_stairs.name=Sternenstahltreppe -item.basemetals.steel_stairs.name=Stahltreppe -item.basemetals.tin_stairs.name=Zinntreppe -item.basemetals.zinc_stairs.name=Zinktreppe - #Tile -tile.basemetals.adamantine_stairs.name=Adamanttreppe -tile.basemetals.aquarium_stairs.name=Aquariumtreppe -tile.basemetals.antimony_stairs.name=Antimontreppe -tile.basemetals.bismuth_stairs.name=Bismuthtreppe -tile.basemetals.brass_stairs.name=Messingtreppe -tile.basemetals.bronze_stairs.name=Bronzetreppe -tile.basemetals.coldiron_stairs.name=Kalteisentreppe -tile.basemetals.copper_stairs.name=Kupfertreppe -tile.basemetals.cupronickel_stairs.name=Kupfernickeltreppe -tile.basemetals.diamond_stairs.name=Diamanttreppe -tile.basemetals.electrum_stairs.name=Elektrontreppe -tile.basemetals.emerald_stairs.name=Smaragdtreppe -tile.basemetals.gold_stairs.name=Goldtreppe -tile.basemetals.invar_stairs.name=Invartreppe -tile.basemetals.iron_stairs.name=Eisentreppe -tile.basemetals.lead_stairs.name=Bleitreppe -tile.basemetals.mithril_stairs.name=Mithriltreppe -tile.basemetals.nickel_stairs.name=Nickeltreppe -tile.basemetals.obsidian_stairs.name=Obsidiantreppe -tile.basemetals.pewter_stairs.name=Hartzinntreppe -tile.basemetals.platinum_stairs.name=Platintreppe -tile.basemetals.silver_stairs.name=Silbertreppe -tile.basemetals.starsteel_stairs.name=Sternenstahltreppe -tile.basemetals.steel_stairs.name=Stahltreppe -tile.basemetals.tin_stairs.name=Zinntreppe -tile.basemetals.zinc_stairs.name=Zinktreppe - -#mauer - #Item -item.basemetals.adamantine_wall.name=Adamantmauer -item.basemetals.aquarium_wall.name=Aquariummauer -item.basemetals.antimony_wall.name=Antimonmauer -item.basemetals.bismuth_wall.name=Bismuthmauer -item.basemetals.brass_wall.name=Messingmauer -item.basemetals.bronze_wall.name=Bronzemauer -item.basemetals.coldiron_wall.name=Kalteisenmauer -item.basemetals.copper_wall.name=Kupfermauer -item.basemetals.cupronickel_wall.name=Kupfernickelmauer -item.basemetals.diamond_wall.name=Diamantmauer -item.basemetals.electrum_wall.name=Elektronmauer -item.basemetals.emerald_wall.name=Smaragdmauer -item.basemetals.gold_wall.name=Goldmauer -item.basemetals.invar_wall.name=Invarmauer -item.basemetals.iron_wall.name=Eisenmauer -item.basemetals.lead_wall.name=Bleimauer -item.basemetals.mithril_wall.name=Mithrilmauer -item.basemetals.nickel_wall.name=Nickelmauer -item.basemetals.obsidian_wall.name=Obsidianmauer -item.basemetals.pewter_wall.name=Hartzinnmauer -item.basemetals.platinum_wall.name=Platinmauer -item.basemetals.quartz_wall.name=Quartzmauer -item.basemetals.silver_wall.name=Silbermauer -item.basemetals.starsteel_wall.name=Sternenstahlmauer -item.basemetals.steel_wall.name=Stahlmauer -item.basemetals.tin_wall.name=Zinnmauer -item.basemetals.zinc_wall.name=Zinkmauer - #Tile -tile.basemetals.adamantine_wall.name=Adamantmauer -tile.basemetals.aquarium_wall.name=Aquariummauer -tile.basemetals.antimony_wall.name=Antimonmauer -tile.basemetals.bismuth_wall.name=Bismuthmauer -tile.basemetals.brass_wall.name=Messingmauer -tile.basemetals.bronze_wall.name=Bronzemauer -tile.basemetals.coldiron_wall.name=Kalteisenmauer -tile.basemetals.copper_wall.name=Kupfermauer -tile.basemetals.cupronickel_wall.name=Kupfernickelmauer -tile.basemetals.diamond_wall.name=Diamantmauer -tile.basemetals.electrum_wall.name=Elektronmauer -tile.basemetals.emerald_wall.name=Smaragdmauer -tile.basemetals.gold_wall.name=Goldmauer -tile.basemetals.invar_wall.name=Invarmauer -tile.basemetals.iron_wall.name=Eisenmauer -tile.basemetals.lead_wall.name=Bleimauer -tile.basemetals.mithril_wall.name=Mithrilmauer -tile.basemetals.nickel_wall.name=Nickelmauer -tile.basemetals.obsidian_wall.name=Obsidianmauer -tile.basemetals.pewter_wall.name=Hartzinnmauer -tile.basemetals.platinum_wall.name=Platinmauer -tile.basemetals.quartz_wall.name=Quartzmauer -tile.basemetals.silver_wall.name=Silbermauer -tile.basemetals.starsteel_wall.name=Sternenstahlmauer -tile.basemetals.steel_wall.name=Stahlmauer -tile.basemetals.tin_wall.name=Zinnmauer -tile.basemetals.zinc_wall.name=Zinkmauer - -modifier.mmd-toxic.name=Giftig -modifier.mmd-toxic.desc=Ziemlich gefährlich - blendet und vergiftet Dinge, die mit Werkzeugen oder Waffen getroffen werden. -modifier.mmd-sparkly.name=Funkelnd -modifier.mmd-sparkly.desc=Selbstreparierendes, glänzendes und funkelndes Zeug -modifier.mmd-soft.name=Weich -modifier.mmd-soft.desc=Nicht wirklich für Werkzeuge, die viel genutzt werden sollen, geeignet, da sich diese schneller abnutzen werden -modifier.mmd-brittle.name=Spröde -modifier.mmd-brittle.desc=Mit zunehmender Abnutzung wird mehr Schaden verursacht - aber Vorsicht, es verletzt auch dich! -modifier.mmd-heavy.name=Schwer -modifier.mmd-heavy.desc=Dieses Zeug ist wirklich, wirklich dicht - die Nutzung von Werkzeugen aus diesem Material wird dich schneller ermüden -modifier.mmd-reactive.name=Reaktiv -modifier.mmd-reactive.desc=Reagiert mit Wasser und nutzt sich dabei schneller ab -modifier.mmd-radioactive.name=Radioaktiv -modifier.mmd-radioactive.desc=Gefährlich zu halten, wenn du dich nicht irgendwie vor den negativen Effekten schützen kannst. - -modifier.toxic-modifier.name=Giftig -modifier.toxic-modifier.desc=§oGIFTIGER RÄCHER!§r\nQuecksilber und seine Ethyl- und Methyl-Salze sind extrem giftig und haben neurodegenerative Effekte.\nSie zu einer Waffe oder einem Werkzeug hinzuzufügen, erlaubt diesen deine Feinde zu blenden und zu vergiften. -modifier.lead-plated.name=Bleibeschichtung -modifier.lead-plated.desc=§oSafety First§r\nWenn du etwas Plutonium oder Uran herumliegen hast und denkst, dass es gut für eine Waffe geeignet wäre, vergiss nicht etwas Abschirmendes hinzuzufügen.\nEine Beschichtung mit Blei wird die tödliche Verstrahlung davon abhalten, dich zu betreffen, während sie deinen Feinden weiterhin schadet. +basemetals.crackhammer=Zerkleinerte Blöcke / Gegenstände + +#Creative Tabs +itemGroup.basemetals.blocks=Base Metals Blöcke +itemGroup.basemetals.combat=Base Metals Combat +itemGroup.basemetals.items=Base Metals Gegenstände +itemGroup.basemetals.tools=Base Metals Werkzeuge + +#ToolTips +tooltip.adamantine.tool=+%d Schaden gegen zähe Feinde +tooltip.adamantine.armor=Volle Rüstung: Schadensreduktion + +tooltip.aquarium.tool=+%d Schaden gegen aquatische Feinde +tooltip.aquarium.armor=Volle Rüstung: Unterwasseratmung + +tooltip.coldiron.tool=+%d Schaden gegen feurige Feinde +tooltip.coldiron.armor=Volle Rüstung: Feuerimmunität + +tooltip.mithril.tool=Blendet Wither und Untote +tooltip.mithril.armor=Volle Rüstung: Immunität gegen Gift & Wither + +tooltip.starsteel.tool=Repariert 1 Schaden alle %d Sekunden +tooltip.starsteel.armor=Volle Rüstung: Gewichtsreduktion + +#Achievements + #Achievement Name +achievement.aquarium_maker=Aquarium +achievement.angel_of_death=Todesengel +achievement.brass_maker=Messing +achievement.bronze_maker=Bronze +achievement.blocktastic=Blocktastisch! +achievement.cupronickel_maker=Kupfernickel +achievement.demon_slayer=Dämonenschlächter +achievement.electrum_maker=Elektron +achievement.geologist=Geologe +achievement.invar_maker=Invar +achievement.juggernaut=Juggernaut +achievement.metallurgy=Metallurgy +achievement.mithril_maker=Mithril +achievement.moon_boots=Moon Walker +achievement.scuba_diver=SCUBA Diver +achievement.steel_maker=Stahl +achievement.this_is_new=Das ist neu ... + #Acheviement Desc +achievement.aquarium_maker.desc=Kombiniere Kupferpulver, Zinkpulver und Prismarinkristalle, um Aquarium herzustellen +achievement.angel_of_death.desc=Trage eine vollständige Mithrilrüstung und führe ein Mithrilschwert +achievement.brass_maker.desc=Kombiniere Kupferpulver und Zinkpulver, um Messing herzustellen +achievement.bronze_maker.desc=Kombiniere Kupferpulver und Zinnpulver, um Bronze herzustellen +achievement.blocktastic.desc=Platziere einen Metallblock, der weder Eisen noch Gold ist +achievement.cupronickel_maker.desc=Kombiniere Kupferpulver und Nickelpulver, um Kupfernickel herzustellen +achievement.demon_slayer.desc=Trage eine vollständige Kalteisenrüstung und führe ein Kalteisenschwert +achievement.electrum_maker.desc=Kombiniere Silberpulver und Goldpulver, um Elektron herzustellen +achievement.geologist.desc=Stelle einen Hammer aus einem Metallblock her +achievement.invar_maker.desc=Kombiniere Eisenpulver und Nickelpulver, um Invar herzustellen +achievement.juggernaut.desc=Trage eine vollständige Adamantrüstung +achievement.metallurgy.desc=Stelle ein beliebiges Gemisch her +achievement.mithril_maker.desc=Kombiniere Silverpulver, Kalteisenpulver und Quecksilberpulver, um Mithril herzustellen +achievement.moon_boots.desc=Trage ein Paar Sternenstahlstiefel +achievement.scuba_diver.desc=Trage eine vollständige Aquariumrüstung und tauche im Wasser +achievement.steel_maker.desc=Kombiniere Eisenpulver mit Holzkohlepulver, um Stahl herzustellen +achievement.this_is_new.desc=Schmelze ein neues Metall des Base Metals Mod + +#axts +item.basemetals.adamantine_axe.name=Adamantaxt +item.basemetals.aquarium_axe.name=Aquariumaxt +item.basemetals.antimony_axe.name=Antimonaxt +item.basemetals.bismuth_axe.name=Bismuthaxt +item.basemetals.brass_axe.name=Messingaxt +item.basemetals.bronze_axe.name=Bronzeaxt +item.basemetals.coldiron_axe.name=Kalteisenaxt +item.basemetals.copper_axe.name=Kupferaxt +item.basemetals.cupronickel_axe.name=Kupfernickelaxt +item.basemetals.electrum_axe.name=Elektronaxt +item.basemetals.emerald_axe.name=Smaragdaxt +item.basemetals.invar_axe.name=Invaraxt +item.basemetals.lead_axe.name=Bleiaxt +item.basemetals.mithril_axe.name=Mithrilaxt +item.basemetals.nickel_axe.name=Nickelaxt +item.basemetals.obsidian_axe.name=Obsdidianaxt +item.basemetals.pewter_axe.name=Hartzinnaxt +item.basemetals.platinum_axe.name=Platinaxt +item.basemetals.quartz_axe.name=Quartzaxt +item.basemetals.silver_axe.name=Silberaxt +item.basemetals.starsteel_axe.name=Sternenstahlaxt +item.basemetals.steel_axe.name=Stahlaxt +item.basemetals.tin_axe.name=Zinnaxt +item.basemetals.zinc_axe.name=Zinkaxt + +#swords +item.basemetals.adamantine_sword.name=Adamantschwert +item.basemetals.aquarium_sword.name=Aquariumschwert +item.basemetals.antimony_sword.name=Antimonschwert +item.basemetals.bismuth_sword.name=Bismuthschwert +item.basemetals.brass_sword.name=Messingschwert +item.basemetals.bronze_sword.name=Bronzeschwert +item.basemetals.coldiron_sword.name=Kalteisenschwert +item.basemetals.copper_sword.name=Kupferschwert +item.basemetals.cupronickel_sword.name=Kupfernickelschwert +item.basemetals.electrum_sword.name=Elektronschwert +item.basemetals.emerald_sword.name=Smaragdschwert +item.basemetals.invar_sword.name=Invarschwert +item.basemetals.lead_sword.name=Bleischwert +item.basemetals.mithril_sword.name=Mithrilschwert +item.basemetals.obsidian_sword.name=Obsidianschwert +item.basemetals.nickel_sword.name=Nickelschwert +item.basemetals.quartz_sword.name=Quartzschwert +item.basemetals.pewter_sword.name=Hartzinnschwert +item.basemetals.platinum_sword.name=Platinschwert +item.basemetals.silver_sword.name=Silberschwert +item.basemetals.starsteel_sword.name=Sternenstahlschwert +item.basemetals.steel_sword.name=Stahlschwert +item.basemetals.tin_sword.name=Zinnschwert +item.basemetals.zinc_sword.name=Zinkschwert + +#spitzhackes +item.basemetals.adamantine_pickaxe.name=Adamantspitzhacke +item.basemetals.aquarium_pickaxe.name=Aquariumspitzhacke +item.basemetals.antimony_pickaxe.name=Antimonspitzhacke +item.basemetals.bismuth_pickaxe.name=Bismuthspitzhacke +item.basemetals.brass_pickaxe.name=Messingspitzhacke +item.basemetals.bronze_pickaxe.name=Bronzespitzhacke +item.basemetals.coldiron_pickaxe.name=Kalteisenspitzhacke +item.basemetals.copper_pickaxe.name=Kupferspitzhacke +item.basemetals.cupronickel_pickaxe.name=Kupfernickelspitzhacke +item.basemetals.electrum_pickaxe.name=Elektronspitzhacke +item.basemetals.emerald_pickaxe.name=Smaragdspitzhacke +item.basemetals.invar_pickaxe.name=Invarspitzhacke +item.basemetals.lead_pickaxe.name=Bleispitzhacke +item.basemetals.mithril_pickaxe.name=Mithrilspitzhacke +item.basemetals.nickel_pickaxe.name=Nickelspitzhacke +item.basemetals.obsidian_pickaxe.name=Obsidianspitzhacke +item.basemetals.pewter_pickaxe.name=Hartzinnspitzhacke +item.basemetals.platinum_pickaxe.name=Platinspitzhacke +item.basemetals.quartz_pickaxe.name=Quartzspitzhacke +item.basemetals.silver_pickaxe.name=Silberspitzhacke +item.basemetals.starsteel_pickaxe.name=Sternenstahlspitzhacke +item.basemetals.steel_pickaxe.name=Stahlspitzhacke +item.basemetals.tin_pickaxe.name=Zinnspitzhacke +item.basemetals.zinc_pickaxe.name=Zinkspitzhacke + +#schaufels +item.basemetals.adamantine_shovel.name=Adamantschaufel +item.basemetals.aquarium_shovel.name=Aquariumschaufel +item.basemetals.antimony_shovel.name=Antimonschaufel +item.basemetals.bismuth_shovel.name=Bismuthschaufel +item.basemetals.brass_shovel.name=Messingschaufel +item.basemetals.bronze_shovel.name=Bronzeschaufel +item.basemetals.coldiron_shovel.name=Kalteisenschaufel +item.basemetals.copper_shovel.name=Kupferschaufel +item.basemetals.cupronickel_shovel.name=Kupfernickelschaufel +item.basemetals.electrum_shovel.name=Elektronschaufel +item.basemetals.emerald_shovel.name=Smaragdschaufel +item.basemetals.invar_shovel.name=Invarschaufel +item.basemetals.lead_shovel.name=Bleischaufel +item.basemetals.mithril_shovel.name=Mithrilschaufel +item.basemetals.nickel_shovel.name=Nickelschaufel +item.basemetals.obsidian_shovel.name=Obsidianschaufel +item.basemetals.pewter_shovel.name=Hartzinnschaufel +item.basemetals.platinum_shovel.name=Platinschaufel +item.basemetals.quartz_shovel.name=Quartzschaufel +item.basemetals.silver_shovel.name=Silberschaufel +item.basemetals.starsteel_shovel.name=Sternenstahlschaufel +item.basemetals.steel_shovel.name=Stahlschaufel +item.basemetals.tin_shovel.name=Zinnschaufel +item.basemetals.zinc_shovel.name=Zinkschaufel + +#hackes +item.basemetals.adamantine_hoe.name=Adamanthacke +item.basemetals.aquarium_hoe.name=Aquariumhacke +item.basemetals.antimony_hoe.name=Antimonhacke +item.basemetals.bismuth_hoe.name=Bismuthhacke +item.basemetals.brass_hoe.name=Messinghacke +item.basemetals.bronze_hoe.name=Bronzehacke +item.basemetals.coldiron_hoe.name=Kalteisenhacke +item.basemetals.copper_hoe.name=Kupferhacke +item.basemetals.cupronickel_hoe.name=Kupfernickelhacke +item.basemetals.electrum_hoe.name=Elektronhacke +item.basemetals.emerald_hoe.name=Smaragdhacke +item.basemetals.invar_hoe.name=Invarhacke +item.basemetals.lead_hoe.name=Bleihacke +item.basemetals.mithril_hoe.name=Mithrilhacke +item.basemetals.nickel_hoe.name=Nickelhacke +item.basemetals.obsidian_hoe.name=Obsidianhacke +item.basemetals.pewter_hoe.name=Hartzinnhacke +item.basemetals.platinum_hoe.name=Platinhacke +item.basemetals.quartz_hoe.name=Quartzhacke +item.basemetals.silver_hoe.name=Silberhacke +item.basemetals.starsteel_hoe.name=Sternenstahlhacke +item.basemetals.steel_hoe.name=Stahlhacke +item.basemetals.tin_hoe.name=Zinnhacke +item.basemetals.zinc_hoe.name=Zinkhacke + +#Crackhammers +item.basemetals.adamantine_crackhammer.name=Adamantbruchhammer +item.basemetals.aquarium_crackhammer.name=Aquariumbruchhammer +item.basemetals.antimony_crackhammer.name=Antimonbruchhammer +item.basemetals.bismuth_crackhammer.name=Bismuthbruchhammer +item.basemetals.brass_crackhammer.name=Messingbruchhammer +item.basemetals.bronze_crackhammer.name=Bronzebruchhammer +item.basemetals.coldiron_crackhammer.name=Kalteisenbruchhammer +item.basemetals.copper_crackhammer.name=Kupferbruchhammer +item.basemetals.cupronickel_crackhammer.name=Kupfernickelbruchhammer +item.basemetals.diamond_crackhammer.name=Diamantbruchhammer +item.basemetals.electrum_crackhammer.name=Elektronbruchhammer +item.basemetals.emerald_crackhammer.name=Smaragdbruchhammer +item.basemetals.gold_crackhammer.name=Goldenbruchhammer +item.basemetals.invar_crackhammer.name=Invarbruchhammer +item.basemetals.iron_crackhammer.name=Eisenbruchhammer +item.basemetals.lead_crackhammer.name=Bleibruchhammer +item.basemetals.mithril_crackhammer.name=Mithrilbruchhammer +item.basemetals.obsidian_crackhammer.name=Obsidianbruchhammer +item.basemetals.platinum_crackhammer.name=Platinbruchhammer +item.basemetals.pewter_crackhammer.name=Hartzinnbruchhammer +item.basemetals.quartz_crackhammer.name=Quartzbruchhammer +item.basemetals.nickel_crackhammer.name=Nickelbruchhammer +item.basemetals.silver_crackhammer.name=Silberbruchhammer +item.basemetals.starsteel_crackhammer.name=Sternenstahlbruchhammer +item.basemetals.steel_crackhammer.name=Stahlbruchhammer +item.basemetals.stone_crackhammer.name=Stonebruchhammer +item.basemetals.tin_crackhammer.name=Zinnbruchhammer +item.basemetals.wood_crackhammer.name=Holzbruchhammer +item.basemetals.zinc_crackhammer.name=Zinkbruchhammer + +#schere +item.basemetals.adamantine_shears.name=Adamantschere +item.basemetals.aquarium_shears.name=Aquariumschere +item.basemetals.antimony_shears.name=Antimonschere +item.basemetals.bismuth_shears.name=Bismuthschere +item.basemetals.brass_shears.name=Messingschere +item.basemetals.bronze_shears.name=Bronzeschere +item.basemetals.coldiron_shears.name=Kalteisenschere +item.basemetals.copper_shears.name=Kupferschere +item.basemetals.cupronickel_shears.name=Kupfernickelschere +item.basemetals.diamond_shears.name=Diamantschere +item.basemetals.electrum_shears.name=Elektronschere +item.basemetals.emerald_shears.name=Smaragdschere +item.basemetals.gold_shears.name=Goldschere +item.basemetals.invar_shears.name=Invarschere +item.basemetals.lead_shears.name=Bleischere +item.basemetals.mithril_shears.name=Mithrilschere +item.basemetals.nickel_shears.name=Nickelschere +item.basemetals.obsidian_shears.name=Obsidianschere +item.basemetals.pewter_shears.name=Hartzinnschere +item.basemetals.platinum_shears.name=Platinschere +item.basemetals.quartz_shears.name=Quartzschere +item.basemetals.silver_shears.name=Silberschere +item.basemetals.starsteel_shears.name=Sternenstahlschere +item.basemetals.steel_shears.name=Stahlschere +item.basemetals.tin_shears.name=Zinnschere +item.basemetals.zinc_shears.name=Zinkschere + +#bogen +item.basemetals.adamantine_bow.name=Adamantbogen +item.basemetals.aquarium_bow.name=Aquariumbogen +item.basemetals.antimony_bow.name=Antimonbogen +item.basemetals.bismuth_bow.name=Bismuthbogen +item.basemetals.brass_bow.name=Messingbogen +item.basemetals.bronze_bow.name=Bronzebogen +item.basemetals.coldiron_bow.name=Kalteisenbogen +item.basemetals.copper_bow.name=Kupferbogen +item.basemetals.cupronickel_bow.name=Kupfernickelbogen +item.basemetals.diamond_bow.name=Diamantbogen +item.basemetals.electrum_bow.name=Elektronbogen +item.basemetals.emerald_bow.name=Smaragdbogen +item.basemetals.gold_bow.name=Goldbogen +item.basemetals.invar_bow.name=Invarbogen +item.basemetals.iron_bow.name=Eisenbogen +item.basemetals.lead_bow.name=Bleibogen +item.basemetals.mithril_bow.name=Mithrilbogen +item.basemetals.nickel_bow.name=Nickelbogen +item.basemetals.obsidian_bow.name=Obsidianbogen +item.basemetals.pewter_bow.name=Hartzinnbogen +item.basemetals.platinum_bow.name=Platinbogen +item.basemetals.quartz_bow.name=Quartzbogen +item.basemetals.silver_bow.name=Silberbogen +item.basemetals.starsteel_bow.name=Sternenstahlbogen +item.basemetals.steel_bow.name=Stahlbogen +item.basemetals.tin_bow.name=Zinnbogen +item.basemetals.zinc_bow.name=Zinkbogen + +#armbrust +item.basemetals.adamantine_crossbow.name=Adamantarmbrust +item.basemetals.aquarium_crossbow.name=Aquariumarmbrust +item.basemetals.antimony_crossbow.name=Antimonarmbrust +item.basemetals.bismuth_crossbow.name=Bismutharmbrust +item.basemetals.brass_crossbow.name=Messingarmbrust +item.basemetals.bronze_crossbow.name=Bronzearmbrust +item.basemetals.coldiron_crossbow.name=Kalteisenarmbrust +item.basemetals.copper_crossbow.name=Kupferarmbrust +item.basemetals.cupronickel_crossbow.name=Kupfernickelarmbrust +item.basemetals.diamond_crossbow.name=Diamantarmbrust +item.basemetals.electrum_crossbow.name=Elektronarmbrust +item.basemetals.emerald_crossbow.name=Smaragdarmbrust +item.basemetals.gold_crossbow.name=Goldarmbrust +item.basemetals.invar_crossbow.name=Invararmbrust +item.basemetals.iron_crossbow.name=Eisenarmbrust +item.basemetals.lead_crossbow.name=Bleiarmbrust +item.basemetals.mithril_crossbow.name=Mithrilarmbrust +item.basemetals.nickel_crossbow.name=Nickelarmbrust +item.basemetals.obsidian_crossbow.name=Obsidianarmbrust +item.basemetals.pewter_crossbow.name=Hartzinnarmbrust +item.basemetals.platinum_crossbow.name=Platinarmbrust +item.basemetals.quartz_crossbow.name=Quartzarmbrust +item.basemetals.silver_crossbow.name=Silberarmbrust +item.basemetals.starsteel_crossbow.name=Sternenstahlarmbrust +item.basemetals.steel_crossbow.name=Stahlarmbrust +item.basemetals.tin_crossbow.name=Zinnarmbrust +item.basemetals.zinc_crossbow.name=Zinkarmbrust + +#angels +item.basemetals.adamantine_fishing_rod.name=Adamantangel +item.basemetals.aquarium_fishing_rod.name=Aquariumangel +item.basemetals.antimony_fishing_rod.name=Antimonangel +item.basemetals.bismuth_fishing_rod.name=Bismuthangel +item.basemetals.brass_fishing_rod.name=Messingangel +item.basemetals.bronze_fishing_rod.name=Bronzeangel +item.basemetals.coldiron_fishing_rod.name=Kalteisenangel +item.basemetals.copper_fishing_rod.name=Kupferangel +item.basemetals.cupronickel_fishing_rod.name=Kupfernickelangel +item.basemetals.diamond_fishing_rod.name=Diamantangel +item.basemetals.electrum_fishing_rod.name=Elektronangel +item.basemetals.emerald_fishing_rod.name=Smaragdangel +item.basemetals.gold_fishing_rod.name=Goldangel +item.basemetals.invar_fishing_rod.name=Invarangel +item.basemetals.iron_fishing_rod.name=Eisenangel +item.basemetals.lead_fishing_rod.name=Bleiangel +item.basemetals.mithril_fishing_rod.name=Mithrilangel +item.basemetals.nickel_fishing_rod.name=Nickelangel +item.basemetals.obsidian_fishing_rod.name=Obsidianangel +item.basemetals.pewter_fishing_rod.name=Hartzinnangel +item.basemetals.platinum_fishing_rod.name=Platinangel +item.basemetals.quartz_fishing_rod.name=Quartzangel +item.basemetals.silver_fishing_rod.name=Silberangel +item.basemetals.starsteel_fishing_rod.name=Sternenstahlangel +item.basemetals.steel_fishing_rod.name=Stahlangel +item.basemetals.tin_fishing_rod.name=Zinnangel +item.basemetals.zinc_fishing_rod.name=Zinkangel + +#schilds +item.basemetals.adamantine_shield.name=Adamantschild +item.basemetals.aquarium_shield.name=Aquariumschild +item.basemetals.antimony_shield.name=Antimonschild +item.basemetals.bismuth_shield.name=Bismuthschild +item.basemetals.brass_shield.name=Messingschild +item.basemetals.bronze_shield.name=Bronzeschild +item.basemetals.coldiron_shield.name=Kalteisenschild +item.basemetals.copper_shield.name=Kupferschild +item.basemetals.cupronickel_shield.name=Kupfernickelschild +item.basemetals.diamond_shield.name=Diamantschild +item.basemetals.electrum_shield.name=Elektronschild +item.basemetals.emerald_shield.name=Smaragdschild +item.basemetals.gold_shield.name=Goldschild +item.basemetals.invar_shield.name=Invarschild +item.basemetals.iron_shield.name=Eisenschild +item.basemetals.lead_shield.name=Bleischild +item.basemetals.mithril_shield.name=Mithrilschild +item.basemetals.obsidian_shield.name=Obsidianschild +item.basemetals.nickel_shield.name=Nickelschild +item.basemetals.pewter_shield.name=Hartzinnschild +item.basemetals.platinum_shield.name=Platinschild +item.basemetals.quartz_shield.name=Quartzschild +item.basemetals.silver_shield.name=Silberschild +item.basemetals.starsteel_shield.name=Sternenstahlschild +item.basemetals.steel_shield.name=Stahlschild +item.basemetals.tin_shield.name=Zinnschild +item.basemetals.zinc_shield.name=Zinkschild + +#pfeil +item.basemetals.adamantine_arrow.name=Adamantpfeil +item.basemetals.aquarium_arrow.name=Aquariumpfeil +item.basemetals.antimony_arrow.name=Antimonpfeil +item.basemetals.bismuth_arrow.name=Bismuthpfeil +item.basemetals.brass_arrow.name=Messingpfeil +item.basemetals.bronze_arrow.name=Bronzepfeil +item.basemetals.coldiron_arrow.name=Kalteisenpfeil +item.basemetals.copper_arrow.name=Kupferpfeil +item.basemetals.cupronickel_arrow.name=Kupfernickelpfeil +item.basemetals.diamond_arrow.name=Diamantpfeil +item.basemetals.electrum_arrow.name=Elektronpfeil +item.basemetals.emerald_arrow.name=Smaragdpfeil +item.basemetals.gold_arrow.name=Goldpfeil +item.basemetals.invar_arrow.name=Invarpfeil +item.basemetals.iron_arrow.name=Eisenpfeil +item.basemetals.lead_arrow.name=Bleipfeil +item.basemetals.mithril_arrow.name=Mithrilpfeil +item.basemetals.nickel_arrow.name=Nickelpfeil +item.basemetals.obsidian_arrow.name=Obsidianpfeil +item.basemetals.pewter_arrow.name=Hartzinnpfeil +item.basemetals.platinum_arrow.name=Platinpfeil +item.basemetals.quartz_arrow.name=Quartzpfeil +item.basemetals.silver_arrow.name=Silberpfeil +item.basemetals.starsteel_arrow.name=Sternenstahlpfeil +item.basemetals.steel_arrow.name=Stahlpfeil +item.basemetals.tin_arrow.name=Zinnpfeil +item.basemetals.zinc_arrow.name=Zinkpfeil + +#bolzen +item.basemetals.adamantine_bolt.name=Adamantbolzen +item.basemetals.aquarium_bolt.name=Aquariumbolzen +item.basemetals.antimony_bolt.name=Antimonbolzen +item.basemetals.bismuth_bolt.name=Bismuthbolzen +item.basemetals.brass_bolt.name=Messingbolzen +item.basemetals.bronze_bolt.name=Bronzebolzen +item.basemetals.coldiron_bolt.name=Kalteisenbolzen +item.basemetals.copper_bolt.name=Kupferbolzen +item.basemetals.cupronickel_bolt.name=Kupfernickelbolzen +item.basemetals.diamond_bolt.name=Diamantbolzen +item.basemetals.electrum_bolt.name=Elektronbolzen +item.basemetals.emerald_bolt.name=Smaragdbolzen +item.basemetals.gold_bolt.name=Goldbolzen +item.basemetals.invar_bolt.name=Invarbolzen +item.basemetals.iron_bolt.name=Eisenbolzen +item.basemetals.lead_bolt.name=Bleibolzen +item.basemetals.mithril_bolt.name=Mithrilbolzen +item.basemetals.nickel_bolt.name=Nickelbolzen +item.basemetals.obsidian_bolt.name=Obsidianbolzen +item.basemetals.pewter_bolt.name=Hartzinnbolzen +item.basemetals.platinum_bolt.name=Platinbolzen +item.basemetals.quartz_bolt.name=Quartzbolzen +item.basemetals.silver_bolt.name=Silberbolzen +item.basemetals.starsteel_bolt.name=Sternenstahlbolzen +item.basemetals.steel_bolt.name=Stahlbolzen +item.basemetals.tin_bolt.name=Zinnbolzen +item.basemetals.zinc_bolt.name=Zinkbolzen + +#Armor Sets + #Adamant +item.basemetals.adamantine_boots.name=Adamantstiefel +item.basemetals.adamantine_chestplate.name=Adamantbrustpanzer +item.basemetals.adamantine_helmet.name=Adamanthelm +item.basemetals.adamantine_leggings.name=Adamantbeinpanzer + #Aquarium +item.basemetals.aquarium_boots.name=Aquariumstiefel +item.basemetals.aquarium_chestplate.name=Aquariumbrustpanzer +item.basemetals.aquarium_helmet.name=Aquariumhelm +item.basemetals.aquarium_leggings.name=Aquariumbeinpanzer + #Antimon +item.basemetals.antimony_boots.name=Antimonstiefel +item.basemetals.antimony_chestplate.name=Antimonbrustpanzer +item.basemetals.antimony_helmet.name=Antimonhelm +item.basemetals.antimony_leggings.name=Antimonbeinpanzer + #Bismuth +item.basemetals.bismuth_boots.name=Bismuthstiefel +item.basemetals.bismuth_chestplate.name=Bismuthbrustpanzer +item.basemetals.bismuth_helmet.name=Bismuthhelm +item.basemetals.bismuth_leggings.name=Bismuthbeinpanzer + #Messing +item.basemetals.brass_boots.name=Messingstiefel +item.basemetals.brass_chestplate.name=Messingbrustpanzer +item.basemetals.brass_helmet.name=Messinghelm +item.basemetals.brass_leggings.name=Messingbeinpanzer + #Bronze +item.basemetals.bronze_boots.name=Bronzestiefel +item.basemetals.bronze_chestplate.name=Bronzebrustpanzer +item.basemetals.bronze_helmet.name=Bronzehelm +item.basemetals.bronze_leggings.name=Bronzebeinpanzer + #Kalteisen +item.basemetals.coldiron_boots.name=Kalteisenstiefel +item.basemetals.coldiron_chestplate.name=Kalteisenbrustpanzer +item.basemetals.coldiron_helmet.name=Kalteisenhelm +item.basemetals.coldiron_leggings.name=Kalteisenbeinpanzer + #Kupfer +item.basemetals.copper_boots.name=Kupferstiefel +item.basemetals.copper_chestplate.name=Kupferbrustpanzer +item.basemetals.copper_helmet.name=Kupferhelm +item.basemetals.copper_leggings.name=Kupferbeinpanzer + #Kupfernickel +item.basemetals.cupronickel_boots.name=Kupfernickelstiefel +item.basemetals.cupronickel_chestplate.name=Kupfernickelbrustpanzer +item.basemetals.cupronickel_helmet.name=Kupfernickelhelm +item.basemetals.cupronickel_leggings.name=Kupfernickelbeinpanzer + #Elektron +item.basemetals.electrum_boots.name=Elektronstiefel +item.basemetals.electrum_chestplate.name=Elektronbrustpanzer +item.basemetals.electrum_helmet.name=Elektronhelm +item.basemetals.electrum_leggings.name=Elektronbeinpanzer + #Smaragd +item.basemetals.emerald_boots.name=Smaragdstiefel +item.basemetals.emerald_chestplate.name=Smaragdbrustpanzer +item.basemetals.emerald_helmet.name=Smaragdhelm +item.basemetals.emerald_leggings.name=Smaragdbeinpanzer + #Invar +item.basemetals.invar_boots.name=Invarstiefel +item.basemetals.invar_chestplate.name=Invarbrustpanzer +item.basemetals.invar_helmet.name=Invarhelm +item.basemetals.invar_leggings.name=Invarbeinpanzer + #Blei +item.basemetals.lead_boots.name=Bleistiefel +item.basemetals.lead_chestplate.name=Bleibrustpanzer +item.basemetals.lead_helmet.name=Bleihelm +item.basemetals.lead_leggings.name=Bleibeinpanzer + #Mithril +item.basemetals.mithril_boots.name=Mithrilstiefel +item.basemetals.mithril_chestplate.name=Mithrilbrustpanzer +item.basemetals.mithril_helmet.name=Mithrilhelm +item.basemetals.mithril_leggings.name=Mithrilbeinpanzer + #Nickel +item.basemetals.nickel_boots.name=Nickelstiefel +item.basemetals.nickel_chestplate.name=Nickelbrustpanzer +item.basemetals.nickel_helmet.name=Nickelhelm +item.basemetals.nickel_leggings.name=Nickelbeinpanzer + #Obsidian +item.basemetals.obsidian_boots.name=Obsidianstiefel +item.basemetals.obsidian_chestplate.name=Obsidianbrustpanzer +item.basemetals.obsidian_helmet.name=Obsidianhelm +item.basemetals.obsidian_leggings.name=Obsidianbeinpanzer + #Hartzinn +item.basemetals.pewter_boots.name=Hartzinnstiefel +item.basemetals.pewter_chestplate.name=Hartzinnbrustpanzer +item.basemetals.pewter_helmet.name=Hartzinnhelm +item.basemetals.pewter_leggings.name=Hartzinnbeinpanzer + #Platin +item.basemetals.platinum_boots.name=Platinstiefel +item.basemetals.platinum_chestplate.name=Platinbrustpanzer +item.basemetals.platinum_helmet.name=Platinhelm +item.basemetals.platinum_leggings.name=Platinbeinpanzer + #Quartz +item.basemetals.quartz_boots.name=Quartzstiefel +item.basemetals.quartz_chestplate.name=Quartzbrustpanzer +item.basemetals.quartz_helmet.name=Quartzhelm +item.basemetals.quartz_leggings.name=Quartzbeinpanzer + #Silber +item.basemetals.silver_boots.name=Silberstiefel +item.basemetals.silver_chestplate.name=Silberbrustpanzer +item.basemetals.silver_helmet.name=Silberhelm +item.basemetals.silver_leggings.name=Silberbeinpanzer + #Sternenstahl +item.basemetals.starsteel_boots.name=Sternenstahlstiefel +item.basemetals.starsteel_chestplate.name=Sternenstahlbrustpanzer +item.basemetals.starsteel_helmet.name=Sternenstahlhelm +item.basemetals.starsteel_leggings.name=Sternenstahlbeinpanzer + #Stahl +item.basemetals.steel_boots.name=Stahlstiefel +item.basemetals.steel_chestplate.name=Stahlbrustpanzer +item.basemetals.steel_helmet.name=Stahlhelm +item.basemetals.steel_leggings.name=Stahlbeinpanzer + #Zinn +item.basemetals.tin_boots.name=Zinnstiefel +item.basemetals.tin_chestplate.name=Zinnbrustpanzer +item.basemetals.tin_helmet.name=Zinnhelm +item.basemetals.tin_leggings.name=Zinnbeinpanzer + #Zink +item.basemetals.zinc_boots.name=Zinkstiefel +item.basemetals.zinc_chestplate.name=Zinkbrustpanzer +item.basemetals.zinc_helmet.name=Zinkhelm +item.basemetals.zinc_leggings.name=Zinkbeinpanzer + +#pferderüstung +item.basemetals.adamantine_horsearmor.name=Adamantpferderüstung +item.basemetals.aquarium_horsearmor.name=Aquariumpferderüstung +item.basemetals.antimony_horsearmor.name=Antimonpferderüstung +item.basemetals.bismuth_horsearmor.name=Bismuthpferderüstung +item.basemetals.brass_horsearmor.name=Messingpferderüstung +item.basemetals.bronze_horsearmor.name=Bronzepferderüstung +item.basemetals.coldiron_horsearmor.name=Kalteisenpferderüstung +item.basemetals.copper_horsearmor.name=Kupferpferderüstung +item.basemetals.cupronickel_horsearmor.name=Kupfernickelpferderüstung +item.basemetals.electrum_horsearmor.name=Elektronpferderüstung +item.basemetals.emerald_horsearmor.name=Smaragdpferderüstung +item.basemetals.invar_horsearmor.name=Invarpferderüstung +item.basemetals.lead_horsearmor.name=Bleipferderüstung +item.basemetals.mercury_horsearmor.name=Quecksilberpferderüstung +item.basemetals.mithril_horsearmor.name=Mithrilpferderüstung +item.basemetals.nickel_horsearmor.name=Nickelpferderüstung +item.basemetals.obsidian_horsearmor.name=Obsidianpferderüstung +item.basemetals.pewter_horsearmor.name=Hartzinnpferderüstung +item.basemetals.platinum_horsearmor.name=Platinpferderüstung +item.basemetals.quartz_horsearmor.name=Quartzpferderüstung +item.basemetals.silver_horsearmor.name=Silberpferderüstung +item.basemetals.starsteel_horsearmor.name=Sternenstahlpferderüstung +item.basemetals.steel_horsearmor.name=Stahlpferderüstung +item.basemetals.tin_horsearmor.name=Zinnpferderüstung +item.basemetals.zinc_horsearmor.name=Zinkpferderüstung + +#barren +item.basemetals.adamantine_ingot.name=Adamantbarren +item.basemetals.aquarium_ingot.name=Aquariumbarren +item.basemetals.antimony_ingot.name=Antimonbarren +item.basemetals.bismuth_ingot.name=Bismuthbarren +item.basemetals.brass_ingot.name=Messingbarren +item.basemetals.bronze_ingot.name=Bronzebarren +item.basemetals.coldiron_ingot.name=Kalteisenbarren +item.basemetals.copper_ingot.name=Kupferbarren +item.basemetals.cupronickel_ingot.name=Kupfernickelbarren +item.basemetals.electrum_ingot.name=Elektronbarren +item.basemetals.invar_ingot.name=Invarbarren +item.basemetals.lead_ingot.name=Bleibarren +item.basemetals.mercury_ingot.name=Flüssiges Quecksilber +item.basemetals.mithril_ingot.name=Mithrilbarren +item.basemetals.nickel_ingot.name=Nickelbarren +item.basemetals.obsidian_ingot.name=Obsidianbarren +item.basemetals.pewter_ingot.name=Hartzinnbarren +item.basemetals.platinum_ingot.name=Platinbarren +item.basemetals.redstone_ingot.name=Redstonebarren +item.basemetals.silver_ingot.name=Silberbarren +item.basemetals.starsteel_ingot.name=Sternenstahlbarren +item.basemetals.steel_ingot.name=Stahlbarren +item.basemetals.tin_ingot.name=Zinnbarren +item.basemetals.zinc_ingot.name=Zinkbarren + +#gitter + #Item +item.basemetals.adamantine_bars.name=Adamantgitter +item.basemetals.aquarium_bars.name=Aquariumgitter +item.basemetals.antimony_bars.name=Antimongitter +item.basemetals.bismuth_bars.name=Bismuthgitter +item.basemetals.brass_bars.name=Messinggitter +item.basemetals.bronze_bars.name=Bronzegitter +item.basemetals.coldiron_bars.name=Kalteisengitter +item.basemetals.copper_bars.name=Kupfergitter +item.basemetals.cupronickel_bars.name=Kupfernickelgitter +item.basemetals.diamond_bars.name=Diamantgitter +item.basemetals.electrum_bars.name=Elektrongitter +item.basemetals.emerald_bars.name=Smaragdgitter +item.basemetals.gold_bars.name=Goldgitter +item.basemetals.invar_bars.name=Invargitter +item.basemetals.lead_bars.name=Bleigitter +item.basemetals.mithril_bars.name=Mithrilgitter +item.basemetals.nickel_bars.name=Nickelgitter +item.basemetals.obsidian_bars.name=Obsidiangitter +item.basemetals.pewter_bars.name=Hartzinngitter +item.basemetals.platinum_bars.name=Platingitter +item.basemetals.quartz_bars.name=Quartzgitter +item.basemetals.silver_bars.name=Silbergitter +item.basemetals.starsteel_bars.name=Sternenstahlgitter +item.basemetals.steel_bars.name=Stahlgitter +item.basemetals.tin_bars.name=Zinngitter +item.basemetals.zinc_bars.name=Zinkgitter + #Tile +tile.basemetals.adamantine_bars.name=Adamantgitter +tile.basemetals.aquarium_bars.name=Aquariumgitter +tile.basemetals.antimony_bars.name=Antimongitter +tile.basemetals.bismuth_bars.name=Bismuthgitter +tile.basemetals.brass_bars.name=Messinggitter +tile.basemetals.bronze_bars.name=Bronzegitter +tile.basemetals.coldiron_bars.name=Kalteisengitter +tile.basemetals.copper_bars.name=Kupfergitter +tile.basemetals.cupronickel_bars.name=Kupfernickelgitter +tile.basemetals.diamond_bars.name=Diamantgitter +tile.basemetals.electrum_bars.name=Elektrongitter +tile.basemetals.emerald_bars.name=Smaragdgitter +tile.basemetals.gold_bars.name=Goldgitter +tile.basemetals.invar_bars.name=Invargitter +tile.basemetals.lead_bars.name=Bleigitter +tile.basemetals.mithril_bars.name=Mithrilgitter +tile.basemetals.nickel_bars.name=Nickelgitter +tile.basemetals.obsidian_bars.name=Obsidiangitter +tile.basemetals.pewter_bars.name=Hartzinngitter +tile.basemetals.platinum_bars.name=Platingitter +tile.basemetals.quartz_bars.name=Quartzgitter +tile.basemetals.silver_bars.name=Silbergitter +tile.basemetals.starsteel_bars.name=Sternenstahlgitter +tile.basemetals.steel_bars.name=Stahlgitter +tile.basemetals.tin_bars.name=Zinngitter +tile.basemetals.zinc_bars.name=Zinkgitter + +#nugget +item.basemetals.adamantine_nugget.name=Adamantnugget +item.basemetals.aquarium_nugget.name=Aquariumnugget +item.basemetals.antimony_nugget.name=Antimonnugget +item.basemetals.bismuth_nugget.name=Bismuthnugget +item.basemetals.brass_nugget.name=Messingnugget +item.basemetals.bronze_nugget.name=Bronzenugget +item.basemetals.charcoal_nugget.name=Charcoalnugget +item.basemetals.coal_nugget.name=Coalnugget +item.basemetals.coldiron_nugget.name=Kalteisennugget +item.basemetals.copper_nugget.name=Kupfernugget +item.basemetals.cupronickel_nugget.name=Kupfernickelnugget +item.basemetals.diamond_nugget.name=Diamant Fragment +item.basemetals.electrum_nugget.name=Elektronnugget +item.basemetals.emerald_nugget.name=Smaragd Fragment +item.basemetals.invar_nugget.name=Invarnugget +item.basemetals.iron_nugget.name=Eisennugget +item.basemetals.lead_nugget.name=Bleinugget +item.basemetals.mercury_nugget.name=Kleiner Tropfen flüssiges Quecksilber +item.basemetals.mithril_nugget.name=Mithrilnugget +item.basemetals.nickel_nugget.name=Nickelnugget +item.basemetals.obsidian_nugget.name=Obsidian Fragment +item.basemetals.pewter_nugget.name=Hartzinnnugget +item.basemetals.platinum_nugget.name=Platinnugget +item.basemetals.quartz_nugget.name=Quartz Fragment +item.basemetals.silver_nugget.name=Silbernugget +item.basemetals.starsteel_nugget.name=Sternenstahlnugget +item.basemetals.steel_nugget.name=Stahlnugget +item.basemetals.tin_nugget.name=Zinnnugget +item.basemetals.zinc_nugget.name=Zinknugget + +#Powdered +item.basemetals.adamantine_powder.name=Adamantpulver +item.basemetals.aquarium_powder.name=Aquariumpulver +item.basemetals.antimony_powder.name=Antimonpulver +item.basemetals.bismuth_powder.name=Bismuthpulver +item.basemetals.brass_powder.name=Messingpulver +item.basemetals.bronze_powder.name=Bronzepulver +item.basemetals.carbon_powder.name=Kohlenstoffpulver +item.basemetals.coal_powder.name=Kohlepulver +item.basemetals.charcoal_powder.name=Holzkohlepulver +item.basemetals.coldiron_powder.name=Kalteisenpulver +item.basemetals.copper_powder.name=Kupferpulver +item.basemetals.cupronickel_powder.name=Kupfernickelpulver +item.basemetals.diamond_powder.name=Diamantpulver +item.basemetals.electrum_powder.name=Elektronpulver +item.basemetals.emerald_powder.name=Smaragdpulver +item.basemetals.gold_powder.name=Goldpulver +item.basemetals.invar_powder.name=Invarpulver +item.basemetals.iron_powder.name=Eisenpulver +item.basemetals.lead_powder.name=Bleipulver +item.basemetals.mercury_powder.name=Quecksilberpulver +item.basemetals.mithril_powder.name=Mithrilpulver +item.basemetals.nickel_powder.name=Nickelpulver +item.basemetals.obsidian_powder.name=Obsidianpulver +item.basemetals.pewter_powder.name=Hartzinnpulver +item.basemetals.platinum_powder.name=Platinpulver +item.basemetals.quartz_powder.name=Quartzpulver +item.basemetals.silver_powder.name=Silberpulver +item.basemetals.starsteel_powder.name=Sternenstahlpulver +item.basemetals.steel_powder.name=Stahlpulver +item.basemetals.tin_powder.name=Zinnpulver +item.basemetals.wood_powder.name=Sägemehl +item.basemetals.zinc_powder.name=Zinkpulver + +#Small Powders +item.basemetals.adamantine_smallpowder.name=Kleiner Adamantpulverhaufen +item.basemetals.aquarium_smallpowder.name=Kleiner Aquariumpulverhaufen +item.basemetals.antimony_smallpowder.name=Kleiner Antimonpulverhaufen +item.basemetals.bismuth_smallpowder.name=Kleiner Bismuthpulverhaufen +item.basemetals.brass_smallpowder.name=Kleiner Messingpulverhaufen +item.basemetals.bronze_smallpowder.name=Kleiner Bronzepulverhaufen +item.basemetals.carbon_smallpowder.name=Kleiner Kohlenstoffpulverhaufen +item.basemetals.coal_smallpowder.name=Kleiner Kohlepulverhaufen +item.basemetals.charcoal_smallpowder.name=Kleiner Holzkohlepulverhaufen +item.basemetals.coldiron_smallpowder.name=Kleiner Kalteisenpulverhaufen +item.basemetals.copper_smallpowder.name=Kleiner Kupferpulverhaufen +item.basemetals.cupronickel_smallpowder.name=Kleiner Kupfernickelpulverhaufen +item.basemetals.diamond_smallpowder.name=Kleiner Diamantpulverhaufen +item.basemetals.electrum_smallpowder.name=Kleiner Elektronpulverhaufen +item.basemetals.emerald_smallpowder.name=Kleiner Smaragdpulverhaufen +item.basemetals.gold_smallpowder.name=Kleiner Goldpulverhaufen +item.basemetals.invar_smallpowder.name=Kleiner Invarpulverhaufen +item.basemetals.iron_smallpowder.name=Kleiner Eisenpulverhaufen +item.basemetals.lapis_smallpowder.name=Kleiner Lapispulverhaufen +item.basemetals.lead_smallpowder.name=Kleiner Bleipulverhaufen +item.basemetals.mercury_smallpowder.name=Kleiner Quecksilberpulverhaufen +item.basemetals.mithril_smallpowder.name=Kleiner Mithrilpulverhaufen +item.basemetals.nickel_smallpowder.name=Kleiner Nickelpulverhaufen +item.basemetals.obsidian_smallpowder.name=Kleiner Obsidianpulverhaufen +item.basemetals.pewter_smallpowder.name=Kleiner Hartzinnpulverhaufen +item.basemetals.platinum_smallpowder.name=Kleiner Platinpulverhaufen +item.basemetals.quartz_smallpowder.name=Kleiner Quartzpulverhaufen +item.basemetals.redstone_smallpowder.name=Kleiner Redstonepulverhaufen +item.basemetals.silver_smallpowder.name=Kleiner Silberpulverhaufen +item.basemetals.starsteel_smallpowder.name=Kleiner Sternenstahlpulverhaufen +item.basemetals.steel_smallpowder.name=Kleiner Stahlpulverhaufen +item.basemetals.tin_smallpowder.name=Kleiner Zinnpulverhaufen +item.basemetals.wood_powder.name=Kleiner Sägemehlhaufen +item.basemetals.zinc_smallpowder.name=Kleiner Zinkpulverhaufen + +#Zerkleinertes +item.basemetals.adamantine_crushed.name=Zerkleinertes Adamant +item.basemetals.aquarium_crushed.name=Zerkleinertes Aquarium +item.basemetals.antimony_crushed.name=Zerkleinertes Antimon +item.basemetals.bismuth_crushed.name=Zerkleinertes Bismuth +item.basemetals.brass_crushed.name=Zerkleinertes Messing +item.basemetals.bronze_crushed.name=Zerkleinerte Bronze +item.basemetals.coldiron_crushed.name=Zerkleinertes Kalteisen +item.basemetals.copper_crushed.name=Zerkleinertes Kupfer +item.basemetals.cupronickel_crushed.name=Zerkleinertes Kupfernickel +item.basemetals.electrum_crushed.name=Zerkleinertes Elektron +item.basemetals.gold_crushed.name=Zerkleinertes Gold +item.basemetals.invar_crushed.name=Zerkleinertes Invar +item.basemetals.iron_crushed.name=Zerkleinertes Eisen +item.basemetals.lead_crushed.name=Zerkleinertes Blei +item.basemetals.mithril_crushed.name=Zerkleinertes Mithril +item.basemetals.nickel_crushed.name=Zerkleinertes Nickel +item.basemetals.pewter_crushed.name=Zerkleinertes Hartzinn +item.basemetals.platinum_crushed.name=Zerkleinertes Platin +item.basemetals.silver_crushed.name=Zerkleinertes Silber +item.basemetals.starsteel_crushed.name=Zerkleinerter Sternenstahl +item.basemetals.steel_crushed.name=Zerkleinerter Stahl +item.basemetals.tin_crushed.name=Zerkleinertes Zinn +item.basemetals.zinc_crushed.name=Zerkleinertes Zink + +#Zerkleinertes Purified +item.basemetals.adamantine_crushed_purified.name=Gereinigtes, zerkleinertes Adamant +item.basemetals.aquarium_crushed_purified.name=Gereinigtes, zerkleinertes Aquarium +item.basemetals.antimony_crushed_purified.name=Gereinigtes, zerkleinertes Antimon +item.basemetals.bismuth_crushed_purified.name=Gereinigtes, zerkleinertes Bismuth +item.basemetals.brass_crushed_purified.name=Gereinigtes, zerkleinertes Messing +item.basemetals.bronze_crushed_purified.name=Gereinigte, zerkleinerte Bronze +item.basemetals.coldiron_crushed_purified.name=Gereinigtes, zerkleinertes Kalteisen +item.basemetals.copper_crushed_purified.name=Gereinigtes, zerkleinertes Kupfer +item.basemetals.cupronickel_crushed_purified.name=Gereinigtes, zerkleinertes Kupfernickel +item.basemetals.electrum_crushed_purified.name=Gereinigtes, zerkleinertes Elektron +item.basemetals.gold_crushed_purified.name=Gereinigtes, zerkleinertes Gold +item.basemetals.invar_crushed_purified.name=Gereinigtes, zerkleinertes Invar +item.basemetals.iron_crushed_purified.name=Gereinigtes, zerkleinertes Eisen +item.basemetals.lead_crushed_purified.name=Gereinigtes, zerkleinertes Blei +item.basemetals.mithril_crushed_purified.name=Gereinigtes, zerkleinertes Mithril +item.basemetals.nickel_crushed_purified.name=Gereinigtes, zerkleinertes Nickel +item.basemetals.pewter_crushed_purified.name=Gereinigtes, zerkleinertes Hartzinn +item.basemetals.platinum_crushed_purified.name=Gereinigtes, zerkleinertes Platin +item.basemetals.silver_crushed_purified.name=Gereinigtes, zerkleinertes Silber +item.basemetals.starsteel_crushed_purified.name=Gereinigter, zerkleinerter Sternenstahl +item.basemetals.steel_crushed_purified.name=Gereinigter, zerkleinerter Stahl +item.basemetals.tin_crushed_purified.name=Gereinigtes, zerkleinertes Zinn +item.basemetals.zinc_crushed_purified.name=Gereinigtes, zerkleinertes Zink + +#erzs + #Item +item.basemetals.adamantine_ore.name=Adamanterz +item.basemetals.aquarium_ore.name=Aquariumerz +item.basemetals.antimony_ore.name=Antimonerz +item.basemetals.bismuth_ore.name=Bismutherz +item.basemetals.coldiron_ore.name=Kalteisenerz +item.basemetals.copper_ore.name=Kupfererz +item.basemetals.lead_ore.name=Bleierz +item.basemetals.mercury_ore.name=Quecksilbererz +item.basemetals.nickel_ore.name=Nickelerz +item.basemetals.pewter_ore.name=Hartzinnerz +item.basemetals.platinum_ore.name=Platinerz +item.basemetals.silver_ore.name=Silbererz +item.basemetals.starsteel_ore.name=Sternenstahlerz +item.basemetals.tin_ore.name=Zinnerz +item.basemetals.zinc_ore.name=Zinkerz + #Tile +tile.basemetals.adamantine_ore.name=Adamanterz +tile.basemetals.aquarium_ore.name=Aquariumerz +tile.basemetals.antimony_ore.name=Antimonerz +tile.basemetals.bismuth_ore.name=Bismutherz +tile.basemetals.coldiron_ore.name=Kalteisenerz +tile.basemetals.copper_ore.name=Kupfererz +tile.basemetals.lead_ore.name=Bleierz +tile.basemetals.mercury_ore.name=Quecksilbererz +tile.basemetals.nickel_ore.name=Nickelerz +tile.basemetals.pewter_ore.name=Hartzinnerz +tile.basemetals.platinum_ore.name=Platinerz +tile.basemetals.silver_ore.name=Silbererz +tile.basemetals.starsteel_ore.name=Sternenstahlerz +tile.basemetals.tin_ore.name=Zinnerz +tile.basemetals.zinc_ore.name=Zinkerz + +#gemischs +item.basemetals.aquarium_blend.name=Aquariumgemisch +item.basemetals.brass_blend.name=Messinggemisch +item.basemetals.bronze_blend.name=Bronzegemisch +item.basemetals.cupronickel_blend.name=Kupfernickelgemisch +item.basemetals.electrum_blend.name=Elektrongemisch +item.basemetals.invar_blend.name=Invargemisch +item.basemetals.mithril_blend.name=Mithrilgemisch +item.basemetals.pewter_blend.name=Hartzinngemisch +item.basemetals.steel_blend.name=Stahlgemisch + +#Smallgemischs +item.basemetals.aquarium_smallblend.name=Kleiner Aquariumgemischhaufen +item.basemetals.brass_smallblend.name=Kleiner Messinggemischhaufen +item.basemetals.bronze_smallblend.name=Kleiner Bronzegemischhaufen +item.basemetals.cupronickel_smallblend.name=Kleiner Kupfernickelgemischhaufen +item.basemetals.electrum_smallblend.name=Kleiner Elektrongemischhaufen +item.basemetals.invar_smallblend.name=Kleiner Invargemischhaufen +item.basemetals.mithril_smallblend.name=Kleiner Mithrilgemischhaufen +item.basemetals.pewter_smallblend.name=Kleiner Hartzinngemischhaufen +item.basemetals.steel_smallblend.name=Kleiner Stahlgemischhaufen + +#Block Of... + #Item +item.basemetals.adamantine_block.name=Adamantblock +item.basemetals.aquarium_block.name=Aquariumblock +item.basemetals.antimony_block.name=Antimonblock +item.basemetals.bismuth_block.name=Bismuthblock +item.basemetals.brass_block.name=Messingblock +item.basemetals.bronze_block.name=Bronzeblock +item.basemetals.charcoal_block.name=Charcoalblock +item.basemetals.coldiron_block.name=Kalteisenblock +item.basemetals.copper_block.name=Kupferblock +item.basemetals.platinum_block.name=Platinblock +item.basemetals.nickel_block.name=Nickelblock +item.basemetals.electrum_block.name=Elektronblock +item.basemetals.invar_block.name=Invarblock +item.basemetals.lead_block.name=Bleiblock +item.basemetals.mithril_block.name=Mithrilblock +item.basemetals.nickel_block.name=Nickelblock +item.basemetals.pewter_block.name=Hartzinnblock +item.basemetals.cupronickel_block.name=Kupfernickelblock +item.basemetals.silver_block.name=Silberblock +item.basemetals.starsteel_block.name=Sternenstahlblock +item.basemetals.steel_block.name=Stahlblock +item.basemetals.tin_block.name=Zinnblock +item.basemetals.zinc_block.name=Zinkblock + #Tile +tile.basemetals.adamantine_block.name=Adamantblock +tile.basemetals.aquarium_block.name=Aquariumblock +tile.basemetals.antimony_block.name=Antimonblock +tile.basemetals.bismuth_block.name=Bismuthblock +tile.basemetals.brass_block.name=Messingblock +tile.basemetals.bronze_block.name=Bronzeblock +tile.basemetals.charcoal_block.name=Charcoalblock +tile.basemetals.coldiron_block.name=Kalteisenblock +tile.basemetals.copper_block.name=Kupferblock +tile.basemetals.cupronickel_block.name=Kupfernickelblock +tile.basemetals.electrum_block.name=Elektronblock +tile.basemetals.invar_block.name=Invarblock +tile.basemetals.lead_block.name=Bleiblock +tile.basemetals.mithril_block.name=Mithrilblock +tile.basemetals.nickel_block.name=Nickelblock +tile.basemetals.pewter_block.name=Hartzinnblock +tile.basemetals.platinum_block.name=Platinblock +tile.basemetals.silver_block.name=Silberblock +tile.basemetals.starsteel_block.name=Sternenstahlblock +tile.basemetals.steel_block.name=Stahlblock +tile.basemetals.tin_block.name=Zinnblock +tile.basemetals.zinc_block.name=Zinkblock + +#Fluids + #Fluid +fluid.basemetals.mercury=Flüssiges Quecksilber +fluid.basemetals.adamantine=Geschmolzenes Adamant +fluid.basemetals.antimony=Geschmolzenes Antimon +fluid.basemetals.aquarium=Geschmolzenes Aquarium +fluid.basemetals.bismuth=Geschmolzenes Bismuth +fluid.basemetals.brass=Geschmolzenes Messing +fluid.basemetals.bronze=Geschmolzenes Bronze +fluid.basemetals.coldiron=Geschmolzenes Kalteisen +fluid.basemetals.copper=Geschmolzenes Kupfer +fluid.basemetals.cupronickel=Geschmolzenes Kupfernickel +fluid.basemetals.electrum=Geschmolzenes Elektron +fluid.basemetals.ender=Geschmolzenes Ender +fluid.basemetals.invar=Geschmolzenes Invar +fluid.basemetals.lead=Geschmolzenes Blei +fluid.basemetals.mithril=Geschmolzenes Mithril +fluid.basemetals.nickel=Geschmolzenes Nickel +fluid.basemetals.pewter=Geschmolzenes Hartzinn +fluid.basemetals.platinum=Geschmolzenes Platin +fluid.basemetals.silver=Geschmolzenes Silber +fluid.basemetals.starsteel=Geschmolzenes Sternenstahl +fluid.basemetals.steel=Geschmolzenes Stahl +fluid.basemetals.tin=Geschmolzenes Zinn +fluid.basemetals.zinc=Geschmolzenes Zink + #Fluid.name +fluid.basemetals.mercury.name=Flüssiges Quecksilber +fluid.basemetals.adamantine.name=Geschmolzenes Adamant +fluid.basemetals.antimony.name=Geschmolzenes Antimon +fluid.basemetals.aquarium.name=Geschmolzenes Aquarium +fluid.basemetals.bismuth.name=Geschmolzenes Bismuth +fluid.basemetals.brass.name=Geschmolzenes Messing +fluid.basemetals.bronze.name=Geschmolzenes Bronze +fluid.basemetals.charcoal.name=Liquifacted Charcoal +fluid.basemetals.coal.name=Liquifacted Coal +fluid.basemetals.coldiron.name=Geschmolzenes Kalteisen +fluid.basemetals.copper.name=Geschmolzenes Kupfer +fluid.basemetals.cupronickel.name=Geschmolzenes Kupfernickel +fluid.basemetals.diamond.name=Geschmolzenes Diamant +fluid.basemetals.electrum.name=Geschmolzenes Elektron +fluid.basemetals.electrum.name=Geschmolzenes Smaragd +fluid.basemetals.invar.name=Geschmolzenes Invar +fluid.basemetals.lead.name=Geschmolzenes Blei +fluid.basemetals.mithril.name=Geschmolzenes Mithril +fluid.basemetals.nickel.name=Geschmolzenes Nickel +fluid.basemetals.pewter.name=Geschmolzenes Hartzinn +fluid.basemetals.platinum.name=Geschmolzenes Platin +fluid.basemetals.prismarine.name=Geschmolzenes Prismarin +fluid.basemetals.redstone.name=Geschmolzenes Redstone +fluid.basemetals.silver.name=Geschmolzenes Silber +fluid.basemetals.starsteel.name=Geschmolzenes Sternenstahl +fluid.basemetals.steel.name=Geschmolzenes Stahl +fluid.basemetals.tin.name=Geschmolzenes Zinn +fluid.basemetals.zinc.name=Geschmolzenes Zink + #Tile +tile.basemetals.mercury.name=Flüssiges Quecksilber +tile.basemetals.adamantine.name=Geschmolzenes Adamant +tile.basemetals.antimony.name=Geschmolzenes Antimon +tile.basemetals.aquarium.name=Geschmolzenes Aquarium +tile.basemetals.bismuth.name=Geschmolzenes Bismuth +tile.basemetals.brass.name=Geschmolzenes Messing +tile.basemetals.bronze.name=Geschmolzenes Bronze +tile.basemetals.charcoal.name=Liquifacted Charcoal +tile.basemetals.coal.name=Liquifacted Coal +tile.basemetals.coldiron.name=Geschmolzenes Kalteisen +tile.basemetals.copper.name=Geschmolzenes Kupfer +tile.basemetals.cupronickel.name=Geschmolzenes Kupfernickel +tile.basemetals.diamond.name=Geschmolzenes Diamant +tile.basemetals.electrum.name=Geschmolzenes Elektron +tile.basemetals.emerald.name=Geschmolzenes Smaragd +tile.basemetals.ender.name=Geschmolzenes Ender +tile.basemetals.gold.name=Geschmolzenes Gold +tile.basemetals.invar.name=Geschmolzenes Invar +tile.basemetals.iron.name=Geschmolzenes Eisen +tile.basemetals.lead.name=Geschmolzenes Blei +tile.basemetals.mithril.name=Geschmolzenes Mithril +tile.basemetals.nickel.name=Geschmolzenes Nickel +tile.basemetals.obsidian.name=Geschmolzenes Obsidian +tile.basemetals.pewter.name=Geschmolzenes Hartzinn +tile.basemetals.platinum.name=Geschmolzenes Platin +tile.basemetals.prismarine.name=Geschmolzenes Prismarin +tile.basemetals.redstone.name=Geschmolzenes Redstone +tile.basemetals.silver.name=Geschmolzenes Silber +tile.basemetals.starsteel.name=Geschmolzenes Sternenstahl +tile.basemetals.steel.name=Geschmolzenes Stahl +tile.basemetals.tin.name=Geschmolzenes Zinn +tile.basemetals.zinc.name=Geschmolzenes Zink + #Bucket +item.bucket.mercury=Eimer mit Quecksilber +item.bucket.adamantine=Eimer mit geschmolzenem Adamant +item.bucket.antimony=Eimer mit geschmolzenem Antimon +item.bucket.aquarium=Eimer mit geschmolzenem Aquarium +item.bucket.bismuth=Eimer mit geschmolzenem Bismuth +item.bucket.brass=Eimer mit geschmolzenem Messing +item.bucket.bronze=Eimer mit geschmolzenem Bronze +item.bucket.charcoal=Eimer mit verflüssigter Holzkohle +item.bucket.coal=Eimer mit verflüssigter Kohle +item.bucket.coldiron=Eimer mit geschmolzenem Kalteisen +item.bucket.copper=Eimer mit geschmolzenem Kupfer +item.bucket.cupronickel=Eimer mit geschmolzenem Kupfernickel +item.bucket.diamond=Eimer mit geschmolzenem Diamant +item.bucket.electrum=Eimer mit geschmolzenem Elektron +item.bucket.emerald=Eimer mit geschmolzenem Smaragd +item.bucket.ender=Eimer mit geschmolzenem Ender +item.bucket.invar=Eimer mit geschmolzenem Invar +item.bucket.lead=Eimer mit geschmolzenem Blei +item.bucket.mithril=Eimer mit geschmolzenem Mithril +item.bucket.nickel=Eimer mit geschmolzenem Nickel +item.bucket.pewter=Eimer mit geschmolzenem Hartzinn +item.bucket.platinum=Eimer mit geschmolzenem Platin +item.bucket.prismarine=Eimer mit geschmolzenem Prismarin +item.bucket.redstone=Eimer mit geschmolzenem Redstone +item.bucket.silver=Eimer mit geschmolzenem Silber +item.bucket.starsteel=Eimer mit geschmolzenem Sternenstahl +item.bucket.steel=Eimer mit geschmolzenem Stahl +item.bucket.tin=Eimer mit geschmolzenem Zinn +item.bucket.zinc=Eimer mit geschmolzenem Zink + Material +material.mercury.name=Quecksilber +material.adamantine.name=Adamant +material.antimony.name=Antimon +material.aquarium.name=Aquarium +material.bismuth.name=Bismuth +material.brass.name=Messing +material.bronze.name=Bronze +material.coldiron.name=Kalteisen +material.copper.name=Kupfer +material.cupronickel.name=Kupfernickel +material.electrum.name=Elektron +material.invar.name=Invar +material.lead.name=Blei +material.mithril.name=Mithril +material.nickel.name=Nickel +material.pewter.name=Hartzinn +material.platinum.name=Platin +material.silver.name=Silber +material.starsteel.name=Sternenstahl +material.steel.name=Stahl +material.tin.name=Zinn +material.zinc.name=Zink + +#türs + #Item +item.basemetals.adamantine_door.name=Adamanttür +item.basemetals.aquarium_door.name=Aquariumtür +item.basemetals.antimony_door.name=Antimontür +item.basemetals.bismuth_door.name=Bismuthtür +item.basemetals.brass_door.name=Messingtür +item.basemetals.bronze_door.name=Bronzetür +item.basemetals.coldiron_door.name=Kalteisentür +item.basemetals.copper_door.name=Kupfertür +item.basemetals.cupronickel_door.name=Kupfernickeltür +item.basemetals.diamond_door.name=Diamanttür +item.basemetals.electrum_door.name=Elektrontür +item.basemetals.emerald_door.name=Smaragdtür +item.basemetals.gold_door.name=Goldtür +item.basemetals.invar_door.name=Invartür +item.basemetals.lead_door.name=Bleitür +item.basemetals.mithril_door.name=Mithriltür +item.basemetals.nickel_door.name=Nickeltür +item.basemetals.obsidian_door.name=Obsidiantür +item.basemetals.pewter_door.name=Hartzinntür +item.basemetals.platinum_door.name=Platintür +item.basemetals.quartz_door.name=Quartztür +item.basemetals.silver_door.name=Silbertür +item.basemetals.starsteel_door.name=Sternenstahltür +item.basemetals.steel_door.name=Stahltür +item.basemetals.tin_door.name=Zinntür +item.basemetals.zinc_door.name=Zinktür + #Tile +tile.basemetals.adamantine_door.name=Adamanttür +tile.basemetals.aquarium_door.name=Aquariumtür +tile.basemetals.antimony_door.name=Antimontür +tile.basemetals.bismuth_door.name=Bismuthtür +tile.basemetals.brass_door.name=Messingtür +tile.basemetals.bronze_door.name=Bronzetür +tile.basemetals.coldiron_door.name=Kalteisentür +tile.basemetals.copper_door.name=Kupfertür +tile.basemetals.cupronickel_door.name=Kupfernickeltür +tile.basemetals.diamond_door.name=Diamanttür +tile.basemetals.electrum_door.name=Elektrontür +tile.basemetals.emerald_door.name=Smaragdtür +tile.basemetals.gold_door.name=Goldtür +tile.basemetals.invar_door.name=Invartür +tile.basemetals.lead_door.name=Bleitür +tile.basemetals.mithril_door.name=Mithriltür +tile.basemetals.nickel_door.name=Nickeltür +tile.basemetals.obsidian_door.name=Obsidiantür +tile.basemetals.pewter_door.name=Hartzinntür +tile.basemetals.platinum_door.name=Platintür +tile.basemetals.quartz_door.name=Quartztür +tile.basemetals.silver_door.name=Silbertür +tile.basemetals.starsteel_door.name=Sternenstahltür +tile.basemetals.steel_door.name=Stahltür +tile.basemetals.tin_door.name=Zinntür +tile.basemetals.zinc_door.name=Zinktür + +#falltürs + #Tiles +tile.basemetals.adamantine_trapdoor.name=Adamantfalltür +tile.basemetals.aquarium_trapdoor.name=Aquariumfalltür +tile.basemetals.antimony_trapdoor.name=Antimonfalltür +tile.basemetals.bismuth_trapdoor.name=Bismuthfalltür +tile.basemetals.brass_trapdoor.name=Messingfalltür +tile.basemetals.bronze_trapdoor.name=Bronzefalltür +tile.basemetals.coldiron_trapdoor.name=Kalteisenfalltür +tile.basemetals.copper_trapdoor.name=Kupferfalltür +tile.basemetals.cupronickel_trapdoor.name=Kupfernickelfalltür +tile.basemetals.diamond_trapdoor.name=Diamantfalltür +tile.basemetals.electrum_trapdoor.name=Elektronfalltür +tile.basemetals.emerald_trapdoor.name=Smaragdfalltür +tile.basemetals.gold_trapdoor.name=Goldfalltür +tile.basemetals.invar_trapdoor.name=Invarfalltür +tile.basemetals.lead_trapdoor.name=Bleifalltür +tile.basemetals.mithril_trapdoor.name=Mithrilfalltür +tile.basemetals.nickel_trapdoor.name=Nickelfalltür +tile.basemetals.obsidian_trapdoor.name=Obsidianfalltür +tile.basemetals.pewter_trapdoor.name=Hartzinnfalltür +tile.basemetals.platinum_trapdoor.name=Platinfalltür +tile.basemetals.quartz_trapdoor.name=Quartzfalltür +tile.basemetals.silver_trapdoor.name=Silberfalltür +tile.basemetals.starsteel_trapdoor.name=Sternenstahlfalltür +tile.basemetals.steel_trapdoor.name=Stahlfalltür +tile.basemetals.tin_trapdoor.name=Zinnfalltür +tile.basemetals.zinc_trapdoor.name=Zinkfalltür + #Items +item.basemetals.adamantine_trapdoor.name=Adamantfalltür +item.basemetals.aquarium_trapdoor.name=Aquariumfalltür +item.basemetals.antimony_trapdoor.name=Antimonfalltür +item.basemetals.bismuth_trapdoor.name=Bismuthfalltür +item.basemetals.brass_trapdoor.name=Messingfalltür +item.basemetals.bronze_trapdoor.name=Bronzefalltür +item.basemetals.coldiron_trapdoor.name=Kalteisenfalltür +item.basemetals.copper_trapdoor.name=Kupferfalltür +item.basemetals.cupronickel_trapdoor.name=Kupfernickelfalltür +item.basemetals.diamond_trapdoor.name=Diamantfalltür +item.basemetals.electrum_trapdoor.name=Elektronfalltür +item.basemetals.emerald_trapdoor.name=Smaragdfalltür +item.basemetals.gold_trapdoor.name=Goldfalltür +item.basemetals.invar_trapdoor.name=Invarfalltür +item.basemetals.lead_trapdoor.name=Bleifalltür +item.basemetals.mithril_trapdoor.name=Mithrilfalltür +item.basemetals.nickel_trapdoor.name=Nickelfalltür +item.basemetals.obsidian_trapdoor.name=Obsidianfalltür +item.basemetals.pewter_trapdoor.name=Hartzinnfalltür +item.basemetals.platinum_trapdoor.name=Platinfalltür +item.basemetals.quartz_trapdoor.name=Quartzfalltür +item.basemetals.silver_trapdoor.name=Silberfalltür +item.basemetals.starsteel_trapdoor.name=Sternenstahlfalltür +item.basemetals.steel_trapdoor.name=Stahlfalltür +item.basemetals.tin_trapdoor.name=Zinnfalltür + +#zahnrads +item.basemetals.adamantine_gear.name=Adamantzahnrad +item.basemetals.aquarium_gear.name=Aquariumzahnrad +item.basemetals.antimony_gear.name=Antimonzahnrad +item.basemetals.bismuth_gear.name=Bismuthzahnrad +item.basemetals.brass_gear.name=Messingzahnrad +item.basemetals.bronze_gear.name=Bronzezahnrad +item.basemetals.coldiron_gear.name=Kalteisenzahnrad +item.basemetals.copper_gear.name=Kupferzahnrad +item.basemetals.cupronickel_gear.name=Kupfernickelzahnrad +item.basemetals.diamond_gear.name=Diamantzahnrad +item.basemetals.electrum_gear.name=Elektronzahnrad +item.basemetals.emerald_gear.name=Smaragdzahnrad +item.basemetals.gold_gear.name=Goldzahnrad +item.basemetals.invar_gear.name=Invarzahnrad +item.basemetals.iron_gear.name=Eisenzahnrad +item.basemetals.lead_gear.name=Bleizahnrad +item.basemetals.mithril_gear.name=Mithrilzahnrad +item.basemetals.nickel_gear.name=Nickelzahnrad +item.basemetals.obsidian_gear.name=Obsidianzahnrad +item.basemetals.pewter_gear.name=Hartzinnzahnrad +item.basemetals.platinum_gear.name=Platinzahnrad +item.basemetals.quartz_gear.name=Quartzzahnrad +item.basemetals.silver_gear.name=Silberzahnrad +item.basemetals.starsteel_gear.name=Sternenstahlzahnrad +item.basemetals.steel_gear.name=Stahlzahnrad +item.basemetals.stone_gear.name=Stonezahnrad +item.basemetals.tin_gear.name=Zinnzahnrad +item.basemetals.wood_gear.name=Holzzahnrad +item.basemetals.zinc_gear.name=Zinkzahnrad + +#stanges +item.basemetals.adamantine_rod.name=Adamantstange +item.basemetals.aquarium_rod.name=Aquariumstange +item.basemetals.antimony_rod.name=Antimonstange +item.basemetals.bismuth_rod.name=Bismuthstange +item.basemetals.brass_rod.name=Messingstange +item.basemetals.bronze_rod.name=Bronzestange +item.basemetals.coldiron_rod.name=Kalteisenstange +item.basemetals.copper_rod.name=Kupferstange +item.basemetals.cupronickel_rod.name=Kupfernickelstange +item.basemetals.diamond_rod.name=Diamantstange +item.basemetals.electrum_rod.name=Elektronstange +item.basemetals.emerald_rod.name=Smaragdstange +item.basemetals.gold_rod.name=Goldstange +item.basemetals.invar_rod.name=Invarstange +item.basemetals.iron_rod.name=Eisenstange +item.basemetals.lead_rod.name=Bleistange +item.basemetals.mithril_rod.name=Mithrilstange +item.basemetals.nickel_rod.name=Nickelstange +item.basemetals.obsidian_rod.name=Obsidianstange +item.basemetals.pewter_rod.name=Hartzinnstange +item.basemetals.platinum_rod.name=Platinstange +item.basemetals.quartz_rod.name=Quartzstange +item.basemetals.silver_rod.name=Silberstange +item.basemetals.starsteel_rod.name=Sternenstahlstange +item.basemetals.steel_rod.name=Stahlstange +item.basemetals.stone_rod.name=Stonestange +item.basemetals.tin_rod.name=Zinnstange +item.basemetals.zinc_rod.name=Zinkstange + +#blechs + #Item +item.basemetals.adamantine_plate.name=Verdichtetes Adamantblech +item.basemetals.aquarium_plate.name=Verdichtetes Aquariumblech +item.basemetals.antimony_plate.name=Verdichtetes Antimonblech +item.basemetals.bismuth_plate.name=Verdichtetes Bismuthblech +item.basemetals.brass_plate.name=Verdichtetes Messingblech +item.basemetals.bronze_plate.name=Verdichtetes Bronzeblech +item.basemetals.coldiron_plate.name=Verdichtetes Kalteisenblech +item.basemetals.copper_plate.name=Verdichtetes Kupferblech +item.basemetals.cupronickel_plate.name=Verdichtetes Kupfernickelblech +item.basemetals.electrum_plate.name=Verdichtetes Elektronblech +item.basemetals.gold_plate.name=Verdichtetes Goldblech +item.basemetals.invar_plate.name=Verdichtetes Invarblech +item.basemetals.lead_plate.name=Verdichtetes Bleiblech +item.basemetals.mithril_plate.name=Verdichtetes Mithrilblech +item.basemetals.nickel_plate.name=Verdichtetes Nickelblech +item.basemetals.pewter_plate.name=Verdichtetes Hartzinnblech +item.basemetals.platinum_plate.name=Verdichtetes Platinblech +item.basemetals.silver_plate.name=Verdichtetes Silberblech +item.basemetals.starsteel_plate.name=Verdichtetes Sternenstahlblech +item.basemetals.steel_plate.name=Verdichtetes Stahlblech +item.basemetals.tin_plate.name=Verdichtetes Zinnblech +item.basemetals.zinc_plate.name=Verdichtetes Zinkblech +item.basemetals.iron_plate.name=Verdichtetes Eisenblech +item.basemetals.gold_plate.name=Verdichtetes Goldblech + #Tile +tile.basemetals.adamantine_plate.name=Verdichtetes Adamantblech +tile.basemetals.aquarium_plate.name=Verdichtetes Aquariumblech +tile.basemetals.antimony_plate.name=Verdichtetes Antimonblech +tile.basemetals.bismuth_plate.name=Verdichtetes Bismuthblech +tile.basemetals.brass_plate.name=Verdichtetes Messingblech +tile.basemetals.bronze_plate.name=Verdichtetes Bronzeblech +tile.basemetals.coldiron_plate.name=Verdichtetes Kalteisenblech +tile.basemetals.copper_plate.name=Verdichtetes Kupferblech +tile.basemetals.cupronickel_plate.name=Verdichtetes Kupfernickelblech +tile.basemetals.electrum_plate.name=Verdichtetes Elektronblech +tile.basemetals.gold_plate.name=Verdichtetes Goldblech +tile.basemetals.invar_plate.name=Verdichtetes Invarblech +tile.basemetals.lead_plate.name=Verdichtetes Bleiblech +tile.basemetals.mithril_plate.name=Verdichtetes Mithrilblech +tile.basemetals.nickel_plate.name=Verdichtetes Nickelblech +tile.basemetals.pewter_plate.name=Verdichtetes Hartzinnblech +tile.basemetals.platinum_plate.name=Verdichtetes Platinblech +tile.basemetals.silver_plate.name=Verdichtetes Silberblech +tile.basemetals.starsteel_plate.name=Verdichtetes Sternenstahlblech +tile.basemetals.steel_plate.name=Verdichtetes Stahlblech +tile.basemetals.tin_plate.name=Verdichtetes Zinnblech +tile.basemetals.zinc_plate.name=Verdichtetes Zinkblech +tile.basemetals.iron_plate.name=Verdichtetes Eisenblech +tile.basemetals.gold_plate.name=Verdichtetes Goldblech + +#Player Detectors (Pressureblechs) + #Items +item.basemetals.human_detector.name=Sicherheits-Druckplatte + #Tiles +tile.basemetals.human_detector.name=Sicherheits-Druckplatte + +#schalter + #Item +item.basemetals.adamantine_button.name=Adamantschalter +item.basemetals.aquarium_button.name=Aquariumschalter +item.basemetals.antimony_button.name=Antimonschalter +item.basemetals.bismuth_button.name=Bismuthschalter +item.basemetals.brass_button.name=Messingschalter +item.basemetals.bronze_button.name=Bronzeschalter +item.basemetals.coldiron_button.name=Kalteisenschalter +item.basemetals.copper_button.name=Kupferschalter +item.basemetals.cupronickel_button.name=Kupfernickelschalter +item.basemetals.diamond_button.name=Diamantschalter +item.basemetals.electrum_button.name=Elektronschalter +item.basemetals.emerald_button.name=Smaragdschalter +item.basemetals.gold_button.name=Goldschalter +item.basemetals.invar_button.name=Invarschalter +item.basemetals.lead_button.name=Bleischalter +item.basemetals.mithril_button.name=Mithrilschalter +item.basemetals.nickel_button.name=Nickelschalter +item.basemetals.obsidian_button.name=Obsidianschalter +item.basemetals.pewter_button.name=Hartzinnschalter +item.basemetals.platinum_button.name=Platinschalter +item.basemetals.quartz_button.name=Quartzschalter +item.basemetals.silver_button.name=Silberschalter +item.basemetals.starsteel_button.name=Sternenstahlschalter +item.basemetals.steel_button.name=Stahlschalter +item.basemetals.tin_button.name=Zinnschalter +item.basemetals.zinc_button.name=Zinkschalter +item.basemetals.iron_button.name=Eisenschalter +item.basemetals.gold_button.name=Goldschalter + #Tile +tile.basemetals.adamantine_button.name=Adamantschalter +tile.basemetals.aquarium_button.name=Aquariumschalter +tile.basemetals.antimony_button.name=Antimonschalter +tile.basemetals.bismuth_button.name=Bismuthschalter +tile.basemetals.brass_button.name=Messingschalter +tile.basemetals.bronze_button.name=Bronzeschalter +tile.basemetals.coldiron_button.name=Kalteisenschalter +tile.basemetals.copper_button.name=Kupferschalter +tile.basemetals.cupronickel_button.name=Kupfernickelschalter +tile.basemetals.diamond_button.name=Diamantschalter +tile.basemetals.electrum_button.name=Elektronschalter +tile.basemetals.emerald_button.name=Smaragdschalter +tile.basemetals.gold_button.name=Goldschalter +tile.basemetals.invar_button.name=Invarschalter +tile.basemetals.lead_button.name=Bleischalter +tile.basemetals.mithril_button.name=Mithrilschalter +tile.basemetals.nickel_button.name=Nickelschalter +tile.basemetals.obsidian_button.name=Obsidianschalter +tile.basemetals.pewter_button.name=Hartzinnschalter +tile.basemetals.platinum_button.name=Platinschalter +tile.basemetals.quartz_button.name=Quartzschalter +tile.basemetals.silver_button.name=Silberschalter +tile.basemetals.starsteel_button.name=Sternenstahlschalter +tile.basemetals.steel_button.name=Stahlschalter +tile.basemetals.tin_button.name=Zinnschalter +tile.basemetals.zinc_button.name=Zinkschalter +tile.basemetals.iron_button.name=Eisenschalter +tile.basemetals.gold_button.name=Goldschalter + +Pressureblech + #Item +item.basemetals.adamantine_pressure_plate.name=Adamantdruckplatte +item.basemetals.aquarium_pressure_plate.name=Aquariumdruckplatte +item.basemetals.antimony_pressure_plate.name=Antimondruckplatte +item.basemetals.bismuth_pressure_plate.name=Bismuthdruckplatte +item.basemetals.brass_pressure_plate.name=Messingdruckplatte +item.basemetals.bronze_pressure_plate.name=Bronzedruckplatte +item.basemetals.coldiron_pressure_plate.name=Kalteisendruckplatte +item.basemetals.copper_pressure_plate.name=Kupferdruckplatte +item.basemetals.cupronickel_pressure_plate.name=Kupfernickeldruckplatte +item.basemetals.diamond_pressure_plate.name=Diamantdruckplatte +item.basemetals.electrum_pressure_plate.name=Elektrondruckplatte +item.basemetals.emerald_pressure_plate.name=Smaragddruckplatte +item.basemetals.invar_pressure_plate.name=Invardruckplatte +item.basemetals.lead_pressure_plate.name=Bleidruckplatte +item.basemetals.mithril_pressure_plate.name=Mithrildruckplatte +item.basemetals.nickel_pressure_plate.name=Nickeldruckplatte +item.basemetals.obsidian_pressure_plate.name=Obsidiandruckplatte +item.basemetals.pewter_pressure_plate.name=Hartzinndruckplatte +item.basemetals.platinum_pressure_plate.name=Platindruckplatte +item.basemetals.quartz_pressure_plate.name=Quartzdruckplatte +item.basemetals.silver_pressure_plate.name=Silberdruckplatte +item.basemetals.starsteel_pressure_plate.name=Sternenstahldruckplatte +item.basemetals.steel_pressure_plate.name=Stahldruckplatte +item.basemetals.tin_pressure_plate.name=Zinndruckplatte +item.basemetals.zinc_pressure_plate.name=Zinkdruckplatte +item.basemetals.iron_pressure_plate.name=Eisendruckplatte +item.basemetals.gold_pressure_plate.name=Golddruckplatte + #Tile +tile.basemetals.adamantine_pressure_plate.name=Adamantdruckplatte +tile.basemetals.aquarium_pressure_plate.name=Aquariumdruckplatte +tile.basemetals.antimony_pressure_plate.name=Antimondruckplatte +tile.basemetals.bismuth_pressure_plate.name=Bismuthdruckplatte +tile.basemetals.brass_pressure_plate.name=Messingdruckplatte +tile.basemetals.bronze_pressure_plate.name=Bronzedruckplatte +tile.basemetals.coldiron_pressure_plate.name=Kalteisendruckplatte +tile.basemetals.copper_pressure_plate.name=Kupferdruckplatte +tile.basemetals.cupronickel_pressure_plate.name=Kupfernickeldruckplatte +tile.basemetals.diamond_pressure_plate.name=Diamantdruckplatte +tile.basemetals.electrum_pressure_plate.name=Elektrondruckplatte +tile.basemetals.emerald_pressure_plate.name=Smaragddruckplatte +tile.basemetals.invar_pressure_plate.name=Invardruckplatte +tile.basemetals.lead_pressure_plate.name=Bleidruckplatte +tile.basemetals.mithril_pressure_plate.name=Mithrildruckplatte +tile.basemetals.nickel_pressure_plate.name=Nickeldruckplatte +tile.basemetals.obsidian_pressure_plate.name=Obsidiandruckplatte +tile.basemetals.pewter_pressure_plate.name=Hartzinndruckplatte +tile.basemetals.platinum_pressure_plate.name=Platindruckplatte +tile.basemetals.quartz_pressure_plate.name=Quartzdruckplatte +tile.basemetals.silver_pressure_plate.name=Silberdruckplatte +tile.basemetals.starsteel_pressure_plate.name=Sternenstahldruckplatte +tile.basemetals.steel_pressure_plate.name=Stahldruckplatte +tile.basemetals.tin_pressure_plate.name=Zinndruckplatte +tile.basemetals.zinc_pressure_plate.name=Zinkdruckplatte +tile.basemetals.iron_pressure_plate.name=Eisendruckplatte +tile.basemetals.gold_pressure_plate.name=Golddruckplatte + +#Crystal +item.basemetals.adamantine_crystal.name=Adamantkristall +item.basemetals.aquarium_crystal.name=Aquariumkristall +item.basemetals.antimony_crystal.name= Antimonkristall +item.basemetals.bismuth_crystal.name= Bismuthkristall +item.basemetals.brass_crystal.name= Messingkristall +item.basemetals.bronze_crystal.name= Bronzekristall +item.basemetals.coldiron_crystal.name= Kalteisenkristall +item.basemetals.copper_crystal.name= Kupferkristall +item.basemetals.cupronickel_crystal.name= Kupfernickelkristall +item.basemetals.electrum_crystal.name= Elektronkristall +item.basemetals.invar_crystal.name= Invarkristall +item.basemetals.lead_crystal.name= Bleikristall +item.basemetals.mithril_crystal.name= Mithrilkristall +item.basemetals.nickel_crystal.name= Nickelkristall +item.basemetals.pewter_crystal.name= Hartzinnkristall +item.basemetals.platinum_crystal.name= Platinkristall +item.basemetals.silver_crystal.name= Silberkristall +item.basemetals.starsteel_crystal.name= Sternenstahlkristall +item.basemetals.steel_crystal.name= Stahlkristall +item.basemetals.tin_crystal.name= Zinnkristall +item.basemetals.zinc_crystal.name=Zinkkristall + +#Clump +item.basemetals.adamantine_clump.name= Adamantklumpen +item.basemetals.aquarium_clump.name= Aquariumklumpen +item.basemetals.antimony_clump.name= Antimonklumpen +item.basemetals.bismuth_clump.name= Bismuthklumpen +item.basemetals.brass_clump.name= Messingklumpen +item.basemetals.bronze_clump.name= Bronzeklumpen +item.basemetals.coldiron_clump.name= Kalteisenklumpen +item.basemetals.copper_clump.name= Kupferklumpen +item.basemetals.cupronickel_clump.name= Kupfernickelklumpen +item.basemetals.electrum_clump.name= Elektronklumpen +item.basemetals.invar_clump.name= Invarklumpen +item.basemetals.lead_clump.name= Bleiklumpen +item.basemetals.mithril_clump.name= Mithrilklumpen +item.basemetals.nickel_clump.name= Nickelklumpen +item.basemetals.pewter_clump.name= Hartzinnklumpen +item.basemetals.platinum_clump.name= Platinklumpen +item.basemetals.silver_clump.name= Silberklumpen +item.basemetals.starsteel_clump.name= Sternenstahlklumpen +item.basemetals.steel_clump.name= Stahlklumpen +item.basemetals.tin_clump.name= Zinnklumpen +item.basemetals.zinc_clump.name= Zinkklumpen + +#Shard +item.basemetals.adamantine_shard.name= Adamantsplitter +item.basemetals.aquarium_shard.name= Aquariumsplitter +item.basemetals.antimony_shard.name= Antimonsplitter +item.basemetals.bismuth_shard.name= Bismuthsplitter +item.basemetals.brass_shard.name= Messingsplitter +item.basemetals.bronze_shard.name= Bronzesplitter +item.basemetals.coldiron_shard.name= Kalteisensplitter +item.basemetals.copper_shard.name= Kupfersplitter +item.basemetals.cupronickel_shard.name= Kupfernickelsplitter +item.basemetals.electrum_shard.name= Elektronsplitter +item.basemetals.invar_shard.name= Invarsplitter +item.basemetals.lead_shard.name= Bleisplitter +item.basemetals.mithril_shard.name= Mithrilsplitter +item.basemetals.nickel_shard.name= Nickelsplitter +item.basemetals.pewter_shard.name= Hartzinnsplitter +item.basemetals.platinum_shard.name= Platinsplitter +item.basemetals.silver_shard.name= Silbersplitter +item.basemetals.starsteel_shard.name= Sternenstahlsplitter +item.basemetals.steel_shard.name= Stahlsplitter +item.basemetals.tin_shard.name= Zinnsplitter +item.basemetals.zinc_shard.name= Zinksplitter + +#Verunreinigtes +item.basemetals.adamantine_powder_dirty.name=Verunreinigtes Adamantpulver +item.basemetals.aquarium_powder_dirty.name=Verunreinigtes Aquariumpulver +item.basemetals.antimony_powder_dirty.name=Verunreinigtes Antimonpulver +item.basemetals.bismuth_powder_dirty.name=Verunreinigtes Bismuthpulver +item.basemetals.brass_powder_dirty.name=Verunreinigtes Messingpulver +item.basemetals.bronze_powder_dirty.name=Verunreinigtes Bronzepulver +item.basemetals.coldiron_powder_dirty.name=Verunreinigtes Kalteisenpulver +item.basemetals.copper_powder_dirty.name=Verunreinigtes Kupferpulver +item.basemetals.cupronickel_powder_dirty.name=Verunreinigtes Kupfernickelpulver +item.basemetals.electrum_powder_dirty.name=Verunreinigtes Elektronpulver +item.basemetals.gold_powder_dirty.name=Verunreinigtes Goldpulver +item.basemetals.invar_powder_dirty.name=Verunreinigtes Invarpulver +item.basemetals.iron_powder_dirty.name=Verunreinigtes Eisenpulver +item.basemetals.lead_powder_dirty.name=Verunreinigtes Bleipulver +item.basemetals.mithril_powder_dirty.name=Verunreinigtes Mithrilpulver +item.basemetals.nickel_powder_dirty.name=Verunreinigtes Nickelpulver +item.basemetals.pewter_powder_dirty.name=Verunreinigtes Hartzinnpulver +item.basemetals.platinum_powder_dirty.name=Verunreinigtes Platinpulver +item.basemetals.silver_powder_dirty.name=Verunreinigtes Silberpulver +item.basemetals.starsteel_powder_dirty.name=Verunreinigtes Sternenstahlpulver +item.basemetals.steel_powder_dirty.name=Verunreinigtes Stahlpulver +item.basemetals.tin_powder_dirty.name=Verunreinigtes Zinnpulver +item.basemetals.zinc_powder_dirty.name=Verunreinigtes Zinkpulver + +#Casing + #Item +item.basemetals.adamantine_casing.name=Adamantgehäuse +item.basemetals.aquarium_casing.name=Aquariumgehäuse +item.basemetals.antimony_casing.name=Antimongehäuse +item.basemetals.bismuth_casing.name=Bismuthgehäuse +item.basemetals.brass_casing.name=Messinggehäuse +item.basemetals.bronze_casing.name=Bronzegehäuse +item.basemetals.coldiron_casing.name=Kalteisengehäuse +item.basemetals.copper_casing.name=Kupfergehäuse +item.basemetals.cupronickel_casing.name=Kupfernickelgehäuse +item.basemetals.electrum_casing.name=Elektrongehäuse +item.basemetals.invar_casing.name=Invargehäuse +item.basemetals.lead_casing.name=Bleigehäuse +item.basemetals.mithril_casing.name=Mithrilgehäuse +item.basemetals.nickel_casing.name=Nickelgehäuse +item.basemetals.pewter_casing.name=Hartzinngehäuse +item.basemetals.platinum_casing.name=Platingehäuse +item.basemetals.silver_casing.name=Silbergehäuse +item.basemetals.starsteel_casing.name=Sternenstahlgehäuse +item.basemetals.steel_casing.name=Stahlgehäuse +item.basemetals.tin_casing.name=Zinngehäuse +item.basemetals.zinc_casing.name=Zinkgehäuse +item.basemetals.iron_casing.name=Eisengehäuse +item.basemetals.gold_casing.name=Goldgehäuse + +#Denseblech + #Item +item.basemetals.adamantine_dense_plate.name=Verdichtetes Adamantblech +item.basemetals.aquarium_dense_plate.name=Verdichtetes Aquariumblech +item.basemetals.antimony_dense_plate.name=Verdichtetes Antimonblech +item.basemetals.bismuth_dense_plate.name=Verdichtetes Bismuthblech +item.basemetals.brass_dense_plate.name=Verdichtetes Messingblech +item.basemetals.bronze_dense_plate.name=Verdichtetes Bronzeblech +item.basemetals.coldiron_dense_plate.name=Verdichtetes Kalteisenblech +item.basemetals.copper_dense_plate.name=Verdichtetes Kupferblech +item.basemetals.cupronickel_dense_plate.name=Verdichtetes Kupfernickelblech +item.basemetals.electrum_dense_plate.name=Verdichtetes Elektronblech +item.basemetals.invar_dense_plate.name=Verdichtetes Invarblech +item.basemetals.lead_dense_plate.name=Verdichtetes Bleiblech +item.basemetals.mithril_dense_plate.name=Verdichtetes Mithrilblech +item.basemetals.nickel_dense_plate.name=Verdichtetes Nickelblech +item.basemetals.pewter_dense_plate.name=Verdichtetes Hartzinnblech +item.basemetals.platinum_dense_plate.name=Verdichtetes Platinblech +item.basemetals.silver_dense_plate.name=Verdichtetes Silberblech +item.basemetals.starsteel_dense_plate.name=Verdichtetes Sternenstahlblech +item.basemetals.steel_dense_plate.name=Verdichtetes Stahlblech +item.basemetals.tin_dense_plate.name=Verdichtetes Zinnblech +item.basemetals.zinc_dense_plate.name=Verdichtetes Zinkblech +item.basemetals.iron_dense_plate.name=Verdichtetes Eisenblech +item.basemetals.gold_dense_plate.name=Verdichtetes Goldblech + #Tile +tile.basemetals.adamantine_dense_plate.name=Verdichtetes Adamantblech +tile.basemetals.aquarium_dense_plate.name=Verdichtetes Aquariumblech +tile.basemetals.antimony_dense_plate.name=Verdichtetes Antimonblech +tile.basemetals.bismuth_dense_plate.name=Verdichtetes Bismuthblech +tile.basemetals.brass_dense_plate.name=Verdichtetes Messingblech +tile.basemetals.bronze_dense_plate.name=Verdichtetes Bronzeblech +tile.basemetals.coldiron_dense_plate.name=Verdichtetes Kalteisenblech +tile.basemetals.copper_dense_plate.name=Verdichtetes Kupferblech +tile.basemetals.cupronickel_dense_plate.name=Verdichtetes Kupfernickelblech +tile.basemetals.electrum_dense_plate.name=Verdichtetes Elektronblech +tile.basemetals.invar_dense_dense_plate.name=Verdichtetes Invarblech +tile.basemetals.lead_dense_plate.name=Verdichtetes Verdichtetes Bleiblech +tile.basemetals.mithril_dense_plate.name=Verdichtetes Verdichtetes Mithrilblech +tile.basemetals.nickel_dense_plate.name=Verdichtetes Verdichtetes Nickelblech +tile.basemetals.pewter_dense_plate.name=Verdichtetes Verdichtetes Hartzinnblech +tile.basemetals.platinum_dense_plate.name=Verdichtetes Verdichtetes Platinblech +tile.basemetals.silver_dense_plate.name=Verdichtetes Verdichtetes Silberblech +tile.basemetals.starsteel_dense_plate.name=Verdichtetes Verdichtetes Sternenstahlblech +tile.basemetals.steel_dense_plate.name=Verdichtetes Verdichtetes Stahlblech +tile.basemetals.tin_dense_plate.name=Verdichtetes Verdichtetes Zinnblech +tile.basemetals.zinc_dense_plate.name=Verdichtetes Verdichtetes Zinkblech +tile.basemetals.iron_dense_plate.name=Verdichtetes Verdichtetes Eisenblech +tile.basemetals.gold_dense_plate.name=Verdichtetes Verdichtetes Goldblech + +#fliese + #Item +item.basemetals.adamantine_slab.name=Adamantfliese +item.basemetals.aquarium_slab.name=Aquariumfliese +item.basemetals.antimony_slab.name=Antimonfliese +item.basemetals.bismuth_slab.name=Bismuthfliese +item.basemetals.brass_slab.name=Messingfliese +item.basemetals.bronze_slab.name=Bronzefliese +item.basemetals.coldiron_slab.name=Kalteisenfliese +item.basemetals.copper_slab.name=Kupferfliese +item.basemetals.cupronickel_slab.name=Kupfernickelfliese +item.basemetals.diamond_slab.name=Diamantfliese +item.basemetals.electrum_slab.name=Elektronfliese +item.basemetals.emerald_slab.name=Smaragdfliese +item.basemetals.gold_slab.name=Goldfliese +item.basemetals.invar_slab.name=Invarfliese +item.basemetals.iron_slab.name=Eisenfliese +item.basemetals.lead_slab.name=Bleifliese +item.basemetals.mithril_slab.name=Mithrilfliese +item.basemetals.nickel_slab.name=Nickelfliese +item.basemetals.obsidian_slab.name=Obsidianfliese +item.basemetals.pewter_slab.name=Hartzinnfliese +item.basemetals.platinum_slab.name=Platinfliese +item.basemetals.silver_slab.name=Silberfliese +item.basemetals.starsteel_slab.name=Sternenstahlfliese +item.basemetals.steel_slab.name=Stahlfliese +item.basemetals.tin_slab.name=Zinnfliese +item.basemetals.zinc_slab.name=Zinkfliese + #Tile +tile.basemetals.adamantine_slab.name=Adamantfliese +tile.basemetals.aquarium_slab.name=Aquariumfliese +tile.basemetals.antimony_slab.name=Antimonfliese +tile.basemetals.bismuth_slab.name=Bismuthfliese +tile.basemetals.brass_slab.name=Messingfliese +tile.basemetals.bronze_slab.name=Bronzefliese +tile.basemetals.coldiron_slab.name=Kalteisenfliese +tile.basemetals.copper_slab.name=Kupferfliese +tile.basemetals.cupronickel_slab.name=Kupfernickelfliese +tile.basemetals.diamond_slab.name=Diamantfliese +tile.basemetals.electrum_slab.name=Elektronfliese +tile.basemetals.emerald_slab.name=Smaragdfliese +tile.basemetals.gold_slab.name=Goldfliese +tile.basemetals.invar_slab.name=Invarfliese +tile.basemetals.iron_slab.name=Eisenfliese +tile.basemetals.lead_slab.name=Bleifliese +tile.basemetals.mithril_slab.name=Mithrilfliese +tile.basemetals.nickel_slab.name=Nickelfliese +tile.basemetals.obsidian_slab.name=Obsidianfliese +tile.basemetals.pewter_slab.name=Hartzinnfliese +tile.basemetals.platinum_slab.name=Platinfliese +tile.basemetals.silver_slab.name=Silberfliese +tile.basemetals.starsteel_slab.name=Sternenstahlfliese +tile.basemetals.steel_slab.name=Stahlfliese +tile.basemetals.tin_slab.name=Zinnfliese +tile.basemetals.zinc_slab.name=Zinkfliese + +#hebel + #Item +item.basemetals.adamantine_lever.name=Adamanthebel +item.basemetals.aquarium_lever.name=Aquariumhebel +item.basemetals.antimony_lever.name=Antimonhebel +item.basemetals.bismuth_lever.name=Bismuthhebel +item.basemetals.brass_lever.name=Messinghebel +item.basemetals.bronze_lever.name=Bronzehebel +item.basemetals.coldiron_lever.name=Kalteisenhebel +item.basemetals.copper_lever.name=Kupferhebel +item.basemetals.cupronickel_lever.name=Kupfernickelhebel +item.basemetals.diamond_lever.name=Diamanthebel +item.basemetals.electrum_lever.name=Elektronhebel +item.basemetals.emerald_lever.name=Smaragdhebel +item.basemetals.gold_lever.name=Goldhebel +item.basemetals.invar_lever.name=Invarhebel +item.basemetals.iron_lever.name=Eisenhebel +item.basemetals.lead_lever.name=Bleihebel +item.basemetals.mithril_lever.name=Mithrilhebel +item.basemetals.nickel_lever.name=Nickelhebel +item.basemetals.obsidian_lever.name=Obsidianhebel +item.basemetals.pewter_lever.name=Hartzinnhebel +item.basemetals.platinum_lever.name=Platinhebel +item.basemetals.quartz_lever.name=Quartzhebel +item.basemetals.silver_lever.name=Silberhebel +item.basemetals.starsteel_lever.name=Sternenstahlhebel +item.basemetals.steel_lever.name=Stahlhebel +item.basemetals.tin_lever.name=Zinnhebel +item.basemetals.zinc_lever.name=Zinkhebel + #Tile +tile.basemetals.adamantine_lever.name=Adamanthebel +tile.basemetals.aquarium_lever.name=Aquariumhebel +tile.basemetals.antimony_lever.name=Antimonhebel +tile.basemetals.bismuth_lever.name=Bismuthhebel +tile.basemetals.brass_lever.name=Messinghebel +tile.basemetals.bronze_lever.name=Bronzehebel +tile.basemetals.coldiron_lever.name=Kalteisenhebel +tile.basemetals.copper_lever.name=Kupferhebel +tile.basemetals.cupronickel_lever.name=Kupfernickelhebel +tile.basemetals.diamond_lever.name=Diamanthebel +tile.basemetals.electrum_lever.name=Elektronhebel +tile.basemetals.emerald_lever.name=Smaragdhebel +tile.basemetals.gold_lever.name=Goldhebel +tile.basemetals.invar_lever.name=Invarhebel +tile.basemetals.iron_lever.name=Eisenhebel +tile.basemetals.lead_lever.name=Bleihebel +tile.basemetals.mithril_lever.name=Mithrilhebel +tile.basemetals.nickel_lever.name=Nickelhebel +tile.basemetals.obsidian_lever.name=Obsidianhebel +tile.basemetals.pewter_lever.name=Hartzinnhebel +tile.basemetals.platinum_lever.name=Platinhebel +tile.basemetals.quartz_lever.name=Quartzhebel +tile.basemetals.silver_lever.name=Silberhebel +tile.basemetals.starsteel_lever.name=Sternenstahlhebel +tile.basemetals.steel_lever.name=Stahlhebel +tile.basemetals.tin_lever.name=Zinnhebel +tile.basemetals.zinc_lever.name=Zinkhebel + +#Stair + #Item +item.basemetals.adamantine_stairs.name=Adamanttreppe +item.basemetals.aquarium_stairs.name=Aquariumtreppe +item.basemetals.antimony_stairs.name=Antimontreppe +item.basemetals.bismuth_stairs.name=Bismuthtreppe +item.basemetals.brass_stairs.name=Messingtreppe +item.basemetals.bronze_stairs.name=Bronzetreppe +item.basemetals.coldiron_stairs.name=Kalteisentreppe +item.basemetals.copper_stairs.name=Kupfertreppe +item.basemetals.cupronickel_stairs.name=Kupfernickeltreppe +item.basemetals.diamond_stairs.name=Diamanttreppe +item.basemetals.electrum_stairs.name=Elektrontreppe +item.basemetals.emerald_stairs.name=Smaragdtreppe +item.basemetals.gold_stairs.name=Goldtreppe +item.basemetals.invar_stairs.name=Invartreppe +item.basemetals.iron_stairs.name=Eisentreppe +item.basemetals.lead_stairs.name=Bleitreppe +item.basemetals.mithril_stairs.name=Mithriltreppe +item.basemetals.nickel_stairs.name=Nickeltreppe +item.basemetals.obsidian_stairs.name=Obsidiantreppe +item.basemetals.pewter_stairs.name=Hartzinntreppe +item.basemetals.platinum_stairs.name=Platintreppe +item.basemetals.silver_stairs.name=Silbertreppe +item.basemetals.starsteel_stairs.name=Sternenstahltreppe +item.basemetals.steel_stairs.name=Stahltreppe +item.basemetals.tin_stairs.name=Zinntreppe +item.basemetals.zinc_stairs.name=Zinktreppe + #Tile +tile.basemetals.adamantine_stairs.name=Adamanttreppe +tile.basemetals.aquarium_stairs.name=Aquariumtreppe +tile.basemetals.antimony_stairs.name=Antimontreppe +tile.basemetals.bismuth_stairs.name=Bismuthtreppe +tile.basemetals.brass_stairs.name=Messingtreppe +tile.basemetals.bronze_stairs.name=Bronzetreppe +tile.basemetals.coldiron_stairs.name=Kalteisentreppe +tile.basemetals.copper_stairs.name=Kupfertreppe +tile.basemetals.cupronickel_stairs.name=Kupfernickeltreppe +tile.basemetals.diamond_stairs.name=Diamanttreppe +tile.basemetals.electrum_stairs.name=Elektrontreppe +tile.basemetals.emerald_stairs.name=Smaragdtreppe +tile.basemetals.gold_stairs.name=Goldtreppe +tile.basemetals.invar_stairs.name=Invartreppe +tile.basemetals.iron_stairs.name=Eisentreppe +tile.basemetals.lead_stairs.name=Bleitreppe +tile.basemetals.mithril_stairs.name=Mithriltreppe +tile.basemetals.nickel_stairs.name=Nickeltreppe +tile.basemetals.obsidian_stairs.name=Obsidiantreppe +tile.basemetals.pewter_stairs.name=Hartzinntreppe +tile.basemetals.platinum_stairs.name=Platintreppe +tile.basemetals.silver_stairs.name=Silbertreppe +tile.basemetals.starsteel_stairs.name=Sternenstahltreppe +tile.basemetals.steel_stairs.name=Stahltreppe +tile.basemetals.tin_stairs.name=Zinntreppe +tile.basemetals.zinc_stairs.name=Zinktreppe + +#mauer + #Item +item.basemetals.adamantine_wall.name=Adamantmauer +item.basemetals.aquarium_wall.name=Aquariummauer +item.basemetals.antimony_wall.name=Antimonmauer +item.basemetals.bismuth_wall.name=Bismuthmauer +item.basemetals.brass_wall.name=Messingmauer +item.basemetals.bronze_wall.name=Bronzemauer +item.basemetals.coldiron_wall.name=Kalteisenmauer +item.basemetals.copper_wall.name=Kupfermauer +item.basemetals.cupronickel_wall.name=Kupfernickelmauer +item.basemetals.diamond_wall.name=Diamantmauer +item.basemetals.electrum_wall.name=Elektronmauer +item.basemetals.emerald_wall.name=Smaragdmauer +item.basemetals.gold_wall.name=Goldmauer +item.basemetals.invar_wall.name=Invarmauer +item.basemetals.iron_wall.name=Eisenmauer +item.basemetals.lead_wall.name=Bleimauer +item.basemetals.mithril_wall.name=Mithrilmauer +item.basemetals.nickel_wall.name=Nickelmauer +item.basemetals.obsidian_wall.name=Obsidianmauer +item.basemetals.pewter_wall.name=Hartzinnmauer +item.basemetals.platinum_wall.name=Platinmauer +item.basemetals.quartz_wall.name=Quartzmauer +item.basemetals.silver_wall.name=Silbermauer +item.basemetals.starsteel_wall.name=Sternenstahlmauer +item.basemetals.steel_wall.name=Stahlmauer +item.basemetals.tin_wall.name=Zinnmauer +item.basemetals.zinc_wall.name=Zinkmauer + #Tile +tile.basemetals.adamantine_wall.name=Adamantmauer +tile.basemetals.aquarium_wall.name=Aquariummauer +tile.basemetals.antimony_wall.name=Antimonmauer +tile.basemetals.bismuth_wall.name=Bismuthmauer +tile.basemetals.brass_wall.name=Messingmauer +tile.basemetals.bronze_wall.name=Bronzemauer +tile.basemetals.coldiron_wall.name=Kalteisenmauer +tile.basemetals.copper_wall.name=Kupfermauer +tile.basemetals.cupronickel_wall.name=Kupfernickelmauer +tile.basemetals.diamond_wall.name=Diamantmauer +tile.basemetals.electrum_wall.name=Elektronmauer +tile.basemetals.emerald_wall.name=Smaragdmauer +tile.basemetals.gold_wall.name=Goldmauer +tile.basemetals.invar_wall.name=Invarmauer +tile.basemetals.iron_wall.name=Eisenmauer +tile.basemetals.lead_wall.name=Bleimauer +tile.basemetals.mithril_wall.name=Mithrilmauer +tile.basemetals.nickel_wall.name=Nickelmauer +tile.basemetals.obsidian_wall.name=Obsidianmauer +tile.basemetals.pewter_wall.name=Hartzinnmauer +tile.basemetals.platinum_wall.name=Platinmauer +tile.basemetals.quartz_wall.name=Quartzmauer +tile.basemetals.silver_wall.name=Silbermauer +tile.basemetals.starsteel_wall.name=Sternenstahlmauer +tile.basemetals.steel_wall.name=Stahlmauer +tile.basemetals.tin_wall.name=Zinnmauer +tile.basemetals.zinc_wall.name=Zinkmauer + +modifier.mmd-toxic.name=Giftig +modifier.mmd-toxic.desc=Ziemlich gefährlich - blendet und vergiftet Dinge, die mit Werkzeugen oder Waffen getroffen werden. +modifier.mmd-sparkly.name=Funkelnd +modifier.mmd-sparkly.desc=Selbstreparierendes, glänzendes und funkelndes Zeug +modifier.mmd-soft.name=Weich +modifier.mmd-soft.desc=Nicht wirklich für Werkzeuge, die viel genutzt werden sollen, geeignet, da sich diese schneller abnutzen werden +modifier.mmd-brittle.name=Spröde +modifier.mmd-brittle.desc=Mit zunehmender Abnutzung wird mehr Schaden verursacht - aber Vorsicht, es verletzt auch dich! +modifier.mmd-heavy.name=Schwer +modifier.mmd-heavy.desc=Dieses Zeug ist wirklich, wirklich dicht - die Nutzung von Werkzeugen aus diesem Material wird dich schneller ermüden +modifier.mmd-reactive.name=Reaktiv +modifier.mmd-reactive.desc=Reagiert mit Wasser und nutzt sich dabei schneller ab +modifier.mmd-radioactive.name=Radioaktiv +modifier.mmd-radioactive.desc=Gefährlich zu halten, wenn du dich nicht irgendwie vor den negativen Effekten schützen kannst. + +modifier.toxic-modifier.name=Giftig +modifier.toxic-modifier.desc=§oGIFTIGER RÄCHER!§r\nQuecksilber und seine Ethyl- und Methyl-Salze sind extrem giftig und haben neurodegenerative Effekte.\nSie zu einer Waffe oder einem Werkzeug hinzuzufügen, erlaubt diesen deine Feinde zu blenden und zu vergiften. +modifier.lead-plated.name=Bleibeschichtung +modifier.lead-plated.desc=§oSafety First§r\nWenn du etwas Plutonium oder Uran herumliegen hast und denkst, dass es gut für eine Waffe geeignet wäre, vergiss nicht etwas Abschirmendes hinzuzufügen.\nEine Beschichtung mit Blei wird die tödliche Verstrahlung davon abhalten, dich zu betreffen, während sie deinen Feinden weiterhin schadet. + +config.basemetals.title=Base-Metals-Konfiguration +config.basemetals.restart_guidance=Neustart erforderlich. Die Erzverteilung wird in OreSpawn konfiguriert. +config.basemetals.category.general=Allgemein +config.basemetals.category.metals=Basismetalle +config.basemetals.category.vanilla=Vanilla-Erweiterungen +config.basemetals.category.fluids=Geschmolzene Flüssigkeiten +config.basemetals.option.content_mode=Fantasy-Stufe +config.basemetals.content_mode.high_fantasy=High Fantasy +config.basemetals.content_mode.low_fantasy=Low Fantasy +high_fantasy=Viel Fantasy +low_fantasy=Wenig Fantasy +config.basemetals.connection.mismatch=Der Server verwendet %s, dein Spiel verwendet %s. Gleiche die Fantasy-Stufe unter Mods > Base Metals > Konfiguration an und starte das Spiel neu. +config.basemetals.connection.protocol=Base Metals konnte die Fantasy-Stufe nicht prüfen. Verwende auf dem Server und im Spiel denselben Build von Base Metals. diff --git a/src/main/resources/assets/basemetals/lang/en_AU.lang b/src/main/resources/assets/basemetals/lang/en_AU.lang index 3bd261e35..b4034c156 100644 --- a/src/main/resources/assets/basemetals/lang/en_AU.lang +++ b/src/main/resources/assets/basemetals/lang/en_AU.lang @@ -572,3 +572,17 @@ item.basemetals.stone_scythe.name=Stone Sickle item.basemetals.tin_scythe.name=Tin Sickle item.basemetals.wood_scythe.name=Wood Sickle item.basemetals.zinc_scythe.name=Zinc Sickle + +config.basemetals.title=Base Metals Configuration +config.basemetals.restart_guidance=Restart required. Ore distribution is configured in OreSpawn. +config.basemetals.category.general=General +config.basemetals.category.metals=Base Metals +config.basemetals.category.vanilla=Vanilla Bits +config.basemetals.category.fluids=Molten Fluids +config.basemetals.option.content_mode=Content Mode +config.basemetals.content_mode.high_fantasy=High Fantasy +config.basemetals.content_mode.low_fantasy=Low Fantasy +high_fantasy=High Fantasy +low_fantasy=Low Fantasy +config.basemetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in Mods > Base Metals > Config and restart. +config.basemetals.connection.protocol=Base Metals could not check the Fantasy Level. Use the same Base Metals build on the server and client. diff --git a/src/main/resources/assets/basemetals/lang/en_CA.lang b/src/main/resources/assets/basemetals/lang/en_CA.lang index ba52bd74d..ecea5326e 100644 --- a/src/main/resources/assets/basemetals/lang/en_CA.lang +++ b/src/main/resources/assets/basemetals/lang/en_CA.lang @@ -574,3 +574,17 @@ item.basemetals.stone_scythe.name=Stone Sickle item.basemetals.tin_scythe.name=Tin Sickle item.basemetals.wood_scythe.name=Wood Sickle item.basemetals.zinc_scythe.name=Zinc Sickle + +config.basemetals.title=Base Metals Configuration +config.basemetals.restart_guidance=Restart required. Ore distribution is configured in OreSpawn. +config.basemetals.category.general=General +config.basemetals.category.metals=Base Metals +config.basemetals.category.vanilla=Vanilla Bits +config.basemetals.category.fluids=Molten Fluids +config.basemetals.option.content_mode=Content Mode +config.basemetals.content_mode.high_fantasy=High Fantasy +config.basemetals.content_mode.low_fantasy=Low Fantasy +high_fantasy=High Fantasy +low_fantasy=Low Fantasy +config.basemetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in Mods > Base Metals > Config and restart. +config.basemetals.connection.protocol=Base Metals could not check the Fantasy Level. Use the same Base Metals build on the server and client. diff --git a/src/main/resources/assets/basemetals/lang/en_EN.lang b/src/main/resources/assets/basemetals/lang/en_EN.lang index 29d67a055..81872e5bd 100644 --- a/src/main/resources/assets/basemetals/lang/en_EN.lang +++ b/src/main/resources/assets/basemetals/lang/en_EN.lang @@ -573,3 +573,17 @@ item.basemetals.stone_scythe.name=Stone Sickle item.basemetals.tin_scythe.name=Tin Sickle item.basemetals.wood_scythe.name=Wood Sickle item.basemetals.zinc_scythe.name=Zinc Sickle + +config.basemetals.title=Base Metals Configuration +config.basemetals.restart_guidance=Restart required. Ore distribution is configured in OreSpawn. +config.basemetals.category.general=General +config.basemetals.category.metals=Base Metals +config.basemetals.category.vanilla=Vanilla Bits +config.basemetals.category.fluids=Molten Fluids +config.basemetals.option.content_mode=Content Mode +config.basemetals.content_mode.high_fantasy=High Fantasy +config.basemetals.content_mode.low_fantasy=Low Fantasy +high_fantasy=High Fantasy +low_fantasy=Low Fantasy +config.basemetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in Mods > Base Metals > Config and restart. +config.basemetals.connection.protocol=Base Metals could not check the Fantasy Level. Use the same Base Metals build on the server and client. diff --git a/src/main/resources/assets/basemetals/lang/en_GB.lang b/src/main/resources/assets/basemetals/lang/en_GB.lang index cbd43e95d..1e7d46243 100644 --- a/src/main/resources/assets/basemetals/lang/en_GB.lang +++ b/src/main/resources/assets/basemetals/lang/en_GB.lang @@ -574,3 +574,17 @@ tile.basemetals.stone_anvil.veryDamaged.name=Badly Damaged Stone Anvil tile.basemetals.adamantine_anvil.intact.name=Adamantine Anvil tile.basemetals.adamantine_anvil.slightlyDamaged.name=Slightly Damaged Adamantine Anvil tile.basemetals.adamantine_anvil.veryDamaged.name=Badly Damaged Adamantine Anvil + +config.basemetals.title=Base Metals Configuration +config.basemetals.restart_guidance=Restart required. Ore distribution is configured in OreSpawn. +config.basemetals.category.general=General +config.basemetals.category.metals=Base Metals +config.basemetals.category.vanilla=Vanilla Bits +config.basemetals.category.fluids=Molten Fluids +config.basemetals.option.content_mode=Content Mode +config.basemetals.content_mode.high_fantasy=High Fantasy +config.basemetals.content_mode.low_fantasy=Low Fantasy +high_fantasy=High Fantasy +low_fantasy=Low Fantasy +config.basemetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in Mods > Base Metals > Config and restart. +config.basemetals.connection.protocol=Base Metals could not check the Fantasy Level. Use the same Base Metals build on the server and client. diff --git a/src/main/resources/assets/basemetals/lang/en_PT.lang b/src/main/resources/assets/basemetals/lang/en_PT.lang index 243866fae..f0b66c586 100644 --- a/src/main/resources/assets/basemetals/lang/en_PT.lang +++ b/src/main/resources/assets/basemetals/lang/en_PT.lang @@ -530,3 +530,17 @@ item.basemetals.tin_gear.name=Tin Gear item.basemetals.zinc_gear.name=Zinc Gear item.basemetals.gold_crackhammer.name=Golden Crack Hammer + +config.basemetals.title=Base Metals Ship's Settings +config.basemetals.restart_guidance=Restart yer game, matey. Chart ore waters in OreSpawn. +config.basemetals.category.general=General Orders +config.basemetals.category.metals=Base Metals Cargo +config.basemetals.category.vanilla=Vanilla Booty +config.basemetals.category.fluids=Molten Cargo +config.basemetals.option.content_mode=Content Course +config.basemetals.content_mode.high_fantasy=High Fantasy +config.basemetals.content_mode.low_fantasy=Low Fantasy +high_fantasy=High Fantasy +low_fantasy=Low Fantasy +config.basemetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in Mods > Base Metals > Config and restart. +config.basemetals.connection.protocol=Base Metals could not check the Fantasy Level. Use the same Base Metals build on the server and client. diff --git a/src/main/resources/assets/basemetals/lang/en_US.lang b/src/main/resources/assets/basemetals/lang/en_US.lang index d3694440c..1f2db458a 100644 --- a/src/main/resources/assets/basemetals/lang/en_US.lang +++ b/src/main/resources/assets/basemetals/lang/en_US.lang @@ -1883,3 +1883,17 @@ gas.cleanGasPlatinum=Clean Platinum Slurry gas.cleanGasNickel=Clean Nickel Slurry gas.cleanGasStarsteel=Clean Star-Steel Slurry gas.cleanGasZinc=Clean Zinc Slurry + +config.basemetals.title=Base Metals Configuration +config.basemetals.restart_guidance=Restart required. Ore distribution is configured in OreSpawn. +config.basemetals.category.general=General +config.basemetals.category.metals=Base Metals +config.basemetals.category.vanilla=Vanilla Bits +config.basemetals.category.fluids=Molten Fluids +config.basemetals.option.content_mode=Fantasy Level +config.basemetals.content_mode.high_fantasy=High Fantasy +config.basemetals.content_mode.low_fantasy=Low Fantasy +high_fantasy=High Fantasy +low_fantasy=Low Fantasy +config.basemetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in Mods > Base Metals > Config and restart. +config.basemetals.connection.protocol=Base Metals could not check the Fantasy Level. Use the same Base Metals build on the server and client. diff --git a/src/main/resources/assets/basemetals/lang/es_ES.lang b/src/main/resources/assets/basemetals/lang/es_ES.lang index a6ad0a3ea..61760c812 100644 --- a/src/main/resources/assets/basemetals/lang/es_ES.lang +++ b/src/main/resources/assets/basemetals/lang/es_ES.lang @@ -529,3 +529,17 @@ item.basemetals.starsteel_gear.name=Engranaje de estrellacero item.basemetals.steel_gear.name=Engranaje de acero item.basemetals.tin_gear.name=Engranaje de estaño item.basemetals.zinc_gear.name=Engranaje de zinc + +config.basemetals.title=Configuración de Base Metals +config.basemetals.restart_guidance=Se requiere reiniciar. La distribución de minerales se configura en OreSpawn. +config.basemetals.category.general=General +config.basemetals.category.metals=Metales básicos +config.basemetals.category.vanilla=Complementos de Vanilla +config.basemetals.category.fluids=Fluidos fundidos +config.basemetals.option.content_mode=Modo de contenido +config.basemetals.content_mode.high_fantasy=Alta fantasía +config.basemetals.content_mode.low_fantasy=Baja fantasía +high_fantasy=Alta fantasía +low_fantasy=Baja fantasía +config.basemetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in Mods > Base Metals > Config and restart. +config.basemetals.connection.protocol=Base Metals could not check the Fantasy Level. Use the same Base Metals build on the server and client. diff --git a/src/main/resources/assets/basemetals/lang/es_MX.lang b/src/main/resources/assets/basemetals/lang/es_MX.lang index e01fe7712..4c8dd6900 100644 --- a/src/main/resources/assets/basemetals/lang/es_MX.lang +++ b/src/main/resources/assets/basemetals/lang/es_MX.lang @@ -530,3 +530,17 @@ item.basemetals.starsteel_gear.name=Engranaje de estrellacero item.basemetals.steel_gear.name=Engranaje de acero item.basemetals.tin_gear.name=Engranaje de estaño item.basemetals.zinc_gear.name=Engranaje de zinc + +config.basemetals.title=Configuración de Base Metals +config.basemetals.restart_guidance=Se requiere reiniciar. La distribución de minerales se configura en OreSpawn. +config.basemetals.category.general=General +config.basemetals.category.metals=Metales básicos +config.basemetals.category.vanilla=Complementos de Vanilla +config.basemetals.category.fluids=Fluidos fundidos +config.basemetals.option.content_mode=Modo de contenido +config.basemetals.content_mode.high_fantasy=Alta fantasía +config.basemetals.content_mode.low_fantasy=Baja fantasía +high_fantasy=Alta fantasía +low_fantasy=Baja fantasía +config.basemetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in Mods > Base Metals > Config and restart. +config.basemetals.connection.protocol=Base Metals could not check the Fantasy Level. Use the same Base Metals build on the server and client. diff --git a/src/main/resources/assets/basemetals/lang/fr_CA.lang b/src/main/resources/assets/basemetals/lang/fr_CA.lang index ba2af567c..4b3b76cc7 100644 --- a/src/main/resources/assets/basemetals/lang/fr_CA.lang +++ b/src/main/resources/assets/basemetals/lang/fr_CA.lang @@ -532,3 +532,17 @@ item.basemetals.starsteel_gear.name=Pignon en acier-étoile item.basemetals.steel_gear.name=Pignon en acier item.basemetals.tin_gear.name=Pignon en étain item.basemetals.zinc_gear.name=Pignon de zinc + +config.basemetals.title=Configuration de Base Metals +config.basemetals.restart_guidance=Redémarrage requis. La répartition des minerais se configure dans OreSpawn. +config.basemetals.category.general=Général +config.basemetals.category.metals=Métaux de base +config.basemetals.category.vanilla=Compléments Vanilla +config.basemetals.category.fluids=Fluides en fusion +config.basemetals.option.content_mode=Mode de contenu +config.basemetals.content_mode.high_fantasy=Fantaisie élevée +config.basemetals.content_mode.low_fantasy=Fantaisie modérée +high_fantasy=Fantaisie élevée +low_fantasy=Fantaisie modérée +config.basemetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in Mods > Base Metals > Config and restart. +config.basemetals.connection.protocol=Base Metals could not check the Fantasy Level. Use the same Base Metals build on the server and client. diff --git a/src/main/resources/assets/basemetals/lang/fr_FR.lang b/src/main/resources/assets/basemetals/lang/fr_FR.lang index c5e99b77d..22127718e 100644 --- a/src/main/resources/assets/basemetals/lang/fr_FR.lang +++ b/src/main/resources/assets/basemetals/lang/fr_FR.lang @@ -532,3 +532,17 @@ item.basemetals.tin_gear.name=Pignon en étain item.basemetals.zinc_gear.name=Pignon de zinc item.basemetals.gold_crackhammer.name=Massette en or + +config.basemetals.title=Configuration de Base Metals +config.basemetals.restart_guidance=Redémarrage requis. La répartition des minerais se configure dans OreSpawn. +config.basemetals.category.general=Général +config.basemetals.category.metals=Métaux de base +config.basemetals.category.vanilla=Compléments Vanilla +config.basemetals.category.fluids=Fluides en fusion +config.basemetals.option.content_mode=Mode de contenu +config.basemetals.content_mode.high_fantasy=Fantaisie élevée +config.basemetals.content_mode.low_fantasy=Fantaisie modérée +high_fantasy=Fantaisie élevée +low_fantasy=Fantaisie modérée +config.basemetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in Mods > Base Metals > Config and restart. +config.basemetals.connection.protocol=Base Metals could not check the Fantasy Level. Use the same Base Metals build on the server and client. diff --git a/src/main/resources/assets/basemetals/lang/it_IT.lang b/src/main/resources/assets/basemetals/lang/it_IT.lang index 32b4459c3..e5a9cb5fa 100644 --- a/src/main/resources/assets/basemetals/lang/it_IT.lang +++ b/src/main/resources/assets/basemetals/lang/it_IT.lang @@ -527,3 +527,17 @@ item.basemetals.starsteel_gear.name=Ferro-Stelle Ingranaggio item.basemetals.steel_gear.name=Acciaio Ingranaggio item.basemetals.tin_gear.name=Latta Ingranaggio item.basemetals.zinc_gear.name=Zinco Ingranaggio + +config.basemetals.title=Configurazione di Base Metals +config.basemetals.restart_guidance=Riavvio necessario. La distribuzione dei minerali si configura in OreSpawn. +config.basemetals.category.general=Generale +config.basemetals.category.metals=Metalli di base +config.basemetals.category.vanilla=Aggiunte Vanilla +config.basemetals.category.fluids=Fluidi fusi +config.basemetals.option.content_mode=Modalità contenuti +config.basemetals.content_mode.high_fantasy=Alta fantasia +config.basemetals.content_mode.low_fantasy=Bassa fantasia +high_fantasy=Alta fantasia +low_fantasy=Bassa fantasia +config.basemetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in Mods > Base Metals > Config and restart. +config.basemetals.connection.protocol=Base Metals could not check the Fantasy Level. Use the same Base Metals build on the server and client. diff --git a/src/main/resources/assets/basemetals/lang/ja_jp.lang b/src/main/resources/assets/basemetals/lang/ja_jp.lang index b00e9ddb3..7d99330c6 100644 --- a/src/main/resources/assets/basemetals/lang/ja_jp.lang +++ b/src/main/resources/assets/basemetals/lang/ja_jp.lang @@ -1867,3 +1867,17 @@ gas.cleanGasPlatinum=きれいなプラチナのスラリー gas.cleanGasNickel=きれいなニッケルのスラリー gas.cleanGasStarsteel=きれいなスタースチールのスラリー gas.cleanGasZinc=きれいな亜鉛のスラリー + +config.basemetals.title=Base Metals 設定 +config.basemetals.restart_guidance=再起動が必要です。鉱石の分布は OreSpawn で設定します。 +config.basemetals.category.general=一般 +config.basemetals.category.metals=Base Metals +config.basemetals.category.vanilla=バニラ追加要素 +config.basemetals.category.fluids=溶融流体 +config.basemetals.option.content_mode=コンテンツモード +config.basemetals.content_mode.high_fantasy=ハイファンタジー +config.basemetals.content_mode.low_fantasy=ローファンタジー +high_fantasy=ハイファンタジー +low_fantasy=ローファンタジー +config.basemetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in Mods > Base Metals > Config and restart. +config.basemetals.connection.protocol=Base Metals could not check the Fantasy Level. Use the same Base Metals build on the server and client. diff --git a/src/main/resources/assets/basemetals/lang/nl_NL.lang b/src/main/resources/assets/basemetals/lang/nl_NL.lang index ec306dbff..66f13b546 100644 --- a/src/main/resources/assets/basemetals/lang/nl_NL.lang +++ b/src/main/resources/assets/basemetals/lang/nl_NL.lang @@ -530,3 +530,17 @@ item.basemetals.starsteel_gear.name=Star-Steel Gear item.basemetals.steel_gear.name=Steel Gear item.basemetals.tin_gear.name=Tin Gear item.basemetals.zinc_gear.name=Zinc Gear + +config.basemetals.title=Base Metals-configuratie +config.basemetals.restart_guidance=Opnieuw opstarten vereist. De ertsverdeling wordt in OreSpawn ingesteld. +config.basemetals.category.general=Algemeen +config.basemetals.category.metals=Basismetalen +config.basemetals.category.vanilla=Vanilla-uitbreidingen +config.basemetals.category.fluids=Gesmolten vloeistoffen +config.basemetals.option.content_mode=Inhoudsmodus +config.basemetals.content_mode.high_fantasy=Hoge fantasie +config.basemetals.content_mode.low_fantasy=Lage fantasie +high_fantasy=Hoge fantasie +low_fantasy=Lage fantasie +config.basemetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in Mods > Base Metals > Config and restart. +config.basemetals.connection.protocol=Base Metals could not check the Fantasy Level. Use the same Base Metals build on the server and client. diff --git a/src/main/resources/assets/basemetals/lang/pt_BR.lang b/src/main/resources/assets/basemetals/lang/pt_BR.lang index 516abac72..a1dc6fe99 100644 --- a/src/main/resources/assets/basemetals/lang/pt_BR.lang +++ b/src/main/resources/assets/basemetals/lang/pt_BR.lang @@ -530,3 +530,17 @@ item.basemetals.starsteel_gear.name=Roda Dentada de Ferro-Estrela item.basemetals.steel_gear.name=Roda Dentada de Aço item.basemetals.tin_gear.name=Roda Dentada de Estanho item.basemetals.zinc_gear.name=Roda Dentada de Zinco + +config.basemetals.title=Configuração do Base Metals +config.basemetals.restart_guidance=É necessário reiniciar. A distribuição de minérios é configurada no OreSpawn. +config.basemetals.category.general=Geral +config.basemetals.category.metals=Metais básicos +config.basemetals.category.vanilla=Adições Vanilla +config.basemetals.category.fluids=Fluidos fundidos +config.basemetals.option.content_mode=Modo de conteúdo +config.basemetals.content_mode.high_fantasy=Alta fantasia +config.basemetals.content_mode.low_fantasy=Baixa fantasia +high_fantasy=Alta fantasia +low_fantasy=Baixa fantasia +config.basemetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in Mods > Base Metals > Config and restart. +config.basemetals.connection.protocol=Base Metals could not check the Fantasy Level. Use the same Base Metals build on the server and client. diff --git a/src/main/resources/assets/basemetals/lang/ru_ru.lang b/src/main/resources/assets/basemetals/lang/ru_ru.lang index 4764bc300..e1a0aa799 100644 --- a/src/main/resources/assets/basemetals/lang/ru_ru.lang +++ b/src/main/resources/assets/basemetals/lang/ru_ru.lang @@ -1844,3 +1844,17 @@ modifier.toxic-modifier.desc=§oТОКСИЧНЫЙ МСТИТЕЛЬ!§r\nРту modifier.lead-plated.name=Свинцовая пластина modifier.lead-plated.desc=§oБезопастность Прежде Всего!§r\nЕсли рядом с вами есть плутоний или уран, я думаю это можно использовать как оружие, не забудьте экранировать излучение.\nХорошая свинцовая пластина может спасти Вас от смертельного излучения, пока Ваших врагов будетубивать радиация. +config.basemetals.title=Настройки Base Metals +config.basemetals.restart_guidance=Требуется перезапуск. Распределение руд настраивается в OreSpawn. +config.basemetals.category.general=Общие +config.basemetals.category.metals=Базовые металлы +config.basemetals.category.vanilla=Дополнения Vanilla +config.basemetals.category.fluids=Расплавленные жидкости +config.basemetals.option.content_mode=Уровень фэнтези +config.basemetals.content_mode.high_fantasy=Высокое фэнтези +config.basemetals.content_mode.low_fantasy=Низкое фэнтези +high_fantasy=Высокий уровень фэнтези +low_fantasy=Низкий уровень фэнтези +config.basemetals.connection.mismatch=Уровень на сервере — %s, в вашей игре — %s. Выберите тот же уровень в меню «Моды > Base Metals > Настройки» и перезапустите игру. +config.basemetals.connection.protocol=Не удалось проверить уровень фэнтези Base Metals. Установите одну и ту же сборку Base Metals на клиенте и сервере. + diff --git a/src/main/resources/assets/basemetals/lang/zh_CN.lang b/src/main/resources/assets/basemetals/lang/zh_CN.lang index 5385483d1..81b9bfa1d 100644 --- a/src/main/resources/assets/basemetals/lang/zh_CN.lang +++ b/src/main/resources/assets/basemetals/lang/zh_CN.lang @@ -1810,3 +1810,17 @@ modifier.brittle.name=易碎 modifier.heavy.name=沉重 modifier.reactive.name=活泼 modifier.radioactive.name=放射 + +config.basemetals.title=Base Metals 配置 +config.basemetals.restart_guidance=需要重启。矿石分布请在 OreSpawn 中配置。 +config.basemetals.category.general=常规 +config.basemetals.category.metals=基础金属 +config.basemetals.category.vanilla=原版扩展 +config.basemetals.category.fluids=熔融流体 +config.basemetals.option.content_mode=奇幻等级 +config.basemetals.content_mode.high_fantasy=高幻想 +config.basemetals.content_mode.low_fantasy=低幻想 +high_fantasy=高奇幻 +low_fantasy=低奇幻 +config.basemetals.connection.mismatch=服务器使用%s,你的游戏使用%s。请在模组 > Base Metals > 配置中选择与服务器一致的奇幻等级,然后重启游戏。 +config.basemetals.connection.protocol=Base Metals 无法核对奇幻等级。请在服务器和客户端使用相同构建版本的 Base Metals。 diff --git a/src/main/resources/assets/basemetals/lang/zh_TW.lang b/src/main/resources/assets/basemetals/lang/zh_TW.lang index 75eda053a..47f058672 100644 --- a/src/main/resources/assets/basemetals/lang/zh_TW.lang +++ b/src/main/resources/assets/basemetals/lang/zh_TW.lang @@ -1884,3 +1884,17 @@ gas.cleanGasPlatinum=純淨的白金漿 gas.cleanGasNickel=純淨的鎳漿 gas.cleanGasStarsteel=純淨的星鋼漿 gas.cleanGasZinc=純淨的鋅漿 + +config.basemetals.title=Base Metals 設定 +config.basemetals.restart_guidance=需要重新啟動。礦石分布請在 OreSpawn 中設定。 +config.basemetals.category.general=一般 +config.basemetals.category.metals=基礎金屬 +config.basemetals.category.vanilla=原版擴充 +config.basemetals.category.fluids=熔融流體 +config.basemetals.option.content_mode=內容模式 +config.basemetals.content_mode.high_fantasy=高幻想 +config.basemetals.content_mode.low_fantasy=低幻想 +high_fantasy=高幻想 +low_fantasy=低幻想 +config.basemetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in Mods > Base Metals > Config and restart. +config.basemetals.connection.protocol=Base Metals could not check the Fantasy Level. Use the same Base Metals build on the server and client. diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index 4cd9edabe..e07957450 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -11,7 +11,7 @@ "credits": "Cyanobacterium (aka DrCyano) For starting the project & geologists everywhere. SeqSEE for helping with shields.", "logoFile": "", "screenshots": [], - "requiredMods": ["orespawn@[4.1.2.110021,5.0.0)"], - "dependencies": ["orespawn@[4.1.2.110021,5.0.0)"] + "requiredMods": ["orespawn@[4.1.6.111021,5.0.0)"], + "dependencies": ["orespawn@[4.1.6.111021,5.0.0)"] } ] diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta index 3ce312dfc..e51b5f9f5 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":"Base Metals" } } diff --git a/src/test/java/zone/moddev/mc/basemetals/content/BarsModelTest.java b/src/test/java/zone/moddev/mc/basemetals/content/BarsModelTest.java new file mode 100644 index 000000000..460b0d760 --- /dev/null +++ b/src/test/java/zone/moddev/mc/basemetals/content/BarsModelTest.java @@ -0,0 +1,126 @@ +package zone.moddev.mc.basemetals.content; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import org.junit.jupiter.api.Test; + +class BarsModelTest { + private static final Path ASSETS = Paths.get("src/main/resources/assets/basemetals"); + private static final String[] DIRECTIONS = { "east", "north", "south", "west" }; + + @Test + void everyBarsConnectionPatternUsesANonOverlappingModel() throws Exception { + int models = 0; + try (Stream files = Files.list(ASSETS.resolve("blockstates"))) { + for (final Path state : (Iterable) files.sorted()::iterator) { + if (!state.getFileName().toString().endsWith("_bars.json")) { + continue; + } + + final JsonObject variants = read(state).getAsJsonObject("variants"); + assertEquals(16, variants.entrySet().size(), state.toString()); + for (int pattern = 0; pattern < 16; pattern++) { + final List bits = new ArrayList<>(); + for (int bit = 0; bit < DIRECTIONS.length; bit++) { + bits.add(DIRECTIONS[bit] + "=" + ((pattern & (1 << bit)) != 0)); + } + final String key = String.join(",", bits); + assertTrue(variants.has(key), state + " lacks " + key); + final String model = variants.getAsJsonObject(key).get("model").getAsString(); + checkFaces(resolveModel(model, new HashSet<>()), model); + } + models++; + } + } + + assertEquals(27, models); + } + + private static JsonArray resolveModel(final String id, final Set parents) throws Exception { + assertTrue(parents.add(id), "Model parent cycle: " + id); + assertTrue(id.startsWith("basemetals:"), "Unexpected bars model " + id); + String name = id.substring("basemetals:".length()); + if (!name.startsWith("block/")) { + name = "block/" + name; + } + final JsonObject model = read(ASSETS.resolve("models/" + name + ".json")); + return model.has("elements") ? model.getAsJsonArray("elements") + : resolveModel(model.get("parent").getAsString(), parents); + } + + private static void checkFaces(final JsonArray elements, final String model) { + final List faces = new ArrayList<>(); + for (final JsonElement value : elements) { + final JsonObject element = value.getAsJsonObject(); + for (final Map.Entry side : element.getAsJsonObject("faces").entrySet()) { + faces.add(new Face(side.getKey(), coordinates(element, "from"), coordinates(element, "to"))); + } + } + + for (int first = 0; first < faces.size(); first++) { + for (int second = first + 1; second < faces.size(); second++) { + assertFalse(faces.get(first).overlaps(faces.get(second)), model + " has overlapping faces"); + } + } + } + + private static double[] coordinates(final JsonObject element, final String name) { + final JsonArray values = element.getAsJsonArray(name); + return new double[] { values.get(0).getAsDouble(), values.get(1).getAsDouble(), values.get(2).getAsDouble() }; + } + + private static JsonObject read(final Path path) throws Exception { + try (Reader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) { + return new JsonParser().parse(reader).getAsJsonObject(); + } + } + + private static final class Face { + private final String side; + private final int axis; + private final double[] from; + private final double[] to; + private final double plane; + + private Face(final String side, final double[] from, final double[] to) { + this.side = side; + this.axis = "west".equals(side) || "east".equals(side) ? 0 + : "down".equals(side) || "up".equals(side) ? 1 : 2; + this.from = from; + this.to = to; + this.plane = "west".equals(side) || "down".equals(side) || "north".equals(side) + ? from[axis] : to[axis]; + } + + private boolean overlaps(final Face other) { + if (!side.equals(other.side) || Math.abs(plane - other.plane) > 0.01) { + return false; + } + for (int dimension = 0; dimension < 3; dimension++) { + if (dimension != axis && Math.min(to[dimension], other.to[dimension]) + - Math.max(from[dimension], other.from[dimension]) < 0.000001) { + return false; + } + } + return true; + } + } +} diff --git a/src/test/java/zone/moddev/mc/basemetals/content/ContentPolicyTest.java b/src/test/java/zone/moddev/mc/basemetals/content/ContentPolicyTest.java new file mode 100644 index 000000000..dcc0c6576 --- /dev/null +++ b/src/test/java/zone/moddev/mc/basemetals/content/ContentPolicyTest.java @@ -0,0 +1,60 @@ +package zone.moddev.mc.basemetals.content; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import net.minecraft.util.ResourceLocation; +import org.junit.jupiter.api.Test; + +class ContentPolicyTest { + private final ContentPolicy low = ContentPolicy.forMode(ContentMode.LOW_FANTASY); + + @Test + void olderConfigsAndInvalidValuesKeepTheFullRecipeSet() { + assertEquals(ContentMode.HIGH_FANTASY, ContentMode.fromSerializedName(null)); + assertEquals(ContentMode.HIGH_FANTASY, ContentMode.fromSerializedName("invalid")); + assertEquals(ContentMode.LOW_FANTASY, ContentMode.fromSerializedName(" Low_Fantasy ")); + + final ContentPolicy high = ContentPolicy.forMode(null); + for (final MaterialForm form : MaterialForm.values()) { + assertTrue(high.allows("adamantine", form)); + assertTrue(high.allows("mercury", form)); + } + } + + @Test + void lowFantasyKeepsMaterialsButLimitsTheFormsTheyCanMake() { + assertTrue(low.allows(id("adamantine_ore"))); + assertTrue(low.allows(id("adamantine_pickaxe"))); + assertTrue(low.allows(id("adamantine_arrow"))); + assertFalse(low.allows(id("adamantine_bow"))); + assertFalse(low.allows(id("steel_crossbow"))); + assertFalse(low.allows(id("steel_fishing_rod"))); + assertFalse(low.allows(id("pewter_chestplate"))); + assertFalse(low.allows(id("pewter_horse_armor"))); + assertTrue(low.allows(id("double_pewter_slab"))); + assertTrue(low.allows(id("silver_sword"))); + assertFalse(low.allows(id("silver_pickaxe"))); + assertTrue(low.allows(id("diamond_crackhammer"))); + assertFalse(low.allows(id("copper_anvil"))); + assertTrue(low.allows(id("steel_anvil"))); + assertTrue(low.allows(id("mercury"))); + assertTrue(low.allows(id("mercury_ingot"))); + assertTrue(low.allows(id("mercury_powder"))); + assertFalse(low.allows(id("mercury_block"))); + assertFalse(low.allows(id("mercury_powder_dirty"))); + } + + @Test + void vanillaAndAddOnsKeepTheirOwnRules() { + assertTrue(low.allows(new ResourceLocation("minecraft:bow"))); + assertTrue(low.allows(new ResourceLocation("basegems:diamond_bow"))); + assertTrue(low.allows(new ResourceLocation("modernmetals:steel_crossbow"))); + assertTrue(low.allows(id("human_detector"))); + } + + private static ResourceLocation id(final String name) { + return new ResourceLocation("basemetals", name); + } +} diff --git a/src/test/java/zone/moddev/mc/basemetals/release/ReleaseSetupTests.java b/src/test/java/zone/moddev/mc/basemetals/release/ReleaseSetupTests.java index c98f12c3b..bc79160fe 100644 --- a/src/test/java/zone/moddev/mc/basemetals/release/ReleaseSetupTests.java +++ b/src/test/java/zone/moddev/mc/basemetals/release/ReleaseSetupTests.java @@ -24,8 +24,8 @@ void releaseMetadataMatchesTheSharedDispatcher() throws Exception { values.load(reader); } - assertEquals("1.10.2", values.getProperty("minecraft_version")); - assertTrue(values.getProperty("mod_version").matches("\\d+\\.\\d+\\.\\d+\\.110021")); + assertEquals("1.11.2", values.getProperty("minecraft_version")); + assertTrue(values.getProperty("mod_version").matches("\\d+\\.\\d+\\.\\d+\\.111021")); assertEquals("forge", values.getProperty("loader_name")); assertEquals("1", values.getProperty("loader_code")); assertEquals("240967", values.getProperty("curseforge_project_id")); @@ -53,7 +53,7 @@ void workflowsUseCanonicalBranchesAndPinnedActions() throws Exception { } } if (!path.endsWith("release-on-tag.yml")) { - assertTrue(workflow.contains("master-1.10.2"), path.toString()); + assertTrue(workflow.contains("master-1.11.2"), path.toString()); assertFalse(workflow.contains("master-1.12"), path.toString()); } } diff --git a/src/test/java/zone/moddev/mc/basemetals/worldgen/BaseMetalsWorldgenProviderTests.java b/src/test/java/zone/moddev/mc/basemetals/worldgen/BaseMetalsWorldgenProviderTests.java index a8879cbf3..816bee504 100644 --- a/src/test/java/zone/moddev/mc/basemetals/worldgen/BaseMetalsWorldgenProviderTests.java +++ b/src/test/java/zone/moddev/mc/basemetals/worldgen/BaseMetalsWorldgenProviderTests.java @@ -29,6 +29,7 @@ void preservesTheElevenHistoricalRules() throws Exception { final JsonObject ore = ores.getAsJsonObject("basemetals:legacy/" + entry.getKey()); final JsonObject parameters = old.getAsJsonObject("parameters"); assertEquals(old.getAsJsonArray("blocks").get(0).getAsJsonObject().get("name"), ore.get("block")); + assertEquals("orespawn:" + entry.getKey().replaceFirst("_ore$", ""), ore.get("material").getAsString()); assertFalse(ore.get("native_generation").getAsBoolean()); assertFalse(ore.get("retrogen").getAsBoolean()); diff --git a/tools/validation/legacy110/README.md b/tools/validation/legacy110/README.md index ba7461506..2d7c38d5f 100644 --- a/tools/validation/legacy110/README.md +++ b/tools/validation/legacy110/README.md @@ -1,8 +1,18 @@ -# 1.10 migration checks +# 1.11.2 packaged checks and 1.10 reference fixtures These checks use disposable worlds. Never point a server launch at the only copy of a player's world. +For 1.11.2, use `packagedForgeRuntimeTest` as described in the +[build guide](../../../docs/BUILDING.md). It runs Forge 13.20.1.2588 against the +public 1.11.2 releases. It checks both Fantasy Levels, molten metal contact, +an old 1.11.2 save, and fresh and reloaded worlds with and without Modern Metals. +It also checks OreSpawn imports, a moved OreSpawn 1 world, and the vanilla-ore +switch. The directory retains its historical name because it also holds the +1.10 fixtures and probes described below. + +## 1.10 reference + The main Gradle project compiles the complete mod with Forge 2511 and stable-29 mappings. Run the repository's wrapper from the project root, using Java 17 for Gradle. The Java 8 compiler and runtime are selected separately: @@ -94,7 +104,7 @@ settings, reloads and later exploration, confirms Base Metals ores still generat and compares 49 existing chunks after switching off, on and back off. The source configuration and fixture world must remain unchanged. -## Automated CI suite +## 1.10 CI reference `packagedForgeRuntimeTest` builds all probes separately and runs `run_ci_checks.py`. It downloads checksum-pinned public releases, creates its own disposable Cyano diff --git a/tools/validation/legacy110/capture-probe/com/mcmoddev/validation/LegacyCapture.java b/tools/validation/legacy110/capture-probe/com/mcmoddev/validation/LegacyCapture.java index 03f46715f..0e0113072 100644 --- a/tools/validation/legacy110/capture-probe/com/mcmoddev/validation/LegacyCapture.java +++ b/tools/validation/legacy110/capture-probe/com/mcmoddev/validation/LegacyCapture.java @@ -55,7 +55,7 @@ public final class LegacyCapture { @EventHandler public void serverStarted(FMLServerStartedEvent event) throws IOException { net.minecraft.server.MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance(); - Path worldRoot = server.worldServerForDimension(0).getSaveHandler().getWorldDirectory().toPath(); + Path worldRoot = server.getWorld(0).getSaveHandler().getWorldDirectory().toPath(); if (Files.isRegularFile(worldRoot.resolve("legacy_registry_manifest_runtime.json"))) { verifySavedFixture(server, worldRoot); server.saveAllWorlds(false); @@ -66,15 +66,15 @@ public void serverStarted(FMLServerStartedEvent event) throws IOException { net.minecraftforge.common.DimensionManager.initDimension(-1); net.minecraftforge.common.DimensionManager.initDimension(1); List worlds = new ArrayList<>(); - worlds.add(server.worldServerForDimension(0)); - worlds.add(server.worldServerForDimension(-1)); - worlds.add(server.worldServerForDimension(1)); + worlds.add(server.getWorld(0)); + worlds.add(server.getWorld(-1)); + worlds.add(server.getWorld(1)); WorldServer world = worlds.get(0); JsonObject manifest = new JsonObject(); - manifest.addProperty("source", "live Forge 1.10.2 registries"); - manifest.addProperty("forge", "12.18.3.2511"); + manifest.addProperty("source", "live Forge 1.11.2 registries"); + manifest.addProperty("forge", "13.20.1.2588"); manifest.addProperty("fixture_format", 2); - manifest.addProperty("source_minecraft", "1.10.2"); + manifest.addProperty("source_minecraft", "1.11.2"); net.minecraftforge.fml.common.ModContainer mod = net.minecraftforge.fml.common.Loader.instance() .getIndexedModList().get("basemetals"); manifest.addProperty("source_basemetals", mod.getVersion()); @@ -105,7 +105,7 @@ public void serverStarted(FMLServerStartedEvent event) throws IOException { } } Files.write(worldDir.resolve("BASEMETALS_1_10_FIXTURE_COMPLETE.txt"), - ("Base Metals 1.10 fixture format 2 captured with " + blockIds.size() + ("Base Metals 1.11 fixture format 2 captured with " + blockIds.size() + " blocks in all three dimensions, " + itemIds.size() + " exact item stacks, filled fluid buckets, armor stands, and player data.\n") .getBytes(StandardCharsets.UTF_8)); @@ -132,7 +132,7 @@ private static void verifySavedFixture(net.minecraft.server.MinecraftServer serv JsonObject block = element.getAsJsonObject(); for (com.google.gson.JsonElement stateElement : block.getAsJsonArray("states")) { JsonObject saved = stateElement.getAsJsonObject(); - WorldServer world = server.worldServerForDimension(saved.get("dimension").getAsInt()); + WorldServer world = server.getWorld(saved.get("dimension").getAsInt()); BlockPos pos = new BlockPos(saved.get("x").getAsInt(), saved.get("y").getAsInt(), saved.get("z").getAsInt()); IBlockState actual = world.getBlockState(pos); @@ -141,7 +141,7 @@ private static void verifySavedFixture(net.minecraft.server.MinecraftServer serv throw new IllegalStateException("Source fixture lost " + expectedId + " at " + pos); } - // Record the state that 1.10 actually saved, not properties computed from neighbours. + // Record the state saved to disk, not properties computed from neighbours. saved.addProperty("saved_metadata", actual.getBlock().getMetaFromState(actual)); JsonObject properties = new JsonObject(); for (Map.Entry, Comparable> property @@ -154,7 +154,7 @@ private static void verifySavedFixture(net.minecraft.server.MinecraftServer serv } } - WorldServer world = server.worldServerForDimension(0); + WorldServer world = server.getWorld(0); int stacks = 0; for (com.google.gson.JsonElement element : manifest.getAsJsonArray("items")) { JsonObject saved = element.getAsJsonObject(); @@ -163,10 +163,11 @@ private static void verifySavedFixture(net.minecraft.server.MinecraftServer serv world.getBlockState(pos); TileEntityChest chest = (TileEntityChest) world.getTileEntity(pos); ItemStack stack = chest.getStackInSlot(saved.get("slot").getAsInt()); - if (stack == null || !stack.getItem().getRegistryName().toString().equals(saved.get("id").getAsString()) - || stack.stackSize != saved.get("count").getAsInt() - || stack.getItemDamage() != saved.get("damage").getAsInt()) { - throw new IllegalStateException("Source fixture inventory changed at " + pos); + if (stack.isEmpty() || !stack.getItem().getRegistryName().toString().equals(saved.get("id").getAsString()) + || stack.getCount() != saved.get("count").getAsInt() + || stack.getItemDamage() != saved.get("damage").getAsInt() + || !String.valueOf(stack.getTagCompound()).equals(saved.get("tag_snbt").getAsString())) { + throw new IllegalStateException("Saved inventory changed: " + saved.get("id") + " at " + pos); } if (saved.has("armor_x")) { BlockPos armorPos = new BlockPos(saved.get("armor_x").getAsDouble(), @@ -179,9 +180,10 @@ private static void verifySavedFixture(net.minecraft.server.MinecraftServer serv for (EntityEquipmentSlot equipment : EntityEquipmentSlot.values()) { if (!equipment.getName().equals(saved.get("armor_slot").getAsString())) continue; ItemStack worn = stand.getItemStackFromSlot(equipment); - found |= worn != null && worn.getItem().getRegistryName().toString() + found |= !worn.isEmpty() && worn.getItem().getRegistryName().toString() .equals(saved.get("id").getAsString()) - && worn.getItemDamage() == saved.get("damage").getAsInt(); + && worn.getItemDamage() == saved.get("damage").getAsInt() + && String.valueOf(worn.getTagCompound()).equals(saved.get("tag_snbt").getAsString()); } } if (!found) throw new IllegalStateException("Source armor stand was not saved: " + saved.get("id")); @@ -250,13 +252,13 @@ private static JsonArray captureItems(WorldServer world, List stack.setItemDamage(Math.max(1, stack.getMaxDamage() / 3)); if (stack.isItemEnchantable()) stack.addEnchantment(Enchantments.UNBREAKING, 2); } - NBTTagCompound fixtureTag = stack.getSubCompound("basemetals_fixture", true); + NBTTagCompound fixtureTag = stack.getOrCreateSubCompound("basemetals_fixture"); fixtureTag.setString("proof", id.toString()); stack.setStackDisplayName("Fixture " + id.toString()); entry.addProperty("custom_name", stack.getDisplayName()); entry.addProperty("metadata", stack.getMetadata()); entry.addProperty("damage", stack.getItemDamage()); - entry.addProperty("count", stack.stackSize); + entry.addProperty("count", stack.getCount()); entry.addProperty("max_damage", stack.getMaxDamage()); entry.addProperty("enchanted", stack.isItemEnchanted()); entry.addProperty("tag_snbt", stack.getTagCompound().toString()); @@ -352,7 +354,7 @@ private static JsonArray capturePlayer(WorldServer world, List for (int slot = 0; slot < Math.min(9, itemIds.size()); slot++) { ResourceLocation id = itemIds.get(slot); ItemStack stack = new ItemStack(ForgeRegistries.ITEMS.getValue(id)); - NBTTagCompound fixtureTag = stack.getSubCompound("basemetals_fixture", true); + NBTTagCompound fixtureTag = stack.getOrCreateSubCompound("basemetals_fixture"); fixtureTag.setString("player_proof", id.toString()); player.inventory.setInventorySlotContents(slot, stack); JsonObject value = new JsonObject(); diff --git a/tools/validation/legacy110/fantasy-probe/review/fantasy/FantasyGuiProbe.java b/tools/validation/legacy110/fantasy-probe/review/fantasy/FantasyGuiProbe.java new file mode 100644 index 000000000..db02bc90d --- /dev/null +++ b/tools/validation/legacy110/fantasy-probe/review/fantasy/FantasyGuiProbe.java @@ -0,0 +1,160 @@ +package review.fantasy; + +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.Arrays; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiDisconnected; +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.minecraft.util.text.ITextComponent; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.client.FMLClientHandler; +import net.minecraftforge.fml.client.config.GuiConfig; +import net.minecraftforge.fml.client.config.GuiConfigEntries; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import zone.moddev.mc.basemetals.content.ContentMode; +import zone.moddev.mc.basemetals.util.Config; +import zone.moddev.mc.orespawn.api.client.WorldSettingsExtensionRegistry; + +@Mod(modid = "basemetalsfantasyguiprobe", name = "Base Metals configuration checks", version = "1", + clientSideOnly = true, dependencies = "required-after:basemetals") +public final class FantasyGuiProbe { + private boolean checked; + + @Mod.EventHandler + public void init(final FMLInitializationEvent event) { + if (Boolean.getBoolean("fantasy.guiProbe") || Boolean.getBoolean("fantasy.mismatchProbe")) { + MinecraftForge.EVENT_BUS.register(this); + } + } + + @SubscribeEvent + public void tick(final TickEvent.ClientTickEvent event) throws Exception { + final Minecraft client = Minecraft.getMinecraft(); + if (checked || event.phase != TickEvent.Phase.END) { + return; + } + if (Boolean.getBoolean("fantasy.mismatchProbe")) { + if (client.currentScreen instanceof GuiDisconnected) { + checkMismatch(client); + } + return; + } + if (!(client.currentScreen instanceof GuiMainMenu)) { + return; + } + checked = true; + final GuiScreen parent = client.currentScreen; + final GuiConfig forge = (GuiConfig) FMLClientHandler.instance() + .getGuiFactoryFor(Loader.instance().getIndexedModList().get("basemetals")) + .createConfigGui(parent); + final GuiConfig oreSpawn = (GuiConfig) WorldSettingsExtensionRegistry.extensions().stream() + .filter(extension -> extension.id().equals(new ResourceLocation("basemetals", "configuration"))) + .findFirst().get().createScreen(parent); + require(forge.configElements.size() == 7 && oreSpawn.configElements.size() == 7, "Expected seven categories"); + require(forge.allRequireMcRestart && oreSpawn.allRequireMcRestart, "Expected restart guidance"); + + final GuiConfig cancelled = openGeneral(client, oreSpawn); + selector(cancelled).valueButtonPressed(0); + escape(cancelled); + escape(oreSpawn); + require(client.currentScreen == parent, "Escape did not return to the parent"); + require("high_fantasy".equals(savedMode()), "Escape saved a pending change"); + + final GuiConfig general = openGeneral(client, forge); + final GuiConfigEntries.CycleValueEntry mode = selector(general); + require(Arrays.equals(new String[] { "high_fantasy", "low_fantasy" }, + mode.getConfigElement().getValidValues()), "Expected two choices"); + require(!I18n.format(mode.getConfigElement().getLanguageKey()) + .equals(mode.getConfigElement().getLanguageKey()), "Missing Fantasy Level label"); + mode.valueButtonPressed(0); + require("low_fantasy".equals(mode.getCurrentValue()), "Low Fantasy was not selected"); + mode.undoChanges(); + require("high_fantasy".equals(mode.getCurrentValue()), "Undo did not restore High Fantasy"); + mode.valueButtonPressed(0); + mode.setToDefault(); + require("high_fantasy".equals(mode.getCurrentValue()), "Defaults did not restore High Fantasy"); + mode.valueButtonPressed(0); + + done(general); + require("high_fantasy".equals(savedMode()), "A category saved before the root screen"); + require(client.currentScreen == forge, "Done did not return to the root screen"); + done(forge); + require("low_fantasy".equals(savedMode()), "Done did not save Low Fantasy"); + require(Config.getActiveContentMode() == ContentMode.HIGH_FANTASY, "Fantasy Level changed before restart"); + Files.write(Paths.get("fantasy-gui-pass.txt"), "Both config routes passed.\n".getBytes(StandardCharsets.UTF_8)); + client.shutdown(); + } + + private void checkMismatch(final Minecraft client) throws Exception { + checked = true; + for (final Field field : GuiDisconnected.class.getDeclaredFields()) { + if (field.getType() == ITextComponent.class) { + field.setAccessible(true); + final String message = ((ITextComponent) field.get(client.currentScreen)).getUnformattedText(); + require(message.contains("The server uses Low Fantasy, but your game uses High Fantasy."), message); + Files.write(Paths.get("fantasy-mismatch-pass.txt"), message.getBytes(StandardCharsets.UTF_8)); + client.shutdown(); + return; + } + } + throw new AssertionError("The disconnect screen had no reason"); + } + + private static GuiConfig openGeneral(final Minecraft client, final GuiConfig root) throws Exception { + client.displayGuiScreen(root); + final Field child = GuiConfigEntries.CategoryEntry.class.getDeclaredField("childScreen"); + child.setAccessible(true); + final GuiConfig general = (GuiConfig) child.get(root.entryList.listEntries.get(0)); + client.displayGuiScreen(general); + return general; + } + + private static GuiConfigEntries.CycleValueEntry selector(final GuiConfig general) { + return (GuiConfigEntries.CycleValueEntry) general.entryList.listEntries.stream() + .filter(entry -> "contentMode".equals(entry.getConfigElement().getName())).findFirst().get(); + } + + private static String savedMode() { + return Config.getConfiguration().getCategory("General").get("contentMode").getString(); + } + + private static void escape(final GuiConfig screen) throws Exception { + callback("keyTyped", "func_73869_a", char.class, int.class).invoke(screen, '\u001b', 1); + } + + private static void done(final GuiConfig screen) throws Exception { + callback("actionPerformed", "func_146284_a", GuiButton.class) + .invoke(screen, new GuiButton(2000, 0, 0, "Done")); + } + + private static Method callback(final String mapped, final String runtime, final Class... parameters) + throws Exception { + Method method; + try { + method = GuiConfig.class.getDeclaredMethod(mapped, parameters); + } catch (NoSuchMethodException missing) { + method = GuiConfig.class.getDeclaredMethod(runtime, parameters); + } + method.setAccessible(true); + return method; + } + + private static void require(final boolean condition, final String reason) { + if (!condition) { + throw new AssertionError(reason); + } + } +} diff --git a/tools/validation/legacy110/fantasy-probe/review/fantasy/FantasyProbe.java b/tools/validation/legacy110/fantasy-probe/review/fantasy/FantasyProbe.java new file mode 100644 index 000000000..f5cf72bbf --- /dev/null +++ b/tools/validation/legacy110/fantasy-probe/review/fantasy/FantasyProbe.java @@ -0,0 +1,95 @@ +package review.fantasy; + +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.mcmoddev.lib.registry.CrusherRecipeRegistry; +import net.minecraft.entity.passive.EntityVillager.ITradeList; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.item.crafting.FurnaceRecipes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.village.MerchantRecipeList; +import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.event.FMLServerStartedEvent; +import net.minecraftforge.fml.common.registry.ForgeRegistries; +import net.minecraftforge.fml.common.registry.VillagerRegistry; +import net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession; + +@Mod(modid = "basemetalsfantasyprobe", name = "Base Metals Fantasy Level checks", version = "1", + serverSideOnly = true, dependencies = "required-after:basemetals") +public final class FantasyProbe { + @Mod.EventHandler + public void started(final FMLServerStartedEvent event) throws Exception { + if (!Boolean.getBoolean("fantasy.serverProbe")) { + return; + } + + final Set registered = new TreeSet<>(); + ForgeRegistries.ITEMS.forEach(item -> registered.add(item.getRegistryName().toString())); + ForgeRegistries.BLOCKS.forEach(block -> registered.add(block.getRegistryName().toString())); + final Map crafting = new TreeMap<>(); + CraftingManager.getInstance().getRecipeList().forEach(recipe -> count(crafting, recipe.getRecipeOutput())); + final Map smelting = new TreeMap<>(); + FurnaceRecipes.instance().getSmeltingList().values().forEach(stack -> count(smelting, stack)); + final Map crushing = new TreeMap<>(); + CrusherRecipeRegistry.getInstance().getAllRecipes().forEach(recipe -> count(crushing, recipe.getOutput())); + + final GsonBuilder gson = new GsonBuilder().setPrettyPrinting(); + final JsonObject result = new JsonObject(); + result.addProperty("passed", true); + result.add("registry", gson.create().toJsonTree(registered)); + result.add("crafting", gson.create().toJsonTree(crafting)); + result.add("smelting", gson.create().toJsonTree(smelting)); + result.add("crushing", gson.create().toJsonTree(crushing)); + result.add("trades", gson.create().toJsonTree(smithTrades())); + if (Loader.isModLoaded("tconstruct")) { + final Class registry = Class.forName("slimeknights.tconstruct.library.TinkerRegistry"); + final Object material = registry.getMethod("getMaterial", String.class).invoke(null, "adamantine"); + result.addProperty("tinkersBow", (Boolean) material.getClass() + .getMethod("hasStats", String.class).invoke(material, "bow")); + result.addProperty("tinkersHead", (Boolean) material.getClass() + .getMethod("hasStats", String.class).invoke(material, "head")); + } + final String phase = System.getProperty("fantasy.phase", "first"); + Files.write(Paths.get(phase + "-fantasy.json"), gson.create().toJson(result).getBytes(StandardCharsets.UTF_8)); + FMLCommonHandler.instance().getMinecraftServerInstance().initiateShutdown(); + } + + private static Map smithTrades() { + final VillagerProfession smith = VillagerRegistry.instance().getRegistry() + .getValue(new ResourceLocation("minecraft:smith")); + final Map results = new TreeMap<>(); + for (int career = 0; career < 3; career++) { + for (int level = 1; level <= 10; level++) { + final List trades = smith.getCareer(career).getTrades(level); + if (trades == null) { + continue; + } + for (final ITradeList trade : trades) { + final MerchantRecipeList recipes = new MerchantRecipeList(); + trade.addMerchantRecipe(null, recipes, new Random(8675309)); + recipes.forEach(recipe -> count(results, recipe.getItemToSell())); + } + } + } + return results; + } + + private static void count(final Map counts, final ItemStack stack) { + if (stack != null && !stack.isEmpty() && stack.getItem().getRegistryName() != null) { + counts.merge(stack.getItem().getRegistryName().toString(), 1, Integer::sum); + } + } +} diff --git a/tools/validation/legacy110/launch-probe/review/launch/DevLaunchProbe.java b/tools/validation/legacy110/launch-probe/review/launch/DevLaunchProbe.java index 8b8d711a6..53c209159 100644 --- a/tools/validation/legacy110/launch-probe/review/launch/DevLaunchProbe.java +++ b/tools/validation/legacy110/launch-probe/review/launch/DevLaunchProbe.java @@ -2,16 +2,22 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; +import com.mojang.authlib.GameProfile; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.UUID; import java.util.concurrent.Future; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiMainMenu; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; +import net.minecraft.init.MobEffects; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.potion.PotionEffect; import net.minecraft.server.MinecraftServer; import net.minecraft.tileentity.TileEntityChest; import net.minecraft.util.ResourceLocation; @@ -60,14 +66,21 @@ public void started(final FMLServerStartedEvent event) throws Exception { } private static void checkWorld(final MinecraftServer server) { - final String expectedVersion = System.getProperty("launch.expectedVersion", "2.5.1.110021"); + final String expectedVersion = System.getProperty("launch.expectedVersion", "2.5.1.111021"); require(expectedVersion.equals(Loader.instance().getIndexedModList().get("basemetals").getVersion()), "Wrong Base Metals version"); require(Loader.isModLoaded("orespawn"), "The ordinary launch did not load OreSpawn"); + final boolean modernMetals = Loader.isModLoaded("modernmetals"); + require(modernMetals == Boolean.getBoolean("launch.modernMetals"), "Unexpected Modern Metals load state"); + if (modernMetals) { + require(net.minecraftforge.fml.common.registry.ForgeRegistries.ITEMS.containsKey( + new ResourceLocation("modernmetals", "aluminum_ingot")), "Modern Metals did not register aluminum"); + } for (final String optional : new String[]{"tconstruct", "ic2", "cofhcore", "Mekanism", "taiga", "golems_metal"}) { require(!Loader.isModLoaded(optional), "Optional mod leaked into ordinary launch: " + optional); } - final WorldServer world = server.worldServerForDimension(0); + final WorldServer world = server.getWorld(0); + if (Boolean.getBoolean("launch.moltenContact")) checkMoltenContact(world); final BlockPos position = new BlockPos(8, 80, 8); final ResourceLocation copper = new ResourceLocation("basemetals", "copper_block"); final Block block = net.minecraftforge.fml.common.registry.ForgeRegistries.BLOCKS.getValue(copper); @@ -88,22 +101,65 @@ private static void checkWorld(final MinecraftServer server) { require(world.getBlockState(position).getBlock() == block, "Saved copper block changed"); final TileEntityChest chest = (TileEntityChest) world.getTileEntity(position.up()); final ItemStack stack = chest.getStackInSlot(0); - require(stack != null && stack.getItem() == ingot && stack.stackSize == 3 + require(stack != null && stack.getItem() == ingot && stack.getCount() == 3 && "FG7 saved copper".equals(stack.getDisplayName()) && "kept across reload".equals(stack.getTagCompound() .getCompoundTag("BaseMetalsBuildCheck").getString("Check")), "Saved stack data changed"); - world.getChunkFromBlockCoords(position).setChunkModified(); + world.getChunkFromBlockCoords(position).markDirty(); if (Boolean.getBoolean("launch.remoteMarker")) { final BlockPos remote = new BlockPos(1288, 80, -1272); world.setBlockState(remote, block.getDefaultState(), 2); world.setBlockState(remote.up(), Blocks.CHEST.getDefaultState(), 2); final ItemStack saved = chest.getStackInSlot(0).copy(); ((TileEntityChest) world.getTileEntity(remote.up())).setInventorySlotContents(0, saved); - world.getChunkFromBlockCoords(remote).setChunkModified(); + world.getChunkFromBlockCoords(remote).markDirty(); } server.saveAllWorlds(false); } + private static void checkMoltenContact(final WorldServer world) { + final BlockPos pos = new BlockPos(8, 80, 12); + final ResourceLocation metalId = new ResourceLocation(System.getProperty("launch.moltenBlock", "basemetals:copper")); + final Block metal = net.minecraftforge.fml.common.registry.ForgeRegistries.BLOCKS.getValue(metalId); + final Block mercury = net.minecraftforge.fml.common.registry.ForgeRegistries.BLOCKS + .getValue(new ResourceLocation("basemetals", "mercury")); + require(metal != null && mercury != null, "Missing " + metalId + " or mercury block"); + try { + world.setBlockState(pos, metal.getDefaultState(), 2); + checkContact(world, pos, "deep " + metalId, 0.25, false, false, 4.0F); + checkContact(world, pos, "above " + metalId, 0.90, false, false, 0.0F); + checkContact(world, pos, "shallow " + metalId, 0.70, false, false, 4.0F); + checkContact(world, pos, "fire resistant player", 0.70, true, false, 0.0F); + checkContact(world, pos, "creative player", 0.70, false, true, 0.0F); + world.setBlockState(pos, metal.getStateFromMeta(1), 2); + checkContact(world, pos, "above flowing " + metalId, 0.80, false, false, 0.0F); + checkContact(world, pos, "shallow flowing " + metalId, 0.70, false, false, 4.0F); + world.setBlockState(pos, Blocks.WATER.getDefaultState(), 2); + checkContact(world, pos, "water", 0.25, false, false, 0.0F); + world.setBlockState(pos, mercury.getDefaultState(), 2); + checkContact(world, pos, "liquid mercury", 0.25, false, false, 0.0F); + } finally { + world.setBlockToAir(pos); + } + } + + private static void checkContact(final WorldServer world, final BlockPos pos, final String label, + final double height, final boolean resistant, final boolean creative, final float damage) { + final EntityPlayer player = new EntityPlayer(world, new GameProfile(UUID.randomUUID(), "FluidCheck")) { + @Override public boolean isSpectator() { return false; } + @Override public boolean isCreative() { return creative; } + }; + player.capabilities.disableDamage = creative; + if (resistant) player.addPotionEffect(new PotionEffect(MobEffects.FIRE_RESISTANCE, 200)); + player.setPosition(pos.getX() - 0.5, pos.getY() + height, pos.getZ() + 0.5); + player.move(net.minecraft.entity.MoverType.SELF, 1.0, 0.0, 0.0); + player.onEntityUpdate(); + final float actual = player.getMaxHealth() - player.getHealth(); + System.out.println("BASE_METALS_MOLTEN_CONTACT " + label + " damage=" + actual + " burning=" + player.isBurning()); + require(actual == damage && (damage == 0.0F || player.isBurning()), + label + " expected " + damage + " damage, got " + actual + ", burning=" + player.isBurning()); + } + private static void report(final boolean passed, final String detail) throws Exception { final JsonObject report = new JsonObject(); report.addProperty("phase", System.getProperty("launch.phase")); @@ -132,6 +188,8 @@ public void tick(final TickEvent.ClientTickEvent event) throws Exception { try { if (!opening && client.currentScreen instanceof GuiMainMenu && ++menuTicks >= 20) { + require("Copper Ingot".equals(I18n.format("item.basemetals.copper_ingot.name")), + "The English item names did not load"); opening = true; System.out.println("BASE_METALS_LAUNCH_MENU"); client.launchIntegratedServer("fg7-launch-check", "FG7 Launch Check", diff --git a/tools/validation/legacy110/orespawn-probe/review/worldgen/OreSpawn110Probe.java b/tools/validation/legacy110/orespawn-probe/review/worldgen/OreSpawn110Probe.java index d3a79aa4d..14d85935e 100644 --- a/tools/validation/legacy110/orespawn-probe/review/worldgen/OreSpawn110Probe.java +++ b/tools/validation/legacy110/orespawn-probe/review/worldgen/OreSpawn110Probe.java @@ -44,7 +44,7 @@ public void started(final FMLServerStartedEvent event) throws Exception { report.addProperty("phase", phase); try { - require("4.1.2.110021".equals(Loader.instance().getIndexedModList().get("orespawn").getVersion()), + require("4.1.6.111021".equals(Loader.instance().getIndexedModList().get("orespawn").getVersion()), "Wrong OreSpawn release"); for (final String retired : new String[] { "com.mcmoddev.orespawn.BaseMetalsOreSpawn", @@ -87,17 +87,17 @@ else require(!ore.getValue().toString().contains("basemetals:"), } require(oreSpawnGenerators == 1, "Expected exactly one OreSpawn generator"); if (System.getProperty("worldgen.vanillaManaged") != null) { - VanillaTakeoverChecks.check(server.worldServerForDimension(0), profile, report); + VanillaTakeoverChecks.check(server.getWorld(0), profile, report); } if (Boolean.getBoolean("worldgen.sample")) sampleOres(server, ores, report); if (Boolean.getBoolean("worldgen.savedMarker")) { - checkSavedMarker(server.worldServerForDimension(0), new BlockPos(8, 80, 8)); + checkSavedMarker(server.getWorld(0), new BlockPos(8, 80, 8)); if (Boolean.getBoolean("worldgen.openRemote")) { - checkSavedMarker(server.worldServerForDimension(0), new BlockPos(1288, 80, -1272)); + checkSavedMarker(server.getWorld(0), new BlockPos(1288, 80, -1272)); } } report.addProperty("passed", true); - System.out.println("BASE_METALS_OS41_PASS " + phase + " rules=" + owned); + System.out.println("BASE_METALS_ORESPAWN_PASS " + phase + " rules=" + owned); server.saveAllWorlds(false); } catch (final Throwable failure) { report.addProperty("passed", false); @@ -114,7 +114,7 @@ private static void sampleOres(final MinecraftServer server, final JsonObject or final JsonObject samples = new JsonObject(); for (final int dimension : new int[] { 0, -1, 1 }) { if (DimensionManager.getWorld(dimension) == null) DimensionManager.initDimension(dimension); - final WorldServer world = server.worldServerForDimension(dimension); + final WorldServer world = server.getWorld(dimension); final String name = dimension == 0 ? "minecraft:overworld" : dimension == -1 ? "minecraft:the_nether" : "minecraft:the_end"; final Map counts = new LinkedHashMap<>(); @@ -168,12 +168,12 @@ private static void checkSavedMarker(final WorldServer world, final BlockPos pos "An existing copper block changed"); final TileEntityChest chest = (TileEntityChest) world.getTileEntity(position.up()); final ItemStack stack = chest.getStackInSlot(0); - require(stack != null && stack.stackSize == 3 + require(stack != null && stack.getCount() == 3 && "basemetals:copper_ingot".equals(stack.getItem().getRegistryName().toString()) && "FG7 saved copper".equals(stack.getDisplayName()) && "kept across reload".equals(stack.getTagCompound() .getCompoundTag("BaseMetalsBuildCheck").getString("Check")), "Saved item data changed"); - world.getChunkFromBlockCoords(position).setChunkModified(); + world.getChunkFromBlockCoords(position).markDirty(); } private static void assertSubset(final JsonElement expected, final JsonElement actual, final String path) { diff --git a/tools/validation/legacy110/run_ci_checks.py b/tools/validation/legacy110/run_ci_checks.py index 2dbd21b39..b1f09a60e 100644 --- a/tools/validation/legacy110/run_ci_checks.py +++ b/tools/validation/legacy110/run_ci_checks.py @@ -2,6 +2,7 @@ import argparse import hashlib +import json import subprocess import sys import time @@ -9,18 +10,17 @@ import urllib.request from pathlib import Path -from run_orespawn_checks import digest, prepare, run +from run_orespawn_checks import JAR_NAME, digest, prepare, reject_dependency, run ROOT = Path(__file__).resolve().parents[3] FIXTURES = Path(__file__).with_name("fixtures") RELEASES = { - "cyano": ("base-metals-240967", "2323100", "F919CEF794C73F02758BBD967346DBA0B53F6383153C7E29BD79F211CDA8C319"), - "mmd": ("base-metals-240967", "2533174", "51F04770C316E62D9ED3EF713144F02FA2EC899645813627091365E12F61C3EF"), - "mmdlib": ("mmdlib-261744", "2400405", "286149F4E8132535135C27285A750916D35AB3ECDDB28AE4475FC604D1FDF178"), - "os3": ("mmd-orespawn-245586", "2533153", "D964148C20175E16CCEFAB02AE43A181A50DC08A1D636A77E59CFE8C8EA8D41A"), - "os1": ("mmd-orespawn-245586", "2323091", "91345E4B825AA06E05F470066F467AABA0C7A2804A8DBCA4D3CD1905ED53607C"), - "orespawn": ("mmd-orespawn-245586", "9276430", "4D4975421FEEBF17505056306D06B0344D7A4553B6275885D7C5C5065B0348A6"), + "mmd": ("base-metals-240967", "2533178", "ABDF704023100AD6BB70351CE72C31A07943AD5BCE8308155564194A25089CCC"), + "os3": ("mmd-orespawn-245586", "2533159", "05CC48E59C7B20ED9B7F29AE014F5E2E5B2F16F289EF7D6F274F017B5E2A6F77"), + "orespawn": ("mmd-orespawn-245586", "9524249", "4246D1EB83FFFC325F04E3D3FE331D1404714F4A8D773ADE278A5D0EBEE5EDBC"), + "old_os4": ("mmd-orespawn-245586", "8840593", "51FF282D41E3C566DB2541CCAD53968030EA12E985A5CEE7307162BBF560C99A"), + "modern_metals": ("modern-metals-244357", "2534044", "8F5011542650A03A7B25E4BCB410D676A5FB6AD705B91552E494A08A6C43087A"), } @@ -49,17 +49,67 @@ def download(directory, name): return target -def capture(java, directory): - log = directory / "capture-console.txt" +def capture(java, directory, phase, marker): + log = directory / f"{phase}-console.txt" with log.open("wb") as output: result = subprocess.run([str(java), "-Xms256M", "-Xmx2G", "-jar", - "forge-1.10.2-12.18.3.2511-universal.jar", "nogui"], + JAR_NAME, "nogui"], cwd=directory, stdout=output, stderr=subprocess.STDOUT, timeout=360) - manifest = directory / "legacy_registry_manifest_runtime.json" - if result.returncode or not manifest.is_file() or "BASEMETALS_LEGACY_CAPTURE" not in log.read_text(errors="replace"): + manifest = directory / "world/legacy_registry_manifest_runtime.json" + if result.returncode or not manifest.is_file() or marker not in log.read_text(errors="replace"): raise AssertionError(f"Legacy fixture capture failed: {log}") +def compare_saved_block_states(source, target): + def states(directory): + manifest = directory / "world/legacy_registry_manifest_runtime.json" + return json.loads(manifest.read_text(encoding="utf-8"))["blocks"] + + before, after = states(source), states(target) + for block in after: + if block["id"].endswith("_slab"): + # The 1.10-based model uses a single named variant; it uses no saved metadata bits. + for state in block["states"]: + props = state["saved_properties"] + if props.get("variant") == "default": + del props["variant"] + if before != after: + raise AssertionError("Saved block metadata or properties changed") + + +def check_fantasy_modes(args, mods): + modes = {} + for name, setting in (("legacy", ""), ("high", "S:contentMode=high_fantasy"), + ("low", "S:contentMode=low_fantasy")): + target = args.output / ("fantasy-" + name) + prepare(target, args.template, mods) + config = target / "config/BaseMetals.cfg" + config.parent.mkdir() + config.write_text(f"general {{\n B:crackhammer_full_stacks=true\n {setting}\n}}\n", encoding="utf-8") + modes[name] = run(args.java, target, "first", {"fantasy.serverProbe": "true"}, report_kind="fantasy") + if "B:crackhammer_full_stacks=true" not in config.read_text(encoding="utf-8"): + raise AssertionError("Reading the Fantasy Level changed an existing setting") + profile = json.loads((target / "world/serverconfig/orespawn-worldgen.json").read_text(encoding="utf-8")) + modes[name]["ores"] = {key: value for key, value in profile["ores"].items() if key.startswith("basemetals:")} + + high, low = modes["high"], modes["low"] + if modes["legacy"] != high: + raise AssertionError("A config without Fantasy Level did not behave like High Fantasy") + if high["registry"] != low["registry"] or high["ores"] != low["ores"] or len(low["ores"]) != 11: + raise AssertionError("Low Fantasy changed the registry or ore rules") + for key in ("basemetals:adamantine_bow", "basemetals:steel_crossbow", + "basemetals:steel_fishing_rod", "basemetals:pewter_chestplate"): + if key not in high["crafting"] or key in low["crafting"]: + raise AssertionError(f"Incorrect crafting availability for {key}") + for key in ("basemetals:adamantine_pickaxe", "basemetals:steel_sword", "minecraft:bow"): + if key not in high["crafting"] or high["crafting"][key] != low["crafting"].get(key): + raise AssertionError(f"Low Fantasy unexpectedly changed {key}") + for key in ("basemetals:brass_pickaxe", "basemetals:electrum_sword"): + if key not in high["trades"] or key in low["trades"]: + raise AssertionError(f"Incorrect villager trade availability for {key}") + print("BASE_METALS_FANTASY_MODES_PASS", flush=True) + + def main(): parser = argparse.ArgumentParser(description=__doc__) for name in ("java", "template", "output"): @@ -70,7 +120,7 @@ def main(): downloads = args.output / "downloads" downloads.mkdir() jars = {name: download(downloads, name) for name in RELEASES} - mod = ROOT / "build/libs/BaseMetals-2.5.1.110021.jar" + mod = ROOT / "build/libs/BaseMetals-2.5.1.111021.jar" probes = ROOT / "build/test-mods" def script(name, *arguments): @@ -79,35 +129,37 @@ def script(name, *arguments): "--mod", str(mod), "--orespawn", str(jars["orespawn"]), "--probe", str(probes / "orespawn-probe-packaged.jar"), *map(str, arguments)], check=True) + launch = probes / "launch-probe-packaged.jar" + reject_dependency(args.java, args.output / "old-os4-rejected", args.template, [mod, jars["old_os4"]]) + check_fantasy_modes(args, [mod, jars["orespawn"], probes / "fantasy-probe-packaged.jar"]) + for name, addons in (("base-only", []), ("modern-metals", [jars["modern_metals"]])): + target = args.output / name + prepare(target, args.template, [mod, jars["orespawn"], launch, *addons]) + for phase in ("fresh", "reload"): + run(args.java, target, phase, {"launch.phase": phase, "launch.moltenContact": "true", + "launch.modernMetals": "true" if addons else "false"}, report_kind="launch") + + probe = probes / "legacy-capture-packaged.jar" + source = args.output / "old-1.11.2" + prepare(source, args.template, [jars["mmd"], jars["os3"], probe]) + properties = source / "server.properties" + properties.write_text(properties.read_text(encoding="utf-8") + "generate-structures=false\n", encoding="utf-8") + capture(args.java, source, "capture", "BASEMETALS_LEGACY_CAPTURE PASS") + capture(args.java, source, "control-reload", "BASEMETALS_LEGACY_CAPTURE_RELOAD PASS") + before = {p.relative_to(source / "world"): digest(p) for p in (source / "world").rglob("*") if p.is_file()} + target = args.output / "upgraded-1.11.2" + prepare(target, args.template, [mod, jars["orespawn"], probe], source / "world") + for phase in ("first", "reload"): + capture(args.java, target, phase, "BASEMETALS_LEGACY_CAPTURE_RELOAD PASS") + compare_saved_block_states(source, target) + after = {p.relative_to(source / "world"): digest(p) for p in (source / "world").rglob("*") if p.is_file()} + if before != after: + raise AssertionError("The source fixture was modified") + script("run_orespawn_checks.py", "--output", args.output / "worldgen", "--os3", FIXTURES / "orespawn3-basemetals.json", "--os1", FIXTURES / "orespawn1-basemetals.json", - "--old-mod", jars["mmd"], "--old-orespawn", jars["os3"], - "--old-support-mod", jars["mmdlib"], "--old-version", "2.5.0-beta4", - "--launch-probe", probes / "launch-probe-packaged.jar") + "--old-mod", jars["mmd"], "--old-orespawn", jars["os3"], "--launch-probe", launch) script("run_vanilla_takeover_checks.py", "--output", args.output / "takeover") - - for family in ("cyano", "mmd"): - source = args.output / (family + "-source") - support = [jars["mmdlib"], jars["os3"]] if family == "mmd" else [jars["os1"]] - prepare(source, args.template, [jars[family], *support, probes / "legacy-capture-packaged.jar"]) - # Villages can otherwise populate over the remote block-state test grid. - properties = source / "server.properties" - properties.write_text(properties.read_text(encoding="utf-8") + "generate-structures=false\n", encoding="utf-8") - capture(args.java, source) - capture(args.java, source) - before = {p.relative_to(source / "world"): digest(p) for p in (source / "world").rglob("*") if p.is_file()} - target = args.output / (family + "-upgraded") - prepare(target, args.template, [mod, jars["orespawn"], probes / "legacy110-probe.jar"], source / "world") - manifest = source / "world/legacy_registry_manifest_runtime.json" - later = target / "world/region/r.-2.2.mca" - unopened = digest(later) - for phase in ("first", "reload", "delayed", "stable"): - run(args.java, target, phase, {"review.phase": phase, "review.manifest": manifest}, report_kind="review") - if phase in ("first", "reload") and digest(later) != unopened: - raise AssertionError("An unopened fixture region changed during upgrade") - after = {p.relative_to(source / "world"): digest(p) for p in (source / "world").rglob("*") if p.is_file()} - if before != after: - raise AssertionError("The source fixture was modified") print("BASE_METALS_CI_RUNTIME_PASS", flush=True) diff --git a/tools/validation/legacy110/run_orespawn_checks.py b/tools/validation/legacy110/run_orespawn_checks.py index e7c0564a2..849b38e59 100644 --- a/tools/validation/legacy110/run_orespawn_checks.py +++ b/tools/validation/legacy110/run_orespawn_checks.py @@ -11,7 +11,7 @@ DIMENSIONS = {-1: "minecraft:the_nether", 0: "minecraft:overworld", 1: "minecraft:the_end"} -JAR_NAME = "forge-1.10.2-12.18.3.2511-universal.jar" +JAR_NAME = "forge-1.11.2-13.20.1.2588-universal.jar" def write_json(path, value): @@ -25,7 +25,7 @@ def digest(path): def prepare(directory, template, mods, world=None, flat=True): directory.mkdir(parents=True, exist_ok=False) - for name in (JAR_NAME, "minecraft_server.1.10.2.jar"): + for name in (JAR_NAME, "minecraft_server.1.11.2.jar"): shutil.copy2(template / name, directory / name) shutil.copytree(template / "libraries", directory / "libraries") (directory / "mods").mkdir() @@ -60,6 +60,9 @@ def run(java, directory, phase, properties, report_kind="worldgen", expected_fai raise AssertionError(f"Did not reproduce the old generator: {report_path}") elif result.returncode or not report.get("passed"): raise AssertionError(f"Runtime check failed: {report_path}; read {log}") + elif any(text in log.read_text(encoding="utf-8", errors="replace") for text in + ("Saving entity NBT", "has thrown an exception trying to write state", "Encountered an unexpected exception")): + raise AssertionError(f"Unexpected save or startup failure; read {log}") print(directory.name, phase, "expected failure" if expected_failure else "passed", flush=True) return report @@ -73,7 +76,7 @@ def reject_dependency(java, directory, template, mods): text = log.read_text(encoding="utf-8", errors="replace") if ("MissingModsException" not in text or "orespawn" not in text - or "4.1.2.110021" not in text or (directory / "world/level.dat").exists()): + or "4.1.6.111021" not in text or (directory / "world/level.dat").exists()): raise AssertionError(f"The unsupported dependency was not clearly rejected; read {log}") print(directory.name, "rejected before world load", flush=True) @@ -122,6 +125,50 @@ def expected_os1(source): return {"ores": ores} +def check_os1_reload_profile(before, after, expected): + # OreSpawn records which imported rules replace native defaults on reload. + # Nothing else in the saved profile should change. + replacements = { + "basemetals:legacy/" + ore["block"].split(":", 1)[1]: rule + for rule, ore in expected["ores"].items() + } + provider = after["providers"]["basemetals"] + if provider.get("legacy_ore_replacements") != replacements: + raise AssertionError("OreSpawn did not record the expected OS1 rule replacements") + if "legacy_ore_replacements" not in before["providers"]["basemetals"]: + del provider["legacy_ore_replacements"] + if before != after: + raise AssertionError("OS1 reload changed more than the rule replacement index") + + +def check_moved_os1_world(args, source, mods, stock): + target = args.output / "os1-world-only-move" + prepare(target, args.template, mods, source / "world") + profile = target / "world/serverconfig/orespawn-worldgen.json" + original = json.loads(profile.read_text(encoding="utf-8")) + imported = {key: value for key, value in original["ores"].items() if key.startswith("basemetals:")} + # Model a world saved before OreSpawn could record replacement IDs. + original["providers"]["basemetals"].pop("legacy_ore_replacements", None) + write_json(profile, original) + expected = dict(imported) + imported_outputs = {ore["block"] for ore in imported.values()} + for key, rule in expected_os3(stock)["ores"].items(): + if rule["block"] not in imported_outputs: + expected[key] = rule + expected_path = target / "expected.json" + write_json(expected_path, {"ores": expected}) + remote = target / "world/region/r.2.-3.mca" + unopened = digest(remote) + for phase in ("first", "reload"): + result = run(args.java, target, phase, {"worldgen.phase": phase, + "worldgen.expected": expected_path, "worldgen.savedMarker": "true"}) + active = result["profile"]["ores"] + if any(active.get(key) != ore for key, ore in imported.items()): + raise AssertionError("Moving the world changed an imported rule") + if digest(remote) != unopened: + raise AssertionError("Moving the world changed an unopened region") + + def main(): parser = argparse.ArgumentParser(description=__doc__) for name in ("java", "template", "mod", "orespawn", "probe", "output", "os3"): @@ -130,7 +177,7 @@ def main(): parser.add_argument("--old-mod", type=Path) parser.add_argument("--old-orespawn", type=Path) parser.add_argument("--old-support-mod", type=Path, action="append", default=[]) - parser.add_argument("--old-version", default="2.5.1.110021") + parser.add_argument("--old-version", default="2.5.0-beta4") parser.add_argument("--launch-probe", type=Path) parser.add_argument("--red", action="store_true") args = parser.parse_args() @@ -192,14 +239,19 @@ def main(): remote = directory / "world/region/r.2.-3.mca" remote_hash = digest(remote) run(args.java, directory, "first", properties) + profile = directory / "world/serverconfig/orespawn-worldgen.json" stable = [directory / "config/basemetals-orespawn.json", directory / "config/orespawn-upgrade-report.txt", - directory / "world/serverconfig/orespawn-worldgen.json"] + profile] hashes = {path: digest(path) for path in stable} + first_profile = json.loads(profile.read_text(encoding="utf-8")) if name == "os1" else None properties["worldgen.phase"] = "reload" run(args.java, directory, "reload", properties) if digest(remote) != remote_hash: raise AssertionError(f"An unopened region changed during upgrade: {directory}") + if first_profile is not None: + check_os1_reload_profile(first_profile, json.loads(profile.read_text(encoding="utf-8")), expected) + hashes[profile] = digest(profile) if digest(legacy) != source_hash or any(digest(path) != value for path, value in hashes.items()): raise AssertionError(f"Migration rewrote a source or was not stable on reload: {directory}") properties["worldgen.openRemote"] = "true" @@ -210,14 +262,22 @@ def main(): raise AssertionError(f"Migration changed after opening later chunks: {directory}") write_json(directory / "migration-hashes.json", {str(path.relative_to(directory)): value for path, value in hashes.items()}) + if args.os1: + check_moved_os1_world(args, args.output / "os1", mods, stock) + fresh = args.output / "native-fresh" prepare(fresh, args.template, mods, flat=False) write_json(fresh / "expected.json", expected_os3(stock)) run(args.java, fresh, "first", {"worldgen.expected": fresh / "expected.json", "worldgen.sample": "true"}) run(args.java, fresh, "reload", {"worldgen.phase": "reload", "worldgen.expected": fresh / "expected.json"}) - existing = args.output / "existing-os4" - prepare(existing, args.template, mods, fresh / "world") + check_saved_overrides(args.java, args.template, args.output, mods, fresh, stock, custom) + print("BASE_METALS_OS3_MIGRATION_SUITE_PASS", flush=True) + + +def check_saved_overrides(java, template, output, mods, fresh, stock, custom): + existing = output / "existing-os4" + prepare(existing, template, mods, fresh / "world") shutil.copytree(fresh / "config", existing / "config", dirs_exist_ok=True) profile_path = existing / "world/serverconfig/orespawn-worldgen.json" profile = json.loads(profile_path.read_text(encoding="utf-8")) @@ -229,29 +289,39 @@ def main(): "ores": {key: copy.deepcopy(value) for key, value in profile["ores"].items() if key.startswith("basemetals:")}} override["ores"][tin]["dimension_selectors"][selector]["frequency"] = 9.0 + # Older OreSpawn 4 releases saved overrides without schema 5's material and channel fields. + older_override = copy.deepcopy(override) + older_override["schema_version"] = 4 + for ore in older_override["ores"].values(): + ore.pop("material", None) + for key in ("dimensions", "dimension_selectors"): + for dimension in ore.get(key, {}).values(): + dimension.pop("placement_channel", None) override_path = existing / "config/basemetals-orespawn.json" - write_json(override_path, override) + write_json(override_path, older_override) write_json(existing / "config/orespawn3/basemetals.json", custom) expected = expected_os3(stock) expected["ores"][tin]["dimension_selectors"][selector]["frequency"] = 6.25 write_json(existing / "expected.json", expected) hashes = {path: digest(path) for path in (profile_path, override_path)} for phase in ("first", "reload"): - run(args.java, existing, phase, {"worldgen.phase": phase, "worldgen.expected": existing / "expected.json"}) - if any(digest(path) != value for path, value in hashes.items()): - raise AssertionError("An existing OS4 override or world profile was overwritten") - - future = args.output / "existing-os4-new-world" - prepare(future, args.template, mods) - write_json(future / "config/basemetals-orespawn.json", override) - write_json(future / "config/orespawn3/basemetals.json", custom) - write_json(future / "expected.json", {"ores": override["ores"]}) - override_hash = digest(future / "config/basemetals-orespawn.json") - for phase in ("first", "reload"): - run(args.java, future, phase, {"worldgen.phase": phase, "worldgen.expected": future / "expected.json"}) - if digest(future / "config/basemetals-orespawn.json") != override_hash: - raise AssertionError("The existing override changed when creating a new world") - print("BASE_METALS_OS41_MIGRATION_SUITE_PASS", flush=True) + run(java, existing, phase, {"worldgen.phase": phase, "worldgen.expected": existing / "expected.json"}) + for path, original in hashes.items(): + if digest(path) != original: + raise AssertionError(f"OreSpawn rewrote an existing configuration during OS3 import: {path}") + + for saved_override in (older_override, override): + future = output / f"existing-os4-schema{saved_override['schema_version']}-new-world" + prepare(future, template, mods) + override_path = future / "config/basemetals-orespawn.json" + write_json(override_path, saved_override) + write_json(future / "config/orespawn3/basemetals.json", custom) + write_json(future / "expected.json", {"ores": saved_override["ores"]}) + override_hash = digest(override_path) + for phase in ("first", "reload"): + run(java, future, phase, {"worldgen.phase": phase, "worldgen.expected": future / "expected.json"}) + if digest(override_path) != override_hash: + raise AssertionError(f"The existing override changed when creating a new world: {future}") if __name__ == "__main__":