diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/depmodules/LanguageModule.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/depmodules/LanguageModule.java index 6e7c942ac..7fb5745b8 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/depmodules/LanguageModule.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/depmodules/LanguageModule.java @@ -20,7 +20,7 @@ package nova.core.wrapper.mc.forge.v17.depmodules; -import nova.core.util.registry.LanguageManager; +import nova.core.language.LanguageManager; import nova.core.wrapper.mc.forge.v17.util.MCLanguageManager; import se.jbee.inject.bind.BinderModule; diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/util/MCLanguageManager.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/util/MCLanguageManager.java index e541506f2..398b6bb4d 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/util/MCLanguageManager.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/util/MCLanguageManager.java @@ -21,33 +21,56 @@ package nova.core.wrapper.mc.forge.v17.util; import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.registry.LanguageRegistry; import net.minecraft.util.StatCollector; -import nova.core.util.registry.LanguageManager; +import nova.core.event.LanguageEvent; +import nova.core.event.bus.EventBus; +import nova.core.language.LanguageManager; +import nova.core.wrapper.mc.forge.v17.launcher.ForgeLoadable; +import nova.core.wrapper.mc.forge.v17.launcher.NovaMinecraft; import nova.internal.core.Game; /** * @author Calclavia */ -public class MCLanguageManager extends LanguageManager { +public class MCLanguageManager extends LanguageManager implements ForgeLoadable { @Override public void register(String language, String key, String value) { - LanguageRegistry.instance().addStringLocalization(key, language, value); + super.register(language, key, value); + } + + public MCLanguageManager() { + NovaMinecraft.registerWrapper(this); } @Override public String getCurrentLanguage() { - return FMLCommonHandler.instance().getCurrentLanguage(); + return FMLCommonHandler.instance().getCurrentLanguage().replace('_', '-'); } @Override public String translate(String key) { - return StatCollector.translateToLocal(key); + String value = super.translate(key); + if (value.equals(key)) + value = StatCollector.translateToLocal(key); + return value; } @Override - public void init() { - Game.events().publish(new Init(this)); + @SuppressWarnings("deprecation") + public void preInit(FMLPreInitializationEvent evt) { + this.languageMap.forEach((language, map) -> { + String lang = language.replace('-', '_'); + map.forEach((key, value) -> LanguageRegistry.instance().addStringLocalization(key, lang, value)); + }); + + Game.events().on(LanguageEvent.RegisterTranslation.class).withPriority(EventBus.PRIORITY_LOW).bind(this::register); + } + + @SuppressWarnings("deprecation") + public void register(LanguageEvent.RegisterTranslation evt) { + LanguageRegistry.instance().addStringLocalization(evt.key, evt.language.replace('-', '_'), evt.value); } } diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/backward/BWBlock.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/backward/BWBlock.java index ec97d9b62..2bfa07ac6 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/backward/BWBlock.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/backward/BWBlock.java @@ -166,4 +166,14 @@ public void load(Data data) { tileEntity.writeToNBT(Game.natives().toNative(data)); } } + + @Override + public String getLocalizedName() { + return mcBlock.getLocalizedName(); + } + + @Override + public String getUnlocalizedName() { + return mcBlock.getUnlocalizedName(); + } } diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java index 7690371cb..5cffd733c 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java @@ -117,7 +117,6 @@ public FWBlock(BlockFactory factory) { this.stepSound = soundTypeStone; } this.blockClass = dummy.getClass(); - this.setBlockName(dummy.getID()); // Recalculate super constructor things after loading the block properly this.opaque = isOpaqueCube(); @@ -402,7 +401,12 @@ public int isProvidingStrongPower(IBlockAccess access, int x, int y, int z, int @Override public String getUnlocalizedName() { - return super.getUnlocalizedName().replaceFirst("tile", "block"); + return factory.getUnlocalizedName(); + } + + @Override + public String getLocalizedName() { + return factory.getLocalizedName(); } /** diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItem.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItem.java index df0eccf39..f9fa468a5 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItem.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItem.java @@ -95,6 +95,16 @@ public net.minecraft.item.ItemStack makeItemStack(int stackSize) { return result; } + @Override + public String getLocalizedName() { + return this.item.getItemStackDisplayName(makeItemStack(count())); + } + + @Override + public String getUnlocalizedName() { + return this.item.getUnlocalizedName(makeItemStack(count())); + } + @Override public String toString() { return getID(); diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItemFactory.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItemFactory.java index 0e07b06b6..c994ee58f 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItemFactory.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItemFactory.java @@ -52,6 +52,11 @@ public int getMeta() { return meta; } + @Override + public String getUnlocalizedName() { + return this.item.getUnlocalizedName(); + } + @Override public Item build(Data data) { int meta = (Integer) data.getOrDefault("damage", this.meta); diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItem.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItem.java index 7c4e8c8ec..3fe40567e 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItem.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItem.java @@ -38,7 +38,6 @@ public class FWItem extends net.minecraft.item.Item implements ItemWrapperMethod public FWItem(ItemFactory item) { this.itemFactory = item; - setUnlocalizedName(item.getID()); setMaxStackSize(item.build().getMaxCount()); } @@ -81,4 +80,19 @@ public int getColorFromItemStack(ItemStack p_82790_1_, int p_82790_2_) { public void registerIcons(IIconRegister ir) { } + + @Override + public String getUnlocalizedName() { + return getItemFactory().getUnlocalizedName(); + } + + @Override + public String getUnlocalizedName(ItemStack stack) { + return ItemConverter.instance().toNova(stack).getUnlocalizedName(); + } + + @Override + public String getItemStackDisplayName(ItemStack stack) { + return ItemConverter.instance().toNova(stack).getLocalizedName(); + } } diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItemBlock.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItemBlock.java index b0e24dfb4..66ade96cd 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItemBlock.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItemBlock.java @@ -78,4 +78,19 @@ public int getColorFromItemStack(ItemStack p_82790_1_, int p_82790_2_) { public void registerIcons(IIconRegister ir) { } + + @Override + public String getUnlocalizedName() { + return getItemFactory().getUnlocalizedName(); + } + + @Override + public String getUnlocalizedName(ItemStack stack) { + return ItemConverter.instance().toNova(stack).getUnlocalizedName(); + } + + @Override + public String getItemStackDisplayName(ItemStack stack) { + return ItemConverter.instance().toNova(stack).getLocalizedName(); + } } diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/depmodules/LanguageModule.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/depmodules/LanguageModule.java index 177866309..efc271808 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/depmodules/LanguageModule.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/depmodules/LanguageModule.java @@ -20,7 +20,7 @@ package nova.core.wrapper.mc.forge.v18.depmodules; -import nova.core.util.registry.LanguageManager; +import nova.core.language.LanguageManager; import nova.core.wrapper.mc.forge.v18.util.MCLanguageManager; import se.jbee.inject.bind.BinderModule; diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/util/MCLanguageManager.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/util/MCLanguageManager.java index 9637b529b..a12154233 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/util/MCLanguageManager.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/util/MCLanguageManager.java @@ -22,32 +22,55 @@ import net.minecraft.util.StatCollector; import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.registry.LanguageRegistry; -import nova.core.util.registry.LanguageManager; +import nova.core.event.LanguageEvent; +import nova.core.event.bus.EventBus; +import nova.core.language.LanguageManager; +import nova.core.wrapper.mc.forge.v18.launcher.ForgeLoadable; +import nova.core.wrapper.mc.forge.v18.launcher.NovaMinecraft; import nova.internal.core.Game; /** * @author Calclavia */ -public class MCLanguageManager extends LanguageManager { +public class MCLanguageManager extends LanguageManager implements ForgeLoadable { @Override public void register(String language, String key, String value) { - LanguageRegistry.instance().addStringLocalization(key, language, value); + super.register(language, key, value); + } + + public MCLanguageManager() { + NovaMinecraft.registerWrapper(this); } @Override public String getCurrentLanguage() { - return FMLCommonHandler.instance().getCurrentLanguage(); + return FMLCommonHandler.instance().getCurrentLanguage().replace('_', '-'); } @Override public String translate(String key) { - return StatCollector.translateToLocal(key); + String value = super.translate(key); + if (value.equals(key)) + value = StatCollector.translateToLocal(key); + return value; } @Override - public void init() { - Game.events().publish(new Init(this)); + @SuppressWarnings("deprecation") + public void preInit(FMLPreInitializationEvent evt) { + this.languageMap.forEach((language, map) -> { + String lang = language.replace('-', '_'); + map.forEach((key, value) -> LanguageRegistry.instance().addStringLocalization(key, lang, value)); + }); + + Game.events().on(LanguageEvent.RegisterTranslation.class).withPriority(EventBus.PRIORITY_LOW).bind(this::register); + } + + @SuppressWarnings("deprecation") + public void register(LanguageEvent.RegisterTranslation evt) { + LanguageRegistry.instance().addStringLocalization(evt.key, evt.language.replace('-', '_'), evt.value); } } diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/backward/BWBlock.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/backward/BWBlock.java index fc642349d..1c1b1bcf5 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/backward/BWBlock.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/backward/BWBlock.java @@ -164,4 +164,14 @@ public void load(Data data) { tileEntity.writeToNBT(Game.natives().toNative(data)); } } + + @Override + public String getLocalizedName() { + return mcBlock.getLocalizedName(); + } + + @Override + public String getUnlocalizedName() { + return mcBlock.getUnlocalizedName(); + } } diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java index 26a8df55e..f46f80c8a 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java @@ -102,7 +102,6 @@ public FWBlock(BlockFactory factory) { this.stepSound = soundTypeStone; } this.blockClass = dummy.getClass(); - this.setUnlocalizedName(dummy.getID()); // Recalculate super constructor things after loading the block properly this.fullBlock = isOpaqueCube(); @@ -366,7 +365,12 @@ public int isProvidingStrongPower(IBlockAccess access, BlockPos pos, IBlockState @Override public String getUnlocalizedName() { - return super.getUnlocalizedName().replaceFirst("tile", "block"); + return factory.getUnlocalizedName(); + } + + @Override + public String getLocalizedName() { + return factory.getLocalizedName(); } @Override diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItem.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItem.java index 7476b9d26..bf500470b 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItem.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItem.java @@ -64,6 +64,16 @@ public ItemStack makeItemStack(int stackSize) { return result; } + @Override + public String getLocalizedName() { + return this.item.getItemStackDisplayName(makeItemStack(count())); + } + + @Override + public String getUnlocalizedName() { + return this.item.getUnlocalizedName(makeItemStack(count())); + } + @Override public String toString() { return getID(); diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItemFactory.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItemFactory.java index 1ef0f138f..43f8c822c 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItemFactory.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItemFactory.java @@ -52,6 +52,11 @@ public int getMeta() { return meta; } + @Override + public String getUnlocalizedName() { + return this.item.getUnlocalizedName(); + } + @Override public Item build(Data data) { int meta = (Integer) data.getOrDefault("damage", this.meta); diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItem.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItem.java index 6ce3b84a4..98959ee54 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItem.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItem.java @@ -38,7 +38,6 @@ public class FWItem extends net.minecraft.item.Item implements ItemWrapperMethod public FWItem(ItemFactory item) { this.itemFactory = item; - setUnlocalizedName(item.getID()); setMaxStackSize(item.build().getMaxCount()); } @@ -67,4 +66,18 @@ public int getColorFromItemStack(ItemStack p_82790_1_, int p_82790_2_) { return ItemWrapperMethods.super.getColorFromItemStack(p_82790_1_, p_82790_2_); } + @Override + public String getUnlocalizedName() { + return getItemFactory().getUnlocalizedName(); + } + + @Override + public String getUnlocalizedName(ItemStack stack) { + return ItemConverter.instance().toNova(stack).getUnlocalizedName(); + } + + @Override + public String getItemStackDisplayName(ItemStack stack) { + return ItemConverter.instance().toNova(stack).getLocalizedName(); + } } diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItemBlock.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItemBlock.java index dad1d3fe6..8c35f97e3 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItemBlock.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItemBlock.java @@ -63,4 +63,19 @@ public ItemStack onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPl public int getColorFromItemStack(ItemStack p_82790_1_, int p_82790_2_) { return ItemWrapperMethods.super.getColorFromItemStack(p_82790_1_, p_82790_2_); } + + @Override + public String getUnlocalizedName() { + return getItemFactory().getUnlocalizedName(); + } + + @Override + public String getUnlocalizedName(ItemStack stack) { + return ItemConverter.instance().toNova(stack).getUnlocalizedName(); + } + + @Override + public String getItemStackDisplayName(ItemStack stack) { + return ItemConverter.instance().toNova(stack).getLocalizedName(); + } } diff --git a/src/main/java/nova/core/block/Block.java b/src/main/java/nova/core/block/Block.java index 385e8b338..9fd2cd42e 100644 --- a/src/main/java/nova/core/block/Block.java +++ b/src/main/java/nova/core/block/Block.java @@ -29,6 +29,7 @@ import nova.core.event.bus.Event; import nova.core.item.Item; import nova.core.item.ItemFactory; +import nova.core.language.Translatable; import nova.core.util.Direction; import nova.core.util.Identifiable; import nova.core.world.World; @@ -43,8 +44,7 @@ /** * @author Calclavia */ -@SuppressWarnings("rawtypes") -public class Block extends SidedComponentProvider implements Identifiable { +public class Block extends SidedComponentProvider implements Identifiable, Translatable { public ItemFactory getItemFactory() { return Game.items().getItemFromBlock(getFactory()); @@ -64,6 +64,16 @@ public final String getID() { return getFactory().getID(); } + @Override + public String getUnlocalizedName() { + return getFactory().getUnlocalizedName(); + } + + @Override + public String getLocalizedName() { + return getFactory().getLocalizedName(); + } + public final BlockTransform transform() { return components.get(BlockTransform.class); } diff --git a/src/main/java/nova/core/block/BlockFactory.java b/src/main/java/nova/core/block/BlockFactory.java index 94443fbd3..06a25a117 100644 --- a/src/main/java/nova/core/block/BlockFactory.java +++ b/src/main/java/nova/core/block/BlockFactory.java @@ -22,6 +22,9 @@ import nova.core.component.misc.FactoryProvider; import nova.core.item.ItemBlock; +import nova.core.item.ItemFactory; +import nova.core.language.LanguageManager; +import nova.core.language.Translatable; import nova.core.util.registry.Factory; import nova.internal.core.Game; @@ -33,13 +36,15 @@ * The factory type for blocks. * @author Calclavia */ -public class BlockFactory extends Factory { +public class BlockFactory extends Factory implements Translatable { final Consumer postRegister; + private String unlocalizedName; public BlockFactory(String id, Supplier constructor, Function processor, Consumer postRegister) { super(id, constructor, processor); this.postRegister = postRegister; + this.setUnlocalizedName(getID().replaceAll(":", ".")); } public BlockFactory(String id, Supplier constructor) { @@ -55,6 +60,7 @@ public BlockFactory(String id, Supplier constructor) { public BlockFactory(String id, Supplier constructor, Consumer postRegister) { super(id, constructor); this.postRegister = postRegister; + this.setUnlocalizedName(getID().replaceAll(":", ".")); } @Override @@ -68,4 +74,19 @@ public Block build() { build.components.add(new FactoryProvider(this)); return build; } + + public BlockFactory setUnlocalizedName(String unlocalizedName) { + this.unlocalizedName = unlocalizedName; + return this; + } + + @Override + public String getUnlocalizedName() { + return "block." + this.unlocalizedName; + } + + @Override + public String getLocalizedName() { + return LanguageManager.instance().translate(getUnlocalizedName() + ".name"); + } } diff --git a/src/main/java/nova/core/event/LanguageEvent.java b/src/main/java/nova/core/event/LanguageEvent.java new file mode 100644 index 000000000..36f037343 --- /dev/null +++ b/src/main/java/nova/core/event/LanguageEvent.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2017 NOVA, All rights reserved. + * This library is free software, licensed under GNU Lesser General Public License version 3 + * + * This file is part of NOVA. + * + * NOVA is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * NOVA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NOVA. If not, see . + */ + +package nova.core.event; + +import nova.core.event.bus.CancelableEvent; + +/** + * All events related to the language. + * @author ExE Boss + */ +public abstract class LanguageEvent extends CancelableEvent { + + public final String language; + + public LanguageEvent(String language) { + this.language = language; + } + + /** + * Event is triggered when a translation is registered. + * + * @see nova.core.language.LanguageManager#register(String, String, String) + */ + public static class RegisterTranslation extends LanguageEvent { + + public final String key; + public String value; + + public RegisterTranslation(String language, String key, String value) { + super(language); + this.key = key; + this.value = value; + } + } + + /** + * Event is triggered when a language is changed. + */ + public static class LanguageChanged extends CancelableEvent { + + public final String newLanguage; + public final String oldLanguage; + + public LanguageChanged(String oldLanguage, String newLanguage) { + this.oldLanguage = oldLanguage; + this.newLanguage = newLanguage; + } + } +} diff --git a/src/main/java/nova/core/item/Item.java b/src/main/java/nova/core/item/Item.java index da436bb22..2a0dad44d 100644 --- a/src/main/java/nova/core/item/Item.java +++ b/src/main/java/nova/core/item/Item.java @@ -25,6 +25,7 @@ import nova.core.component.misc.FactoryProvider; import nova.core.entity.Entity; import nova.core.event.bus.Event; +import nova.core.language.Translatable; import nova.core.render.Color; import nova.core.retention.Storable; import nova.core.util.Direction; @@ -35,8 +36,7 @@ import java.util.Optional; //TODO: This Storable implementation is flawed and not based on ID. -@SuppressWarnings("rawtypes") -public class Item extends ComponentProvider implements Identifiable, Storable, Cloneable { +public class Item extends ComponentProvider implements Identifiable, Storable, Cloneable, Translatable { /** * The amount of this item that is present. @@ -56,6 +56,16 @@ public final String getID() { return getFactory().getID(); } + @Override + public String getUnlocalizedName() { + return getFactory().getUnlocalizedName(); + } + + @Override + public String getLocalizedName() { + return getFactory().getLocalizedName(); + } + public int getMaxCount() { return 64; } diff --git a/src/main/java/nova/core/item/ItemBlock.java b/src/main/java/nova/core/item/ItemBlock.java index c6cdd6b3a..524bc9ec1 100644 --- a/src/main/java/nova/core/item/ItemBlock.java +++ b/src/main/java/nova/core/item/ItemBlock.java @@ -42,6 +42,16 @@ public ItemBlock(BlockFactory blockFactory) { events.on(UseEvent.class).bind(this::onUse); } + @Override + public String getUnlocalizedName() { + return blockFactory.getLocalizedName(); + } + + @Override + public String getLocalizedName() { + return blockFactory.getLocalizedName(); + } + protected void onUse(UseEvent evt) { Optional opBlock = evt.entity.world().getBlock(evt.position); diff --git a/src/main/java/nova/core/item/ItemFactory.java b/src/main/java/nova/core/item/ItemFactory.java index a31f83599..bafd2bd18 100644 --- a/src/main/java/nova/core/item/ItemFactory.java +++ b/src/main/java/nova/core/item/ItemFactory.java @@ -21,6 +21,8 @@ package nova.core.item; import nova.core.component.misc.FactoryProvider; +import nova.core.language.LanguageManager; +import nova.core.language.Translatable; import nova.core.retention.Data; import nova.core.retention.Storable; import nova.core.util.registry.Factory; @@ -32,13 +34,17 @@ /** * @author Calclavia */ -public class ItemFactory extends Factory implements Identifiable { +public class ItemFactory extends Factory implements Identifiable, Translatable { + private String unlocalizedName; + public ItemFactory(String id, Supplier constructor, Function processor) { super(id, constructor, processor); + this.setUnlocalizedName(getID().replaceAll(":", ".")); } public ItemFactory(String id, Supplier constructor) { super(id, constructor); + this.setUnlocalizedName(getID().replaceAll(":", ".")); } /** @@ -73,6 +79,21 @@ public Data save(Item item) { return data; } + public ItemFactory setUnlocalizedName(String unlocalizedName) { + this.unlocalizedName = unlocalizedName; + return this; + } + + @Override + public String getUnlocalizedName() { + return "item." + this.unlocalizedName; + } + + @Override + public String getLocalizedName() { + return LanguageManager.instance().translate(getUnlocalizedName() + ".name"); + } + @Override protected ItemFactory selfConstructor(String id, Supplier constructor, Function processor) { return new ItemFactory(id, constructor, processor); diff --git a/src/main/java/nova/core/language/LanguageManager.java b/src/main/java/nova/core/language/LanguageManager.java new file mode 100644 index 000000000..5c28f259b --- /dev/null +++ b/src/main/java/nova/core/language/LanguageManager.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2015 NOVA, All rights reserved. + * This library is free software, licensed under GNU Lesser General Public License version 3 + * + * This file is part of NOVA. + * + * NOVA is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * NOVA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NOVA. If not, see . + */ + +package nova.core.language; + +import nova.core.event.LanguageEvent; +import nova.internal.core.Game; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import nova.core.util.registry.Manager; + +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Manages translations from key labels to values. + * @author Calclavia + */ +public abstract class LanguageManager extends Manager { + + protected final Map> languageMap = new HashMap<>(); + + /** + * Gets the instance of LanguageManager + * @return The instance of LanguageManager + */ + public static LanguageManager instance() { + return Game.language(); + } + + /** + * Registers a custom key-value language pair + * @param language The language ID + * @param key The unlocalized key + * @param value The localized value + */ + public void register(String language, String key, String value) { + if (!languageMap.containsKey(language)) + languageMap.put(language, new HashMap<>()); + + LanguageEvent.RegisterTranslation event = new LanguageEvent.RegisterTranslation(language, key, value); + languageMap.get(language).put(key, event.value); + Game.events().publish(event); + } + + /** + * Gets the IETF language tag for the current language + * @return The current IETF language tag + */ + public abstract String getCurrentLanguage(); + + /** + * Gets the localization of a key. + * @param key The unlocalized key + * @return The localized string + */ + public String translate(String key) { + return languageMap.getOrDefault(getCurrentLanguage(), Collections.emptyMap()).getOrDefault(key, key); + } + + @Override + public void init() { + Game.events().publish(new Init(this)); + } + + /** + * Gets the localization of a key, but applying a set of replacement strings. + * @param key The unlocalized key + * @param replacements A 2D array of replacements, with keys in the translated string formatted as {@code ${}} or {@code $} + * For keys with non-alphanumeric (a-z, A-Z, 0-9 and underscores) characters, only the former is used. + * To prevent a '$' character from being matched, escape it with a '\, like so: '\$'. + * @return The localized string, modified with replacements + */ + public String translate(String key, String[]... replacements) { + return translate(key, Stream.of(replacements).filter(ary -> ary.length == 2).collect(Collectors.toMap(ary -> ary[0], ary -> ary[1]))); + } + + /** + * Gets the localization of a key, but applying a set of replacement strings. + * @param key The unlocalized key + * @param replacements A map of replacements, with keys in the translated string formatted as {@code ${}} or {@code $} + * For keys with non-alphanumeric (a-z, A-Z, 0-9 and underscores) characters, only the former is used. + * To prevent a '$' character from being matched, escape it with a '\, like so: '\$'. + * @return The localized string, modified with replacements + */ + public String translate(String key, Map replacements) { + String str = translate(key); + + str = str.replaceAll("\\\\\\$", "${$}"); + + for (Map.Entry replacement : replacements.entrySet()) { + if (replacement.getKey().matches("^\\w+$")) + str = str.replaceAll("\\$" + replacement.getKey(), replacement.getValue()); + str = str.replaceAll("\\$\\{" + replacement.getKey() + "\\}", replacement.getValue()); + } + + str = str.replaceAll("\\$\\{\\$\\}", "$"); + + return str; + } + + public class Init extends ManagerEvent { + public Init(LanguageManager manager) { + super(manager); + } + } +} diff --git a/src/main/java/nova/core/language/Translatable.java b/src/main/java/nova/core/language/Translatable.java new file mode 100644 index 000000000..c3bdd0a6f --- /dev/null +++ b/src/main/java/nova/core/language/Translatable.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017 NOVA, All rights reserved. + * This library is free software, licensed under GNU Lesser General Public License version 3 + * + * This file is part of NOVA. + * + * NOVA is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * NOVA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NOVA. If not, see . + */ + +package nova.core.language; + +/** + * Implemented by objects that can be translated. + * + * @author ExE Boss + */ +public interface Translatable { + + /** + * Gets the unlocalized name of this object. + * @return The unlocalized name + */ + public String getUnlocalizedName(); + + /** + * Gets the localized name of this object. + * @return The localized name + */ + public default String getLocalizedName() { + return LanguageManager.instance().translate(this.getLocalizedName()); + } +} diff --git a/src/main/java/nova/core/util/registry/LanguageManager.java b/src/main/java/nova/core/util/registry/LanguageManager.java deleted file mode 100644 index cb2e20b7f..000000000 --- a/src/main/java/nova/core/util/registry/LanguageManager.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2015 NOVA, All rights reserved. - * This library is free software, licensed under GNU Lesser General Public License version 3 - * - * This file is part of NOVA. - * - * NOVA is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * NOVA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NOVA. If not, see . - */ - -package nova.core.util.registry; - -import java.util.Map; - -/** - * Manages translations from key labels to values. - * @author Calclavia - */ -public abstract class LanguageManager extends Manager { - - /** - * Registers a custom key-value language pair - * @param language The language ID - * @param key The unlocalized key - * @param value The localized value - */ - public abstract void register(String language, String key, String value); - - /** - * @return Gets the current language string ID - */ - public abstract String getCurrentLanguage(); - - public abstract String translate(String key); - - /** - * Gets the localization of a key, but applying a set of replacement strings. - * @return The localized string, modified with replacements - */ - public String translate(String key, Map replacements) { - String str = translate(key); - - for (Map.Entry replacement : replacements.entrySet()) { - str = str.replaceAll(replacement.getKey(), replacement.getValue()); - } - return str; - } - - public class Init extends ManagerEvent { - public Init(LanguageManager manager) { - super(manager); - } - } -} diff --git a/src/main/java/nova/internal/core/Game.java b/src/main/java/nova/internal/core/Game.java index 3a7184788..6de896760 100644 --- a/src/main/java/nova/internal/core/Game.java +++ b/src/main/java/nova/internal/core/Game.java @@ -35,7 +35,7 @@ import nova.core.recipes.RecipeManager; import nova.core.recipes.crafting.CraftingRecipeManager; import nova.core.render.RenderManager; -import nova.core.util.registry.LanguageManager; +import nova.core.language.LanguageManager; import nova.core.util.registry.RetentionManager; import nova.core.world.WorldManager; import nova.internal.core.bootstrap.DependencyInjectionEntryPoint; diff --git a/src/test/java/nova/core/language/LanguageManagerTest.java b/src/test/java/nova/core/language/LanguageManagerTest.java new file mode 100644 index 000000000..d7e4320dd --- /dev/null +++ b/src/test/java/nova/core/language/LanguageManagerTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017 NOVA, All rights reserved. + * This library is free software, licensed under GNU Lesser General Public License version 3 + * + * This file is part of NOVA. + * + * NOVA is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * NOVA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NOVA. If not, see . + */ +package nova.core.language; + +import nova.wrappertests.depmodules.FakeLanguageModule.FakeLanguageManager; +import org.junit.Test; + +import static nova.testutils.NovaAssertions.assertThat; + +/** + * + * @author ExE Boss + */ +public class LanguageManagerTest { + + private LanguageManager langauageManager = new FakeLanguageManager(); + + public LanguageManagerTest() { + } + + @Test + public void testInstance() { + } + + @Test + public void testGetCurrentLanguage() { + assertThat(langauageManager.getCurrentLanguage()).isEqualTo("en-US"); + } + + @Test + public void testTranslate() { + assertThat(langauageManager.translate("key.untranslated")).isEqualTo("key.untranslated"); + assertThat(langauageManager.translate("${replacement with spaces} some text $key1, ${key1}", new String[][]{ + {"replacement with spaces","24"}, + {"key1","42"} + })).isEqualTo("24 some text 42, 42"); + } +} diff --git a/src/test/java/nova/wrappertests/depmodules/FakeLanguageModule.java b/src/test/java/nova/wrappertests/depmodules/FakeLanguageModule.java index 9471ea4ad..079981f42 100644 --- a/src/test/java/nova/wrappertests/depmodules/FakeLanguageModule.java +++ b/src/test/java/nova/wrappertests/depmodules/FakeLanguageModule.java @@ -20,7 +20,7 @@ package nova.wrappertests.depmodules; -import nova.core.util.registry.LanguageManager; +import nova.core.language.LanguageManager; import se.jbee.inject.bind.BinderModule; /** @@ -34,24 +34,9 @@ protected void declare() { } public static class FakeLanguageManager extends LanguageManager { - @Override - public void register(String language, String key, String value) { - - } - @Override public String getCurrentLanguage() { - return "en_US"; - } - - @Override - public String translate(String key) { - return key; - } - - @Override - public void init() { - + return "en-US"; } } }