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..bf93bcb5 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,16 +1,14 @@ 2.5.1.110021 for 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..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,10 +173,12 @@ tasks.named('jar', Jar) { tasks.named(name, Jar) { filteringCharset = 'UTF-8' filesMatching(textPatterns, normalizeText) + filesMatching(legacyApiList, normalizeLegacyApi) } } 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"