From a15ed911f263aba7c32f2e2bc97ac91dbc24ac10 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Sat, 7 Nov 2026 21:55:09 +0000 Subject: [PATCH 1/3] Finish Modern Metals for Minecraft 1.10.2 --- .github/workflows/deploy-release.yml | 21 + CHANGELOG.txt | 28 +- README.md | 26 +- build.gradle | 1 + docs/BUILDING.md | 3 + docs/CONTENT_MODE.md | 11 +- docs/ORE_OVERLAYS.md | 31 + docs/RELEASING.md | 8 +- gradle/ore-models.gradle | 71 + gradle/verification/runtime.gradle | 1 + .../moddev/mc/modernmetals/ModernMetals.java | 7 + .../modernmetals/block/OverlayOreBlock.java | 20 + .../client/ModernMetalsConfigScreen.java | 9 +- .../compat/LegacyRegistryMappings.java | 58 + .../content/ContentModeNetwork.java | 64 + .../moddev/mc/modernmetals/init/Blocks.java | 25 +- .../moddev/mc/modernmetals/init/Fluids.java | 14 +- .../mc/modernmetals/init/VillagerTrades.java | 8 +- .../mc/modernmetals/proxy/CommonProxy.java | 16 +- .../moddev/mc/modernmetals/util/Config.java | 10 + .../assets/modernmetals/lang/de_DE.lang | 347 +++- .../assets/modernmetals/lang/en_AU.lang | 51 + .../assets/modernmetals/lang/en_CA.lang | 51 + .../assets/modernmetals/lang/en_GB.lang | 96 + .../assets/modernmetals/lang/en_NZ.lang | 51 + .../assets/modernmetals/lang/en_PT.lang | 90 + .../assets/modernmetals/lang/en_US.lang | 7 + .../assets/modernmetals/lang/ru_RU.lang | 1553 +++++++++++++++++ .../assets/modernmetals/lang/zh_CN.lang | 42 +- .../models/block/aluminum_ore.json | 6 - .../models/block/aluminumbrass_ore.json | 6 - .../models/block/beryllium_ore.json | 6 - .../modernmetals/models/block/boron_ore.json | 6 - .../models/block/cadmium_ore.json | 6 - .../models/block/chromium_ore.json | 6 - .../models/block/galvanizedsteel_ore.json | 6 - .../models/block/iridium_ore.json | 6 - .../models/block/magnesium_ore.json | 6 - .../models/block/manganese_ore.json | 6 - .../models/block/nichrome_ore.json | 6 - .../modernmetals/models/block/osmium_ore.json | 6 - .../models/block/plutonium_ore.json | 6 - .../modernmetals/models/block/rutile_ore.json | 6 - .../models/block/stainlesssteel_ore.json | 6 - .../models/block/tantalum_ore.json | 6 - .../models/block/titanium_ore.json | 6 - .../models/block/tungsten_ore.json | 6 - .../models/block/uranium_ore.json | 6 - .../models/block/zirconium_ore.json | 6 - .../util/ContentModeConfigurationTests.java | 10 + tools/validation/legacy110/README.md | 26 +- tools/validation/legacy110/audit_resources.py | 54 +- .../legacy110/check_multiplayer_mode.py | 81 + .../legacy110/check_original_saves.py | 127 ++ .../legacy110/run_packaged_client.py | 90 +- .../legacy110/run_packaged_suite.py | 12 +- .../review/modern/ClientChecks.java | 88 +- .../review/modern/ModernMetalsProbe.java | 48 +- .../review/modern/OreOverlayChecks.java | 104 ++ update.json | 8 +- 60 files changed, 3234 insertions(+), 254 deletions(-) create mode 100644 docs/ORE_OVERLAYS.md create mode 100644 gradle/ore-models.gradle create mode 100644 src/main/java/zone/moddev/mc/modernmetals/block/OverlayOreBlock.java create mode 100644 src/main/java/zone/moddev/mc/modernmetals/compat/LegacyRegistryMappings.java create mode 100644 src/main/java/zone/moddev/mc/modernmetals/content/ContentModeNetwork.java create mode 100644 src/main/resources/assets/modernmetals/lang/en_AU.lang create mode 100644 src/main/resources/assets/modernmetals/lang/en_CA.lang create mode 100644 src/main/resources/assets/modernmetals/lang/en_GB.lang create mode 100644 src/main/resources/assets/modernmetals/lang/en_NZ.lang create mode 100644 src/main/resources/assets/modernmetals/lang/en_PT.lang create mode 100644 src/main/resources/assets/modernmetals/lang/ru_RU.lang delete mode 100644 src/main/resources/assets/modernmetals/models/block/aluminum_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/aluminumbrass_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/beryllium_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/boron_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/cadmium_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/chromium_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/galvanizedsteel_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/iridium_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/magnesium_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/manganese_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/nichrome_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/osmium_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/plutonium_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/rutile_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/stainlesssteel_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/tantalum_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/titanium_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/tungsten_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/uranium_ore.json delete mode 100644 src/main/resources/assets/modernmetals/models/block/zirconium_ore.json create mode 100644 tools/validation/legacy110/check_multiplayer_mode.py create mode 100644 tools/validation/legacy110/check_original_saves.py create mode 100644 tools/validation/legacy110/runtime-probe/review/modern/OreOverlayChecks.java diff --git a/.github/workflows/deploy-release.yml b/.github/workflows/deploy-release.yml index 90aad270..ff396ac4 100644 --- a/.github/workflows/deploy-release.yml +++ b/.github/workflows/deploy-release.yml @@ -9,6 +9,14 @@ on: description: Four-component Modern Metals version; the target branch is derived from its fourth component. required: true type: string + release_commit: + description: Full commit SHA of the checked MMD target branch. + required: true + type: string + tested_jar_sha256: + description: SHA-256 of the verified Modern Metals game jar. + required: true + type: string curseforge_release_level: description: CurseForge release level only; this does not change the GitHub Release type. required: true @@ -135,6 +143,8 @@ jobs: env: GH_TOKEN: ${{ github.token }} REQUESTED_VERSION: ${{ inputs.release_version }} + REQUESTED_COMMIT: ${{ inputs.release_commit }} + TESTED_JAR_SHA256: ${{ inputs.tested_jar_sha256 }} run: | set -euo pipefail @@ -290,6 +300,14 @@ jobs: fi release_sha="$(git rev-parse HEAD)" + if [[ ! "$REQUESTED_COMMIT" =~ ^[0-9a-f]{40}$ || "$REQUESTED_COMMIT" != "$release_sha" ]]; then + echo 'The target branch no longer points at the checked release commit' >&2 + exit 1 + fi + if [[ ! "$TESTED_JAR_SHA256" =~ ^[0-9a-f]{64}$ ]]; then + echo 'Supply the lowercase SHA-256 of the verified game jar' >&2 + exit 1 + fi release_tag="$release_version" echo "release_sha=$release_sha" >> "$GITHUB_OUTPUT" echo "release_version=$release_version" >> "$GITHUB_OUTPUT" @@ -445,6 +463,8 @@ jobs: - name: Stage the immutable release artifact id: artifact + env: + TESTED_JAR_SHA256: ${{ inputs.tested_jar_sha256 }} run: | set -euo pipefail bundle="$RUNNER_TEMP/release-bundle" @@ -455,6 +475,7 @@ jobs: cp build/release/SHA256SUMS "$bundle/" cp CHANGELOG.txt "$bundle/" (cd "$bundle" && sha256sum --check SHA256SUMS) + printf '%s %s\n' "$TESTED_JAR_SHA256" "$bundle/$MAIN_JAR" | sha256sum --check - echo "name=ModernMetals-${{ needs.preflight.outputs.minecraft_version }}-${{ needs.preflight.outputs.loader_name }}-${{ needs.preflight.outputs.release_sha }}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" >> "$GITHUB_OUTPUT" - name: Upload immutable release artifact diff --git a/CHANGELOG.txt b/CHANGELOG.txt index fb006f2a..f5e3e1d5 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,16 +1,14 @@ -2.5.1.110021 for 1.10.2 +Modern Metals 2.5.1.110021 for Minecraft 1.10.2 -- Updated the build and Eclipse setup to ForgeGradle 7, keeping Java 8 support. -- Added build checks and release workflows. -- Requires Base Metals 2.5.1.110021 and MMD OreSpawn 4.1.2.110021. -- Fixed material settings so enabled metals register their blocks, items and recipes. -- Finished boron, beryllium and thorium, including molten forms, buckets and ore generation. -- Moved ore generation to OreSpawn 4, with support for older configs and saved settings. -- Kept titanium's rutile and magnesium recipe. Titanium ore generation is optional and off by default. -- Added settings access from both the Forge mod list and OreSpawn's Mods list. -- Added High and Low Fantasy settings to ModernMetals.cfg and the config screen. Changes need a restart. -- Low Fantasy restricts unrealistic equipment, building recipes, gears, trades and Tinkers parts. -- Fixed Modern Metals processing recipes with IC2 and Mekanism. -- Fixed aluminum part casting when Tinkers has already registered the fluid. -- Added the missing upper slab models for boron, beryllium and thorium. -- Moved Java packages to zone.moddev.mc.modernmetals. Existing block and item IDs are unchanged. +This brings the 1.10.2 branch up to date. Use Java 8, Forge 12.18.3.2511 or later for 1.10.2, Base Metals 2.5.1.110021 and MMD OreSpawn 4.1.2.110021. + +- Restored boron, beryllium and thorium, including their ores, molten forms and recipes. +- Kept titanium's rutile and magnesium recipe. Titanium ore generation is optional and starts off. +- Moved ore generation to OreSpawn 4. Existing OreSpawn settings can carry forward and retrogen stays off. +- Used KiriCattus's ore overlays so the stone in your resource pack shows through. Thorium keeps its original texture. +- Put Modern Metals settings in both the Forge Mods menu and OreSpawn's Mods list. The screens have German, Simplified Chinese and Russian translations, with regional English files also included. +- Added High and Low Fantasy and a switch for new villager trades. Restart after changing them. Clients need the same Fantasy Level as their server. +- Fixed IC2 and Mekanism processing and a Tinkers casting issue when the aluminum fluid was already registered. +- Checked all 20 ores with the Base Metals crusher registry and the baseSteam and baseElectric crusher lookups. +- Restored old door, fishing rod, horse armor, alloy ore and molten aluminum brass IDs for 0.11.0 worlds. Back up an older world before opening it with the new jars. +- Updated the build and Eclipse setup to ForgeGradle 7. The game still runs on Java 8. diff --git a/README.md b/README.md index 2e73d958..3a8967a0 100644 --- a/README.md +++ b/README.md @@ -34,23 +34,41 @@ is **off by default**. If enabled, it uses the same placement settings as rutile Open **Mods -> Modern Metals -> Config**, or choose Modern Metals from OreSpawn's **Mods** list. Both open the same screen and save to `config/ModernMetals.cfg`. -Done saves your changes; Escape cancels them. Restart the game or server to apply +Done saves your changes. Escape cancels them. Restart the game or server to apply them. Keep materials enabled in worlds that use their blocks and items. **Fantasy Level** defaults to High Fantasy, which keeps the usual recipes. Low Fantasy restricts unrealistic equipment and building recipes across the materials, including trades and Tinkers parts. In 1.10 this is a Modern Metals setting and is independent of Base Metals. See [the fantasy settings](docs/CONTENT_MODE.md) for -the full list of restrictions. +the full list of restrictions. A multiplayer server and its clients need the +same Fantasy Level. Use **Villager Trades** to turn off new Modern Metals offers +in either mode. + +The config screen is available in English, German, Simplified Chinese and +Russian. Regional English strings are included for Australia, Canada, the UK, +New Zealand and Pirate Speak. Ore generation is handled by OreSpawn 4. Use its editor to change ore settings. Existing chunks are left alone and retrogen stays off. See [ore generation and migration](docs/ORE_GENERATION.md) for defaults, ore groups and older config files. +Ores use KiriCattus's overlays over the stone texture, so stone resource packs +also change the background of the ore. Thorium keeps its original texture. + +Modern Metals ores work in the Base Metals Crack Hammer and in the rock +crushers from baseSteam and baseElectric. They use the Base Metals crusher +settings, including the powder yield and any ores you disable there. + +## Updating an older 1.10.2 world + +Keep a backup before opening the world with the new jars. Modern Metals resolves +the old door, fishing rod, horse armor and molten aluminum brass IDs from 0.11.0. +Placed galvanized steel, nichrome and stainless steel ores still load. Those +three ores have no default OreSpawn rules. Keep the materials enabled when first +opening a world that contains them. ## Development The build uses ForgeGradle 7 and still produces Java 8 jars. See [building and Eclipse](docs/BUILDING.md), [integration checks and known limits](tools/validation/legacy110/README.md) and [release preparation](docs/RELEASING.md). - -The 1.11 and 1.12 branches will be updated separately. diff --git a/build.gradle b/build.gradle index 1d7d18d5..4f2ff429 100644 --- a/build.gradle +++ b/build.gradle @@ -169,6 +169,7 @@ tasks.named('jar', Jar) { } ext.modernMetalsBuild = [developmentOutput: developmentOutput].asImmutable() +apply from: 'gradle/ore-models.gradle' apply from: 'gradle/release/artifacts.gradle' apply from: 'gradle/release/publishing.gradle' apply from: 'gradle/verification/runtime.gradle' diff --git a/docs/BUILDING.md b/docs/BUILDING.md index 914ad453..192e2827 100644 --- a/docs/BUILDING.md +++ b/docs/BUILDING.md @@ -40,6 +40,9 @@ metadata is not duplicated. `verifyEclipseProductionClasspath` checks isolation. ## Verification +`generateOreModels` generates the ore block models as part of the normal build. +See [ore overlays](ORE_OVERLAYS.md) for the inputs, output and client checks. + `test` covers config switches, provider conversion, titanium defaults, fantasy policy and namespace compatibility. `verifyProjectResources` parses resources, checks material assets, validates the provider against the pinned OreSpawn schema diff --git a/docs/CONTENT_MODE.md b/docs/CONTENT_MODE.md index 22e483e0..225df704 100644 --- a/docs/CONTENT_MODE.md +++ b/docs/CONTENT_MODE.md @@ -3,14 +3,16 @@ In Minecraft 1.10.2, Modern Metals owns its fantasy setting. Open **Mods → Modern Metals → Config → Fantasy Level** and choose **High Fantasy** or **Low Fantasy**. The same selector is available through OreSpawn's child Mods list. Save with Done -and restart the game/server to apply the recipes. Clients and servers should use -matching settings. +and restart the game or server to apply the recipes. Forge checks for matching +settings before joining a multiplayer world and explains how to fix a mismatch. +Use the same build on both sides so the check is available. The setting is stored in **`config/ModernMetals.cfg`**: ```text general { S:contentMode=low_fantasy + B:enableVillagerTrades=true } ``` @@ -18,6 +20,11 @@ High Fantasy is the default. Missing or invalid values use High Fantasy; invalid file values are normalized at startup. Changes remain pending until a full restart and do not rewrite live registries or recipes. +**Villager Trades** defaults to on. Turn it off to stop new Modern Metals +blacksmith offers in either fantasy mode. The change applies after restart. +Offers already stored in a villager's inventory and offers from Base Metals +keep their existing behavior. + The 1.10 version does not read or change Base Metals' fantasy setting or recipes. If an earlier local candidate used `BaseMetals.cfg`, move the desired value to `ModernMetals.cfg`. Core-mod inheritance is reserved for the 1.12 modernization. diff --git a/docs/ORE_OVERLAYS.md b/docs/ORE_OVERLAYS.md new file mode 100644 index 00000000..46d4b19e --- /dev/null +++ b/docs/ORE_OVERLAYS.md @@ -0,0 +1,31 @@ +# Ore overlays in Forge 1.10.2 + +Ore models use Minecraft's stone texture underneath KiriCattus's transparent +ore art. A resource pack that replaces stone also changes the stone part of +the ore. Thorium still uses its original full texture. + +Forge 1.10 predates Minecraft's data generator. Run `gradlew generateOreModels` +to generate the models without starting the game. The normal build runs it +automatically, and Eclipse uses the processed resources. The inputs are the +existing ore blockstates and PNGs in +`src/main/resources/assets/modernmetals/textures/blocks/ore_overlays/`. +Generated models go to `build/generated/ore-models`; nothing is written to +`src`. Existing blockstate and item model IDs still point to the same block +model names. + +The generated models use the two cubes from Base Metals' generator. The outer +cube sits 0.05 model units above the host faces so they do not fight over the +same depth. On Forge 1.10 both cubes render in the cutout layer with mipmaps, +so the transparent pixels leave the host visible. The ore blocks still inherit +their mining and drop behaviour from Base Metals. + +The 20 overlay files come from [KiriCattus's art commit](https://github.com/MinecraftModDevelopmentMods/ModernMetals/commit/6c892309ab9c2cd19371a8a65ad59b250a647216). +Nineteen are used by registered ores, including the three alloy ores restored +for worlds saved by 0.11.0. The aluminum brass overlay is available as an asset. +OreSpawn still uses the same 17 rules, with titanium disabled by default. + +`verifyProjectResources` checks the generated resources and texture references. +The packaged client probe checks the placed and inventory models, face offsets +and render layer. Add `--ore-host-pack` on its reload run to test a replacement +stone texture and capture the ore display. See the +[validation guide](../tools/validation/legacy110/README.md). diff --git a/docs/RELEASING.md b/docs/RELEASING.md index 2570ccd6..5ea0f567 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -12,7 +12,8 @@ CodeQL/wrapper checks are separate. Actions use full commit hashes. Versions use `Major.Minor.Patch.110021`. Tags validate metadata/prior CI without publishing. The dispatcher requires `confirm_live_publication`, the upstream -repository, matching target/tag/commit and successful hosted checks. It publishes +repository, the full checked target commit, the verified game jar's SHA-256 +and successful hosted checks. It publishes the same candidate bytes to Maven, CurseForge **244357**, then GitHub. CurseForge requires Base Metals **240967** and MMD OreSpawn **245586**, with Additional Loot Tables **243157** optional. Credentials and an HTTPS Maven target are required. @@ -21,3 +22,8 @@ The dispatcher must be installed on the repository's default branch before a manual release can be started. Merging the 1.10 branch does not install it on the 1.12 default branch. Publication is a separate step and needs approval. If an upload times out, check its status before trying again. + +For the default-branch change, copy only the audited `deploy-release.yml`. It +routes the 1.10.2 suffix to the modernized branch and builds there. After a +release is publicly available, update the Forge 1.10.2 entries in `update.json` +to the exact version reported by Forge. diff --git a/gradle/ore-models.gradle b/gradle/ore-models.gradle new file mode 100644 index 00000000..a311777d --- /dev/null +++ b/gradle/ore-models.gradle @@ -0,0 +1,71 @@ +import groovy.json.JsonOutput + +// Forge 1.10 has no GatherDataEvent. Generate the equivalent model resources +// before processResources, without launching Minecraft or writing into src. +def assets = layout.projectDirectory.dir('src/main/resources/assets/modernmetals') +def overlayFiles = fileTree(assets.dir('textures/blocks/ore_overlays')) { include '*_ore.png' } +def oreStates = fileTree(assets.dir('blockstates')) { include '*_ore.json' } +def generated = layout.buildDirectory.dir('generated/ore-models') + +def generateOreModels = tasks.register('generateOreModels') { + group = 'build' + description = 'Generates the Forge 1.10 ore models from KiriCattus’s overlays.' + inputs.files(overlayFiles, oreStates).withPathSensitivity(PathSensitivity.RELATIVE) + outputs.dir(generated) + + doLast { + def names = overlayFiles.files.collect { it.name - '.png' }.sort() + def expected = oreStates.files.collect { it.name - '.json' }.findAll { it != 'thorium_ore' }.sort() + if (names != expected) { + throw new GradleException("Ore overlays do not match ore blockstates: missing ${expected - names}, extra ${names - expected}") + } + + def dir = generated.get().dir('assets/modernmetals/models/block').asFile + dir.mkdirs() + def writeModel = { String name, Map model -> + new File(dir, "${name}.json").setText(JsonOutput.prettyPrint(JsonOutput.toJson(model)) + '\n', 'UTF-8') + } + def cube = { Number from, Number to, String texture -> + def faces = ['down', 'up', 'north', 'south', 'west', 'east'].collectEntries { face -> + [(face): [texture: texture, cullface: face, uv: [0, 0, 16, 16]]] + } + [from: [from, from, from], to: [to, to, to], faces: faces] + } + // Same two cubes and offset as Base Metals, with the legacy texture paths. + writeModel('ore_overlay', [ + parent: 'minecraft:block/block', + elements: [cube(0, 16, '#base'), cube(-0.05, 16.05, '#overlay')] + ]) + names.each { name -> + writeModel(name, [ + parent: 'modernmetals:block/ore_overlay', + textures: [particle: 'minecraft:blocks/stone', base: 'minecraft:blocks/stone', + overlay: "modernmetals:blocks/ore_overlays/${name}"] + ]) + } + // Clean up only obsolete ore JSON files in this task's own output directory. + dir.listFiles().findAll { it.isFile() && it.name.endsWith('_ore.json') && !(it.name - '.json' in names) }.each { + if (!it.delete()) throw new GradleException("Could not remove stale generated ore model ${it.name}") + } + } +} + +tasks.named('processResources', ProcessResources) { + dependsOn generateOreModels + from generated + duplicatesStrategy = DuplicatesStrategy.FAIL + doFirst { + // Copy tasks can leave the old flat textures behind after an incremental upgrade. + overlayFiles.files.each { overlay -> + def flat = new File(destinationDir, "assets/modernmetals/textures/blocks/${overlay.name}") + if (flat.isFile() && !flat.delete()) { + throw new GradleException("Could not remove obsolete processed texture ${flat.name}") + } + } + } +} + +tasks.named('sourcesJar', Jar) { + dependsOn generateOreModels + from generated +} diff --git a/gradle/verification/runtime.gradle b/gradle/verification/runtime.gradle index 28bfead8..c4120c51 100644 --- a/gradle/verification/runtime.gradle +++ b/gradle/verification/runtime.gradle @@ -25,6 +25,7 @@ tasks.named('test', Test) { tasks.register('verifyProjectResources', Exec) { group = 'verification' dependsOn tasks.named('test') + dependsOn tasks.named('processResources') doFirst { commandLine providers.gradleProperty('pythonExecutable').getOrElse('python3'), 'tools/validation/legacy110/audit_resources.py', '--mirror', diff --git a/src/main/java/zone/moddev/mc/modernmetals/ModernMetals.java b/src/main/java/zone/moddev/mc/modernmetals/ModernMetals.java index 5f6a85fe..5e014ba1 100644 --- a/src/main/java/zone/moddev/mc/modernmetals/ModernMetals.java +++ b/src/main/java/zone/moddev/mc/modernmetals/ModernMetals.java @@ -4,6 +4,7 @@ import org.apache.logging.log4j.Logger; import zone.moddev.mc.modernmetals.proxy.CommonProxy; +import zone.moddev.mc.modernmetals.compat.LegacyRegistryMappings; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; @@ -12,6 +13,7 @@ import net.minecraftforge.fml.common.event.FMLFingerprintViolationEvent; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLMissingMappingsEvent; +import net.minecraftforge.fml.common.event.FMLModIdMappingEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; @@ -80,6 +82,11 @@ public static void onRemap(FMLMissingMappingsEvent event) { proxy.onRemap(event); } + @EventHandler + public static void onIdMapping(FMLModIdMappingEvent event) { + LegacyRegistryMappings.restoreItemAliases(); + } + @EventHandler public static void loadComplete(net.minecraftforge.fml.common.event.FMLLoadCompleteEvent event) { zone.moddev.mc.modernmetals.content.ContentPolicy.filterRecipes(); diff --git a/src/main/java/zone/moddev/mc/modernmetals/block/OverlayOreBlock.java b/src/main/java/zone/moddev/mc/modernmetals/block/OverlayOreBlock.java new file mode 100644 index 00000000..9a877421 --- /dev/null +++ b/src/main/java/zone/moddev/mc/modernmetals/block/OverlayOreBlock.java @@ -0,0 +1,20 @@ +package zone.moddev.mc.modernmetals.block; + +import com.mcmoddev.lib.block.BlockMMDOre; +import com.mcmoddev.lib.material.MMDMaterial; +import net.minecraft.util.BlockRenderLayer; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +/** The shared ore block with alpha testing enabled for its model's outer faces. */ +public final class OverlayOreBlock extends BlockMMDOre { + public OverlayOreBlock(MMDMaterial material) { + super(material); + } + + @Override + @SideOnly(Side.CLIENT) + public BlockRenderLayer getBlockLayer() { + return BlockRenderLayer.CUTOUT_MIPPED; + } +} diff --git a/src/main/java/zone/moddev/mc/modernmetals/client/ModernMetalsConfigScreen.java b/src/main/java/zone/moddev/mc/modernmetals/client/ModernMetalsConfigScreen.java index 6bd945ad..8e5f781d 100644 --- a/src/main/java/zone/moddev/mc/modernmetals/client/ModernMetalsConfigScreen.java +++ b/src/main/java/zone/moddev/mc/modernmetals/client/ModernMetalsConfigScreen.java @@ -5,6 +5,7 @@ import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.resources.I18n; import net.minecraftforge.common.config.ConfigElement; +import net.minecraftforge.common.config.Property; import net.minecraftforge.fml.client.config.GuiConfig; import net.minecraftforge.fml.client.config.IConfigElement; import net.minecraftforge.fml.relauncher.Side; @@ -23,7 +24,13 @@ public ModernMetalsConfigScreen(final GuiScreen parent) { private static List elements() { final List elements = new ArrayList<>( new ConfigElement(Config.getConfiguration().getCategory("General")).getChildElements()); - elements.addAll(new ConfigElement(Config.getConfiguration().getCategory("Metals")).getChildElements()); + for (final Property material : Config.getConfiguration().getCategory("Metals").getOrderedValues()) { + elements.add(new ConfigElement(material) { + @Override public String getComment() { + return I18n.format("config.modernmetals.material.tooltip"); + } + }); + } return elements; } } diff --git a/src/main/java/zone/moddev/mc/modernmetals/compat/LegacyRegistryMappings.java b/src/main/java/zone/moddev/mc/modernmetals/compat/LegacyRegistryMappings.java new file mode 100644 index 00000000..24d52537 --- /dev/null +++ b/src/main/java/zone/moddev/mc/modernmetals/compat/LegacyRegistryMappings.java @@ -0,0 +1,58 @@ +package zone.moddev.mc.modernmetals.compat; + +import java.util.LinkedHashMap; +import java.util.Map; + +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.common.event.FMLMissingMappingsEvent; +import net.minecraftforge.fml.common.registry.ForgeRegistries; +import net.minecraftforge.fml.common.registry.GameData; +import net.minecraftforge.fml.common.registry.GameRegistry; +import zone.moddev.mc.modernmetals.ModernMetals; + +/** Registry names written by Modern Metals 0.11.0. */ +public final class LegacyRegistryMappings { + private static final String OLD_BRASS = "alubrass"; + private static final ResourceLocation MOLTEN_BRASS = id("aluminumbrass"); + private static final Map ITEM_ALIASES = itemAliases(); + + private LegacyRegistryMappings() {} + + public static void remap(final FMLMissingMappingsEvent event) { + for (final FMLMissingMappingsEvent.MissingMapping mapping : event.get()) { + if (mapping.type == GameRegistry.Type.BLOCK && mapping.resourceLocation.equals(id(OLD_BRASS)) + && ForgeRegistries.BLOCKS.containsKey(MOLTEN_BRASS)) { + mapping.remap(ForgeRegistries.BLOCKS.getValue(MOLTEN_BRASS)); + } else if (mapping.type == GameRegistry.Type.ITEM) { + final ResourceLocation replacement = ITEM_ALIASES.get(mapping.resourceLocation); + // Some saves contain both the door block's item ID and the old door item ID. + if (replacement != null && ForgeRegistries.ITEMS.containsKey(replacement)) mapping.ignore(); + } + } + } + + public static void restoreItemAliases() { + final Map aliases = new LinkedHashMap<>(); + ITEM_ALIASES.forEach((oldId, newId) -> { + if (ForgeRegistries.ITEMS.containsKey(newId)) aliases.put(oldId, newId); + }); + GameData.getItemRegistry().loadAliases(aliases); + } + + private static Map itemAliases() { + final Map aliases = new LinkedHashMap<>(); + aliases.put(id(OLD_BRASS), MOLTEN_BRASS); + for (final String material : new String[] { "aluminum", "aluminumbrass", "cadmium", "chromium", + "galvanizedsteel", "iridium", "magnesium", "manganese", "nichrome", "osmium", + "plutonium", "rutile", "stainlesssteel", "tantalum", "titanium", "tungsten", "uranium", "zirconium" }) { + aliases.put(id(material + "_door_item"), id(material + "_door")); + aliases.put(id(material + "_fishingrod"), id(material + "_fishing_rod")); + aliases.put(id(material + "_horsearmor"), id(material + "_horse_armor")); + } + return aliases; + } + + private static ResourceLocation id(final String path) { + return new ResourceLocation(ModernMetals.MODID, path); + } +} diff --git a/src/main/java/zone/moddev/mc/modernmetals/content/ContentModeNetwork.java b/src/main/java/zone/moddev/mc/modernmetals/content/ContentModeNetwork.java new file mode 100644 index 00000000..c19b2699 --- /dev/null +++ b/src/main/java/zone/moddev/mc/modernmetals/content/ContentModeNetwork.java @@ -0,0 +1,64 @@ +package zone.moddev.mc.modernmetals.content; + +import java.util.Set; + +import net.minecraft.network.NetworkManager; +import net.minecraft.network.play.server.SPacketDisconnect; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.util.text.TextComponentTranslation; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.network.FMLNetworkEvent.CustomPacketRegistrationEvent; +import net.minecraftforge.fml.common.network.NetworkRegistry; + +/** Advertise the active recipe mode in Forge's login channel registration. */ +public final class ContentModeNetwork { + private static final String HIGH = "ModernMetals|High"; + private static final String LOW = "ModernMetals|Low"; + + private ContentModeNetwork() {} + + public static void register() { + NetworkRegistry.INSTANCE.newEventDrivenChannel(ContentPolicy.active().lowFantasy() ? LOW : HIGH); + MinecraftForge.EVENT_BUS.register(new ContentModeNetwork()); + } + + @SubscribeEvent + public void checkMode(final CustomPacketRegistrationEvent event) { + final Set channels = event.getRegistrations(); + // Forge includes FML|HS in its login registration, not ordinary channel updates. + if (!"REGISTER".equals(event.getOperation()) || !channels.contains("FML|HS")) return; + + final boolean localLow = ContentPolicy.active().lowFantasy(); + final boolean remoteLow = channels.contains(LOW); + final boolean remoteHigh = channels.contains(HIGH); + final boolean server = event.getSide().isServer(); + final ITextComponent reason; + if (remoteLow == remoteHigh) { + // A client with no mode channel may also lack the translation key. + reason = server + ? new TextComponentString("Modern Metals could not check the Fantasy Level. " + + "Use the same Modern Metals build on the server and client.") + : new TextComponentTranslation("config.modernmetals.connection.protocol"); + } else if (remoteLow == localLow) { + return; + } else { + final boolean serverLow = server ? localLow : remoteLow; + reason = new TextComponentTranslation("config.modernmetals.connection.mismatch", + modeLabel(serverLow), modeLabel(!serverLow)); + } + + final NetworkManager manager = event.getManager(); + manager.channel().config().setAutoRead(false); + if (server) { + manager.sendPacket(new SPacketDisconnect(reason), future -> manager.closeChannel(reason)); + } else { + manager.closeChannel(reason); + } + } + + private static ITextComponent modeLabel(final boolean low) { + return new TextComponentTranslation(low ? "low_fantasy" : "high_fantasy"); + } +} diff --git a/src/main/java/zone/moddev/mc/modernmetals/init/Blocks.java b/src/main/java/zone/moddev/mc/modernmetals/init/Blocks.java index a4795964..51384363 100644 --- a/src/main/java/zone/moddev/mc/modernmetals/init/Blocks.java +++ b/src/main/java/zone/moddev/mc/modernmetals/init/Blocks.java @@ -2,12 +2,12 @@ import java.util.Arrays; -import javax.annotation.Nonnull; - import com.mcmoddev.lib.data.Names; import com.mcmoddev.lib.data.SharedStrings; import com.mcmoddev.lib.init.Materials; import com.mcmoddev.lib.material.MMDMaterial; +import com.mcmoddev.lib.util.Oredicts; +import zone.moddev.mc.modernmetals.block.OverlayOreBlock; import zone.moddev.mc.modernmetals.data.MaterialNames; import net.minecraft.block.Block; @@ -67,7 +67,7 @@ public static void init() { create(Names.BLOCK, material); create(Names.PLATE, material); - create(Names.ORE, material); + createOre(material); create(Names.BARS, material); create(Names.DOOR, material); create(Names.TRAPDOOR, material); @@ -83,4 +83,23 @@ public static void init() { initDone = true; } + + private static void createOre(MMDMaterial material) { + if (MaterialNames.THORIUM.equals(material.getName())) { + // Thorium still has its original opaque texture. + create(Names.ORE, material); + } else if ((material.hasOre() || hasLegacyOre(material.getName())) + && !material.hasBlock(Names.ORE) && isNameEnabled(Names.ORE)) { + final Block ore = addBlock(new OverlayOreBlock(material), Names.ORE, material, + ItemGroups.getTab(SharedStrings.TAB_BLOCKS)); + material.addNewBlock(Names.ORE.toString(), ore); + Oredicts.registerOre("ore" + material.getCapitalizedName(), ore); + } + } + + private static boolean hasLegacyOre(final String name) { + // 0.11.0 saved these alloy ores. OreSpawn has no placement rules for them. + return MaterialNames.GALVANIZED_STEEL.equals(name) || MaterialNames.NICHROME.equals(name) + || MaterialNames.STAINLESS_STEEL.equals(name); + } } diff --git a/src/main/java/zone/moddev/mc/modernmetals/init/Fluids.java b/src/main/java/zone/moddev/mc/modernmetals/init/Fluids.java index 31a6c775..c1c9abdb 100644 --- a/src/main/java/zone/moddev/mc/modernmetals/init/Fluids.java +++ b/src/main/java/zone/moddev/mc/modernmetals/init/Fluids.java @@ -1,5 +1,7 @@ package zone.moddev.mc.modernmetals.init; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; import zone.moddev.mc.modernmetals.util.Config.Options; /** @@ -61,8 +63,18 @@ public static void init() { } if (Options.enableAluminumBrass) { - addFluid(Materials.aluminumBrass, 2000, 10000, 500, 10); + final Fluid brass = addFluid(Materials.aluminumBrass, 2000, 10000, 500, 10); addFluidBlock(Materials.aluminumBrass); + // Forge 1.10 saves the fluid name in buckets and tanks independently of the block ID. + if (FluidRegistry.getFluid("alubrass") == null) { + final Fluid legacy = new Fluid("alubrass", brass.getStill(), brass.getFlowing()) { + @Override public int getColor() { return brass.getColor(); } + } + .setUnlocalizedName("modernmetals.aluminumbrass").setDensity(brass.getDensity()) + .setViscosity(brass.getViscosity()).setTemperature(brass.getTemperature()) + .setLuminosity(brass.getLuminosity()).setBlock(Materials.aluminumBrass.getFluidBlock()); + FluidRegistry.registerFluid(legacy); + } } if (Options.enableCadmium) { diff --git a/src/main/java/zone/moddev/mc/modernmetals/init/VillagerTrades.java b/src/main/java/zone/moddev/mc/modernmetals/init/VillagerTrades.java index ec410f2f..322ac3a5 100644 --- a/src/main/java/zone/moddev/mc/modernmetals/init/VillagerTrades.java +++ b/src/main/java/zone/moddev/mc/modernmetals/init/VillagerTrades.java @@ -1,5 +1,7 @@ package zone.moddev.mc.modernmetals.init; +import zone.moddev.mc.modernmetals.util.Config; + /** * * @author Jasmine Iwanek @@ -24,8 +26,10 @@ public static void init() { Materials.init(); Items.init(); - if(zone.moddev.mc.modernmetals.content.ContentPolicy.active().lowFantasy()) registerRestrictedTrades(); - else registerCommonTrades(); + if (Config.Options.enableVillagerTrades) { + if (zone.moddev.mc.modernmetals.content.ContentPolicy.active().lowFantasy()) registerRestrictedTrades(); + else registerCommonTrades(); + } initDone = true; } diff --git a/src/main/java/zone/moddev/mc/modernmetals/proxy/CommonProxy.java b/src/main/java/zone/moddev/mc/modernmetals/proxy/CommonProxy.java index e2f34178..5fd31788 100644 --- a/src/main/java/zone/moddev/mc/modernmetals/proxy/CommonProxy.java +++ b/src/main/java/zone/moddev/mc/modernmetals/proxy/CommonProxy.java @@ -1,6 +1,7 @@ package zone.moddev.mc.modernmetals.proxy; -import zone.moddev.mc.modernmetals.ModernMetals; +import zone.moddev.mc.modernmetals.content.ContentModeNetwork; +import zone.moddev.mc.modernmetals.compat.LegacyRegistryMappings; import zone.moddev.mc.modernmetals.data.MaterialNames; import zone.moddev.mc.modernmetals.init.*; import zone.moddev.mc.modernmetals.util.Config; @@ -11,10 +12,8 @@ import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLInterModComms; import net.minecraftforge.fml.common.event.FMLMissingMappingsEvent; -import net.minecraftforge.fml.common.event.FMLMissingMappingsEvent.MissingMapping; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.registry.GameRegistry; /** * Modern Metals Common Proxy @@ -27,6 +26,7 @@ public class CommonProxy { public void preInit(FMLPreInitializationEvent event) { Config.init(); + ContentModeNetwork.register(); Materials.init(); Fluids.init(); @@ -39,15 +39,7 @@ public void preInit(FMLPreInitializationEvent event) { } public void onRemap(FMLMissingMappingsEvent event) { - for (final MissingMapping mapping : event.get()) { - if (mapping.resourceLocation.getResourceDomain().equals(ModernMetals.MODID)) { - if (mapping.type.equals(GameRegistry.Type.BLOCK)) { - // Dummy - } else if (mapping.type.equals(GameRegistry.Type.ITEM)) { - // Dummy - } - } - } + LegacyRegistryMappings.remap(event); } public void init(FMLInitializationEvent event) { diff --git a/src/main/java/zone/moddev/mc/modernmetals/util/Config.java b/src/main/java/zone/moddev/mc/modernmetals/util/Config.java index 5b8f501d..ae3f4b3a 100644 --- a/src/main/java/zone/moddev/mc/modernmetals/util/Config.java +++ b/src/main/java/zone/moddev/mc/modernmetals/util/Config.java @@ -40,6 +40,7 @@ public static void init() { MinecraftForge.EVENT_BUS.register(new Config()); } zone.moddev.mc.modernmetals.content.ContentPolicy.initialize(contentMode(configuration)); + Options.enableVillagerTrades = villagerTrades(configuration); // METALS Options.enableThorium = material("thorium", "EnableThorium", "Thorium"); @@ -88,6 +89,14 @@ static String contentMode(final Configuration config) { return mode; } + static boolean villagerTrades(final Configuration config) { + final net.minecraftforge.common.config.Property property = config.get("General", "enableVillagerTrades", + true, "Let blacksmiths trade Modern Metals ingots and equipment. Requires a game restart."); + property.setLanguageKey("config.modernmetals.villager_trades"); + property.setRequiresMcRestart(true); + return property.getBoolean(); + } + private static boolean material(final String name, final String key, final String display) { final net.minecraftforge.common.config.Property property = configuration.get(MATERIALS_CAT, key, true, "Enable " + display + " Items and Materials. Requires a game restart."); @@ -100,6 +109,7 @@ private static boolean material(final String name, final String key, final Strin } public static class Options { + public static boolean enableVillagerTrades = true; // MATERIALS public static boolean enableThorium = true; diff --git a/src/main/resources/assets/modernmetals/lang/de_DE.lang b/src/main/resources/assets/modernmetals/lang/de_DE.lang index 815157a6..b2582189 100644 --- a/src/main/resources/assets/modernmetals/lang/de_DE.lang +++ b/src/main/resources/assets/modernmetals/lang/de_DE.lang @@ -36,38 +36,38 @@ item.modernmetals.aluminum_smallpowder.name=Kleiner Aluminiumpulverhaufen item.modernmetals.aluminum_sword.name=Aluminiumschwert item.modernmetals.aluminum_trapdoor.name=Aluminiumfalltür -material.aluminumbrass.name=Duraluminium -item.modernmetals.aluminumbrass_arrow.name=Duraluminiumpfeil -item.modernmetals.aluminumbrass_axe.name=Duraluminiumaxt -item.modernmetals.aluminumbrass_bars.name=Duraluminiumgitter -item.modernmetals.aluminumbrass_blend.name=Duraluminiumgemisch -item.modernmetals.aluminumbrass_block.name=Duraluminiumblock -item.modernmetals.aluminumbrass_boots.name=Duraluminiumstiefel -item.modernmetals.aluminumbrass_bolt.name=Duraluminiumbolzen -item.modernmetals.aluminumbrass_bow.name=Duraluminiumbogen -item.modernmetals.aluminumbrass_chestplate.name=Duraluminiumbrustpanzer -item.modernmetals.aluminumbrass_crackhammer.name=Duraluminiumbruchhammer -item.modernmetals.aluminumbrass_crossbow.name=Duraluminiumarmbrust -item.modernmetals.aluminumbrass_door.name=Duraluminiumtür -item.modernmetals.aluminumbrass_fishing_rod.name=Duraluminiumangel -item.modernmetals.aluminumbrass_gear.name=Duraluminiumzahnrad -item.modernmetals.aluminumbrass_helmet.name=Duraluminiumhelm -item.modernmetals.aluminumbrass_hoe.name=Duraluminiumhacke -item.modernmetals.aluminumbrass_horse_armor.name=Duraluminiumpferderüstung -item.modernmetals.aluminumbrass_ingot.name=Duraluminiumbarren -item.modernmetals.aluminumbrass_leggings.name=Duraluminiumbeinrüstung -item.modernmetals.aluminumbrass_nugget.name=Duraluminiumnugget -item.modernmetals.aluminumbrass_ore.name=Duraluminiumerz -item.modernmetals.aluminumbrass_pickaxe.name=Duraluminiumspitzhacke -item.modernmetals.aluminumbrass_powder.name=Duraluminiumpulver -item.modernmetals.aluminumbrass_rod.name=Duraluminiumstange -item.modernmetals.aluminumbrass_shears.name=Duraluminiumschere -item.modernmetals.aluminumbrass_shield.name=Duraluminiumschild -item.modernmetals.aluminumbrass_shovel.name=Duraluminiumschaufel -item.modernmetals.aluminumbrass_smallblend.name=Kleiner Duraluminiumgemischhaufen -item.modernmetals.aluminumbrass_smallpowder.name=Kleiner Duraluminiumpulverhaufen -item.modernmetals.aluminumbrass_sword.name=Duraluminiumschwert -item.modernmetals.aluminumbrass_trapdoor.name=Duraluminiumfalltür +material.aluminumbrass.name=Aluminiummessing +item.modernmetals.aluminumbrass_arrow.name=Aluminiummessingpfeil +item.modernmetals.aluminumbrass_axe.name=Aluminiummessingaxt +item.modernmetals.aluminumbrass_bars.name=Aluminiummessinggitter +item.modernmetals.aluminumbrass_blend.name=Aluminiummessinggemisch +item.modernmetals.aluminumbrass_block.name=Aluminiummessingblock +item.modernmetals.aluminumbrass_boots.name=Aluminiummessingstiefel +item.modernmetals.aluminumbrass_bolt.name=Aluminiummessingbolzen +item.modernmetals.aluminumbrass_bow.name=Aluminiummessingbogen +item.modernmetals.aluminumbrass_chestplate.name=Aluminiummessingbrustpanzer +item.modernmetals.aluminumbrass_crackhammer.name=Aluminiummessingbruchhammer +item.modernmetals.aluminumbrass_crossbow.name=Aluminiummessingarmbrust +item.modernmetals.aluminumbrass_door.name=Aluminiummessingtür +item.modernmetals.aluminumbrass_fishing_rod.name=Aluminiummessingangel +item.modernmetals.aluminumbrass_gear.name=Aluminiummessingzahnrad +item.modernmetals.aluminumbrass_helmet.name=Aluminiummessinghelm +item.modernmetals.aluminumbrass_hoe.name=Aluminiummessinghacke +item.modernmetals.aluminumbrass_horse_armor.name=Aluminiummessingpferderüstung +item.modernmetals.aluminumbrass_ingot.name=Aluminiummessingbarren +item.modernmetals.aluminumbrass_leggings.name=Aluminiummessingbeinrüstung +item.modernmetals.aluminumbrass_nugget.name=Aluminiummessingnugget +item.modernmetals.aluminumbrass_ore.name=Aluminiummessingerz +item.modernmetals.aluminumbrass_pickaxe.name=Aluminiummessingspitzhacke +item.modernmetals.aluminumbrass_powder.name=Aluminiummessingpulver +item.modernmetals.aluminumbrass_rod.name=Aluminiummessingstange +item.modernmetals.aluminumbrass_shears.name=Aluminiummessingschere +item.modernmetals.aluminumbrass_shield.name=Aluminiummessingschild +item.modernmetals.aluminumbrass_shovel.name=Aluminiummessingschaufel +item.modernmetals.aluminumbrass_smallblend.name=Kleiner Aluminiummessinggemischhaufen +item.modernmetals.aluminumbrass_smallpowder.name=Kleiner Aluminiummessingpulverhaufen +item.modernmetals.aluminumbrass_sword.name=Aluminiummessingschwert +item.modernmetals.aluminumbrass_trapdoor.name=Aluminiummessingfalltür material.antimony.name=Antimon item.modernmetals.antimony_arrow.name=Antimonpfeil @@ -315,7 +315,7 @@ item.modernmetals.manganese_smallpowder.name=Kleiner Manganpulverhaufen item.modernmetals.manganese_sword.name=Manganschwert item.modernmetals.manganese_trapdoor.name=Manganfalltür -material.nichrome.name=Nickel-Chrom- +material.nichrome.name=Nickel-Chrom-Legierung item.modernmetals.nichrome_arrow.name=Nickel-Chrom-Pfeil item.modernmetals.nichrome_axe.name=Nickel-Chrom-Axt item.modernmetals.nichrome_bars.name=Nickel-Chrom-Gitter @@ -677,12 +677,12 @@ tile.modernmetals.aluminum_ore.name=Aluminiumerz tile.modernmetals.aluminum_plate.name=Aluminiumblech tile.modernmetals.aluminum_trapdoor.name=Aluminiumfalltür -tile.modernmetals.aluminumbrass_bars.name=Duraluminiumgitter -tile.modernmetals.aluminumbrass_block.name=Duraluminium -tile.modernmetals.aluminumbrass_door.name=Duraluminiumtür -tile.modernmetals.aluminumbrass_ore.name=Duraluminiumerz -tile.modernmetals.aluminumbrass_plate.name=Duraluminiumblech -tile.modernmetals.aluminumbrass_trapdoor.name=Duraluminiumfalltür +tile.modernmetals.aluminumbrass_bars.name=Aluminiummessinggitter +tile.modernmetals.aluminumbrass_block.name=Aluminiummessing +tile.modernmetals.aluminumbrass_door.name=Aluminiummessingtür +tile.modernmetals.aluminumbrass_ore.name=Aluminiummessingerz +tile.modernmetals.aluminumbrass_plate.name=Aluminiummessingblech +tile.modernmetals.aluminumbrass_trapdoor.name=Aluminiummessingfalltür tile.modernmetals.cadmium_bars.name=Cadmiumgitter tile.modernmetals.cadmium_block.name=Cadmium @@ -834,19 +834,19 @@ tooltip.tungsten.armor=Nichts Besonderes tooltip.uranium.armor=Nichts Besonderes tooltip.zirconium.armor=Nichts Besonderes -achievement.aluminumbrass_maker=Duraluminium +achievement.aluminumbrass_maker=Aluminiummessing achievement.galvanized_steel_maker=Verzinkter Stahl achievement.nichrome_maker=Nickel-Chrom- achievement.stainless_steel_maker=Edelstahl achievement.titanium_maker=Titan -achievement.aluminumbrass_maker.desc=Kombiniere Aluminiumpulver und Kupferpulver, um Duraluminium herzustellen +achievement.aluminumbrass_maker.desc=Kombiniere Aluminiumpulver und Kupferpulver, um Aluminiummessing herzustellen achievement.galvanized_steel_maker.desc=Kombininiere Stahlpulver und Zinkpulver, um verzinkten Stahl herzustellen achievement.nichrome_maker.desc=Kombiniere Nickelpulver und Chrompulver, um Nickel-Chrom herzustellen achievement.stainless_steel_maker.desc=Kombiniere Stahlpulver und Chrompulver, um Edelstahl herzustellen achievement.titanium_maker.desc=Kombiniere Rutilpulver und Magnesiumpulver, um Titan herzustellen fluid.modernmetals.aluminum=Geschmolzenes Aluminium -fluid.modernmetals.aluminumbrass=Geschmolzenes Duraluminium +fluid.modernmetals.aluminumbrass=Geschmolzenes Aluminiummessing fluid.modernmetals.cadmium=Geschmolzenes Cadmium fluid.modernmetals.chromium=Geschmolzenes Chrom fluid.modernmetals.galvanizedsteel=Geschmolzener, vernickelter Stahl @@ -865,7 +865,7 @@ fluid.modernmetals.uranium=Geschmolzenes Uran fluid.modernmetals.zirconium=Geschmolzenes Zirkon fluid.modernmetals.aluminum.name=Geschmolzenes Aluminium -fluid.modernmetals.aluminumbrass.name=Geschmolzenes Duraluminium +fluid.modernmetals.aluminumbrass.name=Geschmolzenes Aluminiummessing fluid.modernmetals.cadmium.name=Geschmolzenes Cadmium fluid.modernmetals.chromium.name=Geschmolzenes Chrom fluid.modernmetals.galvanizedsteel.name=Geschmolzenes Verzinkter Stahl @@ -884,7 +884,7 @@ fluid.modernmetals.uranium.name=Geschmolzenes Uran fluid.modernmetals.zirconium.name=Geschmolzenes Zirkon tile.modernmetals.aluminum.name=Geschmolzenes Aluminium -tile.modernmetals.aluminumbrass.name=Geschmolzenes Duraluminium +tile.modernmetals.aluminumbrass.name=Geschmolzenes Aluminiummessing tile.modernmetals.cadmium.name=Geschmolzenes Cadmium tile.modernmetals.chromium.name=Geschmolzenes Chrom tile.modernmetals.galvanizedsteel.name=Geschmolzenes Verzinkter Stahl @@ -925,27 +925,27 @@ tile.modernmetals.aluminum_stairs.name=Aluminiumtreppe tile.modernmetals.aluminum_wall.name=Aluminiummauer -item.modernmetals.aluminumbrass_clump.name=Duraluminiumklumpen -item.modernmetals.aluminumbrass_crushed.name=Zerkleinertes Duraluminiumerz -item.modernmetals.aluminumbrass_crushed_purified.name=Gereinigtes, zerkleinertes Duraluminiumerz -item.modernmetals.aluminumbrass_crystal.name=Duraluminiumkristall -item.modernmetals.aluminumbrass_dense_plate.name=Verdichtetes Duraluminiumblech -item.modernmetals.aluminumbrass_powder_dirty.name=Verunreinigtes Duraluminiumpulver -item.modernmetals.aluminumbrass_shard.name=Duraluminiumsplitter +item.modernmetals.aluminumbrass_clump.name=Aluminiummessingklumpen +item.modernmetals.aluminumbrass_crushed.name=Zerkleinertes Aluminiummessingerz +item.modernmetals.aluminumbrass_crushed_purified.name=Gereinigtes, zerkleinertes Aluminiummessingerz +item.modernmetals.aluminumbrass_crystal.name=Aluminiummessingkristall +item.modernmetals.aluminumbrass_dense_plate.name=Verdichtetes Aluminiummessingblech +item.modernmetals.aluminumbrass_powder_dirty.name=Verunreinigtes Aluminiummessingpulver +item.modernmetals.aluminumbrass_shard.name=Aluminiummessingsplitter -item.modernmetals.aluminumbrass_button.name=Duraluminiumschalter -item.modernmetals.aluminumbrass_lever.name=Duraluminiumhebel -item.modernmetals.aluminumbrass_pressure_plate.name=Duraluminiumdruckplatte -item.modernmetals.aluminumbrass_slab.name=Duraluminiumfliese -item.modernmetals.aluminumbrass_stairs.name=Duraluminiumtreppe -item.modernmetals.aluminumbrass_wall.name=Duraluminiummauer +item.modernmetals.aluminumbrass_button.name=Aluminiummessingschalter +item.modernmetals.aluminumbrass_lever.name=Aluminiummessinghebel +item.modernmetals.aluminumbrass_pressure_plate.name=Aluminiummessingdruckplatte +item.modernmetals.aluminumbrass_slab.name=Aluminiummessingfliese +item.modernmetals.aluminumbrass_stairs.name=Aluminiummessingtreppe +item.modernmetals.aluminumbrass_wall.name=Aluminiummessingmauer -tile.modernmetals.aluminumbrass_button.name=Duraluminiumschalter -tile.modernmetals.aluminumbrass_lever.name=Duraluminiumhebel -tile.modernmetals.aluminumbrass_pressure_plate.name=Duraluminiumdruckplatte -tile.modernmetals.aluminumbrass_slab.name=Duraluminiumfliese -tile.modernmetals.aluminumbrass_stairs.name=Duraluminiumtreppe -tile.modernmetals.aluminumbrass_wall.name=Duraluminiummauer +tile.modernmetals.aluminumbrass_button.name=Aluminiummessingschalter +tile.modernmetals.aluminumbrass_lever.name=Aluminiummessinghebel +tile.modernmetals.aluminumbrass_pressure_plate.name=Aluminiummessingdruckplatte +tile.modernmetals.aluminumbrass_slab.name=Aluminiummessingfliese +tile.modernmetals.aluminumbrass_stairs.name=Aluminiummessingtreppe +tile.modernmetals.aluminumbrass_wall.name=Aluminiummessingmauer item.modernmetals.cadmium_clump.name=Cadmiumklumpen @@ -1313,4 +1313,223 @@ tile.modernmetals.zirconium_lever.name=Zirkonhebel tile.modernmetals.zirconium_pressure_plate.name=Zirkondruckplatte tile.modernmetals.zirconium_slab.name=Zirkonfliese tile.modernmetals.zirconium_stairs.name=Zirkontreppe -tile.modernmetals.zirconium_wall.name=Zirkonmauer \ No newline at end of file +tile.modernmetals.zirconium_wall.name=Zirkonmauer +# Modern Metals settings and restored content +config.modernmetals.material.tooltip=Legt fest, ob die Blöcke, Gegenstände und Rezepte dieses Materials verfügbar sind. Ein Neustart ist nötig. +config.modernmetals.title=Modern Metals +config.modernmetals.description=Neustart erforderlich. Erze in OreSpawn einstellen. +config.modernmetals.content_mode=Fantasy-Stufe +config.modernmetals.content_mode.tooltip=Viel Fantasy behält alle Rezepte bei. Wenig Fantasy schränkt unrealistische Ausrüstung und Bauteile ein. Ein Neustart ist nötig. +high_fantasy=Viel Fantasy +low_fantasy=Wenig Fantasy +config.modernmetals.villager_trades=Dorfbewohnerhandel +config.modernmetals.villager_trades.tooltip=Schmiede handeln mit Barren und Ausrüstung aus Modern Metals. Ein Neustart ist nötig. +config.modernmetals.connection.mismatch=Der Server verwendet %s, dein Spiel verwendet %s. Gleiche die Fantasy-Stufe unter Mods > Modern Metals > Konfiguration an und starte das Spiel neu. +config.modernmetals.connection.protocol=Modern Metals konnte die Fantasy-Stufe nicht prüfen. Verwende auf dem Server und im Spiel denselben Build von Modern Metals. +itemGroup.modernmetals.combat=Modern Metals – Kampf +material.beryllium.name=Beryllium +item.modernmetals.beryllium_arrow.name=Berylliumpfeil +item.modernmetals.beryllium_axe.name=Berylliumaxt +item.modernmetals.beryllium_bars.name=Berylliumgitter +item.modernmetals.beryllium_blend.name=Berylliumgemisch +item.modernmetals.beryllium_block.name=Berylliumblock +item.modernmetals.beryllium_boots.name=Berylliumstiefel +item.modernmetals.beryllium_bolt.name=Berylliumbolzen +item.modernmetals.beryllium_bow.name=Berylliumbogen +item.modernmetals.beryllium_chestplate.name=Berylliumbrustpanzer +item.modernmetals.beryllium_crackhammer.name=Berylliumbruchhammer +item.modernmetals.beryllium_crossbow.name=Berylliumarmbrust +item.modernmetals.beryllium_door.name=Berylliumtür +item.modernmetals.beryllium_fishing_rod.name=Berylliumangel +item.modernmetals.beryllium_gear.name=Berylliumzahnrad +item.modernmetals.beryllium_helmet.name=Berylliumhelm +item.modernmetals.beryllium_hoe.name=Berylliumhacke +item.modernmetals.beryllium_horse_armor.name=Berylliumpferderüstung +item.modernmetals.beryllium_ingot.name=Berylliumbarren +item.modernmetals.beryllium_leggings.name=Berylliumbeinrüstung +item.modernmetals.beryllium_nugget.name=Berylliumnugget +item.modernmetals.beryllium_ore.name=Berylliumerz +item.modernmetals.beryllium_pickaxe.name=Berylliumspitzhacke +item.modernmetals.beryllium_powder.name=Berylliumpulver +item.modernmetals.beryllium_rod.name=Berylliumstange +item.modernmetals.beryllium_shears.name=Berylliumschere +item.modernmetals.beryllium_shield.name=Berylliumschild +item.modernmetals.beryllium_shovel.name=Berylliumschaufel +item.modernmetals.beryllium_smallblend.name=Kleiner Berylliumgemischhaufen +item.modernmetals.beryllium_smallpowder.name=Kleiner Berylliumpulverhaufen +item.modernmetals.beryllium_sword.name=Berylliumschwert +item.modernmetals.beryllium_trapdoor.name=Berylliumfalltür +material.boron.name=Bor +item.modernmetals.boron_arrow.name=Borpfeil +item.modernmetals.boron_axe.name=Boraxt +item.modernmetals.boron_bars.name=Borgitter +item.modernmetals.boron_blend.name=Borgemisch +item.modernmetals.boron_block.name=Borblock +item.modernmetals.boron_boots.name=Borstiefel +item.modernmetals.boron_bolt.name=Borbolzen +item.modernmetals.boron_bow.name=Borbogen +item.modernmetals.boron_chestplate.name=Borbrustpanzer +item.modernmetals.boron_crackhammer.name=Borbruchhammer +item.modernmetals.boron_crossbow.name=Borarmbrust +item.modernmetals.boron_door.name=Bortür +item.modernmetals.boron_fishing_rod.name=Borangel +item.modernmetals.boron_gear.name=Borzahnrad +item.modernmetals.boron_helmet.name=Borhelm +item.modernmetals.boron_hoe.name=Borhacke +item.modernmetals.boron_horse_armor.name=Borpferderüstung +item.modernmetals.boron_ingot.name=Borbarren +item.modernmetals.boron_leggings.name=Borbeinrüstung +item.modernmetals.boron_nugget.name=Bornugget +item.modernmetals.boron_ore.name=Borerz +item.modernmetals.boron_pickaxe.name=Borspitzhacke +item.modernmetals.boron_powder.name=Borpulver +item.modernmetals.boron_rod.name=Borstange +item.modernmetals.boron_shears.name=Borschere +item.modernmetals.boron_shield.name=Borschild +item.modernmetals.boron_shovel.name=Borschaufel +item.modernmetals.boron_smallblend.name=Kleiner Borgemischhaufen +item.modernmetals.boron_smallpowder.name=Kleiner Borpulverhaufen +item.modernmetals.boron_sword.name=Borschwert +item.modernmetals.boron_trapdoor.name=Borfalltür +tile.modernmetals.boron_bars.name=Borgitter +tile.modernmetals.boron_block.name=Bor +tile.modernmetals.boron_door.name=Bortür +tile.modernmetals.boron_ore.name=Borerz +tile.modernmetals.boron_plate.name=Borblech +tile.modernmetals.boron_trapdoor.name=Borfalltür +fluid.modernmetals.boron=Geschmolzenes Bor +fluid.modernmetals.beryllium=Geschmolzenes Beryllium +fluid.modernmetals.boron.name=Geschmolzenes Bor +fluid.modernmetals.beryllium.name=Geschmolzenes Beryllium +tile.modernmetals.boron.name=Geschmolzenes Bor +tile.modernmetals.beryllium_bars.name=Berylliumgitter +tile.modernmetals.beryllium_block.name=Beryllium +tile.modernmetals.beryllium_door.name=Berylliumtür +tile.modernmetals.beryllium_ore.name=Berylliumerz +tile.modernmetals.beryllium_plate.name=Berylliumblech +tile.modernmetals.beryllium_trapdoor.name=Berylliumfalltür +item.modernmetals.beryllium_clump.name=Berylliumklumpen +item.modernmetals.beryllium_crushed.name=Zerkleinertes Berylliumerz +item.modernmetals.beryllium_crushed_purified.name=Gereinigtes, zerkleinertes Berylliumerz +item.modernmetals.beryllium_crystal.name=Berylliumkristall +item.modernmetals.beryllium_dense_plate.name=Verdichtetes Berylliumblech +item.modernmetals.beryllium_powder_dirty.name=Verunreinigtes Berylliumpulver +item.modernmetals.beryllium_shard.name=Berylliumsplitter +item.modernmetals.beryllium_button.name=Berylliumschalter +item.modernmetals.beryllium_lever.name=Berylliumhebel +item.modernmetals.beryllium_pressure_plate.name=Berylliumdruckplatte +item.modernmetals.beryllium_slab.name=Berylliumfliese +item.modernmetals.beryllium_stairs.name=Berylliumtreppe +item.modernmetals.beryllium_wall.name=Berylliummauer +tile.modernmetals.beryllium.name=Geschmolzenes Beryllium +tile.modernmetals.beryllium_button.name=Berylliumschalter +tile.modernmetals.beryllium_lever.name=Berylliumhebel +tile.modernmetals.beryllium_pressure_plate.name=Berylliumdruckplatte +tile.modernmetals.beryllium_slab.name=Berylliumfliese +tile.modernmetals.beryllium_stairs.name=Berylliumtreppe +tile.modernmetals.beryllium_wall.name=Berylliummauer +item.modernmetals.boron_clump.name=Borklumpen +item.modernmetals.boron_crushed.name=Zerkleinertes Borerz +item.modernmetals.boron_crushed_purified.name=Gereinigtes, zerkleinertes Borerz +item.modernmetals.boron_crystal.name=Borkristall +item.modernmetals.boron_dense_plate.name=Verdichtetes Borblech +item.modernmetals.boron_powder_dirty.name=Verunreinigtes Borpulver +item.modernmetals.boron_shard.name=Borsplitter +item.modernmetals.boron_button.name=Borschalter +item.modernmetals.boron_lever.name=Borhebel +item.modernmetals.boron_pressure_plate.name=Bordruckplatte +item.modernmetals.boron_slab.name=Borfliese +item.modernmetals.boron_stairs.name=Bortreppe +item.modernmetals.boron_wall.name=Bormauer +tile.modernmetals.boron_button.name=Borschalter +tile.modernmetals.boron_lever.name=Borhebel +tile.modernmetals.boron_pressure_plate.name=Bordruckplatte +tile.modernmetals.boron_slab.name=Borfliese +tile.modernmetals.boron_stairs.name=Bortreppe +tile.modernmetals.boron_wall.name=Bormauer +material.thorium.name=Thorium +item.modernmetals.thorium_arrow.name=Thoriumpfeil +item.modernmetals.thorium_axe.name=Thoriumaxt +item.modernmetals.thorium_bars.name=Thoriumgitter +item.modernmetals.thorium_blend.name=Thoriumgemisch +item.modernmetals.thorium_block.name=Thoriumblock +item.modernmetals.thorium_boots.name=Thoriumstiefel +item.modernmetals.thorium_bolt.name=Thoriumbolzen +item.modernmetals.thorium_bow.name=Thoriumbogen +item.modernmetals.thorium_chestplate.name=Thoriumbrustpanzer +item.modernmetals.thorium_crackhammer.name=Thoriumbruchhammer +item.modernmetals.thorium_crossbow.name=Thoriumarmbrust +item.modernmetals.thorium_door.name=Thoriumtür +item.modernmetals.thorium_fishing_rod.name=Thoriumangel +item.modernmetals.thorium_gear.name=Thoriumzahnrad +item.modernmetals.thorium_helmet.name=Thoriumhelm +item.modernmetals.thorium_hoe.name=Thoriumhacke +item.modernmetals.thorium_horse_armor.name=Thoriumpferderüstung +item.modernmetals.thorium_ingot.name=Thoriumbarren +item.modernmetals.thorium_leggings.name=Thoriumbeinrüstung +item.modernmetals.thorium_nugget.name=Thoriumnugget +item.modernmetals.thorium_ore.name=Thoriumerz +item.modernmetals.thorium_pickaxe.name=Thoriumspitzhacke +item.modernmetals.thorium_powder.name=Thoriumpulver +item.modernmetals.thorium_rod.name=Thoriumstange +item.modernmetals.thorium_shears.name=Thoriumschere +item.modernmetals.thorium_shield.name=Thoriumschild +item.modernmetals.thorium_shovel.name=Thoriumschaufel +item.modernmetals.thorium_smallblend.name=Kleiner Thoriumgemischhaufen +item.modernmetals.thorium_smallpowder.name=Kleiner Thoriumpulverhaufen +item.modernmetals.thorium_sword.name=Thoriumschwert +item.modernmetals.thorium_trapdoor.name=Thoriumfalltür +tile.modernmetals.thorium_bars.name=Thoriumgitter +tile.modernmetals.thorium_block.name=Thorium +tile.modernmetals.thorium_door.name=Thoriumtür +tile.modernmetals.thorium_ore.name=Thoriumerz +tile.modernmetals.thorium_plate.name=Thoriumblech +tile.modernmetals.thorium_trapdoor.name=Thoriumfalltür +fluid.modernmetals.thorium=Geschmolzenes Thorium +fluid.modernmetals.thorium.name=Geschmolzenes Thorium +tile.modernmetals.thorium.name=Geschmolzenes Thorium +item.modernmetals.thorium_clump.name=Thoriumklumpen +item.modernmetals.thorium_crushed.name=Zerkleinertes Thoriumerz +item.modernmetals.thorium_crushed_purified.name=Gereinigtes, zerkleinertes Thoriumerz +item.modernmetals.thorium_crystal.name=Thoriumkristall +item.modernmetals.thorium_dense_plate.name=Verdichtetes Thoriumblech +item.modernmetals.thorium_powder_dirty.name=Verunreinigtes Thoriumpulver +item.modernmetals.thorium_shard.name=Thoriumsplitter +item.modernmetals.thorium_button.name=Thoriumschalter +item.modernmetals.thorium_lever.name=Thoriumhebel +item.modernmetals.thorium_pressure_plate.name=Thoriumdruckplatte +item.modernmetals.thorium_slab.name=Thoriumfliese +item.modernmetals.thorium_stairs.name=Thoriumtreppe +item.modernmetals.thorium_wall.name=Thoriummauer +tile.modernmetals.thorium_button.name=Thoriumschalter +tile.modernmetals.thorium_lever.name=Thoriumhebel +tile.modernmetals.thorium_pressure_plate.name=Thoriumdruckplatte +tile.modernmetals.thorium_slab.name=Thoriumfliese +tile.modernmetals.thorium_stairs.name=Thoriumtreppe +tile.modernmetals.thorium_wall.name=Thoriummauer +item.modernmetals.titanium_casing.name=Titangehäuse +item.modernmetals.beryllium_scythe.name=Berylliumsichel +item.modernmetals.boron_scythe.name=Borsichel +item.modernmetals.thorium_scythe.name=Thoriumsichel +item.modernmetals.titanium_scythe.name=Titansichel +config.modernmetals.enable_thorium=Thorium aktivieren +config.modernmetals.enable_boron=Bor aktivieren +config.modernmetals.enable_beryllium=Beryllium aktivieren +config.modernmetals.enable_cadmium=Cadmium aktivieren +config.modernmetals.enable_nichrome=Nickel-Chrom-Legierung aktivieren +config.modernmetals.enable_aluminum=Aluminium aktivieren +config.modernmetals.enable_aluminumbrass=Aluminiummessing aktivieren +config.modernmetals.enable_chromium=Chrom aktivieren +config.modernmetals.enable_galvanizedsteel=Verzinkter Stahl aktivieren +config.modernmetals.enable_iridium=Iridium aktivieren +config.modernmetals.enable_magnesium=Magnesium aktivieren +config.modernmetals.enable_manganese=Mangan aktivieren +config.modernmetals.enable_osmium=Osmium aktivieren +config.modernmetals.enable_plutonium=Plutonium aktivieren +config.modernmetals.enable_rutile=Rutil aktivieren +config.modernmetals.enable_stainlesssteel=Edelstahl aktivieren +config.modernmetals.enable_tantalum=Tantal aktivieren +config.modernmetals.enable_titanium=Titan aktivieren +config.modernmetals.enable_tungsten=Wolfram aktivieren +config.modernmetals.enable_uranium=Uran aktivieren +config.modernmetals.enable_zirconium=Zirkon aktivieren diff --git a/src/main/resources/assets/modernmetals/lang/en_AU.lang b/src/main/resources/assets/modernmetals/lang/en_AU.lang new file mode 100644 index 00000000..0f62b48b --- /dev/null +++ b/src/main/resources/assets/modernmetals/lang/en_AU.lang @@ -0,0 +1,51 @@ +# Regional strings. Minecraft falls back to en_US for other entries. + +# Regional English +item.modernmetals.aluminum_horse_armor.name=Aluminum Horse Armour +item.modernmetals.aluminum_leggings.name=Aluminum Leg Armour +item.modernmetals.aluminumbrass_horse_armor.name=Aluminum Brass Horse Armour +item.modernmetals.aluminumbrass_leggings.name=Aluminum Brass Leg Armour +item.modernmetals.antimony_leggings.name=Antimony Leg Armour +item.modernmetals.beryllium_horse_armor.name=Beryllium Horse Armour +item.modernmetals.beryllium_leggings.name=Beryllium Leg Armour +item.modernmetals.bismuth_leggings.name=Bismuth Leg Armour +item.modernmetals.boron_horse_armor.name=Boron Horse Armour +item.modernmetals.boron_leggings.name=Boron Leg Armour +item.modernmetals.cadmium_horse_armor.name=Cadmium Horse Armour +item.modernmetals.cadmium_leggings.name=Cadmium Leg Armour +item.modernmetals.chromium_horse_armor.name=Chromium Horse Armour +item.modernmetals.chromium_leggings.name=Chromium Leg Armour +item.modernmetals.galvanizedsteel_horse_armor.name=Galvanized Steel Horse Armour +item.modernmetals.galvanizedsteel_leggings.name=Galvanized Steel Leg Armour +item.modernmetals.iridium_horse_armor.name=Iridium Horse Armour +item.modernmetals.iridium_leggings.name=Iridium Leg Armour +item.modernmetals.magnesium_horse_armor.name=Magnesium Horse Armour +item.modernmetals.magnesium_leggings.name=Magnesium Leg Armour +item.modernmetals.manganese_horse_armor.name=Manganese Horse Armour +item.modernmetals.manganese_leggings.name=Manganese Leg Armour +item.modernmetals.nichrome_horse_armor.name=Nichrome Horse Armour +item.modernmetals.nichrome_leggings.name=Nichrome Leg Armour +item.modernmetals.osmium_horse_armor.name=Osmium Horse Armour +item.modernmetals.osmium_leggings.name=Osmium Leg Armour +item.modernmetals.pewter_leggings.name=Pewter Leg Armour +item.modernmetals.plutonium_horse_armor.name=Plutonium Horse Armour +item.modernmetals.plutonium_leggings.name=Plutonium Leg Armour +item.modernmetals.rutile_horse_armor.name=Rutile Horse Armour +item.modernmetals.rutile_leggings.name=Rutile Leg Armour +item.modernmetals.stainlesssteel_horse_armor.name=Stainless Steel Horse Armour +item.modernmetals.stainlesssteel_leggings.name=Stainless Steel Leg Armour +item.modernmetals.tantalum_horse_armor.name=Tantalum Horse Armour +item.modernmetals.tantalum_leggings.name=Tantalum Leg Armour +item.modernmetals.titanium_horse_armor.name=Titanium Horse Armour +item.modernmetals.titanium_leggings.name=Titanium Leg Armour +item.modernmetals.tungsten_horse_armor.name=Tungsten Horse Armour +item.modernmetals.tungsten_leggings.name=Tungsten Leg Armour +item.modernmetals.uranium_horse_armor.name=Uranium Horse Armour +item.modernmetals.uranium_leggings.name=Uranium Leg Armour +item.modernmetals.zirconium_horse_armor.name=Zirconium Horse Armour +item.modernmetals.zirconium_leggings.name=Zirconium Leg Armour +item.modernmetals.thorium_horse_armor.name=Thorium Horse Armour +item.modernmetals.thorium_leggings.name=Thorium Leg Armour +config.modernmetals.enable_aluminum=Enable Aluminium +config.modernmetals.enable_aluminumbrass=Enable Aluminium Brass +config.modernmetals.enable_galvanizedsteel=Enable Galvanised Steel diff --git a/src/main/resources/assets/modernmetals/lang/en_CA.lang b/src/main/resources/assets/modernmetals/lang/en_CA.lang new file mode 100644 index 00000000..0f62b48b --- /dev/null +++ b/src/main/resources/assets/modernmetals/lang/en_CA.lang @@ -0,0 +1,51 @@ +# Regional strings. Minecraft falls back to en_US for other entries. + +# Regional English +item.modernmetals.aluminum_horse_armor.name=Aluminum Horse Armour +item.modernmetals.aluminum_leggings.name=Aluminum Leg Armour +item.modernmetals.aluminumbrass_horse_armor.name=Aluminum Brass Horse Armour +item.modernmetals.aluminumbrass_leggings.name=Aluminum Brass Leg Armour +item.modernmetals.antimony_leggings.name=Antimony Leg Armour +item.modernmetals.beryllium_horse_armor.name=Beryllium Horse Armour +item.modernmetals.beryllium_leggings.name=Beryllium Leg Armour +item.modernmetals.bismuth_leggings.name=Bismuth Leg Armour +item.modernmetals.boron_horse_armor.name=Boron Horse Armour +item.modernmetals.boron_leggings.name=Boron Leg Armour +item.modernmetals.cadmium_horse_armor.name=Cadmium Horse Armour +item.modernmetals.cadmium_leggings.name=Cadmium Leg Armour +item.modernmetals.chromium_horse_armor.name=Chromium Horse Armour +item.modernmetals.chromium_leggings.name=Chromium Leg Armour +item.modernmetals.galvanizedsteel_horse_armor.name=Galvanized Steel Horse Armour +item.modernmetals.galvanizedsteel_leggings.name=Galvanized Steel Leg Armour +item.modernmetals.iridium_horse_armor.name=Iridium Horse Armour +item.modernmetals.iridium_leggings.name=Iridium Leg Armour +item.modernmetals.magnesium_horse_armor.name=Magnesium Horse Armour +item.modernmetals.magnesium_leggings.name=Magnesium Leg Armour +item.modernmetals.manganese_horse_armor.name=Manganese Horse Armour +item.modernmetals.manganese_leggings.name=Manganese Leg Armour +item.modernmetals.nichrome_horse_armor.name=Nichrome Horse Armour +item.modernmetals.nichrome_leggings.name=Nichrome Leg Armour +item.modernmetals.osmium_horse_armor.name=Osmium Horse Armour +item.modernmetals.osmium_leggings.name=Osmium Leg Armour +item.modernmetals.pewter_leggings.name=Pewter Leg Armour +item.modernmetals.plutonium_horse_armor.name=Plutonium Horse Armour +item.modernmetals.plutonium_leggings.name=Plutonium Leg Armour +item.modernmetals.rutile_horse_armor.name=Rutile Horse Armour +item.modernmetals.rutile_leggings.name=Rutile Leg Armour +item.modernmetals.stainlesssteel_horse_armor.name=Stainless Steel Horse Armour +item.modernmetals.stainlesssteel_leggings.name=Stainless Steel Leg Armour +item.modernmetals.tantalum_horse_armor.name=Tantalum Horse Armour +item.modernmetals.tantalum_leggings.name=Tantalum Leg Armour +item.modernmetals.titanium_horse_armor.name=Titanium Horse Armour +item.modernmetals.titanium_leggings.name=Titanium Leg Armour +item.modernmetals.tungsten_horse_armor.name=Tungsten Horse Armour +item.modernmetals.tungsten_leggings.name=Tungsten Leg Armour +item.modernmetals.uranium_horse_armor.name=Uranium Horse Armour +item.modernmetals.uranium_leggings.name=Uranium Leg Armour +item.modernmetals.zirconium_horse_armor.name=Zirconium Horse Armour +item.modernmetals.zirconium_leggings.name=Zirconium Leg Armour +item.modernmetals.thorium_horse_armor.name=Thorium Horse Armour +item.modernmetals.thorium_leggings.name=Thorium Leg Armour +config.modernmetals.enable_aluminum=Enable Aluminium +config.modernmetals.enable_aluminumbrass=Enable Aluminium Brass +config.modernmetals.enable_galvanizedsteel=Enable Galvanised Steel diff --git a/src/main/resources/assets/modernmetals/lang/en_GB.lang b/src/main/resources/assets/modernmetals/lang/en_GB.lang new file mode 100644 index 00000000..9ec41df4 --- /dev/null +++ b/src/main/resources/assets/modernmetals/lang/en_GB.lang @@ -0,0 +1,96 @@ +# Regional strings. Minecraft falls back to en_US for other entries. + +# Regional English +item.modernmetals.aluminum_block.name=Aluminum +item.modernmetals.aluminum_horse_armor.name=Aluminum Horse Armour +item.modernmetals.aluminum_leggings.name=Aluminum Leg Armour +item.modernmetals.aluminumbrass_block.name=Aluminum Brass Block +item.modernmetals.aluminumbrass_horse_armor.name=Aluminum Brass Horse Armour +item.modernmetals.aluminumbrass_leggings.name=Aluminum Brass Leg Armour +item.modernmetals.antimony_block.name=Antimony Block +item.modernmetals.antimony_leggings.name=Antimony Leg Armour +item.modernmetals.beryllium_block.name=Beryllium Block +item.modernmetals.beryllium_horse_armor.name=Beryllium Horse Armour +item.modernmetals.beryllium_leggings.name=Beryllium Leg Armour +item.modernmetals.bismuth_block.name=Bismuth Block +item.modernmetals.bismuth_leggings.name=Bismuth Leg Armour +item.modernmetals.boron_block.name=Boron Block +item.modernmetals.boron_horse_armor.name=Boron Horse Armour +item.modernmetals.boron_leggings.name=Boron Leg Armour +item.modernmetals.cadmium_block.name=Cadmium Block +item.modernmetals.cadmium_horse_armor.name=Cadmium Horse Armour +item.modernmetals.cadmium_leggings.name=Cadmium Leg Armour +item.modernmetals.chromium_block.name=Chromium Block +item.modernmetals.chromium_horse_armor.name=Chromium Horse Armour +item.modernmetals.chromium_leggings.name=Chromium Leg Armour +item.modernmetals.galvanizedsteel_block.name=Galvanized Steel Block +item.modernmetals.galvanizedsteel_horse_armor.name=Galvanized Steel Horse Armour +item.modernmetals.galvanizedsteel_leggings.name=Galvanized Steel Leg Armour +item.modernmetals.iridium_block.name=Iridium Block +item.modernmetals.iridium_horse_armor.name=Iridium Horse Armour +item.modernmetals.iridium_leggings.name=Iridium Leg Armour +item.modernmetals.magnesium_block.name=Magnesium Block +item.modernmetals.magnesium_horse_armor.name=Magnesium Horse Armour +item.modernmetals.magnesium_leggings.name=Magnesium Leg Armour +item.modernmetals.manganese_block.name=Manganese Block +item.modernmetals.manganese_horse_armor.name=Manganese Horse Armour +item.modernmetals.manganese_leggings.name=Manganese Leg Armour +item.modernmetals.nichrome_block.name=Nichrome Block +item.modernmetals.nichrome_horse_armor.name=Nichrome Horse Armour +item.modernmetals.nichrome_leggings.name=Nichrome Leg Armour +item.modernmetals.osmium_block.name=Osmium Block +item.modernmetals.osmium_horse_armor.name=Osmium Horse Armour +item.modernmetals.osmium_leggings.name=Osmium Leg Armour +item.modernmetals.pewter_block.name=Pewter Block +item.modernmetals.pewter_leggings.name=Pewter Leg Armour +item.modernmetals.plutonium_block.name=Plutonium Block +item.modernmetals.plutonium_horse_armor.name=Plutonium Horse Armour +item.modernmetals.plutonium_leggings.name=Plutonium Leg Armour +item.modernmetals.rutile_block.name=Rutile Block +item.modernmetals.rutile_horse_armor.name=Rutile Horse Armour +item.modernmetals.rutile_leggings.name=Rutile Leg Armour +item.modernmetals.stainlesssteel_block.name=Stainless Steel Block +item.modernmetals.stainlesssteel_horse_armor.name=Stainless Steel Horse Armour +item.modernmetals.stainlesssteel_leggings.name=Stainless Steel Leg Armour +item.modernmetals.tantalum_block.name=Tantalum Block +item.modernmetals.tantalum_horse_armor.name=Tantalum Horse Armour +item.modernmetals.tantalum_leggings.name=Tantalum Leg Armour +item.modernmetals.titanium_block.name=Titanium Block +item.modernmetals.titanium_horse_armor.name=Titanium Horse Armour +item.modernmetals.titanium_leggings.name=Titanium Leg Armour +item.modernmetals.tungsten_block.name=Tungsten Block +item.modernmetals.tungsten_horse_armor.name=Tungsten Horse Armour +item.modernmetals.tungsten_leggings.name=Tungsten Leg Armour +item.modernmetals.uranium_block.name=Uranium Block +item.modernmetals.uranium_horse_armor.name=Uranium Horse Armour +item.modernmetals.uranium_leggings.name=Uranium Leg Armour +item.modernmetals.zirconium_block.name=Zirconium Block +item.modernmetals.zirconium_horse_armor.name=Zirconium Horse Armour +item.modernmetals.zirconium_leggings.name=Zirconium Leg Armour +tile.modernmetals.aluminum_block.name=Aluminum Block +tile.modernmetals.aluminumbrass_block.name=Aluminum Brass Block +tile.modernmetals.boron_block.name=Boron Block +tile.modernmetals.cadmium_block.name=Cadmium Block +tile.modernmetals.chromium_block.name=Chromium Block +tile.modernmetals.galvanizedsteel_block.name=Galvanized Steel Block +tile.modernmetals.iridium_block.name=Iridium Block +tile.modernmetals.magnesium_block.name=Magnesium Block +tile.modernmetals.manganese_block.name=Manganese Block +tile.modernmetals.nichrome_block.name=Nichrome Block +tile.modernmetals.osmium_block.name=Osmium Block +tile.modernmetals.plutonium_block.name=Plutonium Block +tile.modernmetals.rutile_block.name=Rutile Block +tile.modernmetals.stainlesssteel_block.name=Stainless Steel Block +tile.modernmetals.tantalum_block.name=Tantalum +tile.modernmetals.titanium_block.name=Titanium +tile.modernmetals.tungsten_block.name=Tungsten +tile.modernmetals.uranium_block.name=Uranium +tile.modernmetals.zirconium_block.name=Zirconium +tile.modernmetals.beryllium_block.name=Beryllium +item.modernmetals.thorium_block.name=Thorium +item.modernmetals.thorium_horse_armor.name=Thorium Horse Armour +item.modernmetals.thorium_leggings.name=Thorium Leg Armour +tile.modernmetals.thorium_block.name=Thorium +config.modernmetals.enable_aluminum=Enable Aluminium +config.modernmetals.enable_aluminumbrass=Enable Aluminium Brass +config.modernmetals.enable_galvanizedsteel=Enable Galvanised Steel diff --git a/src/main/resources/assets/modernmetals/lang/en_NZ.lang b/src/main/resources/assets/modernmetals/lang/en_NZ.lang new file mode 100644 index 00000000..0f62b48b --- /dev/null +++ b/src/main/resources/assets/modernmetals/lang/en_NZ.lang @@ -0,0 +1,51 @@ +# Regional strings. Minecraft falls back to en_US for other entries. + +# Regional English +item.modernmetals.aluminum_horse_armor.name=Aluminum Horse Armour +item.modernmetals.aluminum_leggings.name=Aluminum Leg Armour +item.modernmetals.aluminumbrass_horse_armor.name=Aluminum Brass Horse Armour +item.modernmetals.aluminumbrass_leggings.name=Aluminum Brass Leg Armour +item.modernmetals.antimony_leggings.name=Antimony Leg Armour +item.modernmetals.beryllium_horse_armor.name=Beryllium Horse Armour +item.modernmetals.beryllium_leggings.name=Beryllium Leg Armour +item.modernmetals.bismuth_leggings.name=Bismuth Leg Armour +item.modernmetals.boron_horse_armor.name=Boron Horse Armour +item.modernmetals.boron_leggings.name=Boron Leg Armour +item.modernmetals.cadmium_horse_armor.name=Cadmium Horse Armour +item.modernmetals.cadmium_leggings.name=Cadmium Leg Armour +item.modernmetals.chromium_horse_armor.name=Chromium Horse Armour +item.modernmetals.chromium_leggings.name=Chromium Leg Armour +item.modernmetals.galvanizedsteel_horse_armor.name=Galvanized Steel Horse Armour +item.modernmetals.galvanizedsteel_leggings.name=Galvanized Steel Leg Armour +item.modernmetals.iridium_horse_armor.name=Iridium Horse Armour +item.modernmetals.iridium_leggings.name=Iridium Leg Armour +item.modernmetals.magnesium_horse_armor.name=Magnesium Horse Armour +item.modernmetals.magnesium_leggings.name=Magnesium Leg Armour +item.modernmetals.manganese_horse_armor.name=Manganese Horse Armour +item.modernmetals.manganese_leggings.name=Manganese Leg Armour +item.modernmetals.nichrome_horse_armor.name=Nichrome Horse Armour +item.modernmetals.nichrome_leggings.name=Nichrome Leg Armour +item.modernmetals.osmium_horse_armor.name=Osmium Horse Armour +item.modernmetals.osmium_leggings.name=Osmium Leg Armour +item.modernmetals.pewter_leggings.name=Pewter Leg Armour +item.modernmetals.plutonium_horse_armor.name=Plutonium Horse Armour +item.modernmetals.plutonium_leggings.name=Plutonium Leg Armour +item.modernmetals.rutile_horse_armor.name=Rutile Horse Armour +item.modernmetals.rutile_leggings.name=Rutile Leg Armour +item.modernmetals.stainlesssteel_horse_armor.name=Stainless Steel Horse Armour +item.modernmetals.stainlesssteel_leggings.name=Stainless Steel Leg Armour +item.modernmetals.tantalum_horse_armor.name=Tantalum Horse Armour +item.modernmetals.tantalum_leggings.name=Tantalum Leg Armour +item.modernmetals.titanium_horse_armor.name=Titanium Horse Armour +item.modernmetals.titanium_leggings.name=Titanium Leg Armour +item.modernmetals.tungsten_horse_armor.name=Tungsten Horse Armour +item.modernmetals.tungsten_leggings.name=Tungsten Leg Armour +item.modernmetals.uranium_horse_armor.name=Uranium Horse Armour +item.modernmetals.uranium_leggings.name=Uranium Leg Armour +item.modernmetals.zirconium_horse_armor.name=Zirconium Horse Armour +item.modernmetals.zirconium_leggings.name=Zirconium Leg Armour +item.modernmetals.thorium_horse_armor.name=Thorium Horse Armour +item.modernmetals.thorium_leggings.name=Thorium Leg Armour +config.modernmetals.enable_aluminum=Enable Aluminium +config.modernmetals.enable_aluminumbrass=Enable Aluminium Brass +config.modernmetals.enable_galvanizedsteel=Enable Galvanised Steel diff --git a/src/main/resources/assets/modernmetals/lang/en_PT.lang b/src/main/resources/assets/modernmetals/lang/en_PT.lang new file mode 100644 index 00000000..4b2fa57e --- /dev/null +++ b/src/main/resources/assets/modernmetals/lang/en_PT.lang @@ -0,0 +1,90 @@ +# Regional strings. Minecraft falls back to en_US for other entries. + +# Regional English +item.modernmetals.aluminum_block.name=Block o' Aluminum +item.modernmetals.aluminumbrass_block.name=Block o' Aluminum Brass +item.modernmetals.antimony_block.name=Block o' Antimony +item.modernmetals.beryllium_block.name=Block o' Beryllium +item.modernmetals.bismuth_block.name=Block o' Bismuth +item.modernmetals.boron_block.name=Block o' Boron +item.modernmetals.cadmium_block.name=Block o' Cadmium +item.modernmetals.chromium_block.name=Block o' Chromium +item.modernmetals.galvanizedsteel_block.name=Block o' Galvanized Steel +item.modernmetals.iridium_block.name=Block o' Iridium +item.modernmetals.magnesium_block.name=Block o' Magnesium +item.modernmetals.manganese_block.name=Block o' Manganese +item.modernmetals.nichrome_block.name=Block o' Nichrome +item.modernmetals.osmium_block.name=Block o' Osmium +item.modernmetals.pewter_block.name=Block o' Pewter +item.modernmetals.plutonium_block.name=Block o' Plutonium +item.modernmetals.rutile_block.name=Block o' Rutile +item.modernmetals.stainlesssteel_block.name=Block o' Stainless Steel +item.modernmetals.tantalum_block.name=Block o' Tantalum +item.modernmetals.titanium_block.name=Block o' Titanium +item.modernmetals.tungsten_block.name=Block o' Tungsten +item.modernmetals.uranium_block.name=Block o' Uranium +item.modernmetals.zirconium_block.name=Block o' Zirconium +tile.modernmetals.aluminum_block.name=Block o' Aluminum +tile.modernmetals.aluminum_plate.name=Plate o' Aluminum +tile.modernmetals.aluminumbrass_block.name=Block o' Aluminum Brass +tile.modernmetals.aluminumbrass_plate.name=Plate o' Aluminum Brass +tile.modernmetals.boron_block.name=Block o' Boron +tile.modernmetals.boron_plate.name=Plate o' Boron +tile.modernmetals.cadmium_block.name=Block o' Cadmium +tile.modernmetals.cadmium_plate.name=Plate o' Cadmium +tile.modernmetals.chromium_block.name=Block o' Chromium +tile.modernmetals.chromium_plate.name=Plate o' Chromium +tile.modernmetals.galvanizedsteel_block.name=Block o' Galvanized Steel +tile.modernmetals.galvanizedsteel_plate.name=Plate o' Galvanized Steel +tile.modernmetals.iridium_block.name=Block o' Iridium +tile.modernmetals.iridium_plate.name=Plate o' Iridium +tile.modernmetals.magnesium_block.name=Block o' Magnesium +tile.modernmetals.magnesium_plate.name=Plate o' Magnesium +tile.modernmetals.manganese_block.name=Block o' Manganese +tile.modernmetals.manganese_plate.name=Plate o' Manganese +tile.modernmetals.nichrome_block.name=Block o' Nichrome +tile.modernmetals.nichrome_plate.name=Plate o' Nichrome +tile.modernmetals.osmium_block.name=Block o' Osmium +tile.modernmetals.osmium_plate.name=Plate o' Osmium +tile.modernmetals.plutonium_block.name=Block o' Plutonium +tile.modernmetals.plutonium_plate.name=Plate o' Plutonium +tile.modernmetals.rutile_block.name=Block o' Rutile +tile.modernmetals.rutile_plate.name=Plate o' Rutile +tile.modernmetals.stainlesssteel_block.name=Block o' Stainless Steel +tile.modernmetals.stainlesssteel_plate.name=Plate o' Stainless Steel +tile.modernmetals.tantalum_block.name=Block o' Tantalum +tile.modernmetals.tantalum_plate.name=Plate o' Tantalum +tile.modernmetals.titanium_block.name=Block o' Titanium +tile.modernmetals.titanium_plate.name=Plate o' Titanium +tile.modernmetals.tungsten_block.name=Block o' Tungsten +tile.modernmetals.tungsten_plate.name=Plate o' Tungsten +tile.modernmetals.uranium_block.name=Block o' Uranium +tile.modernmetals.uranium_plate.name=Plate o' Uranium +tile.modernmetals.zirconium_block.name=Block o' Zirconium +tile.modernmetals.zirconium_plate.name=Plate o' Zirconium +item.modernmetals.aluminum_dense_plate.name=Dense Plate o' Aluminum +item.modernmetals.aluminumbrass_dense_plate.name=Dense Plate o' Aluminum Brass +tile.modernmetals.beryllium_block.name=Block o' Beryllium +tile.modernmetals.beryllium_plate.name=Plate o' Beryllium +item.modernmetals.beryllium_dense_plate.name=Dense Plate o' Beryllium +item.modernmetals.boron_dense_plate.name=Dense Plate o' Boron +item.modernmetals.cadmium_dense_plate.name=Dense Plate o' Cadmium +item.modernmetals.chromium_dense_plate.name=Dense Plate o' Chromium +item.modernmetals.galvanizedsteel_dense_plate.name=Dense Plate o' Galvanized Steel +item.modernmetals.iridium_dense_plate.name=Dense Plate o' Iridium +item.modernmetals.magnesium_dense_plate.name=Dense Plate o' Magnesium +item.modernmetals.manganese_dense_plate.name=Dense Plate o' Manganese +item.modernmetals.nichrome_dense_plate.name=Dense Plate o' Nichrome +item.modernmetals.osmium_dense_plate.name=Dense Plate o' Osmium +item.modernmetals.plutonium_dense_plate.name=Dense Plate o' Plutonium +item.modernmetals.rutile_dense_plate.name=Dense Plate o' Rutile +item.modernmetals.stainlesssteel_dense_plate.name=Dense Plate o' Stainless Steel +item.modernmetals.tantalum_dense_plate.name=Dense Plate o' Tantalum +item.modernmetals.titanium_dense_plate.name=Dense Plate o' Titanium +item.modernmetals.tungsten_dense_plate.name=Dense Plate o' Tungsten +item.modernmetals.uranium_dense_plate.name=Dense Plate o' Uranium +item.modernmetals.zirconium_dense_plate.name=Dense Plate o' Zirconium +item.modernmetals.thorium_block.name=Block o' Thorium +tile.modernmetals.thorium_block.name=Block o' Thorium +tile.modernmetals.thorium_plate.name=Plate o' Thorium +item.modernmetals.thorium_dense_plate.name=Dense Plate o' Thorium diff --git a/src/main/resources/assets/modernmetals/lang/en_US.lang b/src/main/resources/assets/modernmetals/lang/en_US.lang index 19ed056d..e5087e0a 100644 --- a/src/main/resources/assets/modernmetals/lang/en_US.lang +++ b/src/main/resources/assets/modernmetals/lang/en_US.lang @@ -1573,3 +1573,10 @@ config.modernmetals.enable_titanium=Enable Titanium config.modernmetals.enable_tungsten=Enable Tungsten config.modernmetals.enable_uranium=Enable Uranium config.modernmetals.enable_zirconium=Enable Zirconium + +# Modern Metals settings and restored content +config.modernmetals.material.tooltip=Controls which blocks, items and recipes are available for this material. Requires a game restart. +config.modernmetals.villager_trades=Villager Trades +config.modernmetals.villager_trades.tooltip=Let blacksmiths trade Modern Metals ingots and equipment. Requires a game restart. +config.modernmetals.connection.mismatch=The server uses %s, but your game uses %s. Match the Fantasy Level in Mods > Modern Metals > Config and restart. +config.modernmetals.connection.protocol=Modern Metals could not check the Fantasy Level. Use the same Modern Metals build on the server and client. diff --git a/src/main/resources/assets/modernmetals/lang/ru_RU.lang b/src/main/resources/assets/modernmetals/lang/ru_RU.lang new file mode 100644 index 00000000..6ce949f6 --- /dev/null +++ b/src/main/resources/assets/modernmetals/lang/ru_RU.lang @@ -0,0 +1,1553 @@ +itemGroup.modernmetals.items=Modern Metals Предметы +itemGroup.modernmetals.tools=Modern Metals Инструменты +itemGroup.modernmetals.blocks=Modern Metals Блоки +nei.modernmetals.recipehandler.crusher.name=Crushed Blocks/Items + +material.aluminum.name=Алюминий +item.modernmetals.aluminum_arrow.name=Алюминиевая Стрела +item.modernmetals.aluminum_axe.name=Алюминиевый Топор +item.modernmetals.aluminum_bars.name=Алюминиевый Прутья +item.modernmetals.aluminum_blend.name=Алюминиевый Смеси +item.modernmetals.aluminum_block.name=Блок Алюминя +item.modernmetals.aluminum_boots.name=Алюминиевый Ботинки +item.modernmetals.aluminum_bolt.name=Алюминиевый Арбалетная Стрела +item.modernmetals.aluminum_bow.name=Алюминиевый Лук +item.modernmetals.aluminum_chestplate.name=Алюминиевый Нагрудник +item.modernmetals.aluminum_crackhammer.name=Алюминиевый Измельчающий Молот +item.modernmetals.aluminum_crossbow.name=Алюминиевый Арбалет +item.modernmetals.aluminum_door.name=Алюминиевый Двери +item.modernmetals.aluminum_fishing_rod.name=Алюминиевый Удочка +item.modernmetals.aluminum_gear.name=Алюминиевый Шестерня +item.modernmetals.aluminum_helmet.name=Алюминиевый Шлем +item.modernmetals.aluminum_hoe.name=Алюминиевый Мотыга +item.modernmetals.aluminum_horse_armor.name=Алюминиевый Конская Броня +item.modernmetals.aluminum_ingot.name=Алюминиевый Слиток +item.modernmetals.aluminum_leggings.name=Алюминиевый Поножки +item.modernmetals.aluminum_nugget.name=Алюминиевый Самородок +item.modernmetals.aluminum_ore.name=Алюминиевый Руда +item.modernmetals.aluminum_pickaxe.name=Алюминиевый Кирка +item.modernmetals.aluminum_powder.name=Измельчённый Алюминиевый +item.modernmetals.aluminum_rod.name=Алюминиевый Стержень +item.modernmetals.aluminum_shears.name=Алюминиевый Ножницы +item.modernmetals.aluminum_shield.name=Алюминиевый Щит +item.modernmetals.aluminum_shovel.name=Алюминиевый Лопата +item.modernmetals.aluminum_smallblend.name=Маленькая Кучка Алюминиевый Смеси +item.modernmetals.aluminum_smallpowder.name=Маленькая Кучка Измельчённого Алюминиевый +item.modernmetals.aluminum_sword.name=Алюминиевый Меч +item.modernmetals.aluminum_trapdoor.name=Алюминиевый Люк + +material.aluminumbrass.name=Алюминиевая Латунь +item.modernmetals.aluminumbrass_arrow.name=Алюминиево-Латунный Стрела +item.modernmetals.aluminumbrass_axe.name=Алюминиево-Латунный Топор +item.modernmetals.aluminumbrass_bars.name=Алюминиево-Латунный Прутья +item.modernmetals.aluminumbrass_blend.name=Алюминиево-Латунный Смеси +item.modernmetals.aluminumbrass_block.name=Блок Алюминиево-Латунный +item.modernmetals.aluminumbrass_boots.name=Алюминиево-Латунный Ботинки +item.modernmetals.aluminumbrass_bolt.name=Алюминиево-Латунный Арбалетная Стрела +item.modernmetals.aluminumbrass_bow.name=Алюминиево-Латунный Лук +item.modernmetals.aluminumbrass_chestplate.name=Алюминиево-Латунный Нагрудник +item.modernmetals.aluminumbrass_crackhammer.name=Алюминиево-Латунный Измельчающий Молот +item.modernmetals.aluminumbrass_crossbow.name=Алюминиево-Латунный Арбалет +item.modernmetals.aluminumbrass_door.name=Алюминиево-Латунный Двери +item.modernmetals.aluminumbrass_fishing_rod.name=Алюминиево-Латунный Удочка +item.modernmetals.aluminumbrass_gear.name=Алюминиево-Латунный Шестерня +item.modernmetals.aluminumbrass_helmet.name=Алюминиево-Латунный Шлем +item.modernmetals.aluminumbrass_hoe.name=Алюминиево-Латунный Мотыга +item.modernmetals.aluminumbrass_horse_armor.name=Алюминиево-Латунный Конская Броня +item.modernmetals.aluminumbrass_ingot.name=Алюминиево-Латунный Слиток +item.modernmetals.aluminumbrass_leggings.name=Алюминиево-Латунный Поножки +item.modernmetals.aluminumbrass_nugget.name=Алюминиево-Латунный Самородок +item.modernmetals.aluminumbrass_ore.name=Алюминиево-Латунный Руда +item.modernmetals.aluminumbrass_pickaxe.name=Алюминиево-Латунный Кирка +item.modernmetals.aluminumbrass_powder.name=Измельчённый Алюминиево-Латунный +item.modernmetals.aluminumbrass_rod.name=Алюминиево-Латунный Стержень +item.modernmetals.aluminumbrass_shears.name=Алюминиево-Латунный Ножницы +item.modernmetals.aluminumbrass_shield.name=Алюминиево-Латунный Щит +item.modernmetals.aluminumbrass_shovel.name=Алюминиево-Латунный Лопата +item.modernmetals.aluminumbrass_smallblend.name=Маленькая Кучка Алюминиево-Латунный Смеси +item.modernmetals.aluminumbrass_smallpowder.name=Маленькая Кучка Измельчённого Алюминиево-Латунный +item.modernmetals.aluminumbrass_sword.name=Алюминиево-Латунный Меч +item.modernmetals.aluminumbrass_trapdoor.name=Алюминиево-Латунный Люк + +material.antimony.name=Antimony +item.modernmetals.antimony_arrow.name=Antimony Стрела +item.modernmetals.antimony_axe.name=Antimony Топор +item.modernmetals.antimony_bars.name=Antimony Прутья +item.modernmetals.antimony_block.name=Блок Antimony +item.modernmetals.antimony_boots.name=Antimony Ботинки +item.modernmetals.antimony_chestplate.name=Antimony Нагрудник +item.modernmetals.antimony_crackhammer.name=Antimony Измельчающий Молот +item.modernmetals.antimony_door.name=Antimony Двери +item.modernmetals.antimony_helmet.name=Antimony Шлем +item.modernmetals.antimony_hoe.name=Antimony Мотыга +item.modernmetals.antimony_ingot.name=Antimony Слиток +item.modernmetals.antimony_leggings.name=Antimony Поножки +item.modernmetals.antimony_nugget.name=Antimony Самородок +item.modernmetals.antimony_ore.name=Antimony Руда +item.modernmetals.antimony_pickaxe.name=Antimony Кирка +item.modernmetals.antimony_powder.name=Измельчённый Antimony +item.modernmetals.antimony_shears.name=Antimony Ножницы +item.modernmetals.antimony_shield.name=Antimony Щит +item.modernmetals.antimony_shovel.name=Antimony Лопата +item.modernmetals.antimony_smallpowder.name=Маленькая Кучка Измельчённого Antimony +item.modernmetals.antimony_sword.name=Antimony Меч +item.modernmetals.antimony_trapdoor.name=Antimony Люк + +material.beryllium.name=Beryllium +item.modernmetals.beryllium_arrow.name=Beryllium Стрела +item.modernmetals.beryllium_axe.name=Beryllium Топор +item.modernmetals.beryllium_bars.name=Beryllium Прутья +item.modernmetals.beryllium_blend.name=Beryllium Смеси +item.modernmetals.beryllium_block.name=Блок Beryllium +item.modernmetals.beryllium_boots.name=Beryllium Ботинки +item.modernmetals.beryllium_bolt.name=Beryllium Арбалетная Стрела +item.modernmetals.beryllium_bow.name=Beryllium Лук +item.modernmetals.beryllium_chestplate.name=Beryllium Нагрудник +item.modernmetals.beryllium_crackhammer.name=Beryllium Измельчающий Молот +item.modernmetals.beryllium_crossbow.name=Beryllium Арбалет +item.modernmetals.beryllium_door.name=Beryllium Двери +item.modernmetals.beryllium_fishing_rod.name=Beryllium Удочка +item.modernmetals.beryllium_gear.name=Beryllium Шестерня +item.modernmetals.beryllium_helmet.name=Beryllium Шлем +item.modernmetals.beryllium_hoe.name=Beryllium Мотыга +item.modernmetals.beryllium_horse_armor.name=Beryllium Конская Броня +item.modernmetals.beryllium_ingot.name=Beryllium Слиток +item.modernmetals.beryllium_leggings.name=Beryllium Поножки +item.modernmetals.beryllium_nugget.name=Beryllium Самородок +item.modernmetals.beryllium_ore.name=Beryllium Руда +item.modernmetals.beryllium_pickaxe.name=Beryllium Кирка +item.modernmetals.beryllium_powder.name=Измельчённый Beryllium +item.modernmetals.beryllium_rod.name=Beryllium Стержень +item.modernmetals.beryllium_shears.name=Beryllium Ножницы +item.modernmetals.beryllium_shield.name=Beryllium Щит +item.modernmetals.beryllium_shovel.name=Beryllium Лопата +item.modernmetals.beryllium_smallblend.name=Маленькая Кучка Beryllium Смеси +item.modernmetals.beryllium_smallpowder.name=Маленькая Кучка Измельчённого Beryllium +item.modernmetals.beryllium_sword.name=Beryllium Меч +item.modernmetals.beryllium_trapdoor.name=Beryllium Люк + + +material.bismuth.name=Bismuth +item.modernmetals.bismuth_arrow.name=Bismuth Стрела +item.modernmetals.bismuth_axe.name=Bismuth Топор +item.modernmetals.bismuth_bars.name=Bismuth Прутья +item.modernmetals.bismuth_block.name=Блок Bismuth +item.modernmetals.bismuth_boots.name=Bismuth Ботинки +item.modernmetals.bismuth_chestplate.name=Bismuth Нагрудник +item.modernmetals.bismuth_crackhammer.name=Bismuth Измельчающий Молот +item.modernmetals.bismuth_door.name=Bismuth Двери +item.modernmetals.bismuth_helmet.name=Bismuth Шлем +item.modernmetals.bismuth_hoe.name=Bismuth Мотыга +item.modernmetals.bismuth_ingot.name=Bismuth Слиток +item.modernmetals.bismuth_leggings.name=Bismuth Поножки +item.modernmetals.bismuth_nugget.name=Bismuth Самородок +item.modernmetals.bismuth_ore.name=Bismuth Руда +item.modernmetals.bismuth_pickaxe.name=Bismuth Кирка +item.modernmetals.bismuth_powder.name=Измельчённый Bismuth +item.modernmetals.bismuth_shears.name=Bismuth Ножницы +item.modernmetals.bismuth_shovel.name=Bismuth Лопата +item.modernmetals.bismuth_shield.name=Bismuth Щит +item.modernmetals.bismuth_smallpowder.name=Маленькая Кучка Измельчённого Bismuth +item.modernmetals.bismuth_sword.name=Bismuth Меч +item.modernmetals.bismuth_trapdoor.name=Bismuth Люк + +material.boron.name=Boron +item.modernmetals.boron_arrow.name=Boron Стрела +item.modernmetals.boron_axe.name=Boron Топор +item.modernmetals.boron_bars.name=Boron Прутья +item.modernmetals.boron_blend.name=Boron Смеси +item.modernmetals.boron_block.name=Блок Boron +item.modernmetals.boron_boots.name=Boron Ботинки +item.modernmetals.boron_bolt.name=Boron Арбалетная Стрела +item.modernmetals.boron_bow.name=Boron Лук +item.modernmetals.boron_chestplate.name=Boron Нагрудник +item.modernmetals.boron_crackhammer.name=Boron Измельчающий Молот +item.modernmetals.boron_crossbow.name=Boron Арбалет +item.modernmetals.boron_door.name=Boron Двери +item.modernmetals.boron_fishing_rod.name=Boron Удочка +item.modernmetals.boron_gear.name=Boron Шестерня +item.modernmetals.boron_helmet.name=Boron Шлем +item.modernmetals.boron_hoe.name=Boron Мотыга +item.modernmetals.boron_horse_armor.name=Boron Конская Броня +item.modernmetals.boron_ingot.name=Boron Слиток +item.modernmetals.boron_leggings.name=Boron Поножки +item.modernmetals.boron_nugget.name=Boron Самородок +item.modernmetals.boron_ore.name=Boron Руда +item.modernmetals.boron_pickaxe.name=Boron Кирка +item.modernmetals.boron_powder.name=Измельчённый Boron +item.modernmetals.boron_rod.name=Boron Стержень +item.modernmetals.boron_shears.name=Boron Ножницы +item.modernmetals.boron_shield.name=Boron Щит +item.modernmetals.boron_shovel.name=Boron Лопата +item.modernmetals.boron_smallblend.name=Маленькая Кучка Boron Смеси +item.modernmetals.boron_smallpowder.name=Маленькая Кучка Измельчённого Boron +item.modernmetals.boron_sword.name=Boron Меч +item.modernmetals.boron_trapdoor.name=Boron Люк + +material.cadmium.name=Cadmium +item.modernmetals.cadmium_arrow.name=Cadmium Стрела +item.modernmetals.cadmium_axe.name=Cadmium Топор +item.modernmetals.cadmium_bars.name=Cadmium Прутья +item.modernmetals.cadmium_blend.name=Cadmium Смеси +item.modernmetals.cadmium_block.name=Блок Cadmium +item.modernmetals.cadmium_bolt.name=Cadmium Арбалетная Стрела +item.modernmetals.cadmium_boots.name=Cadmium Ботинки +item.modernmetals.cadmium_bow.name=Cadmium Лук +item.modernmetals.cadmium_chestplate.name=Cadmium Нагрудник +item.modernmetals.cadmium_crackhammer.name=Cadmium Измельчающий Молот +item.modernmetals.cadmium_crossbow.name=Cadmium Арбалет +item.modernmetals.cadmium_door.name=Cadmium Двери +item.modernmetals.cadmium_fishing_rod.name=Cadmium Удочка +item.modernmetals.cadmium_gear.name=Cadmium Шестерня +item.modernmetals.cadmium_helmet.name=Cadmium Шлем +item.modernmetals.cadmium_hoe.name=Cadmium Мотыга +item.modernmetals.cadmium_horse_armor.name=Cadmium Конская Броня + + +item.modernmetals.cadmium_ingot.name=Cadmium Слиток +item.modernmetals.cadmium_leggings.name=Cadmium Поножки +item.modernmetals.cadmium_nugget.name=Cadmium Самородок +item.modernmetals.cadmium_ore.name=Cadmium Руда +item.modernmetals.cadmium_pickaxe.name=Cadmium Кирка +item.modernmetals.cadmium_powder.name=Измельчённый Cadmium +item.modernmetals.cadmium_rod.name=Cadmium Стержень +item.modernmetals.cadmium_shears.name=Cadmium Ножницы +item.modernmetals.cadmium_shovel.name=Cadmium Лопата +item.modernmetals.cadmium_shield.name=Cadmium Щит +item.modernmetals.cadmium_smallblend.name=Маленькая Кучка Cadmium Смеси +item.modernmetals.cadmium_smallpowder.name=Маленькая Кучка Измельчённого Cadmium +item.modernmetals.cadmium_sword.name=Cadmium Меч +item.modernmetals.cadmium_trapdoor.name=Cadmium Люк + +material.chromium.name=Chromium +item.modernmetals.chromium_arrow.name=Chromium Стрела +item.modernmetals.chromium_axe.name=Chromium Топор +item.modernmetals.chromium_bars.name=Chromium Прутья +item.modernmetals.chromium_blend.name=Chromium Смеси +item.modernmetals.chromium_block.name=Блок Chromium +item.modernmetals.chromium_bolt.name=Chromium Арбалетная Стрела +item.modernmetals.chromium_boots.name=Chromium Ботинки +item.modernmetals.chromium_bow.name=Chromium Лук +item.modernmetals.chromium_chestplate.name=Chromium Нагрудник +item.modernmetals.chromium_crackhammer.name=Chromium Измельчающий Молот +item.modernmetals.chromium_crossbow.name=Chromium Арбалет +item.modernmetals.chromium_door.name=Chromium Двери +item.modernmetals.chromium_fishing_rod.name=Chromium Удочка +item.modernmetals.chromium_gear.name=Chromium Шестерня +item.modernmetals.chromium_helmet.name=Chromium Шлем +item.modernmetals.chromium_hoe.name=Chromium Мотыга +item.modernmetals.chromium_horse_armor.name=Chromium Конская Броня +item.modernmetals.chromium_ingot.name=Chromium Слиток +item.modernmetals.chromium_leggings.name=Chromium Поножки +item.modernmetals.chromium_nugget.name=Chromium Самородок +item.modernmetals.chromium_ore.name=Chromium Руда +item.modernmetals.chromium_pickaxe.name=Chromium Кирка +item.modernmetals.chromium_powder.name=Измельчённый Chromium +item.modernmetals.chromium_rod.name=Chromium Стержень +item.modernmetals.chromium_shears.name=Chromium Ножницы +item.modernmetals.chromium_shield.name=Chromium Щит +item.modernmetals.chromium_shovel.name=Chromium Лопата +item.modernmetals.chromium_smallblend.name=Маленькая Кучка Chromium Смеси +item.modernmetals.chromium_smallpowder.name=Маленькая Кучка Измельчённого Chromium +item.modernmetals.chromium_sword.name=Chromium Меч +item.modernmetals.chromium_trapdoor.name=Chromium Люк + +material.galvanizedsteel.name=Galvanized Steel +item.modernmetals.galvanizedsteel_arrow.name=Galvanized Steel Стрела +item.modernmetals.galvanizedsteel_axe.name=Galvanized Steel Топор +item.modernmetals.galvanizedsteel_bars.name=Galvanized Steel Прутья +item.modernmetals.galvanizedsteel_blend.name=Galvanized Steel Смеси +item.modernmetals.galvanizedsteel_block.name=Блок Galvanized Steel +item.modernmetals.galvanizedsteel_bolt.name=Galvanized Steel Арбалетная Стрела +item.modernmetals.galvanizedsteel_boots.name=Galvanized Steel Ботинки +item.modernmetals.galvanizedsteel_bow.name=Galvanized Steel Лук +item.modernmetals.galvanizedsteel_chestplate.name=Galvanized Steel Нагрудник +item.modernmetals.galvanizedsteel_crackhammer.name=Galvanized Steel Измельчающий Молот +item.modernmetals.galvanizedsteel_crossbow.name=Galvanized Steel Арбалет +item.modernmetals.galvanizedsteel_door.name=Galvanized Steel Двери +item.modernmetals.galvanizedsteel_fishing_rod.name=Galvanized Steel Удочка +item.modernmetals.galvanizedsteel_gear.name=Galvanized Steel Шестерня +item.modernmetals.galvanizedsteel_helmet.name=Galvanized Steel Шлем +item.modernmetals.galvanizedsteel_hoe.name=Galvanized Steel Мотыга +item.modernmetals.galvanizedsteel_horse_armor.name=Galvanized Steel Конская Броня +item.modernmetals.galvanizedsteel_ingot.name=Galvanized Steel Слиток +item.modernmetals.galvanizedsteel_leggings.name=Galvanized Steel Поножки +item.modernmetals.galvanizedsteel_nugget.name=Galvanized Steel Самородок +item.modernmetals.galvanizedsteel_ore.name=Galvanized Steel Руда +item.modernmetals.galvanizedsteel_pickaxe.name=Galvanized Steel Кирка +item.modernmetals.galvanizedsteel_powder.name=Измельчённый Galvanized Steel +item.modernmetals.galvanizedsteel_rod.name=Galvanized Steel Стержень +item.modernmetals.galvanizedsteel_shears.name=Galvanized Steel Ножницы +item.modernmetals.galvanizedsteel_shield.name=Galvanized Steel Щит +item.modernmetals.galvanizedsteel_shovel.name=Galvanized Steel Лопата +item.modernmetals.galvanizedsteel_smallblend.name=Маленькая Кучка Galvanized Steel Смеси +item.modernmetals.galvanizedsteel_smallpowder.name=Маленькая Кучка Измельчённого Galvanized Steel +item.modernmetals.galvanizedsteel_sword.name=Galvanized Steel Меч +item.modernmetals.galvanizedsteel_trapdoor.name=Galvanized Steel Люк + +material.iridium.name=Iridium +item.modernmetals.iridium_arrow.name=Iridium Стрела +item.modernmetals.iridium_axe.name=Iridium Топор +item.modernmetals.iridium_bars.name=Iridium Прутья +item.modernmetals.iridium_blend.name=Iridium Смеси +item.modernmetals.iridium_block.name=Блок Iridium +item.modernmetals.iridium_bolt.name=Iridium Арбалетная Стрела +item.modernmetals.iridium_boots.name=Iridium Ботинки +item.modernmetals.iridium_bow.name=Iridium Лук +item.modernmetals.iridium_chestplate.name=Iridium Нагрудник +item.modernmetals.iridium_crackhammer.name=Iridium Измельчающий Молот +item.modernmetals.iridium_crossbow.name=Iridium Арбалет +item.modernmetals.iridium_door.name=Iridium Двери +item.modernmetals.iridium_fishing_rod.name=Iridium Удочка +item.modernmetals.iridium_gear.name=Iridium Шестерня +item.modernmetals.iridium_helmet.name=Iridium Шлем +item.modernmetals.iridium_hoe.name=Iridium Мотыга +item.modernmetals.iridium_horse_armor.name=Iridium Конская Броня +item.modernmetals.iridium_ingot.name=Iridium Слиток +item.modernmetals.iridium_leggings.name=Iridium Поножки +item.modernmetals.iridium_nugget.name=Iridium Самородок +item.modernmetals.iridium_ore.name=Iridium Руда +item.modernmetals.iridium_pickaxe.name=Iridium Кирка +item.modernmetals.iridium_powder.name=Измельчённый Iridium +item.modernmetals.iridium_rod.name=Iridium Стержень +item.modernmetals.iridium_shears.name=Iridium Ножницы +item.modernmetals.iridium_shield.name=Iridium Щит +item.modernmetals.iridium_shovel.name=Iridium Лопата +item.modernmetals.iridium_smallblend.name=Маленькая Кучка Iridium Смеси +item.modernmetals.iridium_smallpowder.name=Маленькая Кучка Измельчённого Iridium +item.modernmetals.iridium_sword.name=Iridium Меч +item.modernmetals.iridium_trapdoor.name=Iridium Люк + +material.magnesium.name=Magnesium +item.modernmetals.magnesium_arrow.name=Magnesium Стрела +item.modernmetals.magnesium_axe.name=Magnesium Топор +item.modernmetals.magnesium_bars.name=Magnesium Прутья +item.modernmetals.magnesium_blend.name=Magnesium Смеси +item.modernmetals.magnesium_block.name=Блок Magnesium +item.modernmetals.magnesium_boots.name=Magnesium Ботинки +item.modernmetals.magnesium_bolt.name=Magnesium Арбалетная Стрела +item.modernmetals.magnesium_bow.name=Magnesium Лук +item.modernmetals.magnesium_chestplate.name=Magnesium Нагрудник +item.modernmetals.magnesium_crackhammer.name=Magnesium Измельчающий Молот +item.modernmetals.magnesium_crossbow.name=Magnesium Арбалет +item.modernmetals.magnesium_door.name=Magnesium Двери +item.modernmetals.magnesium_fishing_rod.name=Magnesium Удочка +item.modernmetals.magnesium_gear.name=Magnesium Шестерня +item.modernmetals.magnesium_helmet.name=Magnesium Шлем +item.modernmetals.magnesium_hoe.name=Magnesium Мотыга +item.modernmetals.magnesium_horse_armor.name=Magnesium Конская Броня +item.modernmetals.magnesium_ingot.name=Magnesium Слиток +item.modernmetals.magnesium_leggings.name=Magnesium Поножки +item.modernmetals.magnesium_nugget.name=Magnesium Самородок +item.modernmetals.magnesium_ore.name=Magnesium Руда +item.modernmetals.magnesium_pickaxe.name=Magnesium Кирка +item.modernmetals.magnesium_powder.name=Измельчённый Magnesium +item.modernmetals.magnesium_rod.name=Magnesium Стержень +item.modernmetals.magnesium_shears.name=Magnesium Ножницы +item.modernmetals.magnesium_shield.name=Magnesium Щит +item.modernmetals.magnesium_shovel.name=Magnesium Лопата +item.modernmetals.magnesium_smallblend.name=Маленькая Кучка Magnesium Смеси +item.modernmetals.magnesium_smallpowder.name=Маленькая Кучка Измельчённого Magnesium +item.modernmetals.magnesium_sword.name=Magnesium Меч +item.modernmetals.magnesium_trapdoor.name=Magnesium Люк + +material.manganese.name=Manganese +item.modernmetals.manganese_arrow.name=Manganese Стрела +item.modernmetals.manganese_axe.name=Manganese Топор +item.modernmetals.manganese_bars.name=Manganese Прутья +item.modernmetals.manganese_blend.name=Manganese Смеси +item.modernmetals.manganese_block.name=Блок Manganese +item.modernmetals.manganese_bolt.name=Manganese Арбалетная Стрела +item.modernmetals.manganese_boots.name=Manganese Ботинки +item.modernmetals.manganese_bow.name=Manganese Лук +item.modernmetals.manganese_chestplate.name=Manganese Нагрудник +item.modernmetals.manganese_crackhammer.name=Manganese Измельчающий Молот +item.modernmetals.manganese_crossbow.name=Manganese Арбалет +item.modernmetals.manganese_door.name=Manganese Двери +item.modernmetals.manganese_fishing_rod.name=Manganese Удочка +item.modernmetals.manganese_gear.name=Manganese Шестерня +item.modernmetals.manganese_helmet.name=Manganese Шлем +item.modernmetals.manganese_hoe.name=Manganese Мотыга +item.modernmetals.manganese_horse_armor.name=Manganese Конская Броня +item.modernmetals.manganese_ingot.name=Manganese Слиток +item.modernmetals.manganese_leggings.name=Manganese Поножки +item.modernmetals.manganese_nugget.name=Manganese Самородок +item.modernmetals.manganese_ore.name=Manganese Руда +item.modernmetals.manganese_pickaxe.name=Manganese Кирка +item.modernmetals.manganese_powder.name=Измельчённый Manganese +item.modernmetals.manganese_rod.name=Manganese Стержень +item.modernmetals.manganese_shears.name=Manganese Ножницы +item.modernmetals.manganese_shield.name=Manganese Щит +item.modernmetals.manganese_shovel.name=Manganese Лопата +item.modernmetals.manganese_smallblend.name=Маленькая Кучка Manganese Смеси +item.modernmetals.manganese_smallpowder.name=Маленькая Кучка Измельчённого Manganese +item.modernmetals.manganese_sword.name=Manganese Меч +item.modernmetals.manganese_trapdoor.name=Manganese Люк + +material.nichrome.name=Nichrome +item.modernmetals.nichrome_arrow.name=Nichrome Стрела +item.modernmetals.nichrome_axe.name=Nichrome Топор +item.modernmetals.nichrome_bars.name=Nichrome Прутья +item.modernmetals.nichrome_blend.name=Nichrome Смеси +item.modernmetals.nichrome_block.name=Блок Nichrome +item.modernmetals.nichrome_bolt.name=Nichrome Арбалетная Стрела +item.modernmetals.nichrome_boots.name=Nichrome Ботинки +item.modernmetals.nichrome_bow.name=Nichrome Лук +item.modernmetals.nichrome_chestplate.name=Nichrome Нагрудник +item.modernmetals.nichrome_crackhammer.name=Nichrome Измельчающий Молот +item.modernmetals.nichrome_crossbow.name=Nichrome Арбалет +item.modernmetals.nichrome_door.name=Nichrome Двери +item.modernmetals.nichrome_fishing_rod.name=Nichrome Удочка +item.modernmetals.nichrome_gear.name=Nichrome Шестерня +item.modernmetals.nichrome_helmet.name=Nichrome Шлем +item.modernmetals.nichrome_hoe.name=Nichrome Мотыга +item.modernmetals.nichrome_horse_armor.name=Nichrome Конская Броня +item.modernmetals.nichrome_ingot.name=Nichrome Слиток +item.modernmetals.nichrome_leggings.name=Nichrome Поножки +item.modernmetals.nichrome_nugget.name=Nichrome Самородок +item.modernmetals.nichrome_ore.name=Nichrome Руда +item.modernmetals.nichrome_pickaxe.name=Nichrome Кирка +item.modernmetals.nichrome_powder.name=Измельчённый Nichrome +item.modernmetals.nichrome_rod.name=Nichrome Стержень +item.modernmetals.nichrome_shears.name=Nichrome Ножницы +item.modernmetals.nichrome_shield.name=Nichrome Щит +item.modernmetals.nichrome_shovel.name=Nichrome Лопата +item.modernmetals.nichrome_smallblend.name=Маленькая Кучка Nichrome Смеси +item.modernmetals.nichrome_smallpowder.name=Маленькая Кучка Измельчённого Nichrome +item.modernmetals.nichrome_sword.name=Nichrome Меч +item.modernmetals.nichrome_trapdoor.name=Nichrome Люк + +material.osmium.name=Osmium +item.modernmetals.osmium_arrow.name=Osmium Стрела +item.modernmetals.osmium_axe.name=Osmium Топор +item.modernmetals.osmium_bars.name=Osmium Прутья +item.modernmetals.osmium_blend.name=Osmium Смеси +item.modernmetals.osmium_block.name=Блок Osmium +item.modernmetals.osmium_boots.name=Osmium Ботинки +item.modernmetals.osmium_bolt.name=Osmium Арбалетная Стрела +item.modernmetals.osmium_bow.name=Osmium Лук +item.modernmetals.osmium_chestplate.name=Osmium Нагрудник +item.modernmetals.osmium_crackhammer.name=Osmium Измельчающий Молот +item.modernmetals.osmium_crossbow.name=Osmium Арбалет +item.modernmetals.osmium_door.name=Osmium Двери +item.modernmetals.osmium_fishing_rod.name=Osmium Удочка +item.modernmetals.osmium_gear.name=Osmium Шестерня +item.modernmetals.osmium_helmet.name=Osmium Шлем +item.modernmetals.osmium_hoe.name=Osmium Мотыга +item.modernmetals.osmium_horse_armor.name=Osmium Конская Броня +item.modernmetals.osmium_ingot.name=Osmium Слиток +item.modernmetals.osmium_leggings.name=Osmium Поножки +item.modernmetals.osmium_nugget.name=Osmium Самородок +item.modernmetals.osmium_ore.name=Osmium Руда +item.modernmetals.osmium_pickaxe.name=Osmium Кирка +item.modernmetals.osmium_powder.name=Измельчённый Osmium +item.modernmetals.osmium_rod.name=Osmium Стержень +item.modernmetals.osmium_shears.name=Osmium Ножницы +item.modernmetals.osmium_shield.name=Osmium Щит +item.modernmetals.osmium_shovel.name=Osmium Лопата +item.modernmetals.osmium_smallblend.name=Маленькая Кучка Osmium Смеси +item.modernmetals.osmium_smallpowder.name=Маленькая Кучка Измельчённого Osmium +item.modernmetals.osmium_sword.name=Osmium Меч +item.modernmetals.osmium_trapdoor.name=Osmium Люк + +material.pewter.name=Pewter +item.modernmetals.pewter_arrow.name=Pewter Стрела +item.modernmetals.pewter_axe.name=Pewter Топор +item.modernmetals.pewter_bars.name=Pewter Прутья +item.modernmetals.pewter_blend.name=Pewter Смеси +item.modernmetals.pewter_block.name=Блок Pewter +item.modernmetals.pewter_boots.name=Pewter Ботинки +item.modernmetals.pewter_chestplate.name=Pewter Нагрудник +item.modernmetals.pewter_crackhammer.name=Pewter Измельчающий Молот +item.modernmetals.pewter_door.name=Pewter Двери +item.modernmetals.pewter_helmet.name=Pewter Шлем +item.modernmetals.pewter_hoe.name=Pewter Мотыга +item.modernmetals.pewter_ingot.name=Pewter Слиток +item.modernmetals.pewter_leggings.name=Pewter Поножки +item.modernmetals.pewter_nugget.name=Pewter Самородок +item.modernmetals.pewter_ore.name=Pewter Руда +item.modernmetals.pewter_pickaxe.name=Pewter Кирка +item.modernmetals.pewter_powder.name=Измельчённый Pewter +item.modernmetals.pewter_shears.name=Pewter Ножницы +item.modernmetals.pewter_shield.name=Pewter Щит +item.modernmetals.pewter_shovel.name=Pewter Лопата +item.modernmetals.pewter_smallpowder.name=Маленькая Кучка Измельчённого Pewter +item.modernmetals.pewter_sword.name=Pewter Меч +item.modernmetals.pewter_trapdoor.name=Pewter Люк + +material.plutonium.name=Plutonium +item.modernmetals.plutonium_arrow.name=Plutonium Стрела +item.modernmetals.plutonium_axe.name=Plutonium Топор +item.modernmetals.plutonium_bars.name=Plutonium Прутья +item.modernmetals.plutonium_blend.name=Plutonium Смеси +item.modernmetals.plutonium_block.name=Блок Plutonium +item.modernmetals.plutonium_bolt.name=Plutonium Арбалетная Стрела +item.modernmetals.plutonium_boots.name=Plutonium Ботинки +item.modernmetals.plutonium_bow.name=Plutonium Лук +item.modernmetals.plutonium_chestplate.name=Plutonium Нагрудник +item.modernmetals.plutonium_crackhammer.name=Plutonium Измельчающий Молот +item.modernmetals.plutonium_crossbow.name=Plutonium Арбалет +item.modernmetals.plutonium_door.name=Plutonium Двери +item.modernmetals.plutonium_fishing_rod.name=Plutonium Удочка +item.modernmetals.plutonium_gear.name=Plutonium Шестерня +item.modernmetals.plutonium_helmet.name=Plutonium Шлем +item.modernmetals.plutonium_hoe.name=Plutonium Мотыга +item.modernmetals.plutonium_horse_armor.name=Plutonium Конская Броня +item.modernmetals.plutonium_ingot.name=Plutonium Слиток +item.modernmetals.plutonium_leggings.name=Plutonium Поножки +item.modernmetals.plutonium_nugget.name=Plutonium Самородок +item.modernmetals.plutonium_ore.name=Plutonium Руда +item.modernmetals.plutonium_pickaxe.name=Plutonium Кирка +item.modernmetals.plutonium_powder.name=Измельчённый Plutonium +item.modernmetals.plutonium_rod.name=Plutonium Стержень +item.modernmetals.plutonium_shears.name=Plutonium Ножницы +item.modernmetals.plutonium_shield.name=Plutonium Щит +item.modernmetals.plutonium_shovel.name=Plutonium Лопата +item.modernmetals.plutonium_smallblend.name=Маленькая Кучка Plutonium Смеси +item.modernmetals.plutonium_smallpowder.name=Маленькая Кучка Измельчённого Plutonium +item.modernmetals.plutonium_sword.name=Plutonium Меч +item.modernmetals.plutonium_trapdoor.name=Plutonium Люк + +material.rutile.name=Rutile +item.modernmetals.rutile_arrow.name=Rutile Стрела +item.modernmetals.rutile_axe.name=Rutile Топор +item.modernmetals.rutile_bars.name=Rutile Прутья +item.modernmetals.rutile_blend.name=Rutile Смеси +item.modernmetals.rutile_block.name=Блок Rutile +item.modernmetals.rutile_boots.name=Rutile Ботинки +item.modernmetals.rutile_bolt.name=Rutile Арбалетная Стрела +item.modernmetals.rutile_bow.name=Rutile Лук +item.modernmetals.rutile_chestplate.name=Rutile Нагрудник +item.modernmetals.rutile_crackhammer.name=Rutile Измельчающий Молот +item.modernmetals.rutile_crossbow.name=Rutile Арбалет +item.modernmetals.rutile_door.name=Rutile Двери +item.modernmetals.rutile_fishing_rod.name=Rutile Удочка +item.modernmetals.rutile_gear.name=Rutile Шестерня +item.modernmetals.rutile_helmet.name=Rutile Шлем +item.modernmetals.rutile_hoe.name=Rutile Мотыга +item.modernmetals.rutile_horse_armor.name=Rutile Конская Броня +item.modernmetals.rutile_ingot.name=Rutile Слиток +item.modernmetals.rutile_leggings.name=Rutile Поножки +item.modernmetals.rutile_nugget.name=Rutile Самородок +item.modernmetals.rutile_ore.name=Rutile Руда +item.modernmetals.rutile_pickaxe.name=Rutile Кирка +item.modernmetals.rutile_powder.name=Измельчённый Rutile +item.modernmetals.rutile_rod.name=Rutile Стержень +item.modernmetals.rutile_shears.name=Rutile Ножницы +item.modernmetals.rutile_shield.name=Rutile Щит +item.modernmetals.rutile_shovel.name=Rutile Лопата +item.modernmetals.rutile_smallblend.name=Маленькая Кучка Rutile Смеси +item.modernmetals.rutile_smallpowder.name=Маленькая Кучка Измельчённого Rutile +item.modernmetals.rutile_sword.name=Rutile Меч +item.modernmetals.rutile_trapdoor.name=Rutile Люк + +material.stainlesssteel.name=Stainless Steel +item.modernmetals.stainlesssteel_arrow.name=Stainless Steel Стрела +item.modernmetals.stainlesssteel_axe.name=Stainless Steel Топор +item.modernmetals.stainlesssteel_bars.name=Stainless Steel Прутья +item.modernmetals.stainlesssteel_blend.name=Stainless Steel Смеси +item.modernmetals.stainlesssteel_block.name=Блок Stainless Steel +item.modernmetals.stainlesssteel_bolt.name=Stainless Steel Арбалетная Стрела +item.modernmetals.stainlesssteel_boots.name=Stainless Steel Ботинки +item.modernmetals.stainlesssteel_bow.name=Stainless Steel Лук +item.modernmetals.stainlesssteel_chestplate.name=Stainless Steel Нагрудник +item.modernmetals.stainlesssteel_crackhammer.name=Stainless Steel Измельчающий Молот +item.modernmetals.stainlesssteel_crossbow.name=Stainless Steel Арбалет +item.modernmetals.stainlesssteel_door.name=Stainless Steel Двери +item.modernmetals.stainlesssteel_fishing_rod.name=Stainless Steel Удочка +item.modernmetals.stainlesssteel_gear.name=Stainless Steel Шестерня +item.modernmetals.stainlesssteel_helmet.name=Stainless Steel Шлем +item.modernmetals.stainlesssteel_hoe.name=Stainless Steel Мотыга +item.modernmetals.stainlesssteel_horse_armor.name=Stainless Steel Конская Броня +item.modernmetals.stainlesssteel_ingot.name=Stainless Steel Слиток +item.modernmetals.stainlesssteel_leggings.name=Stainless Steel Поножки +item.modernmetals.stainlesssteel_nugget.name=Stainless Steel Самородок +item.modernmetals.stainlesssteel_ore.name=Stainless Steel Руда +item.modernmetals.stainlesssteel_pickaxe.name=Stainless Steel Кирка +item.modernmetals.stainlesssteel_powder.name=Измельчённый Stainless Steel +item.modernmetals.stainlesssteel_rod.name=Stainless Steel Стержень +item.modernmetals.stainlesssteel_shears.name=Stainless Steel Ножницы +item.modernmetals.stainlesssteel_shield.name=Stainless Steel Щит +item.modernmetals.stainlesssteel_shovel.name=Stainless Steel Лопата +item.modernmetals.stainlesssteel_smallblend.name=Маленькая Кучка Stainless Steel Смеси +item.modernmetals.stainlesssteel_smallpowder.name=Маленькая Кучка Измельчённого Stainless Steel +item.modernmetals.stainlesssteel_sword.name=Stainless Steel Меч +item.modernmetals.stainlesssteel_trapdoor.name=Stainless Steel Люк + +material.tantalum.name=Tantalum +item.modernmetals.tantalum_arrow.name=Tantalum Стрела +item.modernmetals.tantalum_axe.name=Tantalum Топор +item.modernmetals.tantalum_bars.name=Tantalum Прутья +item.modernmetals.tantalum_blend.name=Tantalum Смеси +item.modernmetals.tantalum_block.name=Блок Tantalum +item.modernmetals.tantalum_bolt.name=Tantalum Арбалетная Стрела +item.modernmetals.tantalum_boots.name=Tantalum Ботинки +item.modernmetals.tantalum_bow.name=Tantalum Лук +item.modernmetals.tantalum_chestplate.name=Tantalum Нагрудник +item.modernmetals.tantalum_crackhammer.name=Tantalum Измельчающий Молот +item.modernmetals.tantalum_crossbow.name=Tantalum Арбалет +item.modernmetals.tantalum_door.name=Tantalum Двери +item.modernmetals.tantalum_fishing_rod.name=Tantalum Удочка +item.modernmetals.tantalum_gear.name=Tantalum Шестерня +item.modernmetals.tantalum_helmet.name=Tantalum Шлем +item.modernmetals.tantalum_hoe.name=Tantalum Мотыга +item.modernmetals.tantalum_horse_armor.name=Tantalum Конская Броня +item.modernmetals.tantalum_ingot.name=Tantalum Слиток +item.modernmetals.tantalum_leggings.name=Tantalum Поножки +item.modernmetals.tantalum_nugget.name=Tantalum Самородок +item.modernmetals.tantalum_ore.name=Tantalum Руда +item.modernmetals.tantalum_pickaxe.name=Tantalum Кирка +item.modernmetals.tantalum_powder.name=Измельчённый Tantalum +item.modernmetals.tantalum_rod.name=Tantalum Стержень +item.modernmetals.tantalum_shears.name=Tantalum Ножницы +item.modernmetals.tantalum_shield.name=Tantalum Щит +item.modernmetals.tantalum_shovel.name=Tantalum Лопата +item.modernmetals.tantalum_smallblend.name=Маленькая Кучка Tantalum Смеси +item.modernmetals.tantalum_smallpowder.name=Маленькая Кучка Измельчённого Tantalum +item.modernmetals.tantalum_sword.name=Tantalum Меч +item.modernmetals.tantalum_trapdoor.name=Tantalum Люк + +material.titanium.name=Titanium +item.modernmetals.titanium_arrow.name=Titanium Стрела +item.modernmetals.titanium_axe.name=Titanium Топор +item.modernmetals.titanium_bars.name=Titanium Прутья +item.modernmetals.titanium_blend.name=Titanium Смеси +item.modernmetals.titanium_block.name=Блок Titanium +item.modernmetals.titanium_boots.name=Titanium Ботинки +item.modernmetals.titanium_bolt.name=Titanium Арбалетная Стрела +item.modernmetals.titanium_bow.name=Titanium Лук +item.modernmetals.titanium_chestplate.name=Titanium Нагрудник +item.modernmetals.titanium_crackhammer.name=Titanium Измельчающий Молот +item.modernmetals.titanium_crossbow.name=Titanium Арбалет +item.modernmetals.titanium_door.name=Titanium Двери +item.modernmetals.titanium_fishing_rod.name=Titanium Удочка +item.modernmetals.titanium_gear.name=Titanium Шестерня +item.modernmetals.titanium_helmet.name=Titanium Шлем +item.modernmetals.titanium_hoe.name=Titanium Мотыга +item.modernmetals.titanium_horse_armor.name=Titanium Конская Броня +item.modernmetals.titanium_ingot.name=Titanium Слиток +item.modernmetals.titanium_leggings.name=Titanium Поножки +item.modernmetals.titanium_nugget.name=Titanium Самородок +item.modernmetals.titanium_ore.name=Titanium Руда +item.modernmetals.titanium_pickaxe.name=Titanium Кирка +item.modernmetals.titanium_powder.name=Измельчённый Titanium +item.modernmetals.titanium_rod.name=Titanium Стержень +item.modernmetals.titanium_shears.name=Titanium Ножницы +item.modernmetals.titanium_shield.name=Titanium Щит +item.modernmetals.titanium_shovel.name=Titanium Лопата +item.modernmetals.titanium_smallblend.name=Маленькая Кучка Titanium Смеси +item.modernmetals.titanium_smallpowder.name=Маленькая Кучка Измельчённого Titanium +item.modernmetals.titanium_sword.name=Titanium Меч +item.modernmetals.titanium_trapdoor.name=Titanium Люк + +material.tungsten.name=Tungsten +item.modernmetals.tungsten_arrow.name=Tungsten Стрела +item.modernmetals.tungsten_axe.name=Tungsten Топор +item.modernmetals.tungsten_bars.name=Tungsten Прутья +item.modernmetals.tungsten_blend.name=Tungsten Смеси +item.modernmetals.tungsten_block.name=Блок Tungsten +item.modernmetals.tungsten_boots.name=Tungsten Ботинки +item.modernmetals.tungsten_bolt.name=Tungsten Арбалетная Стрела +item.modernmetals.tungsten_bow.name=Tungsten Лук +item.modernmetals.tungsten_chestplate.name=Tungsten Нагрудник +item.modernmetals.tungsten_crackhammer.name=Tungsten Измельчающий Молот +item.modernmetals.tungsten_crossbow.name=Tungsten Арбалет +item.modernmetals.tungsten_door.name=Tungsten Двери +item.modernmetals.tungsten_fishing_rod.name=Tungsten Удочка +item.modernmetals.tungsten_gear.name=Tungsten Шестерня +item.modernmetals.tungsten_helmet.name=Tungsten Шлем +item.modernmetals.tungsten_hoe.name=Tungsten Мотыга +item.modernmetals.tungsten_horse_armor.name=Tungsten Конская Броня +item.modernmetals.tungsten_ingot.name=Tungsten Слиток +item.modernmetals.tungsten_leggings.name=Tungsten Поножки +item.modernmetals.tungsten_nugget.name=Tungsten Самородок +item.modernmetals.tungsten_ore.name=Tungsten Руда +item.modernmetals.tungsten_pickaxe.name=Tungsten Кирка +item.modernmetals.tungsten_powder.name=Измельчённый Tungsten +item.modernmetals.tungsten_rod.name=Tungsten Стержень +item.modernmetals.tungsten_shears.name=Tungsten Ножницы +item.modernmetals.tungsten_shield.name=Tungsten Щит +item.modernmetals.tungsten_shovel.name=Tungsten Лопата +item.modernmetals.tungsten_smallblend.name=Маленькая Кучка Tungsten Смеси +item.modernmetals.tungsten_smallpowder.name=Маленькая Кучка Измельчённого Tungsten +item.modernmetals.tungsten_sword.name=Tungsten Меч +item.modernmetals.tungsten_trapdoor.name=Tungsten Люк + +material.uranium.name=Uranium +item.modernmetals.uranium_arrow.name=Uranium Стрела +item.modernmetals.uranium_axe.name=Uranium Топор +item.modernmetals.uranium_bars.name=Uranium Прутья +item.modernmetals.uranium_blend.name=Uranium Смеси +item.modernmetals.uranium_block.name=Блок Uranium +item.modernmetals.uranium_boots.name=Uranium Ботинки +item.modernmetals.uranium_bolt.name=Uranium Арбалетная Стрела +item.modernmetals.uranium_bow.name=Uranium Лук +item.modernmetals.uranium_chestplate.name=Uranium Нагрудник +item.modernmetals.uranium_crackhammer.name=Uranium Измельчающий Молот +item.modernmetals.uranium_crossbow.name=Uranium Арбалет +item.modernmetals.uranium_door.name=Uranium Двери +item.modernmetals.uranium_fishing_rod.name=Uranium Удочка +item.modernmetals.uranium_gear.name=Uranium Шестерня +item.modernmetals.uranium_helmet.name=Uranium Шлем +item.modernmetals.uranium_hoe.name=Uranium Мотыга +item.modernmetals.uranium_horse_armor.name=Uranium Конская Броня +item.modernmetals.uranium_ingot.name=Uranium Слиток +item.modernmetals.uranium_leggings.name=Uranium Поножки +item.modernmetals.uranium_nugget.name=Uranium Самородок +item.modernmetals.uranium_ore.name=Uranium Руда +item.modernmetals.uranium_pickaxe.name=Uranium Кирка +item.modernmetals.uranium_powder.name=Измельчённый Uranium +item.modernmetals.uranium_rod.name=Uranium Стержень +item.modernmetals.uranium_shears.name=Uranium Ножницы +item.modernmetals.uranium_shield.name=Uranium Щит +item.modernmetals.uranium_shovel.name=Uranium Лопата +item.modernmetals.uranium_smallblend.name=Маленькая Кучка Uranium Смеси +item.modernmetals.uranium_smallpowder.name=Маленькая Кучка Измельчённого Uranium +item.modernmetals.uranium_sword.name=Uranium Меч +item.modernmetals.uranium_trapdoor.name=Uranium Люк + +material.zirconium.name=Zirconium +item.modernmetals.zirconium_arrow.name=Zirconium Стрела +item.modernmetals.zirconium_axe.name=Zirconium Топор +item.modernmetals.zirconium_bars.name=Zirconium Прутья +item.modernmetals.zirconium_blend.name=Zirconium Смеси +item.modernmetals.zirconium_block.name=Блок Zirconium +item.modernmetals.zirconium_bolt.name=Zirconium Арбалетная Стрела +item.modernmetals.zirconium_boots.name=Zirconium Ботинки +item.modernmetals.zirconium_bow.name=Zirconium Лук +item.modernmetals.zirconium_chestplate.name=Zirconium Нагрудник +item.modernmetals.zirconium_crackhammer.name=Zirconium Измельчающий Молот +item.modernmetals.zirconium_crossbow.name=Zirconium Арбалет +item.modernmetals.zirconium_door.name=Zirconium Двери +item.modernmetals.zirconium_fishing_rod.name=Zirconium Удочка +item.modernmetals.zirconium_gear.name=Zirconium Шестерня +item.modernmetals.zirconium_helmet.name=Zirconium Шлем +item.modernmetals.zirconium_hoe.name=Zirconium Мотыга +item.modernmetals.zirconium_horse_armor.name=Zirconium Конская Броня +item.modernmetals.zirconium_ingot.name=Zirconium Слиток +item.modernmetals.zirconium_leggings.name=Zirconium Поножки +item.modernmetals.zirconium_nugget.name=Zirconium Самородок +item.modernmetals.zirconium_ore.name=Zirconium Руда +item.modernmetals.zirconium_pickaxe.name=Zirconium Кирка +item.modernmetals.zirconium_powder.name=Измельчённый Zirconium +item.modernmetals.zirconium_rod.name=Zirconium Стержень +item.modernmetals.zirconium_shears.name=Zirconium Ножницы +item.modernmetals.zirconium_shield.name=Zirconium Щит +item.modernmetals.zirconium_shovel.name=Zirconium Лопата +item.modernmetals.zirconium_smallblend.name=Маленькая Кучка Zirconium Смеси +item.modernmetals.zirconium_smallpowder.name=Маленькая Кучка Измельчённого Zirconium +item.modernmetals.zirconium_sword.name=Zirconium Меч +item.modernmetals.zirconium_trapdoor.name=Zirconium Люк + +tile.modernmetals.aluminum_bars.name=Алюминиевый Прутья +tile.modernmetals.aluminum_block.name=Блок Алюминиевый +tile.modernmetals.aluminum_door.name=Алюминиевый Двери +tile.modernmetals.aluminum_ore.name=Алюминиевый Руда +tile.modernmetals.aluminum_plate.name=Алюминиевый Plate +tile.modernmetals.aluminum_trapdoor.name=Алюминиевый Люк + +tile.modernmetals.aluminumbrass_bars.name=Алюминиево-Латунный Прутья +tile.modernmetals.aluminumbrass_block.name=Блок Алюминиево-Латунный +tile.modernmetals.aluminumbrass_door.name=Алюминиево-Латунный Двери +tile.modernmetals.aluminumbrass_ore.name=Алюминиево-Латунный Руда +tile.modernmetals.aluminumbrass_plate.name=Алюминиево-Латунный Plate +tile.modernmetals.aluminumbrass_trapdoor.name=Алюминиево-Латунный Люк + +tile.modernmetals.boron_bars.name=Boron Прутья +tile.modernmetals.boron_block.name=Блок Boron +tile.modernmetals.boron_door.name=Boron Двери +tile.modernmetals.boron_ore.name=Boron Руда +tile.modernmetals.boron_plate.name=Boron Plate +tile.modernmetals.boron_trapdoor.name=Boron Люк + +tile.modernmetals.cadmium_bars.name=Cadmium Прутья +tile.modernmetals.cadmium_block.name=Блок Cadmium +tile.modernmetals.cadmium_door.name=Cadmium Двери +tile.modernmetals.cadmium_ore.name=Cadmium Руда +tile.modernmetals.cadmium_plate.name=Cadmium Plate +tile.modernmetals.cadmium_trapdoor.name=Cadmium Люк + +tile.modernmetals.chromium_bars.name=Chromium Прутья +tile.modernmetals.chromium_block.name=Блок Chromium +tile.modernmetals.chromium_door.name=Chromium Двери +tile.modernmetals.chromium_ore.name=Chromium Руда +tile.modernmetals.chromium_plate.name=Chromium Plate +tile.modernmetals.chromium_trapdoor.name=Chromium Люк + +tile.modernmetals.galvanizedsteel_bars.name=Galvanized Steel Прутья +tile.modernmetals.galvanizedsteel_block.name=Блок Galvanized Steel +tile.modernmetals.galvanizedsteel_door.name=Galvanized Steel Двери +tile.modernmetals.galvanizedsteel_ore.name=Galvanized Steel Руда +tile.modernmetals.galvanizedsteel_plate.name=Galvanized Steel Plate +tile.modernmetals.galvanizedsteel_trapdoor.name=Galvanized Steel Люк + +tile.modernmetals.iridium_bars.name=Iridium Прутья +tile.modernmetals.iridium_block.name=Блок Iridium +tile.modernmetals.iridium_door.name=Iridium Двери +tile.modernmetals.iridium_ore.name=Iridium Руда +tile.modernmetals.iridium_plate.name=Iridium Plate +tile.modernmetals.iridium_trapdoor.name=Iridium Люк + +tile.modernmetals.magnesium_bars.name=Magnesium Прутья +tile.modernmetals.magnesium_block.name=Блок Magnesium +tile.modernmetals.magnesium_door.name=Magnesium Двери +tile.modernmetals.magnesium_ore.name=Magnesium Руда +tile.modernmetals.magnesium_plate.name=Magnesium Plate +tile.modernmetals.magnesium_trapdoor.name=Magnesium Люк + +tile.modernmetals.manganese_bars.name=Manganese Прутья +tile.modernmetals.manganese_block.name=Блок Manganese +tile.modernmetals.manganese_door.name=Manganese Двери +tile.modernmetals.manganese_ore.name=Manganese Руда +tile.modernmetals.manganese_plate.name=Manganese Plate +tile.modernmetals.manganese_trapdoor.name=Manganese Люк + +tile.modernmetals.nichrome_bars.name=Nichrome Прутья +tile.modernmetals.nichrome_block.name=Блок Nichrome +tile.modernmetals.nichrome_door.name=Nichrome Двери +tile.modernmetals.nichrome_ore.name=Nichrome Руда +tile.modernmetals.nichrome_plate.name=Nichrome Plate +tile.modernmetals.nichrome_trapdoor.name=Nichrome Люк + +tile.modernmetals.osmium_bars.name=Osmium Прутья +tile.modernmetals.osmium_block.name=Блок Osmium +tile.modernmetals.osmium_door.name=Osmium Двери +tile.modernmetals.osmium_ore.name=Osmium Руда +tile.modernmetals.osmium_plate.name=Osmium Plate +tile.modernmetals.osmium_trapdoor.name=Osmium Люк + +tile.modernmetals.plutonium_bars.name=Plutonium Прутья +tile.modernmetals.plutonium_block.name=Блок Plutonium +tile.modernmetals.plutonium_door.name=Plutonium Двери +tile.modernmetals.plutonium_ore.name=Plutonium Руда +tile.modernmetals.plutonium_plate.name=Plutonium Plate +tile.modernmetals.plutonium_trapdoor.name=Plutonium Люк + +tile.modernmetals.rutile_bars.name=Rutile Прутья +tile.modernmetals.rutile_block.name=Блок Rutile +tile.modernmetals.rutile_door.name=Rutile Двери +tile.modernmetals.rutile_ore.name=Rutile Руда +tile.modernmetals.rutile_plate.name=Rutile Plate +tile.modernmetals.rutile_trapdoor.name=Rutile Люк + +tile.modernmetals.stainlesssteel_bars.name=Stainless Steel Прутья +tile.modernmetals.stainlesssteel_block.name=Блок Stainless Steel +tile.modernmetals.stainlesssteel_door.name=Stainless Steel Двери +tile.modernmetals.stainlesssteel_ore.name=Stainless Steel Руда +tile.modernmetals.stainlesssteel_plate.name=Stainless Steel Plate +tile.modernmetals.stainlesssteel_trapdoor.name=Stainless Steel Люк + +tile.modernmetals.tantalum_bars.name=Tantalum Прутья +tile.modernmetals.tantalum_block.name=Блок Tantalum +tile.modernmetals.tantalum_door.name=Tantalum Двери +tile.modernmetals.tantalum_ore.name=Tantalum Руда +tile.modernmetals.tantalum_plate.name=Tantalum Plate +tile.modernmetals.tantalum_trapdoor.name=Tantalum Люк + +tile.modernmetals.titanium_bars.name=Titanium Прутья +tile.modernmetals.titanium_block.name=Блок Titanium +tile.modernmetals.titanium_door.name=Titanium Двери +tile.modernmetals.titanium_ore.name=Titanium Руда +tile.modernmetals.titanium_plate.name=Titanium Plate +tile.modernmetals.titanium_trapdoor.name=Titanium Люк + +tile.modernmetals.tungsten_bars.name=Tungsten Прутья +tile.modernmetals.tungsten_block.name=Блок Tungsten +tile.modernmetals.tungsten_door.name=Tungsten Двери +tile.modernmetals.tungsten_ore.name=Tungsten Руда +tile.modernmetals.tungsten_plate.name=Tungsten Plate +tile.modernmetals.tungsten_trapdoor.name=Tungsten Люк + +tile.modernmetals.uranium_bars.name=Uranium Прутья +tile.modernmetals.uranium_block.name=Блок Uranium +tile.modernmetals.uranium_door.name=Uranium Двери +tile.modernmetals.uranium_ore.name=Uranium Руда +tile.modernmetals.uranium_plate.name=Uranium Plate +tile.modernmetals.uranium_trapdoor.name=Uranium Люк + +tile.modernmetals.zirconium_bars.name=Zirconium Прутья +tile.modernmetals.zirconium_block.name=Блок Zirconium +tile.modernmetals.zirconium_door.name=Zirconium Двери +tile.modernmetals.zirconium_ore.name=Zirconium Руда +tile.modernmetals.zirconium_plate.name=Zirconium Plate +tile.modernmetals.zirconium_trapdoor.name=Zirconium Люк + +tooltip.aluminum.tool=Nothing Special +tooltip.aluminumbrass.tool=Nothing Special +tooltip.cadmium.tool=Nothing Special +tooltip.chromium.tool=Nothing Special +tooltip.galvanized_steel.tool=Nothing Special +tooltip.iridium.tool=Nothing Special +tooltip.magnesium.tool=Nothing Special +tooltip.manganese.tool=Nothing Special +tooltip.nichrome.tool=Nothing Special +tooltip.osmium.tool=Nothing Special +tooltip.plutonium.tool=Nothing Special +tooltip.rutile.tool=Nothing Special +tooltip.stainless_steel.tool=Nothing Special +tooltip.tantalum.tool=Nothing Special +tooltip.titanium.tool=Nothing Special +tooltip.tungsten.tool=Nothing Special +tooltip.uranium.tool=Nothing Special +tooltip.zirconium.tool=Nothing Special + +tooltip.aluminum.armor=Nothing Special +tooltip.aluminumbrass.armor=Nothing Special +tooltip.cadmium.armor=Nothing Special +tooltip.chromium.armor=Nothing Special +tooltip.galvanized_steel.armor=Nothing Special +tooltip.iridium.armor=Nothing Special +tooltip.magnesium.armor=Nothing Special +tooltip.manganese.armor=Nothing Special +tooltip.nichrome.armor=Nothing Special +tooltip.osmium.armor=Nothing Special +tooltip.plutonium.armor=Nothing Special +tooltip.rutile.armor=Nothing Special +tooltip.stainless_steel.armor=Nothing Special +tooltip.tantalum.armor=Nothing Special +tooltip.titanium.armor=Nothing Special +tooltip.tungsten.armor=Nothing Special +tooltip.uranium.armor=Nothing Special +tooltip.zirconium.armor=Nothing Special + +achievement.aluminumbrass_maker=Алюминиево-Латунный +achievement.galvanized_steel_maker=Galvanized Steel +achievement.nichrome_maker=Nichrome +achievement.stainless_steel_maker=Stainless Steel +achievement.titanium_maker=Titanium +achievement.aluminumbrass_maker.desc=Combine powdered Алюминиевый and Brass to make Алюминиево-Латунный +achievement.galvanized_steel_maker.desc=Combine powdered Steel and Zinc to make Galvanized Steel +achievement.nichrome_maker.desc=Combine powdered Nickel and Chrome to make Nichrome +achievement.stainless_steel_maker.desc=Combine powdered Steel and Chrome to make Stainless Steel +achievement.titanium_maker.desc=Combine powdered Rutile and Magnesium to make Titanium + +fluid.modernmetals.aluminum=Molten Алюминиевый +fluid.modernmetals.aluminumbrass=Molten Алюминиево-Латунный +fluid.modernmetals.boron=Molten Boron +fluid.modernmetals.beryllium=Molten Beryllium +fluid.modernmetals.cadmium=Molten Cadmium +fluid.modernmetals.chromium=Molten Chromium +fluid.modernmetals.galvanizedsteel=Molten Galvanized Steel +fluid.modernmetals.iridium=Molten Iridium +fluid.modernmetals.magnesium=Molten Magnesium +fluid.modernmetals.manganese=Molten Manganese +fluid.modernmetals.nichrome=Molten Nichrome +fluid.modernmetals.osmium=Molten Osmium +fluid.modernmetals.plutonium=Molten Plutonium +fluid.modernmetals.rutile=Molten Rutile +fluid.modernmetals.stainlesssteel=Molten Stainless Steel +fluid.modernmetals.tantalum=Molten Tantalum +fluid.modernmetals.titanium=Molten Titanium +fluid.modernmetals.tungsten=Molten Tungsten +fluid.modernmetals.uranium=Molten Uranium +fluid.modernmetals.zirconium=Molten Zirconium + +fluid.modernmetals.aluminum.name=Molten Алюминиевый +fluid.modernmetals.aluminumbrass.name=Molten Алюминиево-Латунный +fluid.modernmetals.boron.name=Molten Boron +fluid.modernmetals.beryllium.name=Molten Beryllium +fluid.modernmetals.cadmium.name=Molten Cadmium +fluid.modernmetals.chromium.name=Molten Chromium +fluid.modernmetals.galvanizedsteel.name=Molten Galvanized Steel +fluid.modernmetals.iridium.name=Molten Iridium +fluid.modernmetals.magnesium.name=Molten Magnesium +fluid.modernmetals.manganese.name=Molten Manganese +fluid.modernmetals.nichrome.name=Molten Nichrome +fluid.modernmetals.osmium.name=Molten Osmium +fluid.modernmetals.plutonium.name=Molten Plutonium +fluid.modernmetals.rutile.name=Molten Rutile +fluid.modernmetals.stainlesssteel.name=Molten Stainless Steel +fluid.modernmetals.tantalum.name=Molten Tantalum +fluid.modernmetals.titanium.name=Molten Titanium +fluid.modernmetals.tungsten.name=Molten Tungsten +fluid.modernmetals.uranium.name=Molten Uranium +fluid.modernmetals.zirconium.name=Molten Zirconium + +tile.modernmetals.aluminum.name=Molten Алюминиевый +tile.modernmetals.aluminumbrass.name=Molten Алюминиево-Латунный +tile.modernmetals.boron.name=Molten Boron +tile.modernmetals.cadmium.name=Molten Cadmium +tile.modernmetals.chromium.name=Molten Chromium +tile.modernmetals.galvanizedsteel.name=Molten Galvanized Steel +tile.modernmetals.iridium.name=Molten Iridium +tile.modernmetals.magnesium.name=Molten Magnesium +tile.modernmetals.manganese.name=Molten Manganese +tile.modernmetals.nichrome.name=Molten Nichrome +tile.modernmetals.osmium.name=Molten Osmium +tile.modernmetals.plutonium.name=Molten Plutonium +tile.modernmetals.rutile.name=Molten Rutile +tile.modernmetals.stainlesssteel.name=Molten Stainless Steel +tile.modernmetals.tantalum.name=Molten Tantalum +tile.modernmetals.titanium.name=Molten Titanium +tile.modernmetals.tungsten.name=Molten Tungsten +tile.modernmetals.uranium.name=Molten Uranium +tile.modernmetals.zirconium.name=Molten Zirconium + +item.modernmetals.aluminum_clump.name=Алюминиевый Clump +item.modernmetals.aluminum_crushed.name=Crushed Алюминиевый Руда +item.modernmetals.aluminum_crushed_purified.name=Purified Crushed Алюминиевый Руда +item.modernmetals.aluminum_crystal.name=Алюминиевый Crystal +item.modernmetals.aluminum_dense_plate.name=Dense Алюминиевый Plate +item.modernmetals.aluminum_powder_dirty.name=Dirty Алюминиевый Dust +item.modernmetals.aluminum_shard.name=Алюминиевый Shard + +item.modernmetals.aluminum_button.name=Алюминиевый Button +item.modernmetals.aluminum_lever.name=Алюминиевый Lever +item.modernmetals.aluminum_pressure_plate.name=Алюминиевый Pressure Plate +item.modernmetals.aluminum_slab.name=Алюминиевый Slab +item.modernmetals.aluminum_stairs.name=Алюминиевый Stairs +item.modernmetals.aluminum_wall.name=Алюминиевый Wall + +tile.modernmetals.aluminum_button.name=Алюминиевый Button +tile.modernmetals.aluminum_lever.name=Алюминиевый Lever +tile.modernmetals.aluminum_pressure_plate.name=Алюминиевый Pressure Plate +tile.modernmetals.aluminum_slab.name=Алюминиевый Slab +tile.modernmetals.aluminum_stairs.name=Алюминиевый Stairs +tile.modernmetals.aluminum_wall.name=Алюминиевый Wall + + +item.modernmetals.aluminumbrass_clump.name=Алюминиево-Латунный Clump +item.modernmetals.aluminumbrass_crushed.name=Crushed Алюминиево-Латунный Руда +item.modernmetals.aluminumbrass_crushed_purified.name=Purified Crushed Алюминиево-Латунный Руда +item.modernmetals.aluminumbrass_crystal.name=Алюминиево-Латунный Crystal +item.modernmetals.aluminumbrass_dense_plate.name=Dense Алюминиево-Латунный Plate +item.modernmetals.aluminumbrass_powder_dirty.name=Dirty Алюминиево-Латунный Dust +item.modernmetals.aluminumbrass_shard.name=Алюминиево-Латунный Shard + +item.modernmetals.aluminumbrass_button.name=Алюминиево-Латунный Button +item.modernmetals.aluminumbrass_lever.name=Алюминиево-Латунный Lever +item.modernmetals.aluminumbrass_pressure_plate.name=Алюминиево-Латунный Pressure Plate +item.modernmetals.aluminumbrass_slab.name=Алюминиево-Латунный Slab +item.modernmetals.aluminumbrass_stairs.name=Алюминиево-Латунный Stairs +item.modernmetals.aluminumbrass_wall.name=Алюминиево-Латунный Wall + +tile.modernmetals.aluminumbrass_button.name=Алюминиево-Латунный Button +tile.modernmetals.aluminumbrass_lever.name=Алюминиево-Латунный Lever +tile.modernmetals.aluminumbrass_pressure_plate.name=Алюминиево-Латунный Pressure Plate +tile.modernmetals.aluminumbrass_slab.name=Алюминиево-Латунный Slab +tile.modernmetals.aluminumbrass_stairs.name=Алюминиево-Латунный Stairs +tile.modernmetals.aluminumbrass_wall.name=Алюминиево-Латунный Wall + + +tile.modernmetals.beryllium_bars.name=Beryllium Прутья +tile.modernmetals.beryllium_block.name=Блок Beryllium +tile.modernmetals.beryllium_door.name=Beryllium Двери +tile.modernmetals.beryllium_ore.name=Beryllium Руда +tile.modernmetals.beryllium_plate.name=Beryllium Plate +tile.modernmetals.beryllium_trapdoor.name=Beryllium Люк + +item.modernmetals.beryllium_clump.name=Beryllium Clump +item.modernmetals.beryllium_crushed.name=Crushed Beryllium Руда +item.modernmetals.beryllium_crushed_purified.name=Purified Crushed Beryllium Руда +item.modernmetals.beryllium_crystal.name=Beryllium Crystal +item.modernmetals.beryllium_dense_plate.name=Dense Beryllium Plate +item.modernmetals.beryllium_powder_dirty.name=Dirty Beryllium Dust +item.modernmetals.beryllium_shard.name=Beryllium Shard +item.modernmetals.beryllium_button.name=Beryllium Button +item.modernmetals.beryllium_lever.name=Beryllium Lever +item.modernmetals.beryllium_pressure_plate.name=Beryllium Pressure Plate +item.modernmetals.beryllium_slab.name=Beryllium Slab +item.modernmetals.beryllium_stairs.name=Beryllium Stairs +item.modernmetals.beryllium_wall.name=Beryllium Wall + + +tile.modernmetals.beryllium.name=Molten Beryllium +tile.modernmetals.beryllium_button.name=Beryllium Button +tile.modernmetals.beryllium_lever.name=Beryllium Lever +tile.modernmetals.beryllium_pressure_plate.name=Beryllium Pressure Plate +tile.modernmetals.beryllium_slab.name=Beryllium Slab +tile.modernmetals.beryllium_stairs.name=Beryllium Stairs +tile.modernmetals.beryllium_wall.name=Beryllium Wall + + +item.modernmetals.boron_clump.name=Boron Clump +item.modernmetals.boron_crushed.name=Crushed Boron Руда +item.modernmetals.boron_crushed_purified.name=Purified Crushed Boron Руда +item.modernmetals.boron_crystal.name=Boron Crystal +item.modernmetals.boron_dense_plate.name=Dense Boron Plate +item.modernmetals.boron_powder_dirty.name=Dirty Boron Dust +item.modernmetals.boron_shard.name=Boron Shard + +item.modernmetals.boron_button.name=Boron Button +item.modernmetals.boron_lever.name=Boron Lever +item.modernmetals.boron_pressure_plate.name=Boron Pressure Plate +item.modernmetals.boron_slab.name=Boron Slab +item.modernmetals.boron_stairs.name=Boron Stairs +item.modernmetals.boron_wall.name=Boron Wall + +tile.modernmetals.boron_button.name=Boron Button +tile.modernmetals.boron_lever.name=Boron Lever +tile.modernmetals.boron_pressure_plate.name=Boron Pressure Plate +tile.modernmetals.boron_slab.name=Boron Slab +tile.modernmetals.boron_stairs.name=Boron Stairs +tile.modernmetals.boron_wall.name=Boron Wall + + +item.modernmetals.cadmium_clump.name=Cadmium Clump +item.modernmetals.cadmium_crushed.name=Crushed Cadmium Руда +item.modernmetals.cadmium_crushed_purified.name=Purified Crushed Cadmium Руда +item.modernmetals.cadmium_crystal.name=Cadmium Crystal +item.modernmetals.cadmium_dense_plate.name=Dense Cadmium Plate +item.modernmetals.cadmium_powder_dirty.name=Dirty Cadmium Dust +item.modernmetals.cadmium_shard.name=Cadmium Shard + +item.modernmetals.cadmium_button.name=Cadmium Button +item.modernmetals.cadmium_lever.name=Cadmium Lever +item.modernmetals.cadmium_pressure_plate.name=Cadmium Pressure Plate +item.modernmetals.cadmium_slab.name=Cadmium Slab +item.modernmetals.cadmium_stairs.name=Cadmium Stairs +item.modernmetals.cadmium_wall.name=Cadmium Wall + +tile.modernmetals.cadmium_button.name=Cadmium Button +tile.modernmetals.cadmium_lever.name=Cadmium Lever +tile.modernmetals.cadmium_pressure_plate.name=Cadmium Pressure Plate +tile.modernmetals.cadmium_slab.name=Cadmium Slab +tile.modernmetals.cadmium_stairs.name=Cadmium Stairs +tile.modernmetals.cadmium_wall.name=Cadmium Wall + + +item.modernmetals.chromium_clump.name=Chromium Clump +item.modernmetals.chromium_crushed.name=Crushed Chromium Руда +item.modernmetals.chromium_crushed_purified.name=Purified Crushed Chromium Руда +item.modernmetals.chromium_crystal.name=Chromium Crystal +item.modernmetals.chromium_dense_plate.name=Dense Chromium Plate +item.modernmetals.chromium_powder_dirty.name=Dirty Chromium Dust +item.modernmetals.chromium_shard.name=Chromium Shard + +item.modernmetals.chromium_button.name=Chromium Button +item.modernmetals.chromium_lever.name=Chromium Lever +item.modernmetals.chromium_pressure_plate.name=Chromium Pressure Plate +item.modernmetals.chromium_slab.name=Chromium Slab +item.modernmetals.chromium_stairs.name=Chromium Stairs +item.modernmetals.chromium_wall.name=Chromium Wall + +tile.modernmetals.chromium_button.name=Chromium Button +tile.modernmetals.chromium_lever.name=Chromium Lever +tile.modernmetals.chromium_pressure_plate.name=Chromium Pressure Plate +tile.modernmetals.chromium_slab.name=Chromium Slab +tile.modernmetals.chromium_stairs.name=Chromium Stairs +tile.modernmetals.chromium_wall.name=Chromium Wall + + +item.modernmetals.galvanizedsteel_clump.name=Galvanized Steel Clump +item.modernmetals.galvanizedsteel_crushed.name=Crushed Galvanized Steel Руда +item.modernmetals.galvanizedsteel_crushed_purified.name=Purified Crushed Galvanized Steel Руда +item.modernmetals.galvanizedsteel_crystal.name=Galvanized Steel Crystal +item.modernmetals.galvanizedsteel_dense_plate.name=Dense Galvanized Steel Plate +item.modernmetals.galvanizedsteel_powder_dirty.name=Dirty Galvanized Steel Dust +item.modernmetals.galvanizedsteel_shard.name=Galvanized Steel Shard + +item.modernmetals.galvanizedsteel_button.name=Galvanized Steel Button +item.modernmetals.galvanizedsteel_lever.name=Galvanized Steel Lever +item.modernmetals.galvanizedsteel_pressure_plate.name=Galvanized Steel Pressure Plate +item.modernmetals.galvanizedsteel_slab.name=Galvanized Steel Slab +item.modernmetals.galvanizedsteel_stairs.name=Galvanized Steel Stairs +item.modernmetals.galvanizedsteel_wall.name=Galvanized Steel Wall + +tile.modernmetals.galvanizedsteel_button.name=Galvanized Steel Button +tile.modernmetals.galvanizedsteel_lever.name=Galvanized Steel Lever +tile.modernmetals.galvanizedsteel_pressure_plate.name=Galvanized Steel Pressure Plate +tile.modernmetals.galvanizedsteel_slab.name=Galvanized Steel Slab +tile.modernmetals.galvanizedsteel_stairs.name=Galvanized Steel Stairs +tile.modernmetals.galvanizedsteel_wall.name=Galvanized Steel Wall + + +item.modernmetals.iridium_clump.name=Iridium Clump +item.modernmetals.iridium_crushed.name=Crushed Iridium Руда +item.modernmetals.iridium_crushed_purified.name=Purified Crushed Iridium Руда +item.modernmetals.iridium_crystal.name=Iridium Crystal +item.modernmetals.iridium_dense_plate.name=Dense Iridium Plate +item.modernmetals.iridium_powder_dirty.name=Dirty Iridium Dust +item.modernmetals.iridium_shard.name=Iridium Shard + +item.modernmetals.iridium_button.name=Iridium Button +item.modernmetals.iridium_lever.name=Iridium Lever +item.modernmetals.iridium_pressure_plate.name=Iridium Pressure Plate +item.modernmetals.iridium_slab.name=Iridium Slab +item.modernmetals.iridium_stairs.name=Iridium Stairs +item.modernmetals.iridium_wall.name=Iridium Wall + +tile.modernmetals.iridium_button.name=Iridium Button +tile.modernmetals.iridium_lever.name=Iridium Lever +tile.modernmetals.iridium_pressure_plate.name=Iridium Pressure Plate +tile.modernmetals.iridium_slab.name=Iridium Slab +tile.modernmetals.iridium_stairs.name=Iridium Stairs +tile.modernmetals.iridium_wall.name=Iridium Wall + + +item.modernmetals.magnesium_clump.name=Magnesium Clump +item.modernmetals.magnesium_crushed.name=Crushed Magnesium Руда +item.modernmetals.magnesium_crushed_purified.name=Purified Crushed Magnesium Руда +item.modernmetals.magnesium_crystal.name=Magnesium Crystal +item.modernmetals.magnesium_dense_plate.name=Dense Magnesium Plate +item.modernmetals.magnesium_powder_dirty.name=Dirty Magnesium Dust +item.modernmetals.magnesium_shard.name=Magnesium Shard + +item.modernmetals.magnesium_button.name=Magnesium Button +item.modernmetals.magnesium_lever.name=Magnesium Lever +item.modernmetals.magnesium_pressure_plate.name=Magnesium Pressure Plate +item.modernmetals.magnesium_slab.name=Magnesium Slab +item.modernmetals.magnesium_stairs.name=Magnesium Stairs +item.modernmetals.magnesium_wall.name=Magnesium Wall + +tile.modernmetals.magnesium_button.name=Magnesium Button +tile.modernmetals.magnesium_lever.name=Magnesium Lever +tile.modernmetals.magnesium_pressure_plate.name=Magnesium Pressure Plate +tile.modernmetals.magnesium_slab.name=Magnesium Slab +tile.modernmetals.magnesium_stairs.name=Magnesium Stairs +tile.modernmetals.magnesium_wall.name=Magnesium Wall + + +item.modernmetals.manganese_clump.name=Manganese Clump +item.modernmetals.manganese_crushed.name=Crushed Manganese Руда +item.modernmetals.manganese_crushed_purified.name=Purified Crushed Manganese Руда +item.modernmetals.manganese_crystal.name=Manganese Crystal +item.modernmetals.manganese_dense_plate.name=Dense Manganese Plate +item.modernmetals.manganese_powder_dirty.name=Dirty Manganese Dust +item.modernmetals.manganese_shard.name=Manganese Shard + +item.modernmetals.manganese_button.name=Manganese Button +item.modernmetals.manganese_lever.name=Manganese Lever +item.modernmetals.manganese_pressure_plate.name=Manganese Pressure Plate +item.modernmetals.manganese_slab.name=Manganese Slab +item.modernmetals.manganese_stairs.name=Manganese Stairs +item.modernmetals.manganese_wall.name=Manganese Wall + +tile.modernmetals.manganese_button.name=Manganese Button +tile.modernmetals.manganese_lever.name=Manganese Lever +tile.modernmetals.manganese_pressure_plate.name=Manganese Pressure Plate +tile.modernmetals.manganese_slab.name=Manganese Slab +tile.modernmetals.manganese_stairs.name=Manganese Stairs +tile.modernmetals.manganese_wall.name=Manganese Wall + + +item.modernmetals.nichrome_clump.name=Nichrome Clump +item.modernmetals.nichrome_crushed.name=Crushed Nichrome Руда +item.modernmetals.nichrome_crushed_purified.name=Purified Crushed Nichrome Руда +item.modernmetals.nichrome_crystal.name=Nichrome Crystal +item.modernmetals.nichrome_dense_plate.name=Dense Nichrome Plate +item.modernmetals.nichrome_powder_dirty.name=Dirty Nichrome Dust +item.modernmetals.nichrome_shard.name=Nichrome Shard + +item.modernmetals.nichrome_button.name=Nichrome Button +item.modernmetals.nichrome_lever.name=Nichrome Lever +item.modernmetals.nichrome_pressure_plate.name=Nichrome Pressure Plate +item.modernmetals.nichrome_slab.name=Nichrome Slab +item.modernmetals.nichrome_stairs.name=Nichrome Stairs +item.modernmetals.nichrome_wall.name=Nichrome Wall + +tile.modernmetals.nichrome_button.name=Nichrome Button +tile.modernmetals.nichrome_lever.name=Nichrome Lever +tile.modernmetals.nichrome_pressure_plate.name=Nichrome Pressure Plate +tile.modernmetals.nichrome_slab.name=Nichrome Slab +tile.modernmetals.nichrome_stairs.name=Nichrome Stairs +tile.modernmetals.nichrome_wall.name=Nichrome Wall + + +item.modernmetals.osmium_clump.name=Osmium Clump +item.modernmetals.osmium_crushed.name=Crushed Osmium Руда +item.modernmetals.osmium_crushed_purified.name=Purified Crushed Osmium Руда +item.modernmetals.osmium_crystal.name=Osmium Crystal +item.modernmetals.osmium_dense_plate.name=Dense Osmium Plate +item.modernmetals.osmium_powder_dirty.name=Dirty Osmium Dust +item.modernmetals.osmium_shard.name=Osmium Shard + +item.modernmetals.osmium_button.name=Osmium Button +item.modernmetals.osmium_lever.name=Osmium Lever +item.modernmetals.osmium_pressure_plate.name=Osmium Pressure Plate +item.modernmetals.osmium_slab.name=Osmium Slab +item.modernmetals.osmium_stairs.name=Osmium Stairs +item.modernmetals.osmium_wall.name=Osmium Wall + +tile.modernmetals.osmium_button.name=Osmium Button +tile.modernmetals.osmium_lever.name=Osmium Lever +tile.modernmetals.osmium_pressure_plate.name=Osmium Pressure Plate +tile.modernmetals.osmium_slab.name=Osmium Slab +tile.modernmetals.osmium_stairs.name=Osmium Stairs +tile.modernmetals.osmium_wall.name=Osmium Wall + + +item.modernmetals.plutonium_clump.name=Plutonium Clump +item.modernmetals.plutonium_crushed.name=Crushed Plutonium Руда +item.modernmetals.plutonium_crushed_purified.name=Purified Crushed Plutonium Руда +item.modernmetals.plutonium_crystal.name=Plutonium Crystal +item.modernmetals.plutonium_dense_plate.name=Dense Plutonium Plate +item.modernmetals.plutonium_powder_dirty.name=Dirty Plutonium Dust +item.modernmetals.plutonium_shard.name=Plutonium Shard + +item.modernmetals.plutonium_button.name=Plutonium Button +item.modernmetals.plutonium_lever.name=Plutonium Lever +item.modernmetals.plutonium_pressure_plate.name=Plutonium Pressure Plate +item.modernmetals.plutonium_slab.name=Plutonium Slab +item.modernmetals.plutonium_stairs.name=Plutonium Stairs +item.modernmetals.plutonium_wall.name=Plutonium Wall + +tile.modernmetals.plutonium_button.name=Plutonium Button +tile.modernmetals.plutonium_lever.name=Plutonium Lever +tile.modernmetals.plutonium_pressure_plate.name=Plutonium Pressure Plate +tile.modernmetals.plutonium_slab.name=Plutonium Slab +tile.modernmetals.plutonium_stairs.name=Plutonium Stairs +tile.modernmetals.plutonium_wall.name=Plutonium Wall + + +item.modernmetals.rutile_clump.name=Rutile Clump +item.modernmetals.rutile_crushed.name=Crushed Rutile Руда +item.modernmetals.rutile_crushed_purified.name=Purified Crushed Rutile Руда +item.modernmetals.rutile_crystal.name=Rutile Crystal +item.modernmetals.rutile_dense_plate.name=Dense Rutile Plate +item.modernmetals.rutile_powder_dirty.name=Dirty Rutile Dust +item.modernmetals.rutile_shard.name=Rutile Shard + +item.modernmetals.rutile_button.name=Rutile Button +item.modernmetals.rutile_lever.name=Rutile Lever +item.modernmetals.rutile_pressure_plate.name=Rutile Pressure Plate +item.modernmetals.rutile_slab.name=Rutile Slab +item.modernmetals.rutile_stairs.name=Rutile Stairs +item.modernmetals.rutile_wall.name=Rutile Wall + +tile.modernmetals.rutile_button.name=Rutile Button +tile.modernmetals.rutile_lever.name=Rutile Lever +tile.modernmetals.rutile_pressure_plate.name=Rutile Pressure Plate +tile.modernmetals.rutile_slab.name=Rutile Slab +tile.modernmetals.rutile_stairs.name=Rutile Stairs +tile.modernmetals.rutile_wall.name=Rutile Wall + + +item.modernmetals.stainlesssteel_clump.name=Stainless Steel Clump +item.modernmetals.stainlesssteel_crushed.name=Crushed Stainless Steel Руда +item.modernmetals.stainlesssteel_crushed_purified.name=Purified Crushed Stainless Steel Руда +item.modernmetals.stainlesssteel_crystal.name=Stainless Steel Crystal +item.modernmetals.stainlesssteel_dense_plate.name=Dense Stainless Steel Plate +item.modernmetals.stainlesssteel_powder_dirty.name=Dirty Stainless Steel Dust +item.modernmetals.stainlesssteel_shard.name=Stainless Steel Shard + +item.modernmetals.stainlesssteel_button.name=Stainless Steel Button +item.modernmetals.stainlesssteel_lever.name=Stainless Steel Lever +item.modernmetals.stainlesssteel_pressure_plate.name=Stainless Steel Pressure Plate +item.modernmetals.stainlesssteel_slab.name=Stainless Steel Slab +item.modernmetals.stainlesssteel_stairs.name=Stainless Steel Stairs +item.modernmetals.stainlesssteel_wall.name=Stainless Steel Wall + +tile.modernmetals.stainlesssteel_button.name=Stainless Steel Button +tile.modernmetals.stainlesssteel_lever.name=Stainless Steel Lever +tile.modernmetals.stainlesssteel_pressure_plate.name=Stainless Steel Pressure Plate +tile.modernmetals.stainlesssteel_slab.name=Stainless Steel Slab +tile.modernmetals.stainlesssteel_stairs.name=Stainless Steel Stairs +tile.modernmetals.stainlesssteel_wall.name=Stainless Steel Wall + + +item.modernmetals.tantalum_clump.name=Tantalum Clump +item.modernmetals.tantalum_crushed.name=Crushed Tantalum Руда +item.modernmetals.tantalum_crushed_purified.name=Purified Crushed Tantalum Руда +item.modernmetals.tantalum_crystal.name=Tantalum Crystal +item.modernmetals.tantalum_dense_plate.name=Dense Tantalum Plate +item.modernmetals.tantalum_powder_dirty.name=Dirty Tantalum Dust +item.modernmetals.tantalum_shard.name=Tantalum Shard + +item.modernmetals.tantalum_button.name=Tantalum Button +item.modernmetals.tantalum_lever.name=Tantalum Lever +item.modernmetals.tantalum_pressure_plate.name=Tantalum Pressure Plate +item.modernmetals.tantalum_slab.name=Tantalum Slab +item.modernmetals.tantalum_stairs.name=Tantalum Stairs +item.modernmetals.tantalum_wall.name=Tantalum Wall + +tile.modernmetals.tantalum_button.name=Tantalum Button +tile.modernmetals.tantalum_lever.name=Tantalum Lever +tile.modernmetals.tantalum_pressure_plate.name=Tantalum Pressure Plate +tile.modernmetals.tantalum_slab.name=Tantalum Slab +tile.modernmetals.tantalum_stairs.name=Tantalum Stairs +tile.modernmetals.tantalum_wall.name=Tantalum Wall + + +item.modernmetals.titanium_clump.name=Titanium Clump +item.modernmetals.titanium_crushed.name=Crushed Titanium Руда +item.modernmetals.titanium_crushed_purified.name=Purified Crushed Titanium Руда +item.modernmetals.titanium_crystal.name=Titanium Crystal +item.modernmetals.titanium_dense_plate.name=Dense Titanium Plate +item.modernmetals.titanium_powder_dirty.name=Dirty Titanium Dust +item.modernmetals.titanium_shard.name=Titanium Shard + +item.modernmetals.titanium_button.name=Titanium Button +item.modernmetals.titanium_lever.name=Titanium Lever +item.modernmetals.titanium_pressure_plate.name=Titanium Pressure Plate +item.modernmetals.titanium_slab.name=Titanium Slab +item.modernmetals.titanium_stairs.name=Titanium Stairs +item.modernmetals.titanium_wall.name=Titanium Wall + +tile.modernmetals.titanium_button.name=Titanium Button +tile.modernmetals.titanium_lever.name=Titanium Lever +tile.modernmetals.titanium_pressure_plate.name=Titanium Pressure Plate +tile.modernmetals.titanium_slab.name=Titanium Slab +tile.modernmetals.titanium_stairs.name=Titanium Stairs +tile.modernmetals.titanium_wall.name=Titanium Wall + + +item.modernmetals.tungsten_clump.name=Tungsten Clump +item.modernmetals.tungsten_crushed.name=Crushed Tungsten Руда +item.modernmetals.tungsten_crushed_purified.name=Purified Crushed Tungsten Руда +item.modernmetals.tungsten_crystal.name=Tungsten Crystal +item.modernmetals.tungsten_dense_plate.name=Dense Tungsten Plate +item.modernmetals.tungsten_powder_dirty.name=Dirty Tungsten Dust +item.modernmetals.tungsten_shard.name=Tungsten Shard + +item.modernmetals.tungsten_button.name=Tungsten Button +item.modernmetals.tungsten_lever.name=Tungsten Lever +item.modernmetals.tungsten_pressure_plate.name=Tungsten Pressure Plate +item.modernmetals.tungsten_slab.name=Tungsten Slab +item.modernmetals.tungsten_stairs.name=Tungsten Stairs +item.modernmetals.tungsten_wall.name=Tungsten Wall + +tile.modernmetals.tungsten_button.name=Tungsten Button +tile.modernmetals.tungsten_lever.name=Tungsten Lever +tile.modernmetals.tungsten_pressure_plate.name=Tungsten Pressure Plate +tile.modernmetals.tungsten_slab.name=Tungsten Slab +tile.modernmetals.tungsten_stairs.name=Tungsten Stairs +tile.modernmetals.tungsten_wall.name=Tungsten Wall + + +item.modernmetals.uranium_clump.name=Uranium Clump +item.modernmetals.uranium_crushed.name=Crushed Uranium Руда +item.modernmetals.uranium_crushed_purified.name=Purified Crushed Uranium Руда +item.modernmetals.uranium_crystal.name=Uranium Crystal +item.modernmetals.uranium_dense_plate.name=Dense Uranium Plate +item.modernmetals.uranium_powder_dirty.name=Dirty Uranium Dust +item.modernmetals.uranium_shard.name=Uranium Shard + +item.modernmetals.uranium_button.name=Uranium Button +item.modernmetals.uranium_lever.name=Uranium Lever +item.modernmetals.uranium_pressure_plate.name=Uranium Pressure Plate +item.modernmetals.uranium_slab.name=Uranium Slab +item.modernmetals.uranium_stairs.name=Uranium Stairs +item.modernmetals.uranium_wall.name=Uranium Wall + +tile.modernmetals.uranium_button.name=Uranium Button +tile.modernmetals.uranium_lever.name=Uranium Lever +tile.modernmetals.uranium_pressure_plate.name=Uranium Pressure Plate +tile.modernmetals.uranium_slab.name=Uranium Slab +tile.modernmetals.uranium_stairs.name=Uranium Stairs +tile.modernmetals.uranium_wall.name=Uranium Wall + + +item.modernmetals.zirconium_clump.name=Zirconium Clump +item.modernmetals.zirconium_crushed.name=Crushed Zirconium Руда +item.modernmetals.zirconium_crushed_purified.name=Purified Crushed Zirconium Руда +item.modernmetals.zirconium_crystal.name=Zirconium Crystal +item.modernmetals.zirconium_dense_plate.name=Dense Zirconium Plate +item.modernmetals.zirconium_powder_dirty.name=Dirty Zirconium Dust +item.modernmetals.zirconium_shard.name=Zirconium Shard + +item.modernmetals.zirconium_button.name=Zirconium Button +item.modernmetals.zirconium_lever.name=Zirconium Lever +item.modernmetals.zirconium_pressure_plate.name=Zirconium Pressure Plate +item.modernmetals.zirconium_slab.name=Zirconium Slab +item.modernmetals.zirconium_stairs.name=Zirconium Stairs +item.modernmetals.zirconium_wall.name=Zirconium Wall + +tile.modernmetals.zirconium_button.name=Zirconium Button +tile.modernmetals.zirconium_lever.name=Zirconium Lever +tile.modernmetals.zirconium_pressure_plate.name=Zirconium Pressure Plate +tile.modernmetals.zirconium_slab.name=Zirconium Slab +tile.modernmetals.zirconium_stairs.name=Zirconium Stairs +tile.modernmetals.zirconium_wall.name=Zirconium Wall + + +material.thorium.name=Thorium +item.modernmetals.thorium_arrow.name=Thorium Стрела +item.modernmetals.thorium_axe.name=Thorium Топор +item.modernmetals.thorium_bars.name=Thorium Прутья +item.modernmetals.thorium_blend.name=Thorium Смеси +item.modernmetals.thorium_block.name=Блок Thorium +item.modernmetals.thorium_boots.name=Thorium Ботинки +item.modernmetals.thorium_bolt.name=Thorium Арбалетная Стрела +item.modernmetals.thorium_bow.name=Thorium Лук +item.modernmetals.thorium_chestplate.name=Thorium Нагрудник +item.modernmetals.thorium_crackhammer.name=Thorium Измельчающий Молот +item.modernmetals.thorium_crossbow.name=Thorium Арбалет +item.modernmetals.thorium_door.name=Thorium Двери +item.modernmetals.thorium_fishing_rod.name=Thorium Удочка +item.modernmetals.thorium_gear.name=Thorium Шестерня +item.modernmetals.thorium_helmet.name=Thorium Шлем +item.modernmetals.thorium_hoe.name=Thorium Мотыга +item.modernmetals.thorium_horse_armor.name=Thorium Конская Броня +item.modernmetals.thorium_ingot.name=Thorium Слиток +item.modernmetals.thorium_leggings.name=Thorium Поножки +item.modernmetals.thorium_nugget.name=Thorium Самородок +item.modernmetals.thorium_ore.name=Thorium Руда +item.modernmetals.thorium_pickaxe.name=Thorium Кирка +item.modernmetals.thorium_powder.name=Измельчённый Thorium +item.modernmetals.thorium_rod.name=Thorium Стержень +item.modernmetals.thorium_shears.name=Thorium Ножницы +item.modernmetals.thorium_shield.name=Thorium Щит +item.modernmetals.thorium_shovel.name=Thorium Лопата +item.modernmetals.thorium_smallblend.name=Маленькая Кучка Thorium Смеси +item.modernmetals.thorium_smallpowder.name=Маленькая Кучка Измельчённого Thorium +item.modernmetals.thorium_sword.name=Thorium Меч +item.modernmetals.thorium_trapdoor.name=Thorium Люк +tile.modernmetals.thorium_bars.name=Thorium Прутья +tile.modernmetals.thorium_block.name=Блок Thorium +tile.modernmetals.thorium_door.name=Thorium Двери +tile.modernmetals.thorium_ore.name=Thorium Руда +tile.modernmetals.thorium_plate.name=Thorium Plate +tile.modernmetals.thorium_trapdoor.name=Thorium Люк +fluid.modernmetals.thorium=Molten Thorium +fluid.modernmetals.thorium.name=Molten Thorium +tile.modernmetals.thorium.name=Molten Thorium +item.modernmetals.thorium_clump.name=Thorium Clump +item.modernmetals.thorium_crushed.name=Crushed Thorium Руда +item.modernmetals.thorium_crushed_purified.name=Purified Crushed Thorium Руда +item.modernmetals.thorium_crystal.name=Thorium Crystal +item.modernmetals.thorium_dense_plate.name=Dense Thorium Plate +item.modernmetals.thorium_powder_dirty.name=Dirty Thorium Dust +item.modernmetals.thorium_shard.name=Thorium Shard +item.modernmetals.thorium_button.name=Thorium Button +item.modernmetals.thorium_lever.name=Thorium Lever +item.modernmetals.thorium_pressure_plate.name=Thorium Pressure Plate +item.modernmetals.thorium_slab.name=Thorium Slab +item.modernmetals.thorium_stairs.name=Thorium Stairs +item.modernmetals.thorium_wall.name=Thorium Wall +tile.modernmetals.thorium_button.name=Thorium Button +tile.modernmetals.thorium_lever.name=Thorium Lever +tile.modernmetals.thorium_pressure_plate.name=Thorium Pressure Plate +tile.modernmetals.thorium_slab.name=Thorium Slab +tile.modernmetals.thorium_stairs.name=Thorium Stairs +tile.modernmetals.thorium_wall.name=Thorium Wall + +# Modern Metals settings and restored content +config.modernmetals.material.tooltip=Включает блоки, предметы и рецепты этого материала. Требуется перезапуск игры. +config.modernmetals.title=Modern Metals +config.modernmetals.description=Для применения нужен перезапуск. Руды настраиваются в OreSpawn. +config.modernmetals.content_mode=Уровень фэнтези +config.modernmetals.content_mode.tooltip=Высокий уровень сохраняет все рецепты. Низкий ограничивает нереалистичное снаряжение и строительные блоки. Требуется перезапуск игры. +high_fantasy=Высокий уровень фэнтези +low_fantasy=Низкий уровень фэнтези +config.modernmetals.villager_trades=Торговля с жителями +config.modernmetals.villager_trades.tooltip=Кузнецы могут торговать слитками и снаряжением Modern Metals. Требуется перезапуск игры. +config.modernmetals.connection.mismatch=Уровень на сервере — %s, в вашей игре — %s. Выберите тот же уровень в меню «Моды > Modern Metals > Настройки» и перезапустите игру. +config.modernmetals.connection.protocol=Не удалось проверить уровень фэнтези Modern Metals. Установите одну и ту же сборку Modern Metals на клиенте и сервере. +itemGroup.modernmetals.combat=Modern Metals: боевое снаряжение +item.modernmetals.titanium_casing.name=Корпус из материала «Титан» +item.modernmetals.beryllium_scythe.name=Серп из материала «Бериллий» +item.modernmetals.boron_scythe.name=Серп из материала «Бор» +item.modernmetals.thorium_scythe.name=Серп из материала «Торий» +item.modernmetals.titanium_scythe.name=Серп из материала «Титан» +config.modernmetals.enable_thorium=Включить торий +config.modernmetals.enable_boron=Включить бор +config.modernmetals.enable_beryllium=Включить бериллий +config.modernmetals.enable_cadmium=Включить кадмий +config.modernmetals.enable_nichrome=Включить нихром +config.modernmetals.enable_aluminum=Включить алюминий +config.modernmetals.enable_aluminumbrass=Включить алюминиевую латунь +config.modernmetals.enable_chromium=Включить хром +config.modernmetals.enable_galvanizedsteel=Включить оцинкованную сталь +config.modernmetals.enable_iridium=Включить иридий +config.modernmetals.enable_magnesium=Включить магний +config.modernmetals.enable_manganese=Включить марганец +config.modernmetals.enable_osmium=Включить осмий +config.modernmetals.enable_plutonium=Включить плутоний +config.modernmetals.enable_rutile=Включить рутил +config.modernmetals.enable_stainlesssteel=Включить нержавеющую сталь +config.modernmetals.enable_tantalum=Включить тантал +config.modernmetals.enable_titanium=Включить титан +config.modernmetals.enable_tungsten=Включить вольфрам +config.modernmetals.enable_uranium=Включить уран +config.modernmetals.enable_zirconium=Включить цирконий diff --git a/src/main/resources/assets/modernmetals/lang/zh_CN.lang b/src/main/resources/assets/modernmetals/lang/zh_CN.lang index 57e1b4f6..5957db78 100644 --- a/src/main/resources/assets/modernmetals/lang/zh_CN.lang +++ b/src/main/resources/assets/modernmetals/lang/zh_CN.lang @@ -3,7 +3,7 @@ itemGroup.modernmetals.tools=Modern Metals itemGroup.modernmetals.blocks=Modern Metals nei.modernmetals.recipehandler.crusher.name=粉碎的方块/物品 -material.aluminum.name=Aluminum +material.aluminum.name=铝 item.modernmetals.aluminum_arrow.name=铝箭 item.modernmetals.aluminum_axe.name=铝斧 item.modernmetals.aluminum_bars.name=铝栏杆 @@ -1513,3 +1513,43 @@ tile.modernmetals.thorium_stairs.name=钍楼梯 tile.modernmetals.thorium_wall.name=钍墙 + +# Modern Metals settings and restored content +config.modernmetals.material.tooltip=控制是否启用此材料的方块、物品和配方。需要重启游戏。 +config.modernmetals.title=Modern Metals +config.modernmetals.description=重启游戏后应用更改。请在 OreSpawn 中设置矿石生成。 +config.modernmetals.content_mode=奇幻等级 +config.modernmetals.content_mode.tooltip=高奇幻保留全部配方。低奇幻限制不符合现实的装备和建筑部件。需要重启游戏。 +high_fantasy=高奇幻 +low_fantasy=低奇幻 +config.modernmetals.villager_trades=村民交易 +config.modernmetals.villager_trades.tooltip=允许铁匠交易 Modern Metals 的金属锭和装备。需要重启游戏。 +config.modernmetals.connection.mismatch=服务器使用%s,你的游戏使用%s。请在模组 > Modern Metals > 配置中选择与服务器一致的奇幻等级,然后重启游戏。 +config.modernmetals.connection.protocol=Modern Metals 无法核对奇幻等级。请在服务器和客户端使用相同构建版本的 Modern Metals。 +itemGroup.modernmetals.combat=Modern Metals 战斗用品 +item.modernmetals.titanium_casing.name=钛外壳 +item.modernmetals.beryllium_scythe.name=铍镰刀 +item.modernmetals.boron_scythe.name=硼镰刀 +item.modernmetals.thorium_scythe.name=钍镰刀 +item.modernmetals.titanium_scythe.name=钛镰刀 +config.modernmetals.enable_thorium=启用钍 +config.modernmetals.enable_boron=启用硼 +config.modernmetals.enable_beryllium=启用铍 +config.modernmetals.enable_cadmium=启用镉 +config.modernmetals.enable_nichrome=启用镍铬合金 +config.modernmetals.enable_aluminum=启用铝 +config.modernmetals.enable_aluminumbrass=启用铝黄铜 +config.modernmetals.enable_chromium=启用铬 +config.modernmetals.enable_galvanizedsteel=启用镀锌钢 +config.modernmetals.enable_iridium=启用铱 +config.modernmetals.enable_magnesium=启用镁 +config.modernmetals.enable_manganese=启用锰 +config.modernmetals.enable_osmium=启用锇 +config.modernmetals.enable_plutonium=启用钚 +config.modernmetals.enable_rutile=启用金红石 +config.modernmetals.enable_stainlesssteel=启用不锈钢 +config.modernmetals.enable_tantalum=启用钽 +config.modernmetals.enable_titanium=启用钛 +config.modernmetals.enable_tungsten=启用钨 +config.modernmetals.enable_uranium=启用铀 +config.modernmetals.enable_zirconium=启用锆 diff --git a/src/main/resources/assets/modernmetals/models/block/aluminum_ore.json b/src/main/resources/assets/modernmetals/models/block/aluminum_ore.json deleted file mode 100644 index 4616b535..00000000 --- a/src/main/resources/assets/modernmetals/models/block/aluminum_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/aluminum_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/aluminumbrass_ore.json b/src/main/resources/assets/modernmetals/models/block/aluminumbrass_ore.json deleted file mode 100644 index ed015015..00000000 --- a/src/main/resources/assets/modernmetals/models/block/aluminumbrass_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/aluminumbrass_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/beryllium_ore.json b/src/main/resources/assets/modernmetals/models/block/beryllium_ore.json deleted file mode 100644 index 6e531aa2..00000000 --- a/src/main/resources/assets/modernmetals/models/block/beryllium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/beryllium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/boron_ore.json b/src/main/resources/assets/modernmetals/models/block/boron_ore.json deleted file mode 100644 index 13dfb423..00000000 --- a/src/main/resources/assets/modernmetals/models/block/boron_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/boron_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/cadmium_ore.json b/src/main/resources/assets/modernmetals/models/block/cadmium_ore.json deleted file mode 100644 index cf3636e0..00000000 --- a/src/main/resources/assets/modernmetals/models/block/cadmium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/cadmium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/chromium_ore.json b/src/main/resources/assets/modernmetals/models/block/chromium_ore.json deleted file mode 100644 index f867a0b3..00000000 --- a/src/main/resources/assets/modernmetals/models/block/chromium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/chromium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/galvanizedsteel_ore.json b/src/main/resources/assets/modernmetals/models/block/galvanizedsteel_ore.json deleted file mode 100644 index f7e8487e..00000000 --- a/src/main/resources/assets/modernmetals/models/block/galvanizedsteel_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/galvanizedsteel_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/iridium_ore.json b/src/main/resources/assets/modernmetals/models/block/iridium_ore.json deleted file mode 100644 index b3bd98cb..00000000 --- a/src/main/resources/assets/modernmetals/models/block/iridium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/iridium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/magnesium_ore.json b/src/main/resources/assets/modernmetals/models/block/magnesium_ore.json deleted file mode 100644 index 9f6fb257..00000000 --- a/src/main/resources/assets/modernmetals/models/block/magnesium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/magnesium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/manganese_ore.json b/src/main/resources/assets/modernmetals/models/block/manganese_ore.json deleted file mode 100644 index 6c79d985..00000000 --- a/src/main/resources/assets/modernmetals/models/block/manganese_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/manganese_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/nichrome_ore.json b/src/main/resources/assets/modernmetals/models/block/nichrome_ore.json deleted file mode 100644 index 88f7cf51..00000000 --- a/src/main/resources/assets/modernmetals/models/block/nichrome_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/nichrome_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/osmium_ore.json b/src/main/resources/assets/modernmetals/models/block/osmium_ore.json deleted file mode 100644 index 9aabe0d0..00000000 --- a/src/main/resources/assets/modernmetals/models/block/osmium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/osmium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/plutonium_ore.json b/src/main/resources/assets/modernmetals/models/block/plutonium_ore.json deleted file mode 100644 index 2e4233ea..00000000 --- a/src/main/resources/assets/modernmetals/models/block/plutonium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/plutonium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/rutile_ore.json b/src/main/resources/assets/modernmetals/models/block/rutile_ore.json deleted file mode 100644 index 29f9be6c..00000000 --- a/src/main/resources/assets/modernmetals/models/block/rutile_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/rutile_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/stainlesssteel_ore.json b/src/main/resources/assets/modernmetals/models/block/stainlesssteel_ore.json deleted file mode 100644 index e757848f..00000000 --- a/src/main/resources/assets/modernmetals/models/block/stainlesssteel_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/stainlesssteel_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/tantalum_ore.json b/src/main/resources/assets/modernmetals/models/block/tantalum_ore.json deleted file mode 100644 index 4aae5e70..00000000 --- a/src/main/resources/assets/modernmetals/models/block/tantalum_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/tantalum_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/titanium_ore.json b/src/main/resources/assets/modernmetals/models/block/titanium_ore.json deleted file mode 100644 index ddfbdce7..00000000 --- a/src/main/resources/assets/modernmetals/models/block/titanium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/titanium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/tungsten_ore.json b/src/main/resources/assets/modernmetals/models/block/tungsten_ore.json deleted file mode 100644 index 369e7432..00000000 --- a/src/main/resources/assets/modernmetals/models/block/tungsten_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/tungsten_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/uranium_ore.json b/src/main/resources/assets/modernmetals/models/block/uranium_ore.json deleted file mode 100644 index b0dadbef..00000000 --- a/src/main/resources/assets/modernmetals/models/block/uranium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/uranium_ore" - } -} diff --git a/src/main/resources/assets/modernmetals/models/block/zirconium_ore.json b/src/main/resources/assets/modernmetals/models/block/zirconium_ore.json deleted file mode 100644 index c5835215..00000000 --- a/src/main/resources/assets/modernmetals/models/block/zirconium_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "modernmetals:blocks/zirconium_ore" - } -} diff --git a/src/test/java/zone/moddev/mc/modernmetals/util/ContentModeConfigurationTests.java b/src/test/java/zone/moddev/mc/modernmetals/util/ContentModeConfigurationTests.java index e5285e01..8af4a5bd 100644 --- a/src/test/java/zone/moddev/mc/modernmetals/util/ContentModeConfigurationTests.java +++ b/src/test/java/zone/moddev/mc/modernmetals/util/ContentModeConfigurationTests.java @@ -28,4 +28,14 @@ final class ContentModeConfigurationTests { assertEquals("high_fantasy", Config.contentMode(config)); assertEquals("high_fantasy", config.getCategory("General").get("contentMode").getString()); } + + @Test void tradeSwitchDefaultsToEnabledAndPreservesAnExplicitOptOut() { + final Configuration config = new Configuration(); + assertTrue(Config.villagerTrades(config)); + final Property selector = config.getCategory("General").get("enableVillagerTrades"); + assertTrue(selector.requiresMcRestart()); + assertEquals("config.modernmetals.villager_trades", selector.getLanguageKey()); + selector.set(false); + assertFalse(Config.villagerTrades(config)); + } } diff --git a/tools/validation/legacy110/README.md b/tools/validation/legacy110/README.md index 0252ee34..20bc1477 100644 --- a/tools/validation/legacy110/README.md +++ b/tools/validation/legacy110/README.md @@ -51,8 +51,8 @@ output first. Keep the editor's `bin/main` unchanged during qualification. On Windows, `run_packaged_client.py` launches the installed jar against the unmodified obfuscated Minecraft client and Forge universal jar. Supply `--java`, `--cache`, `--installer`, `--template`, `--output` and `--phase first|reload`. -It verifies the Forge installer and Minecraft client hashes, uses existing verified -libraries/natives, and isolates the universal jar from the server jar named +It verifies the Forge installer and Minecraft client hashes, stages verified +Windows natives in the disposable game directory, and isolates the universal jar from the server jar named in its manifest. Every ordinary installed mod is copied into the disposable directory; no development output enters its classpath. Inspect the generated client reports and screenshots separately from manual acceptance. @@ -61,6 +61,28 @@ in a disposable asset directory. Cached matching objects are copied; missing one are downloaded from Mojang. A different branch's shared Gradle asset index is not overwritten or assumed to match Minecraft 1.10.2. +For the overlay check, run `--phase first` with vanilla textures, then run +`--phase reload --ore-host-pack` against the same disposable world. The probe +checks the baked block and inventory faces and records an ore display screenshot +in each run. Copy the first screenshot before reloading to compare both. +Use `--language de_DE`, `zh_CN` or `ru_RU` to check the actual localized +settings and selector values. + +## Multiplayer and original saves + +`check_multiplayer_mode.py` uses the same client inputs and a loopback-only +dedicated server. Supply `--server-jar` and `--client-jar` to test the installed +archives. The four default scenarios cover each pair of High and Low Fantasy. +The server log verifies that a rejected client never enters the world. + +`check_original_saves.py --java --template +--public-jars --candidate +--output ` verifies the SHA-256 of the original +public jars, creates the 0.11.0 and beta4.19 fixtures, and checks separate +upgraded copies on first load and reload. It checks placed blocks, filled +buckets and item stacks with non-default count or damage. It stops on any Forge +prompt to remove missing blocks or items. The source worlds are fingerprinted. + ## Limits and separately owned defects Public Base Metals 2.5.1.110021 catches errors in its own optional IC2/Mekanism diff --git a/tools/validation/legacy110/audit_resources.py b/tools/validation/legacy110/audit_resources.py index 2b9947df..a44fddd6 100644 --- a/tools/validation/legacy110/audit_resources.py +++ b/tools/validation/legacy110/audit_resources.py @@ -9,12 +9,47 @@ import yaml from run_runtime_checks import ROOT, dependency + +def language_entries(path): + entries = {} + for line in path.read_text(encoding='utf-8-sig').splitlines(): + if '=' not in line or line.startswith('#'): + continue + key, value = line.split('=', 1) + assert key not in entries, f'{path.name}: duplicate key {key}' + entries[key] = value + return entries + + +def audit_languages(directory, materials): + languages = {path.stem: language_entries(path) for path in directory.glob('*.lang')} + settings = { + 'config.modernmetals.title', 'config.modernmetals.description', + 'config.modernmetals.content_mode', 'config.modernmetals.content_mode.tooltip', + 'config.modernmetals.villager_trades', 'config.modernmetals.villager_trades.tooltip', + 'config.modernmetals.material.tooltip', + 'config.modernmetals.connection.mismatch', 'config.modernmetals.connection.protocol', + 'high_fantasy', 'low_fantasy', 'itemGroup.modernmetals.combat', + } + settings.update('config.modernmetals.enable_' + name for name in materials) + english = languages['en_US'] + restored_material = re.compile(r'\b(?:boron|beryllium|thorium|titanium)(?=\b|_)') + content = {key for key in english if restored_material.search(key)} + for locale in ('en_US', 'de_DE', 'ru_RU', 'zh_CN'): + entries = languages.get(locale, {}) + missing = {key for key in settings | content if not entries.get(key)} + assert not missing, f'{locale}: missing translations {sorted(missing)}' + assert entries['config.modernmetals.connection.mismatch'].count('%s') == 2, locale + for locale in ('en_AU', 'en_CA', 'en_GB', 'en_NZ', 'en_PT'): + assert locale in languages, f'{locale}: missing regional English file' + def main(): parser=argparse.ArgumentParser(description=__doc__) parser.add_argument('--mirror',type=Path) args=parser.parse_args() checked=0 - for path in (ROOT/'src/main/resources').rglob('*'): + resources=ROOT/'build/resources/main' + for path in resources.rglob('*'): if path.is_file() and (path.suffix in ('.json','.mcmeta') or path.name=='mcmod.info'): json.loads(path.read_text(encoding='utf-8-sig')); checked+=1 def references(value,key): @@ -24,8 +59,9 @@ def references(value,key): else:yield from references(child,key) elif isinstance(value,list): for child in value:yield from references(child,key) - assets=ROOT/'src/main/resources/assets/modernmetals' + assets=resources/'assets/modernmetals' materials=re.findall(r'material\("([a-z]+)",', (ROOT/'src/main/java/zone/moddev/mc/modernmetals/util/Config.java').read_text()) + audit_languages(assets/'lang', materials) for path in (assets/'blockstates').glob('*.json'): for model in references(json.loads(path.read_text()),'model'): assert (assets/'models/block'/(model+'.json')).is_file(),f'{path.name}: missing block model {model}' @@ -35,6 +71,20 @@ def references(value,key): if path.parent.name=='item' and path.stem.startswith('silicon_') and 'silicon' not in materials:continue for parent in references(json.loads(path.read_text()),'parent'): assert (assets/'models'/(parent+'.json')).is_file(),f'{path.name}: missing parent {parent}' + ore_states=sorted((assets/'blockstates').glob('*_ore.json')) + assert ore_states, 'Processed ore assets are missing; run processResources first' + for state in ore_states: + name=state.stem + model=json.loads((assets/'models/block'/state.name).read_text()) + for value in model['textures'].values(): + if value.startswith('modernmetals:'): + texture=value.split(':',1)[1] + assert (assets/'textures'/(texture+'.png')).is_file(),f'{name}: missing texture {texture}' + if name!='thorium_ore': + assert model['parent']=='modernmetals:block/ore_overlay',name + assert model['textures']['base']=='minecraft:blocks/stone',name + assert model['textures']['overlay']==f'modernmetals:blocks/ore_overlays/{name}',name + assert not (assets/'textures/blocks'/(name+'.png')).exists(),f'{name}: stale flat texture' specs=json.loads((ROOT/'gradle/dependencies.json').read_text()) with zipfile.ZipFile(dependency(next(s for s in specs if s['id']=='orespawn'),args.mirror)) as jar: schemas=[json.loads(jar.read(n)) for n in jar.namelist() if n.startswith('META-INF/orespawn/docs/schemas/') and n.endswith('.json')] diff --git a/tools/validation/legacy110/check_multiplayer_mode.py b/tools/validation/legacy110/check_multiplayer_mode.py new file mode 100644 index 00000000..20eef53f --- /dev/null +++ b/tools/validation/legacy110/check_multiplayer_mode.py @@ -0,0 +1,81 @@ +"""Exercise the fantasy mode handshake over a real loopback Forge connection.""" +import argparse +import json +import socket +import subprocess +import sys +import time +from pathlib import Path + +from run_runtime_checks import FORGE, ROOT, dependency, digest, prepare, write_json + + +def check(args, server_mode, client_mode): + output = args.output / f"{server_mode}-{client_mode}" + server = output / "server" + specs = json.loads((ROOT / "gradle/dependencies.json").read_text()) + jars = [dependency(spec) for spec in specs if spec.get("runtime")] + prepare(server, args.template, jars + [args.server_jar]) + with socket.socket() as reservation: + reservation.bind(("127.0.0.1", 0)) + port = reservation.getsockname()[1] + properties = server / "server.properties" + properties.write_text(properties.read_text().replace("server-port=0", f"server-port={port}")) + config = server / "config/ModernMetals.cfg" + config.parent.mkdir() + config.write_text(f"general {{\n S:contentMode={server_mode}_fantasy\n}}\n") + console = server / "console.log" + mismatch = server_mode != client_mode + rejection = args.incompatible_build or mismatch + with console.open("wb") as log, subprocess.Popen( + [str(args.java), "-Xmx2G", "-jar", FORGE, "nogui"], cwd=server, + stdin=subprocess.PIPE, stdout=log, stderr=subprocess.STDOUT + ) as process: + try: + deadline = time.monotonic() + 90 + while 'For help, type "help"' not in console.read_text(errors="replace"): + if process.poll() is not None or time.monotonic() >= deadline: + raise AssertionError(f"Dedicated server did not start: {console}") + time.sleep(0.25) + command = [sys.executable, str(Path(__file__).with_name("run_packaged_client.py")), + "--java", str(args.java), "--cache", str(args.cache), "--installer", str(args.installer), + "--template", str(args.template), "--output", str(output / "client"), + "--mod-jar", str(args.client_jar), "--remote-port", str(port)] + if client_mode == "low": + command.append("--low-fantasy") + if args.incompatible_build: + command += ["--expected-disconnect", "Use the same Modern Metals build"] + elif mismatch: + command += ["--expected-disconnect", f"The server uses {server_mode.title()} Fantasy, " + f"but your game uses {client_mode.title()} Fantasy"] + subprocess.run(command, check=True, timeout=360) + finally: + if process.poll() is None: + try: + process.communicate(b"stop\n", timeout=45) + except subprocess.TimeoutExpired: + process.kill() + process.wait() + raise + assert process.returncode == 0, console + assert ("ModernCheck joined the game" in console.read_text(errors="replace")) == (not rejection), console + write_json(output / "receipt.json", { + "passed": True, "server_mode": server_mode, "client_mode": client_mode, + "server_sha256": digest(args.server_jar), "client_sha256": digest(args.client_jar), + "joined": not rejection, + }) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + for name in ("java", "cache", "installer", "template", "output", "server-jar", "client-jar"): + parser.add_argument("--" + name, required=True, type=lambda path: Path(path).resolve()) + parser.add_argument("--scenario", action="append", choices=["high-high", "high-low", "low-high", "low-low"]) + parser.add_argument("--incompatible-build", action="store_true", help="Expect a missing mode advertisement.") + args = parser.parse_args() + for scenario in args.scenario or ["high-low", "low-high", "high-high", "low-low"]: + check(args, *scenario.split("-")) + + +if __name__ == "__main__": + main() diff --git a/tools/validation/legacy110/check_original_saves.py b/tools/validation/legacy110/check_original_saves.py new file mode 100644 index 00000000..1189924a --- /dev/null +++ b/tools/validation/legacy110/check_original_saves.py @@ -0,0 +1,127 @@ +"""Create and upgrade disposable worlds using the two public 1.10.2 releases.""" +import argparse +import json +import subprocess +import time +from pathlib import Path + +from run_packaged_suite import fingerprint +from run_runtime_checks import FORGE, ROOT, dependency, digest, prepare, write_json + + +PUBLIC_JARS = { + "cyano": { + "modern-metals-244357-2305634": "F8FC0FD92CB2A3C76DD7ABE39926AD44A8A52A08F9BE76CD677AEBD35D492490", + "base-metals-240967-2323100": "F919CEF794C73F02758BBD967346DBA0B53F6383153C7E29BD79F211CDA8C319", + "mmd-orespawn-245586-2323091": "91345E4B825AA06E05F470066F467AABA0C7A2804A8DBCA4D3CD1905ED53607C", + }, + "mmd": { + "modern-metals-244357-2533187": "B721359D37269D632DDA9ED1B7CEC6392EC295FB9C1111A47720B240622848D9", + "base-metals-240967-2533174": "51F04770C316E62D9ED3EF713144F02FA2EC899645813627091365E12F61C3EF", + "mmdlib-261744-2400405": "286149F4E8132535135C27285A750916D35AB3ECDDB28AE4475FC604D1FDF178", + "mmd-orespawn-245586-2533153": "D964148C20175E16CCEFAB02AE43A181A50DC08A1D636A77E59CFE8C8EA8D41A", + }, +} +# Enclose the molten blocks so the fixtures retain source states after the server ticks. +CONTAINERS = ["fill 5 99 5 9 102 9 minecraft:stone hollow", "fill 13 99 5 17 102 9 minecraft:stone hollow"] +CYANO_ORES = ["aluminum_ore", "chromium_ore", "tungsten_block", + "galvanizedsteel_ore", "nichrome_ore", "stainlesssteel_ore"] + + +def positions(family, original): + if family == "mmd": + # The public beta4.19 jar only registers fluid blocks/items in this stack. + return [("7 100 7", "aluminumbrass"), ("15 100 7", "titanium")] + brass = "alubrass" if original else "aluminumbrass" + return [(f"{x} 100 0", block) for x, block in enumerate(CYANO_ORES)] + [("7 100 7", brass)] + + +def chest(family, original): + if family == "mmd": + items = [("aluminumbrass", 1, 0), ("titanium", 1, 0)] + else: + items = [ + ("aluminum_ingot", 7, 0), ("titanium_pickaxe", 1, 17), ("plutonium_pickaxe", 1, 3), + ("aluminum_door_item" if original else "aluminum_door", 2, 0), + ("tungsten_fishingrod" if original else "tungsten_fishing_rod", 1, 4), + ("titanium_horsearmor" if original else "titanium_horse_armor", 1, 0), + ("nichrome_ore", 2, 0), ("alubrass" if original else "aluminumbrass", 1, 0), + ] + nbt = [f'{{Slot:{slot}b,id:"modernmetals:{item}",Count:{count}b,Damage:{damage}s}}' + for slot, (item, count, damage) in enumerate(items)] + if family == "cyano": + nbt.append('{Slot:8b,id:"forge:bucketFilled",Count:1b,Damage:0s,tag:{FluidName:"alubrass",Amount:1000}}') + return "{Items:[" + ",".join(nbt) + "]}" + + +def place(family): + blocks = [f"setblock {pos} modernmetals:{block}" for pos, block in positions(family, True)] + return CONTAINERS + blocks + [f"setblock 0 100 2 minecraft:chest 0 replace {chest(family, True)}"] + + +def verify(family, original): + blocks = [f"testforblock {pos} modernmetals:{block}" for pos, block in positions(family, original)] + return blocks + [f"testforblock 0 100 2 minecraft:chest -1 {chest(family, original)}"] + + +def run(java, directory, phase, setup, checks): + console = directory / (phase + "-console.log") + with console.open("wb") as log, subprocess.Popen( + [str(java), "-Xmx2G", "-jar", FORGE, "nogui"], + cwd=directory, stdin=subprocess.PIPE, stdout=log, stderr=subprocess.STDOUT + ) as process: + try: + deadline = time.monotonic() + 100 + while 'For help, type "help"' not in (output := console.read_text(errors="replace")): + if "Run the command /fml confirm" in output: + raise AssertionError(f"Forge requested permission to remove old entries: {console}") + if process.poll() is not None or time.monotonic() >= deadline: + raise AssertionError(f"Server did not reach the world: {console}") + time.sleep(0.25) + commands = setup + checks + ["save-all", "stop"] + process.communicate(("\n".join(commands) + "\n").encode("ascii"), timeout=60) + assert process.returncode == 0, console + finally: + if process.poll() is None: + process.kill() + process.wait() + assert console.read_text(errors="replace").count("Successfully found the block") == len(checks), console + print(f"{directory.name} {phase} passed {len(checks)} block and chest checks", flush=True) + + +def check(args, family): + jars = [] + for name, expected in PUBLIC_JARS[family].items(): + jar = args.public_jars / (name + ".jar") + assert digest(jar).upper() == expected, f"Public jar checksum mismatch: {jar}" + jars.append(jar) + source = args.output / (family + "-source") + prepare(source, args.template, jars) + run(args.java, source, "capture", place(family), verify(family, True)) + world = source / "world" + before = fingerprint(world) + specs = json.loads((ROOT / "gradle/dependencies.json").read_text()) + jars = [dependency(spec) for spec in specs if spec.get("runtime")] + target = args.output / (family + "-upgraded") + prepare(target, args.template, jars + [args.candidate], world) + try: + for phase in ("first", "reload"): + run(args.java, target, phase, [], verify(family, False)) + finally: + assert fingerprint(world) == before, "Original fixture was modified" + write_json(target / "receipt.json", {"passed": True, "candidate_sha256": digest(args.candidate), + "source_world_unchanged": True, "public_jars": PUBLIC_JARS[family]}) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + for name in ("java", "template", "output", "public-jars", "candidate"): + parser.add_argument("--" + name, required=True, type=lambda path: Path(path).resolve()) + parser.add_argument("--family", choices=tuple(PUBLIC_JARS)) + args = parser.parse_args() + for family in (args.family,) if args.family else PUBLIC_JARS: + check(args, family) + + +if __name__ == "__main__": + main() diff --git a/tools/validation/legacy110/run_packaged_client.py b/tools/validation/legacy110/run_packaged_client.py index 1f5533ff..ad7b48ff 100644 --- a/tools/validation/legacy110/run_packaged_client.py +++ b/tools/validation/legacy110/run_packaged_client.py @@ -1,10 +1,31 @@ """Run installed release jars on the obfuscated Forge client, in a disposable game directory.""" -import argparse,hashlib,json,os,shutil,subprocess,time,zipfile +import argparse,hashlib,json,os,shutil,struct,subprocess,time,zipfile,zlib from concurrent.futures import ThreadPoolExecutor from pathlib import Path from urllib.request import urlopen from run_runtime_checks import ROOT,dependency,FORGE +def install_ore_host_pack(game): + # A solid test colour makes the host/ore separation easy to see in a screenshot. + pack=game/'resourcepacks/ore-host-probe' + target=pack/'assets/minecraft/textures/blocks/stone.png' + target.parent.mkdir(parents=True,exist_ok=True) + (pack/'pack.mcmeta').write_text(json.dumps({'pack':{'pack_format':2,'description':'Ore host probe'}}),encoding='utf-8') + def chunk(name,data): + return struct.pack('>I',len(data))+name+data+struct.pack('>I',zlib.crc32(name+data)) + target.write_bytes(b'\x89PNG\r\n\x1a\n'+chunk(b'IHDR',struct.pack('>IIBBBBB',16,16,8,2,0,0,0)) + +chunk(b'IDAT',zlib.compress((b'\0'+bytes((57,180,142))*16)*16))+chunk(b'IEND',b'')) + +def configure_client(game,host_pack): + options=game/'options.txt' + lines=options.read_text(encoding='utf-8').splitlines() if options.is_file() else [] + # Do not let losing window focus pause the disposable world during screenshots. + if host_pack:install_ore_host_pack(game) + packs=['ore-host-probe'] if host_pack else [] + settings=['pauseOnLostFocus:false','resourcePacks:'+json.dumps(packs),'incompatibleResourcePacks:[]'] + keys=tuple(line.split(':',1)[0]+':' for line in settings) + options.write_text('\n'.join([line for line in lines if not line.startswith(keys)]+settings)+'\n',encoding='utf-8') + def prepare_assets(output,cache,metadata): """Use this version's verified index without overwriting a shared Gradle index.""" assets=output/'assets' @@ -32,10 +53,48 @@ def stage(spec): print('MODERN_METALS_CLIENT_ASSETS_VERIFIED',metadata['id'],len(unique),flush=True) return assets +def windows_allowed(library): + allowed='rules' not in library + for rule in library.get('rules',[]): + if not rule.get('os') or rule['os'].get('name')=='windows': + allowed=rule['action']=='allow' + return allowed + +def prepare_natives(output,cache,libraries): + # An Eclipse launch is not required to populate a shared natives directory. + natives=output/'natives' + natives.mkdir(exist_ok=True) + for library in libraries: + classifier=library.get('natives',{}).get('windows') + if not classifier or not windows_allowed(library):continue + spec=library['downloads']['classifiers'][classifier.replace('${arch}','64')] + group,artifact,version=library['name'].split(':') + name=Path(spec['path']).name + archive=output/'engine'/name + if not archive.is_file(): + cached=next((cache/'caches/modules-2/files-2.1'/group/artifact/version).glob(f'*/{name}'),None) + if cached and hashlib.sha1(cached.read_bytes()).hexdigest()==spec['sha1']: + shutil.copy2(cached,archive) + else: + with urlopen(spec['url'],timeout=60) as response:archive.write_bytes(response.read()) + assert hashlib.sha1(archive.read_bytes()).hexdigest()==spec['sha1'],name + with zipfile.ZipFile(archive) as jar: + for member in jar.namelist(): + if Path(member).name==member and member.endswith('.dll'): + (natives/member).write_bytes(jar.read(member)) + assert (natives/'lwjgl64.dll').is_file() + return natives + def main(): parser=argparse.ArgumentParser(description=__doc__) for name in ('java','cache','installer','template','output'):parser.add_argument('--'+name,type=Path,required=True) parser.add_argument('--phase',choices=['first','reload'],default='first') + parser.add_argument('--ore-host-pack',action='store_true',help='Replace vanilla stone with a test texture in this disposable client.') + parser.add_argument('--language',choices=['de_DE','en_US','ru_RU','zh_CN']) + parser.add_argument('--remote-port',type=int,help='Connect to a disposable server on loopback.') + parser.add_argument('--expected-disconnect',help='Expected text in a pre-world disconnect.') + parser.add_argument('--low-fantasy',action='store_true',help='Start the remote client in Low Fantasy.') + parser.add_argument('--mod-jar',type=Path,default=ROOT/'build/libs/ModernMetals-2.5.1.110021.jar') args=parser.parse_args() if args.phase=='first':args.output.mkdir(parents=True,exist_ok=False) assert hashlib.sha256(args.installer.read_bytes()).hexdigest().upper()=='664393C5A924B8F06CFB953903ABCF9FE5E99ECBE6AF8C7EA217339C766E519C' @@ -47,12 +106,7 @@ def main(): libraries.update({lib['name']:lib for lib in forge['libraries']}) classpath=[] for coordinate,lib in libraries.items(): - if lib.get('clientreq') is False:continue - if 'rules' in lib: - allowed=False - for rule in lib['rules']: - if not rule.get('os') or rule['os'].get('name')=='windows':allowed=rule['action']=='allow' - if not allowed:continue + if lib.get('clientreq') is False or not windows_allowed(lib):continue group,artifact,version,*classifier=coordinate.split(':') if group=='net.minecraftforge' and artifact=='forge': # The server distribution's manifest names its neighboring server jar. @@ -73,12 +127,28 @@ def main(): (args.output/'mods').mkdir() specs=json.loads((ROOT/'gradle/dependencies.json').read_text()) jars=[dependency(s) for s in specs if s.get('runtime')] - jars+=[ROOT/'build/libs/ModernMetals-2.5.1.110021.jar',ROOT/'build/test-mods/modernmetals-probe-packaged.jar'] + jars+=[args.mod_jar,ROOT/'build/test-mods/modernmetals-probe-packaged.jar'] for jar in jars:shutil.copy2(jar,args.output/'mods'/jar.name) - natives=args.cache/'caches/minecraftforge/forgegradle/slime-launcher/cache/net/minecraftforge/forge/1.10.2-12.18.3.2511/natives' + natives=prepare_natives(args.output,args.cache,vanilla['libraries']) assets=prepare_assets(args.output,args.cache,vanilla['assetIndex']) + configure_client(args.output,args.ore_host_pack) + if args.language: + options=args.output/'options.txt' + lines=[line for line in options.read_text(encoding='utf-8').splitlines() if not line.startswith('lang:')] + options.write_text('\n'.join(lines+[f'lang:{args.language}'])+'\n',encoding='utf-8') + if args.remote_port and args.low_fantasy: + config=args.output/'config/ModernMetals.cfg' + config.parent.mkdir(exist_ok=True) + config.write_text('general {\n S:contentMode=low_fantasy\n}\n',encoding='utf-8') + remote=[] + if args.remote_port: + remote=[f'-Dmodern.remoteServer=127.0.0.1:{args.remote_port}', + f'-Dmodern.expectedDisconnect={args.expected_disconnect or ""}'] command=[str(args.java),'-Xmx3G',f'-Djava.library.path={natives}',f'-Dmodern.phase={args.phase}', '-Dmodern.saved=true','-Dmodern.client=true','-Dmodern.lowFantasy='+str(args.phase=='reload').lower(), + '-Dmodern.oreHostPack='+str(args.ore_host_pack).lower(), + '-Dmodern.language='+(args.language or 'en_US'), + *remote, '-cp',os.pathsep.join(map(str,classpath)),forge['mainClass'], '--username','ModernCheck','--uuid','00000000000000000000000000000001','--accessToken','0', '--version',forge['id'],'--gameDir',str(args.output),'--assetsDir',str(assets),'--assetIndex',vanilla['assetIndex']['id'], @@ -86,7 +156,7 @@ def main(): started=time.time_ns() with (args.output/(args.phase+'-console.log')).open('wb') as log: result=subprocess.run(command,cwd=args.output,stdout=log,stderr=subprocess.STDOUT,timeout=300) - for suffix in ('client','modern'): + for suffix in (('client',) if args.remote_port else ('client','modern')): report=args.output/(args.phase+'-'+suffix+'.json') assert report.is_file() and report.stat().st_mtime_ns>started,report assert json.loads(report.read_text())['passed'],report diff --git a/tools/validation/legacy110/run_packaged_suite.py b/tools/validation/legacy110/run_packaged_suite.py index c71b34b9..f75e8bfe 100644 --- a/tools/validation/legacy110/run_packaged_suite.py +++ b/tools/validation/legacy110/run_packaged_suite.py @@ -44,7 +44,7 @@ def check(target,expected=None,properties=None,sample=False,saved=False): fresh=setup('native-fresh') (fresh/'config').mkdir(exist_ok=True) (fresh/'config/BaseMetals.cfg').write_text('general {\n S:contentMode=low_fantasy\n}\n',encoding='utf-8') - report=check(fresh,{'ores':native['ores']},properties={'modern.lowFantasy':'false'},sample=True,saved=True) + report=check(fresh,{'ores':native['ores']},properties={'modern.lowFantasy':'false','modern.trades':'true'},sample=True,saved=True) base_profile=report['profile'] assert len([key for key in base_profile['ores'] if key.startswith('modernmetals:')])==17 before=fingerprint(fresh/'world') @@ -132,7 +132,13 @@ def check(target,expected=None,properties=None,sample=False,saved=False): (low/'config').mkdir(exist_ok=True) (low/'config/ModernMetals.cfg').write_text('general {\n S:contentMode=low_fantasy\n}\n',encoding='utf-8') (low/'config/BaseMetals.cfg').write_text('general {\n S:contentMode=high_fantasy\n}\n',encoding='utf-8') - check(low,properties={'modern.lowFantasy':'true'},saved=True) + check(low,properties={'modern.lowFantasy':'true','modern.trades':'true'},saved=True) + for mode in ('high','low'): + trade_off=setup(f'{mode}-fantasy-trades-disabled') + config=trade_off/'config/ModernMetals.cfg' + config.parent.mkdir() + config.write_text(f'general {{\n S:contentMode={mode}_fantasy\n B:enableVillagerTrades=false\n}}\n',encoding='utf-8') + run(args.java,trade_off,'first',{'modern.lowFantasy':str(mode=='low').lower(),'modern.trades':'false'}) switched=setup('high-to-low-existing-world',fresh/'world') (switched/'config').mkdir(exist_ok=True) (switched/'config/ModernMetals.cfg').write_text('general {\n S:contentMode=low_fantasy\n}\n',encoding='utf-8') @@ -165,7 +171,7 @@ def check(target,expected=None,properties=None,sample=False,saved=False): verify(args.java,args.template,args.output,dependency(next(s for s in specs if s['id']=='basemetals'),args.mirror), dependency(next(s for s in specs if s['id']=='orespawn'),args.mirror),ROOT/'build/libs/ModernMetals-2.5.1.110021.jar') assert fingerprint(fresh/'world')==before,'A source fixture world changed' - write_json(args.output/'qualification.json',{'passed':True,'scenarios':16,'source_world_unchanged':True}) + write_json(args.output/'qualification.json',{'passed':True,'scenarios':18,'source_world_unchanged':True}) print('MODERN_METALS_PACKAGED_SUITE_PASS',flush=True) if __name__=='__main__':main() diff --git a/tools/validation/legacy110/runtime-probe/review/modern/ClientChecks.java b/tools/validation/legacy110/runtime-probe/review/modern/ClientChecks.java index 702b6cd5..c6fe0159 100644 --- a/tools/validation/legacy110/runtime-probe/review/modern/ClientChecks.java +++ b/tools/validation/legacy110/runtime-probe/review/modern/ClientChecks.java @@ -11,8 +11,11 @@ import java.util.concurrent.Future; 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.multiplayer.GuiConnecting; +import net.minecraft.client.multiplayer.ServerData; import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.item.ItemStack; import net.minecraft.world.GameType; @@ -39,11 +42,59 @@ acceptableRemoteVersions="*",dependencies="required-after:modernmetalsprobe") public final class ClientChecks { @Mod.EventHandler public void init(final FMLInitializationEvent event) { - if (Boolean.getBoolean("modern.client")) MinecraftForge.EVENT_BUS.register(new Checks()); + if (!Boolean.getBoolean("modern.client")) return; + final String server = System.getProperty("modern.remoteServer"); + MinecraftForge.EVENT_BUS.register(server == null ? new Checks() : new RemoteCheck(server)); } private static void require(final boolean pass, final String detail) { if (!pass) throw new AssertionError(detail); } + + public static final class RemoteCheck { + private final String address; + private final long deadline = System.currentTimeMillis() + 90000; + private boolean connecting; + private boolean finished; + + RemoteCheck(final String address) { this.address = address; } + + @SubscribeEvent public void tick(final TickEvent.ClientTickEvent event) throws Exception { + if (event.phase != TickEvent.Phase.END || finished) return; + final Minecraft mc = Minecraft.getMinecraft(); + if (!connecting && mc.currentScreen instanceof GuiMainMenu) { + mc.displayGuiScreen(new GuiConnecting(mc.currentScreen, mc, new ServerData("Disposable Forge", address, false))); + connecting = true; + return; + } + final String expectedDisconnect = System.getProperty("modern.expectedDisconnect", ""); + final boolean expectRejection = !expectedDisconnect.isEmpty(); + if (mc.world != null && mc.player != null) { + finish(mc, !expectRejection, "Dedicated server world entered"); + } else if (connecting && mc.currentScreen instanceof GuiDisconnected) { + final String reason = disconnectReason((GuiDisconnected) mc.currentScreen); + finish(mc, expectRejection && reason.contains(expectedDisconnect), reason); + } else if (System.currentTimeMillis() >= deadline) { + finish(mc, false, "Dedicated server login timed out"); + } + } + + private static String disconnectReason(final GuiDisconnected screen) throws Exception { + for (final java.lang.reflect.Field field : GuiDisconnected.class.getDeclaredFields()) { + if (field.getType() == net.minecraft.util.text.ITextComponent.class) { + field.setAccessible(true); + return ((net.minecraft.util.text.ITextComponent) field.get(screen)).getUnformattedText(); + } + } + throw new AssertionError("Disconnect reason field missing"); + } + + private void finish(final Minecraft mc, final boolean pass, final String detail) throws Exception { + Checks.screenshot(mc, "dedicated-login.png"); + Checks.report(pass, detail); + finished = true; + mc.shutdown(); + } + } public static final class Checks { private long started=System.currentTimeMillis(); private int ticks; @@ -63,9 +114,17 @@ public static final class Checks { screen=(GuiConfig)factory.mainConfigGuiClass().getConstructor(GuiScreen.class).newInstance(parent); mc.displayGuiScreen(screen); state=1;ticks=0; } else if(state==1 && ++ticks>=20) { - require(screen.parentScreen==parent && screen.configElements.size()==22,"Forge config parent or fantasy/material options incorrect"); + require(screen.parentScreen==parent && screen.configElements.size()==23,"Forge config parent or settings incorrect"); require(screen.allRequireMcRestart,"Registry switches must require a restart"); require(!screen.title.startsWith("config."),"Untranslated config title"); + final String locale = System.getProperty("modern.language", "en_US"); + require(locale.equals(mc.gameSettings.language), "Minecraft did not load language " + locale); + if (!"en_US".equals(locale)) { + require(!"Fantasy Level".equals(net.minecraft.client.resources.I18n.format("config.modernmetals.content_mode")), + "Fantasy selector fell back to English in " + locale); + require(!"High Fantasy".equals(net.minecraft.client.resources.I18n.format("high_fantasy")), + "Fantasy value fell back to English in " + locale); + } for(final net.minecraftforge.fml.client.config.IConfigElement element:screen.configElements) require(net.minecraft.client.resources.I18n.hasKey(element.getLanguageKey()),"Untranslated material label: "+element.getName()); final String startupMode=Boolean.getBoolean("modern.lowFantasy")?"low_fantasy":"high_fantasy"; @@ -75,9 +134,11 @@ public static final class Checks { mode(screen).valueButtonPressed(0); final BooleanEntry entry=entry(screen,"EnableBoron"); entry.valueButtonPressed(0); + entry(screen,"enableVillagerTrades").valueButtonPressed(0); invoke(screen,"keyTyped",new Class[]{char.class,int.class},'\0',1); require(mc.currentScreen==parent,"Escape did not return to Forge parent"); require(Config.getConfiguration().get("Metals","EnableBoron",true).getBoolean(),"Escape saved a discarded switch"); + require(Config.getConfiguration().get("General","enableVillagerTrades",true).getBoolean(),"Escape saved discarded trade settings"); require(Config.getConfiguration().getCategory("General").get("contentMode").getString().equals(startupMode),"Escape saved a discarded fantasy selection"); final WorldSettingsExtension extension=WorldSettingsExtensionRegistry.extensions().stream() .filter(e->"modernmetals".equals(e.id().getResourceDomain())).findFirst().orElse(null); @@ -85,15 +146,18 @@ public static final class Checks { screen=(GuiConfig)extension.createScreen(parent); mc.displayGuiScreen(screen);state=2;ticks=0; } else if(state==2 && ++ticks>=20) { - require(screen.parentScreen==parent && screen.configElements.size()==22,"OreSpawn config parent or options incorrect"); + require(screen.parentScreen==parent && screen.configElements.size()==23,"OreSpawn config parent or options incorrect"); screenshot(mc,"orespawn-child-mods-config.png"); mode(screen).valueButtonPressed(0); screen.entryList.scrollBy(10000); require(screen.entryList.getAmountScrolled()>0,"Material list cannot scroll"); entry(screen,"EnableBoron").valueButtonPressed(0); + entry(screen,"enableVillagerTrades").valueButtonPressed(0); invoke(screen,"actionPerformed",new Class[]{GuiButton.class},new GuiButton(2000,0,0,"Done")); require(!Config.getConfiguration().get("Metals","EnableBoron",true).getBoolean(),"Done did not save the switch"); require(Config.Options.enableBoron && Materials.hasMaterial("boron"),"GUI rebuilt live registries"); + require(!Config.getConfiguration().get("General","enableVillagerTrades",true).getBoolean() + && Config.Options.enableVillagerTrades,"Trade settings did not save for the next restart"); final String pendingMode=Boolean.getBoolean("modern.lowFantasy")?"high_fantasy":"low_fantasy"; require(Config.getConfiguration().getCategory("General").get("contentMode").getString().equals(pendingMode),"Done did not save the fantasy selection"); require(ContentPolicy.active().lowFantasy()==Boolean.getBoolean("modern.lowFantasy"),"GUI applied fantasy recipes without a restart"); @@ -103,11 +167,13 @@ public static final class Checks { screen=new zone.moddev.mc.modernmetals.client.ModernMetalsConfigScreen(parent); mc.displayGuiScreen(screen); entry(screen,"EnableBoron").valueButtonPressed(0); + entry(screen,"enableVillagerTrades").valueButtonPressed(0); invoke(screen,"actionPerformed",new Class[]{GuiButton.class},new GuiButton(2000,0,0,"Done")); mc.displayGuiScreen(parent); mc.launchIntegratedServer("modern-check","Modern Metals disposable checks",new WorldSettings(8675309L,GameType.CREATIVE,false,false,WorldType.DEFAULT)); state=3; } else if(state==3 && mc.world!=null && mc.player!=null && check==null) { + OreOverlayChecks.verify(mc); for(final net.minecraft.block.Block block:net.minecraftforge.fml.common.registry.ForgeRegistries.BLOCKS.getValues()) { if(!"modernmetals".equals(block.getRegistryName().getResourceDomain())) continue; for(final net.minecraft.block.state.IBlockState variant:block.getBlockState().getValidStates()) @@ -136,11 +202,21 @@ public static final class Checks { } } check=mc.getIntegratedServer().addScheduledTask(()->{ - try { ModernMetalsProbe.run(mc.getIntegratedServer()); } + try { + ModernMetalsProbe.run(mc.getIntegratedServer()); + OreOverlayChecks.placeDisplay(mc.getIntegratedServer()); + } catch(Exception failure) {throw new RuntimeException(failure);} }); - } else if(check!=null && check.isDone()) { - check.get(); screenshot(mc,"integrated-world.png"); report(true,"Forge Mods and OreSpawn config, fantasy selector save/cancel and full restart, material switches, baked models and integrated saved world"); + } else if(state==3 && check!=null && check.isDone()) { + check.get(); + mc.displayGuiScreen(null); + mc.gameSettings.hideGUI=true; + state=4; + ticks=0; + } else if(state==4 && ++ticks>=40) { + screenshot(mc,"ore-overlay-display.png"); + report(true,"Both config screens, fantasy restart, baked ore block/item overlays, stone host and integrated saved world"); finished=true;mc.shutdown(); } if(System.currentTimeMillis()-started>240000) throw new AssertionError("Client check timed out, state="+state); diff --git a/tools/validation/legacy110/runtime-probe/review/modern/ModernMetalsProbe.java b/tools/validation/legacy110/runtime-probe/review/modern/ModernMetalsProbe.java index a7205725..6ac9595b 100644 --- a/tools/validation/legacy110/runtime-probe/review/modern/ModernMetalsProbe.java +++ b/tools/validation/legacy110/runtime-probe/review/modern/ModernMetalsProbe.java @@ -102,6 +102,16 @@ public static void run(final MinecraftServer server) throws Exception { catalog.add(name, entry); } report.add("materials", catalog); + if (!Boolean.getBoolean("modern.baseline") && Materials.hasMaterial("aluminumbrass") + && !Loader.isModLoaded("tconstruct")) { + final net.minecraft.nbt.NBTTagCompound savedFluid = new net.minecraft.nbt.NBTTagCompound(); + savedFluid.setString("FluidName", "alubrass"); + savedFluid.setInteger("Amount", 1000); + final net.minecraftforge.fluids.FluidStack legacy = net.minecraftforge.fluids.FluidStack.loadFluidStackFromNBT(savedFluid); + check(legacy != null && legacy.amount == 1000 + && legacy.getFluid().getBlock() == Materials.getMaterialByName("aluminumbrass").getFluidBlock(), + "A saved 0.11.0 aluminum brass bucket no longer resolves", failures); + } for(final String[] alias:new String[][]{{"chromium","Chrome"},{"chromium","Chromium"},{"tungsten","Wolfram"},{"tungsten","Tungsten"},{"aluminum","Aluminium"}}) { if(!Materials.hasMaterial(alias[0])) continue; boolean found=false; @@ -125,7 +135,8 @@ public static void run(final MinecraftServer server) throws Exception { if(output!=null && output.getItem()==material.getItem(Names.PICKAXE)) recipe=true; } check(recipe==(!low || suitable),"Fantasy mode pickaxe recipe incorrect: "+name,failures); - check(material.hasItem(Names.PICKAXE) && material.hasBlock(Names.ORE)==material.hasOre(),"Fantasy mode changed registry identities: "+name,failures); + final boolean hasOre = material.hasOre() || name.equals("stainlesssteel") || name.equals("galvanizedsteel"); + check(material.hasItem(Names.PICKAXE) && material.hasBlock(Names.ORE)==hasOre,"Fantasy mode changed registry identities: "+name,failures); } if(low) { for(final net.minecraft.item.crafting.IRecipe recipe:CraftingManager.getInstance().getRecipeList()) { @@ -140,6 +151,7 @@ public static void run(final MinecraftServer server) throws Exception { } } } + if (System.getProperty("modern.trades") != null) checkTrades(failures); OptionalIntegrationChecks.run(failures); final WorldServer world = server.worldServerForDimension(0); for (final String[] alloy : new String[][] {{"aluminumbrass","aluminum","brass"}, @@ -264,5 +276,39 @@ private static void saved(final WorldServer world, final String phase, final Jso } world.getChunkFromBlockCoords(pos).setChunkModified(); } + private static void checkTrades(final JsonArray failures) { + final net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession smith = + net.minecraftforge.fml.common.registry.VillagerRegistry.instance().getRegistry() + .getValue(new ResourceLocation("minecraft:smith")); + final net.minecraft.village.MerchantRecipeList offers = new net.minecraft.village.MerchantRecipeList(); + final java.util.Random random = new java.util.Random(8675309L); + for (int career = 1; career <= 3; career++) { + for (int level = 0; level < 8; level++) { + final java.util.List trades = + smith.getCareer(career).getTrades(level); + if (trades != null) trades.forEach(trade -> trade.modifyMerchantRecipeList(offers, random)); + } + } + int modern = 0; + int base = 0; + final zone.moddev.mc.modernmetals.content.ContentPolicy policy = + zone.moddev.mc.modernmetals.content.ContentPolicy.active(); + for (final net.minecraft.village.MerchantRecipe offer : offers) { + for (final ItemStack stack : new ItemStack[] { + offer.getItemToBuy(), offer.getSecondItemToBuy(), offer.getItemToSell() }) { + if (stack == null || stack.getItem().getRegistryName() == null) continue; + final String domain = stack.getItem().getRegistryName().getResourceDomain(); + if ("modernmetals".equals(domain)) { + modern++; + check(policy.allows(stack), "Fantasy mode allowed a restricted trade: " + stack, failures); + } else if ("basemetals".equals(domain)) { + base++; + } + } + } + check((modern > 0) == Boolean.getBoolean("modern.trades"), "Modern Metals trade switch ignored", failures); + check(base > 0, "Modern Metals settings removed Base Metals trades", failures); + } + private static void check(final boolean pass, final String detail, final JsonArray failures) { if (!pass) failures.add(new JsonPrimitive(detail)); } } diff --git a/tools/validation/legacy110/runtime-probe/review/modern/OreOverlayChecks.java b/tools/validation/legacy110/runtime-probe/review/modern/OreOverlayChecks.java new file mode 100644 index 00000000..3f3326a3 --- /dev/null +++ b/tools/validation/legacy110/runtime-probe/review/modern/OreOverlayChecks.java @@ -0,0 +1,104 @@ +package review.modern; + +import com.mcmoddev.lib.data.Names; +import com.mcmoddev.lib.init.Materials; +import java.util.List; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.WorldServer; +import net.minecraftforge.fml.common.registry.ForgeRegistries; +import net.minecraftforge.oredict.OreDictionary; + +/** Checks the installed client's baked models, including the inventory forms. */ +final class OreOverlayChecks { + private static final String STONE = "minecraft:blocks/stone"; + private static final int TEST_STONE = 0xFF39B48E; + + static void verify(Minecraft minecraft) { + final IBakedModel missing = minecraft.getRenderItem().getItemModelMesher().getModelManager().getMissingModel(); + int overlaid = 0; + int fallback = 0; + for (com.mcmoddev.lib.material.MMDMaterial material : Materials.getMaterialsByMod("modernmetals")) { + if (!material.hasBlock(Names.ORE)) continue; + final Block ore = material.getBlock(Names.ORE); + final IBlockState state = ore.getDefaultState(); + final Item item = Item.getItemFromBlock(ore); + final String name = material.getName() + "_ore"; + require(ore.getRegistryName().equals(new ResourceLocation("modernmetals", name)), "Ore registry ID changed: " + name); + require(ore.getRegistryName().equals(item.getRegistryName()), "Ore item registry ID changed: " + name); + require(OreDictionary.getOres("ore" + material.getCapitalizedName()).stream().anyMatch(s -> s.getItem() == item), + "Ore Dictionary entry missing: " + name); + final boolean thorium = name.equals("thorium_ore"); + require(ore.getBlockLayer() == (thorium ? BlockRenderLayer.SOLID : BlockRenderLayer.CUTOUT_MIPPED), + "Wrong render layer: " + name); + final IBakedModel blockModel = minecraft.getBlockRendererDispatcher().getBlockModelShapes().getModelForState(state); + final IBakedModel itemModel = minecraft.getRenderItem().getItemModelMesher().getItemModel(new ItemStack(item)); + require(blockModel != missing && itemModel != missing, "Missing baked ore block or item: " + name); + verifyModel(blockModel, state, name, thorium); + verifyModel(itemModel, null, name, thorium); + if (thorium) fallback++; else overlaid++; + } + require(overlaid == 19 && fallback == 1, "Unexpected registered ore set: " + overlaid + " overlays, " + fallback + " fallback"); + final TextureAtlasSprite stone = minecraft.getTextureMapBlocks().getAtlasSprite(STONE); + require((stone.getFrameTextureData(0)[0][0] == TEST_STONE) == Boolean.getBoolean("modern.oreHostPack"), + "The expected stone resource pack was not applied"); + System.out.println("MODERN_METALS_ORE_OVERLAYS_PASS ores=" + overlaid + " fallback=" + fallback + + " hostPack=" + Boolean.getBoolean("modern.oreHostPack")); + } + + private static void verifyModel(IBakedModel model, IBlockState state, String name, boolean thorium) { + final String base = thorium ? "modernmetals:blocks/thorium_ore" : STONE; + final String overlay = "modernmetals:blocks/ore_overlays/" + name; + require(base.equals(model.getParticleTexture().getIconName()), "Wrong particles: " + name); + for (EnumFacing face : EnumFacing.values()) { + final List quads = model.getQuads(state, face, 0); + require(quads.size() == (thorium ? 1 : 2), "Wrong face count: " + name + " " + face); + verifyFace(quads, face, base, 0.0F); + if (!thorium) verifyFace(quads, face, overlay, 0.05F / 16.0F); + } + } + + private static void verifyFace(List quads, EnumFacing face, String texture, float offset) { + final BakedQuad quad = quads.stream().filter(q -> texture.equals(q.getSprite().getIconName())) + .findFirst().orElseThrow(() -> new AssertionError("Missing baked sprite: " + texture)); + final int axis = face.getFrontOffsetX() != 0 ? 0 : face.getFrontOffsetY() != 0 ? 1 : 2; + final float expected = face.getAxisDirection() == EnumFacing.AxisDirection.POSITIVE ? 1.0F + offset : -offset; + final int[] data = quad.getVertexData(); + for (int vertex = 0; vertex < 4; vertex++) { + require(Math.abs(Float.intBitsToFloat(data[vertex * (data.length / 4) + axis]) - expected) < 0.0001F, + "Wrong face depth for " + texture + " " + face); + } + } + + static void placeDisplay(MinecraftServer server) { + final WorldServer world = server.worldServerForDimension(0); + for (int x = 0; x < 5; x++) { + for (int z = -5; z <= 0; z++) { + world.setBlockState(new BlockPos(x, 199, z), Blocks.STONE.getDefaultState()); + } + } + final String[] ores = {"aluminum_ore", "boron_ore", "rutile_ore", "thorium_ore"}; + for (int x = 0; x < ores.length; x++) { + final Block ore = ForgeRegistries.BLOCKS.getValue(new ResourceLocation("modernmetals", ores[x])); + world.setBlockState(new BlockPos(x, 200, 0), ore.getDefaultState()); + } + world.setBlockState(new BlockPos(4, 200, 0), Blocks.STONE.getDefaultState()); + server.getPlayerList().getPlayers().get(0).connection.setPlayerLocation(2.5, 200, -4, 0, 13); + } + + private static void require(boolean condition, String detail) { + if (!condition) throw new AssertionError(detail); + } +} diff --git a/update.json b/update.json index 34cccc7c..4e511647 100644 --- a/update.json +++ b/update.json @@ -1,9 +1,9 @@ { - "homepage": "http://minecraft.curseforge.com/projects/modern-metals", + "homepage": "https://www.curseforge.com/minecraft/mc-mods/modern-metals/files/all?version=1.10.2", "promos": { "1.11.2-latest": "0.0.0", "1.11-latest": "0.0.0", - "1.10.2-latest": "0.0.0", + "1.10.2-latest": "2.5.0-beta4", "1.10-latest": "0.0.0", "1.9.4-latest": "0.0.0", "1.9-latest": "0.11.0", @@ -15,7 +15,7 @@ "1.6.4-latest": "0.0.0", "1.11.2-recommended": "0.0.0", "1.11-recommended": "0.0.0", - "1.10.2-recommended": "0.0.0", + "1.10.2-recommended": "2.5.0-beta4", "1.10-recommended": "0.0.0", "1.9.4-recommended": "0.0.0", "1.9-recommended": "0.11.0", @@ -33,7 +33,7 @@ "0.0.0": "No Release" }, "1.10.2": { - "0.0.0": "No Release" + "2.5.0-beta4": "Modern Metals 2.5.0-beta4.19 for Minecraft 1.10.2" }, "1.10": { "0.0.0": "No Release" From 2ae9f9c7bc5a2ca6d57ca02e8a9a69db19eb4dde Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Sat, 7 Nov 2026 22:08:14 +0000 Subject: [PATCH 2/3] Keep the release version at the start of the changelog --- CHANGELOG.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index f5e3e1d5..bf93bcb5 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,4 +1,4 @@ -Modern Metals 2.5.1.110021 for Minecraft 1.10.2 +2.5.1.110021 for 1.10.2 This brings the 1.10.2 branch up to date. Use Java 8, Forge 12.18.3.2511 or later for 1.10.2, Base Metals 2.5.1.110021 and MMD OreSpawn 4.1.2.110021. From 80c46372a186c11ddab9890e6cbd545a78f41ce6 Mon Sep 17 00:00:00 2001 From: JohnBraham Date: Sat, 7 Nov 2026 22:25:52 +0000 Subject: [PATCH 3/3] Package the legacy API list consistently --- build.gradle | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/build.gradle b/build.gradle index 4f2ff429..744c801d 100644 --- a/build.gradle +++ b/build.gradle @@ -57,6 +57,13 @@ def normalizeText = { details -> eof: FixCrLfFilter.AddAsisRemove.newInstance('asis')) } +// Preserve the tested game jar's line endings for this compatibility list. +def legacyApiList = 'META-INF/modernmetals-legacy-api.list' +def normalizeLegacyApi = { details -> + details.filter(FixCrLfFilter, eol: FixCrLfFilter.CrLf.newInstance('crlf'), + eof: FixCrLfFilter.AddAsisRemove.newInstance('asis')) +} + def developmentOutput = layout.buildDirectory.dir('forge10-development/main') def prepareDevelopmentMod = tasks.register('prepareDevelopmentMod', Sync) { group = 'ide' @@ -150,6 +157,7 @@ tasks.named('processResources', ProcessResources) { filesMatching('mcmod.info') { expand version: project.version, mcversion: project.minecraft_version } rename '(.+_at.cfg)', 'META-INF/$1' filesMatching(textPatterns, normalizeText) + filesMatching(legacyApiList, normalizeLegacyApi) } tasks.named('jar', Jar) { @@ -165,6 +173,7 @@ tasks.named('jar', Jar) { tasks.named(name, Jar) { filteringCharset = 'UTF-8' filesMatching(textPatterns, normalizeText) + filesMatching(legacyApiList, normalizeLegacyApi) } }