diff --git a/gradle.properties b/gradle.properties index 5e5c427e..131ec8ef 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ modGroup = com.nomiceu.nomilabs # Version of your mod. # This field can be left empty if you want your mod's version to be determined by the latest git tag instead. -modVersion = 0.6.29 +modVersion = 0.7 # Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version) includeMCVersionJar = false diff --git a/src/main/groovy-tests/jeiTests.groovy b/src/main/groovy-tests/jeiTests.groovy index 5e6f9594..3dc7616b 100644 --- a/src/main/groovy-tests/jeiTests.groovy +++ b/src/main/groovy-tests/jeiTests.groovy @@ -1,28 +1,60 @@ +import gregtech.client.utils.TooltipHelper import net.minecraft.util.text.TextFormatting import static com.nomiceu.nomilabs.groovy.GroovyHelpers.JEIHelpers.* import static com.nomiceu.nomilabs.groovy.GroovyHelpers.TranslationHelpers.* -// JEI Helpers. (Goes in Post Init) +// JEI and Translation Helpers. (Goes in Post Init) + +// There are two types of translations: translate and translatable. +// Translate translates the input NOW, whilst translatable translates the input when it is needed. +// All JEI Pages use Translatable, so that the language can be changed on-the-fly. + +// Translate: Instantly Translate Something, on Server or Client, with Parameters +// Use TranslateFormat to Translate with Parameters and a GT Format Code wrapped around the string! +// (Note, normal format codes should be included in the lang itself, and thus are not available with `translateFormat`) +// (Note, normal format codes are still available with `format`) +println('Translated Hand Framing Tool Side: ' + translate('tooltip.nomilabs.hand_framing_tool.side', format('Hi', TextFormatting.AQUA))) +println('Translated Hand Framing Tool Main: ' + translateFormat('tooltip.nomilabs.hand_framing_tool.not_set', TooltipHelper.RAINBOW)) + +// Translatable: Save something to be translated later +var translatableObj = translatable('tooltip.nomilabs.excitationcoil.description') + +// You can add formatting (TextFormatting, GTFormatCode, or Format) +translatableObj.addFormat(TextFormatting.AQUA) + +// You can append other translatable objects +// Note that appended objects will be concatenated with no seperator, and in this order: +// If translatable1 has translated2 and translated3 appended in that order, and translated2 has p1 and p2 appended in that order: +// transtable1 + translated2 + p1 + p2 + translated3 +translatableObj.append(translatable('tooltip.nomilabs.hand_framing_tool.front', format('Hello World!', TextFormatting.RED))) + +// Very flexible, you can even append literal strings +translatableObj.append(translatableLiteral('Hello World!')) + +// Call `toString` or `translate` to retrieve the translated and concatenated string +println('Translatable Object: ' + translatableObj.translate()) + +/* JEI Pages. Each Method requires Translatable Objects. */ /* Description Pages. Each entry is seperated by double new lines. */ // Add a description page for a stack -addDescription(item('minecraft:apple'), format("An Ordinary Apple... Not Poisoned.", TextFormatting.DARK_GREEN), "Eat it!") +addDescription(item('minecraft:apple'), translatableLiteral('An Ordinary Apple... Not Poisoned.').addFormat(TextFormatting.DARK_GREEN), translatableLiteral('Eat it!')) // Add a translated description page for a stack -addDescription(item('minecraft:iron_ingot'), translate("tooltip.nomilabs.greenhouse.description"), translate("tooltip.nomilabs.dme_sim_chamber.description")) +addDescription(item('minecraft:iron_ingot'), translatable('tooltip.nomilabs.greenhouse.description'), translatable('tooltip.nomilabs.dme_sim_chamber.description')) /* Recipe Output Tooltips. These are tooltips that appear on CRAFTING recipes that output that stack. */ // Add a crafting recipe output tooltip for a stack -addRecipeOutputTooltip(item('minecraft:gold_ingot'), format("A Very Low Carrot Gold Ingot.", TextFormatting.GOLD), "Oops! Meant Carat!") +addRecipeOutputTooltip(item('minecraft:gold_ingot'), translatableLiteral('A Very Low Carrot Gold Ingot.').addFormat(TextFormatting.GOLD)) // Add a translated crafting recipe output tooltip for a stack -addRecipeOutputTooltip(item('minecraft:iron_ingot'), translate("tooltip.nomilabs.greenhouse.description"), translate("tooltip.nomilabs.dme_sim_chamber.description")) +addRecipeOutputTooltip(item('minecraft:iron_ingot'), translatable('tooltip.nomilabs.greenhouse.description'), translatable('tooltip.nomilabs.dme_sim_chamber.description')) // Add a crafting recipe output tooltip for a specific recipe for a stack (Higher Priority than wild) -addRecipeOutputTooltip(item('minecraft:gold_ingot'), resource('minecraft:gold_ingot_from_block'), format("A Very High Carat Gold Ingot.", TextFormatting.GOLD), "Precious!") +addRecipeOutputTooltip(item('minecraft:gold_ingot'), resource('minecraft:gold_ingot_from_block'), translatableLiteral('A Very High Carrot Gold Ingot.').addFormat(TextFormatting.GOLD)) // Add a translated crafting recipe output tooltip for a specific recipe for a stack (Higher Priority than wild) -addRecipeOutputTooltip(item('minecraft:iron_ingot'), resource('minecraft:iron_ingot_from_nuggets'), translate("tooltip.nomilabs.universalnavigator.description"), translate("tooltip.nomilabs.greenhouse.description"), translate("tooltip.nomilabs.dme_sim_chamber.description")) +addRecipeOutputTooltip(item('minecraft:iron_ingot'), resource('minecraft:iron_ingot_from_nuggets'), translatable('tooltip.nomilabs.universalnavigator.description'), translatable('tooltip.nomilabs.greenhouse.description'), translatable('tooltip.nomilabs.dme_sim_chamber.description')) diff --git a/src/main/java/com/nomiceu/nomilabs/event/ClientProxy.java b/src/main/java/com/nomiceu/nomilabs/event/ClientProxy.java index 5d706cb8..9882e812 100644 --- a/src/main/java/com/nomiceu/nomilabs/event/ClientProxy.java +++ b/src/main/java/com/nomiceu/nomilabs/event/ClientProxy.java @@ -11,6 +11,7 @@ import net.minecraftforge.fml.relauncher.SideOnly; import com.cleanroommc.groovyscript.event.ScriptRunEvent; +import com.cleanroommc.groovyscript.registry.ReloadableRegistryManager; import com.nomiceu.nomilabs.LabsValues; import com.nomiceu.nomilabs.NomiLabs; import com.nomiceu.nomilabs.fluid.registry.LabsFluids; @@ -55,6 +56,13 @@ public static void addTooltipNormal(ItemTooltipEvent event) { TooltipAdder.addTooltipNormal(event.getToolTip(), event.getItemStack()); } + @SubscribeEvent + public static void languageChanged(LabsLanguageChangedEvent event) { + // Reload JEI to refresh description text + // noinspection UnstableApiUsage + ReloadableRegistryManager.reloadJei(false); + } + @SubscribeEvent public static void afterScriptLoad(ScriptRunEvent.Post event) { NomiLabs.LOGGER.info("Reloading Options File."); diff --git a/src/main/java/com/nomiceu/nomilabs/event/LabsLanguageChangedEvent.java b/src/main/java/com/nomiceu/nomilabs/event/LabsLanguageChangedEvent.java new file mode 100644 index 00000000..1bd20e5b --- /dev/null +++ b/src/main/java/com/nomiceu/nomilabs/event/LabsLanguageChangedEvent.java @@ -0,0 +1,20 @@ +package com.nomiceu.nomilabs.event; + +import net.minecraft.client.resources.Language; +import net.minecraftforge.fml.common.eventhandler.Event; + +/** + * An event that is called AFTER language is changed, and resources are refreshed. + *

+ * Called Client Side ONLY. + */ +public class LabsLanguageChangedEvent extends Event { + + public final Language oldLanguage; + public final Language newLanguage; + + public LabsLanguageChangedEvent(Language oldLanguage, Language newLanguage) { + this.oldLanguage = oldLanguage; + this.newLanguage = newLanguage; + } +} diff --git a/src/main/java/com/nomiceu/nomilabs/groovy/GroovyHelpers.java b/src/main/java/com/nomiceu/nomilabs/groovy/GroovyHelpers.java index f7c59cb3..6e1110aa 100644 --- a/src/main/java/com/nomiceu/nomilabs/groovy/GroovyHelpers.java +++ b/src/main/java/com/nomiceu/nomilabs/groovy/GroovyHelpers.java @@ -67,6 +67,14 @@ public static String format(String str, TooltipHelper.GTFormatCode... formats) { public static String format(String str, LabsTranslate.Format... formats) { return LabsTranslate.format(str, formats); } + + public static LabsTranslate.Translatable translatable(String key, Object... params) { + return LabsTranslate.translatable(key, params); + } + + public static LabsTranslate.Translatable translatableLiteral(String text) { + return LabsTranslate.translatableLiteral(text); + } } public static class SafeMethodHelpers { @@ -134,15 +142,16 @@ public static Object callMethod(Class clazz, @Nullable Object caller, @NotNul public static class JEIHelpers { /* Description + Tooltip */ - public static void addDescription(ItemStack stack, String... description) { + public static void addDescription(ItemStack stack, LabsTranslate.Translatable... description) { JEIPlugin.addGroovyDescription(stack, description); } - public static void addRecipeOutputTooltip(ItemStack stack, String... tooltip) { + public static void addRecipeOutputTooltip(ItemStack stack, LabsTranslate.Translatable... tooltip) { JEIPlugin.addGroovyRecipeOutputTooltip(stack, tooltip); } - public static void addRecipeOutputTooltip(ItemStack stack, ResourceLocation recipeName, String... tooltip) { + public static void addRecipeOutputTooltip(ItemStack stack, ResourceLocation recipeName, + LabsTranslate.Translatable... tooltip) { JEIPlugin.addGroovyRecipeOutputTooltip(stack, recipeName, tooltip); } diff --git a/src/main/java/com/nomiceu/nomilabs/integration/jei/JEIPlugin.java b/src/main/java/com/nomiceu/nomilabs/integration/jei/JEIPlugin.java index 7983421b..3c8fd44f 100644 --- a/src/main/java/com/nomiceu/nomilabs/integration/jei/JEIPlugin.java +++ b/src/main/java/com/nomiceu/nomilabs/integration/jei/JEIPlugin.java @@ -1,8 +1,11 @@ package com.nomiceu.nomilabs.integration.jei; +import static com.nomiceu.nomilabs.util.LabsTranslate.Translatable; + import java.util.*; import java.util.function.Consumer; import java.util.function.Function; +import java.util.stream.Collectors; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; @@ -19,10 +22,13 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Table; import com.nomiceu.nomilabs.groovy.PartialRecipe; +import com.nomiceu.nomilabs.item.registry.LabsItems; import com.nomiceu.nomilabs.util.ItemTagMeta; +import mezz.jei.api.IJeiRuntime; import mezz.jei.api.IModPlugin; import mezz.jei.api.IModRegistry; +import mezz.jei.api.ingredients.IIngredientRegistry; import mezz.jei.api.ingredients.VanillaTypes; import mezz.jei.api.recipe.VanillaRecipeCategoryUid; @@ -32,27 +38,37 @@ public class JEIPlugin implements IModPlugin { private static final ResourceLocation WILDCARD_LOCATION = new ResourceLocation("*", "*"); - private static final Map> DESCRIPTIONS = new HashMap<>(); - private static final Map> GROOVY_DESCRIPTIONS = new HashMap<>(); - private static final Table> RECIPE_OUTPUT_TOOLTIPS = HashBasedTable + private static final Map> DESCRIPTIONS = new HashMap<>(); + private static final Map> GROOVY_DESCRIPTIONS = new HashMap<>(); + private static final Table> RECIPE_OUTPUT_TOOLTIPS = HashBasedTable .create(); - private static final Table> GROOVY_RECIPE_OUTPUT_TOOLTIPS = HashBasedTable + private static final Table> GROOVY_RECIPE_OUTPUT_TOOLTIPS = HashBasedTable .create(); private static final List>> IGNORE_NBT_HIDE = new ArrayList<>(); + private static IIngredientRegistry itemRegistry; + @Override public void register(IModRegistry registry) { var jeiHelpers = registry.getJeiHelpers(); + itemRegistry = registry.getIngredientRegistry(); // JEI does not recognise Custom Recipe Classes on its own registry.handleRecipes(PartialRecipe.class, recipe -> new PartialRecipeWrapper(jeiHelpers, recipe), VanillaRecipeCategoryUid.CRAFTING); // Add Descriptions - Map> tempMap = new HashMap<>(DESCRIPTIONS); + Map> tempMap = new HashMap<>(DESCRIPTIONS); GROOVY_DESCRIPTIONS.forEach(((key, value) -> addDescription(tempMap, key, (list) -> list.addAll(value)))); tempMap.forEach(((itemTagMeta, strings) -> registry.addIngredientInfo(itemTagMeta.toStack(), VanillaTypes.ITEM, - String.join("\n\n", strings)))); + strings.stream().map(Translatable::translate).collect(Collectors.joining("\n\n"))))); + } + + @Override + public void onRuntimeAvailable(@NotNull IJeiRuntime jeiRuntime) { + // Remove Info Item from JEI + itemRegistry.removeIngredientsAtRuntime(VanillaTypes.ITEM, + Collections.singletonList(new ItemStack(LabsItems.INFO_ITEM))); } public static void hideItemNBTMatch(ItemStack itemStack, Function condition) { @@ -74,43 +90,43 @@ public static List>> getIgnore return ImmutableList.copyOf(IGNORE_NBT_HIDE); } - public static void addDescription(@NotNull ItemStack stack, String... description) { + public static void addDescription(@NotNull ItemStack stack, Translatable... description) { addDescription(DESCRIPTIONS, new ItemTagMeta(stack), (list) -> Collections.addAll(list, description)); } - public static void addGroovyDescription(@NotNull ItemStack stack, String... description) { + public static void addGroovyDescription(@NotNull ItemStack stack, Translatable... description) { addDescription(GROOVY_DESCRIPTIONS, new ItemTagMeta(stack), (list) -> Collections.addAll(list, description)); } - private static void addDescription(Map> map, - @NotNull ItemTagMeta stack, Consumer> addToList) { + private static void addDescription(Map> map, + @NotNull ItemTagMeta stack, Consumer> addToList) { map.computeIfAbsent(stack, (k) -> new ArrayList<>()); addToList.accept(map.get(stack)); } - public static void addRecipeOutputTooltip(@NotNull ItemStack stack, String... tooltip) { + public static void addRecipeOutputTooltip(@NotNull ItemStack stack, Translatable... tooltip) { addRecipeOutputTooltip(stack, WILDCARD_LOCATION, tooltip); } public static void addRecipeOutputTooltip(@NotNull ItemStack stack, ResourceLocation recipeName, - String... tooltip) { + Translatable... tooltip) { addRecipeOutputTooltip(RECIPE_OUTPUT_TOOLTIPS, new ItemTagMeta(stack), recipeName, (list) -> Collections.addAll(list, tooltip)); } - public static void addGroovyRecipeOutputTooltip(@NotNull ItemStack stack, String... tooltip) { + public static void addGroovyRecipeOutputTooltip(@NotNull ItemStack stack, Translatable... tooltip) { addGroovyRecipeOutputTooltip(stack, WILDCARD_LOCATION, tooltip); } public static void addGroovyRecipeOutputTooltip(@NotNull ItemStack stack, ResourceLocation recipeName, - String... tooltip) { + Translatable... tooltip) { addRecipeOutputTooltip(GROOVY_RECIPE_OUTPUT_TOOLTIPS, new ItemTagMeta(stack), recipeName, (list) -> Collections.addAll(list, tooltip)); } - private static void addRecipeOutputTooltip(Table> table, + private static void addRecipeOutputTooltip(Table> table, @NotNull ItemTagMeta stack, ResourceLocation recipeName, - Consumer> addToList) { + Consumer> addToList) { var list = table.get(stack, recipeName); if (list == null) list = new ArrayList<>(); addToList.accept(list); @@ -123,11 +139,13 @@ public static List getRecipeOutputTooltip(ItemStack stack, ResourceLocat .forEach((cell) -> addRecipeOutputTooltip(tempTable, Objects.requireNonNull(cell.getRowKey()), cell.getColumnKey(), (list) -> list.addAll(Objects.requireNonNull(cell.getValue())))); + var itemTagMeta = new ItemTagMeta(stack); var specific = tempTable.get(itemTagMeta, recipeName); - if (specific != null) return specific; + if (specific != null) return specific.stream().map(Translatable::translate).collect(Collectors.toList()); + var wildcard = tempTable.get(itemTagMeta, WILDCARD_LOCATION); - if (wildcard != null) return wildcard; + if (wildcard != null) return wildcard.stream().map(Translatable::translate).collect(Collectors.toList()); return new ArrayList<>(); } diff --git a/src/main/java/com/nomiceu/nomilabs/item/ItemHandFramingTool.java b/src/main/java/com/nomiceu/nomilabs/item/ItemHandFramingTool.java index d064e0fd..a50d256a 100644 --- a/src/main/java/com/nomiceu/nomilabs/item/ItemHandFramingTool.java +++ b/src/main/java/com/nomiceu/nomilabs/item/ItemHandFramingTool.java @@ -300,11 +300,11 @@ private static NBTTagCompound getMaterialTag(@Nonnull ItemStack stack) { public void addDescription() { JEIPlugin.addDescription(new ItemStack(this), - translate("item.nomilabs.hand_framing_tool.desc1"), - translate("item.nomilabs.hand_framing_tool.desc2"), - translate("item.nomilabs.hand_framing_tool.desc3"), - translate("item.nomilabs.hand_framing_tool.desc4"), - translate("item.nomilabs.hand_framing_tool.desc5"), - translate("item.nomilabs.hand_framing_tool.desc6")); + translatable("item.nomilabs.hand_framing_tool.desc1"), + translatable("item.nomilabs.hand_framing_tool.desc2"), + translatable("item.nomilabs.hand_framing_tool.desc3"), + translatable("item.nomilabs.hand_framing_tool.desc4"), + translatable("item.nomilabs.hand_framing_tool.desc5"), + translatable("item.nomilabs.hand_framing_tool.desc6")); } } diff --git a/src/main/java/com/nomiceu/nomilabs/item/ItemInfo.java b/src/main/java/com/nomiceu/nomilabs/item/ItemInfo.java new file mode 100644 index 00000000..a258bb72 --- /dev/null +++ b/src/main/java/com/nomiceu/nomilabs/item/ItemInfo.java @@ -0,0 +1,80 @@ +package com.nomiceu.nomilabs.item; + +import static com.nomiceu.nomilabs.util.LabsTranslate.*; + +import java.util.*; + +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.EnumRarity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import net.minecraftforge.common.IRarity; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * An item specifically designed to show information, via the tooltip. + *

+ * Note that this item is not in any creative tabs or JEI! + */ +public class ItemInfo extends Item { + + private final EnumRarity rarity; + private static final Map TOOLTIP_MAP; + + public static final int AE2_STUFF_REMAP_INFO = 1; + + public ItemInfo(ResourceLocation rl, EnumRarity rarity) { + setRegistryName(rl); + setMaxStackSize(64); + setHasSubtypes(true); + + this.rarity = rarity; + } + + /** + * Does not include the item with no meta. + */ + public Set getSubMetas() { + return TOOLTIP_MAP.keySet(); + } + + @Override + protected boolean isInCreativeTab(@NotNull CreativeTabs targetTab) { + return false; + } + + @Override + public @NotNull IRarity getForgeRarity(@NotNull ItemStack stack) { + return rarity; + } + + @Override + public void addInformation(ItemStack stack, @Nullable World worldIn, @NotNull List tooltip, + @NotNull ITooltipFlag flagIn) { + if (!TOOLTIP_MAP.containsKey(stack.getMetadata())) return; + + var tooltipList = TOOLTIP_MAP.get(stack.getMetadata()); + for (var line : tooltipList) { + tooltip.add(line.translate()); + } + } + + static { + TOOLTIP_MAP = new HashMap<>(); + // Leave Meta 0 as Nothing, so its almost a normal item + TOOLTIP_MAP.put(AE2_STUFF_REMAP_INFO, new Translatable[] { + translatable("tooltip.nomilabs.info.ae2-stuff.1"), + translatableLiteral(""), + translatable("tooltip.nomilabs.info.ae2-stuff.2"), + translatableLiteral(""), + translatable("tooltip.nomilabs.info.ae2-stuff.3"), + translatable("tooltip.nomilabs.info.ae2-stuff.4"), + translatable("tooltip.nomilabs.info.ae2-stuff.5") + }); + } +} diff --git a/src/main/java/com/nomiceu/nomilabs/item/registry/LabsItems.java b/src/main/java/com/nomiceu/nomilabs/item/registry/LabsItems.java index a68d616c..8e188380 100644 --- a/src/main/java/com/nomiceu/nomilabs/item/registry/LabsItems.java +++ b/src/main/java/com/nomiceu/nomilabs/item/registry/LabsItems.java @@ -189,6 +189,8 @@ public class LabsItems { public static ItemBase MAGNETRON; + public static ItemInfo INFO_ITEM; + public static ItemBase PULSATING_DUST; public static ItemBase PULSATING_MESH; @@ -277,6 +279,16 @@ private static void registerCustomModels() { // Add Animated Model var mrlBlaze1 = new ModelResourceLocation("blaze_powder_animated", "inventory"); ModelLoader.setCustomModelResourceLocation(Items.BLAZE_POWDER, 1, mrlBlaze1); + + // Add the same model for all metas in ItemInfo + var rlInfo = Objects.requireNonNull(INFO_ITEM.getRegistryName()); + ModelBakery.registerItemVariants(INFO_ITEM, rlInfo); + var mrlInfo = new ModelResourceLocation(rlInfo, "inventory"); + ModelLoader.setCustomModelResourceLocation(INFO_ITEM, 0, mrlInfo); + + for (var meta : INFO_ITEM.getSubMetas()) { + ModelLoader.setCustomModelResourceLocation(INFO_ITEM, meta, mrlInfo); + } } public static T createItem(T item) { diff --git a/src/main/java/com/nomiceu/nomilabs/item/registry/register/LabsMisc.java b/src/main/java/com/nomiceu/nomilabs/item/registry/register/LabsMisc.java index 2ba795e8..feb46e2b 100644 --- a/src/main/java/com/nomiceu/nomilabs/item/registry/register/LabsMisc.java +++ b/src/main/java/com/nomiceu/nomilabs/item/registry/register/LabsMisc.java @@ -9,6 +9,7 @@ import com.nomiceu.nomilabs.creativetab.registry.LabsCreativeTabs; import com.nomiceu.nomilabs.item.ItemBase; +import com.nomiceu.nomilabs.item.ItemInfo; import com.nomiceu.nomilabs.item.ItemSmore; public class LabsMisc { @@ -37,6 +38,9 @@ public static void initMisc() { MAGNETRON = createItem(new ItemBase(makeLabsName("magnetron"), LabsCreativeTabs.TAB_NOMI_LABS)); + // Custom model handling is in LabsItems + INFO_ITEM = createItemWithoutModelHandling(new ItemInfo(makeLabsName("info_item"), EnumRarity.EPIC)); + PULSATING_DUST = createItem(new ItemBase(makeLabsName("pulsatingdust"), LabsCreativeTabs.TAB_NOMI_LABS)); PULSATING_MESH = createItem(new ItemBase(makeLabsName("pulsatingmesh"), LabsCreativeTabs.TAB_NOMI_LABS)); } diff --git a/src/main/java/com/nomiceu/nomilabs/mixin/GuiLanguageMixin.java b/src/main/java/com/nomiceu/nomilabs/mixin/GuiLanguageMixin.java index 826ea0d7..37ac73ac 100644 --- a/src/main/java/com/nomiceu/nomilabs/mixin/GuiLanguageMixin.java +++ b/src/main/java/com/nomiceu/nomilabs/mixin/GuiLanguageMixin.java @@ -6,10 +6,12 @@ import net.minecraft.client.gui.*; import net.minecraft.client.resources.I18n; +import net.minecraft.client.resources.Language; import net.minecraft.client.resources.LanguageManager; import net.minecraft.client.settings.GameSettings; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.client.resource.VanillaResourceType; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.client.FMLClientHandler; import org.spongepowered.asm.mixin.Final; @@ -22,6 +24,7 @@ import com.nomiceu.nomilabs.NomiLabs; import com.nomiceu.nomilabs.config.LabsConfig; +import com.nomiceu.nomilabs.event.LabsLanguageChangedEvent; import com.nomiceu.nomilabs.mixinhelper.AccessibleGuiLanguage; import com.nomiceu.nomilabs.mixinhelper.GuiCustomConfirmOpenLink; @@ -47,7 +50,7 @@ public abstract class GuiLanguageMixin extends GuiScreen implements AccessibleGu private String downloadPackNote; @Unique - private String previousLangCode; + private Language previousLang; @Shadow private GuiOptionButton forceUnicodeFontBtn; @@ -66,7 +69,7 @@ public abstract class GuiLanguageMixin extends GuiScreen implements AccessibleGu @Inject(method = "", at = @At("TAIL")) public void savePreviousLang(GuiScreen screen, GameSettings gameSettingsObj, LanguageManager manager, CallbackInfo ci) { - previousLangCode = manager.getCurrentLanguage().getLanguageCode(); + previousLang = manager.getCurrentLanguage(); } @Inject(method = "initGui", at = @At("TAIL")) @@ -110,7 +113,7 @@ public void handleCustomActions(GuiButton button, CallbackInfo ci) { case 6: // Done Button var language = languageManager.getCurrentLanguage(); var code = language.getLanguageCode(); - if (code.equals(previousLangCode)) break; + if (code.equals(previousLang.getLanguageCode())) break; game_settings_3.language = code; FMLClientHandler.instance().refreshResources(VanillaResourceType.LANGUAGES); @@ -118,6 +121,9 @@ public void handleCustomActions(GuiButton button, CallbackInfo ci) { .setUnicodeFlag(languageManager.isCurrentLocaleUnicode() || game_settings_3.forceUnicodeFont); fontRenderer.setBidiFlag(languageManager.isCurrentLanguageBidirectional()); game_settings_3.saveOptions(); + + // Fire Lang Change Event + MinecraftForge.EVENT_BUS.post(new LabsLanguageChangedEvent(previousLang, language)); break; case DOWNLOAD_PACK_BTN_ID: mc.displayGuiScreen(new GuiCustomConfirmOpenLink(this, TRANSLATIONS_DOWNLOAD, downloadPackNote, @@ -148,7 +154,7 @@ public void confirmClicked(boolean result, int id) { if (result) { try { Class desktopClass = Class.forName("java.awt.Desktop"); - Object desktopObj = desktopClass.getMethod("getDesktop").invoke((Object) null); + Object desktopObj = desktopClass.getMethod("getDesktop").invoke(null); desktopClass.getMethod("browse", URI.class).invoke(desktopObj, new URI(url)); } catch (URISyntaxException | ClassNotFoundException | InvocationTargetException | IllegalAccessException | NoSuchMethodException e) { diff --git a/src/main/java/com/nomiceu/nomilabs/remap/LabsRemappers.java b/src/main/java/com/nomiceu/nomilabs/remap/LabsRemappers.java index d15e5e53..3422fe07 100644 --- a/src/main/java/com/nomiceu/nomilabs/remap/LabsRemappers.java +++ b/src/main/java/com/nomiceu/nomilabs/remap/LabsRemappers.java @@ -112,7 +112,8 @@ private static void initRemappers() { /* * Remap AE2 Stuff Pattern Encoders (Removed in AE2 Stuff Unofficial) to AE2 Interfaces. - * Tile Entity NBT Data and Metadata also needs to be changed (to preserve patterns and to change the id), + * Tile Entity NBT Data and Metadata also needs to be changed (to preserve patterns and to change the + * id), * but that is performed in LabsFixes. * Technically, this is useless, but it prevents warnings and acts as a fallback. */ diff --git a/src/main/java/com/nomiceu/nomilabs/remap/datafixer/LabsFixes.java b/src/main/java/com/nomiceu/nomilabs/remap/datafixer/LabsFixes.java index f2f3b5cf..2567612a 100644 --- a/src/main/java/com/nomiceu/nomilabs/remap/datafixer/LabsFixes.java +++ b/src/main/java/com/nomiceu/nomilabs/remap/datafixer/LabsFixes.java @@ -8,7 +8,6 @@ import java.util.function.Function; import java.util.stream.Collectors; -import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; @@ -22,6 +21,8 @@ import com.google.common.collect.ImmutableMap; import com.nomiceu.nomilabs.config.LabsConfig; +import com.nomiceu.nomilabs.item.ItemInfo; +import com.nomiceu.nomilabs.item.registry.LabsItems; import com.nomiceu.nomilabs.remap.LabsRemapHelper; import com.nomiceu.nomilabs.remap.LabsRemappers; import com.nomiceu.nomilabs.remap.datafixer.storage.ItemStackLike; @@ -387,7 +388,7 @@ public static void init() { state.tileEntityTag.setBoolean("omniDirectional", true); // Default setting, required // Set a custom name - state.tileEntityTag.setString("customName", "Replaced AE2 Stuff Pattern Encoder"); + state.tileEntityTag.setString("customName", "Replaced Pattern Encoder"); // Check if we have to port patterns if (state.tileEntityTag.getTagList("Items", Constants.NBT.TAG_COMPOUND).isEmpty()) { @@ -433,24 +434,8 @@ public static void init() { patternItems.appendTag(patternTag); } - var infoItem = new ItemStack(Items.PAPER); - var infoItemTag = new NBTTagCompound(); - var infoItemDisplay = new NBTTagCompound(); - var infoItemLore = new NBTTagList(); - - infoItemLore.appendTag(new NBTTagString("§cAE2 Pattern Encoders have been removed.§r")); - infoItemLore.appendTag(new NBTTagString("")); - infoItemLore.appendTag(new NBTTagString("§6Please use AE2 Pattern Terminals instead.§r")); - infoItemLore.appendTag(new NBTTagString("")); - infoItemLore.appendTag(new NBTTagString( - "§6All Existing Items §l(including in Patterns)§r§6, Blocks, and usages in Recipes, have been replaced by AE2 Interfaces.§r")); - - infoItemDisplay.setString("Name", "Information"); - infoItemDisplay.setTag("Lore", infoItemLore); - infoItemTag.setTag("display", infoItemDisplay); - infoItem.setTagCompound(infoItemTag); - - var infoTag = infoItem.writeToNBT(new NBTTagCompound()); + var infoTag = new ItemStack(LabsItems.INFO_ITEM, 1, ItemInfo.AE2_STUFF_REMAP_INFO) + .writeToNBT(new NBTTagCompound()); infoTag.setInteger("Slot", patternTag == null ? 0 : 1); patternItems.appendTag(infoTag); diff --git a/src/main/java/com/nomiceu/nomilabs/util/LabsTranslate.java b/src/main/java/com/nomiceu/nomilabs/util/LabsTranslate.java index bbdee8a8..29b6a06f 100644 --- a/src/main/java/com/nomiceu/nomilabs/util/LabsTranslate.java +++ b/src/main/java/com/nomiceu/nomilabs/util/LabsTranslate.java @@ -1,7 +1,9 @@ package com.nomiceu.nomilabs.util; +import java.util.ArrayList; import java.util.Arrays; import java.util.IllegalFormatException; +import java.util.List; import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.translation.I18n; @@ -42,9 +44,10 @@ private static String translateServerSide(String key, Object... params) { } } - // Only GT Format Code version is available. - // If need Text Formatting format, place it in lang. - + /** + * Only GT Format Code version is available.
+ * If need Text Formatting format, place it in lang. + */ public static String translateFormat(String key, TooltipHelper.GTFormatCode format, Object... params) { return format(translate(key, params), format); } @@ -65,6 +68,14 @@ public static String format(String str, Format... formats) { TextFormatting.RESET; } + public static Translatable translatable(String key, Object... params) { + return new Translatable(key, params); + } + + public static Translatable translatableLiteral(String text) { + return new TranslatableLiteral(text); + } + public static class Format { public final String format; @@ -73,12 +84,90 @@ private Format(String format) { this.format = format; } - public Format of(TextFormatting format) { + public static Format of(TextFormatting format) { return new Format(format.toString()); } - public Format of(TooltipHelper.GTFormatCode format) { + public static Format of(TooltipHelper.GTFormatCode format) { return new Format(format.toString()); } } + + /** + * A translatable object, which has its value translated dynamically (allowing for on-the-fly language changes) + */ + @SuppressWarnings("unused") + public static class Translatable { + + public final String key; + public final Object[] params; + + protected List format; + protected List appended; + + public Translatable(String key, Object... params) { + this.key = key; + this.params = params; + this.format = new ArrayList<>(); + this.appended = new ArrayList<>(); + } + + public Translatable addFormat(Format format) { + this.format.add(format); + return this; + } + + public Translatable addFormat(TextFormatting format) { + this.format.add(Format.of(format)); + return this; + } + + public Translatable addFormat(TooltipHelper.GTFormatCode format) { + this.format.add(Format.of(format)); + return this; + } + + public Translatable append(Translatable append) { + this.appended.add(append); + return this; + } + + public String translate() { + String translated = translateThis(); + + for (var toAppend : appended) { + translated = translated.concat(toAppend.translate()); + } + + return translated; + } + + protected String translateThis() { + if (format.isEmpty()) return LabsTranslate.translate(key, params); + + return LabsTranslate.format(LabsTranslate.translate(key, params), format.toArray(new Format[0])); + } + + @Override + public String toString() { + return translate(); + } + } + + /** + * A translatable object with literal text, designed to be appended to a Translatable object. + */ + public static class TranslatableLiteral extends Translatable { + + public TranslatableLiteral(String text) { + super(text); + } + + @Override + protected String translateThis() { + if (format.isEmpty()) return key; + + return LabsTranslate.format(key, format.toArray(new Format[0])); + } + } } diff --git a/src/main/resources/assets/nomilabs/lang/en_us.lang b/src/main/resources/assets/nomilabs/lang/en_us.lang index 54434e08..889a9b86 100644 --- a/src/main/resources/assets/nomilabs/lang/en_us.lang +++ b/src/main/resources/assets/nomilabs/lang/en_us.lang @@ -512,6 +512,8 @@ item.nomilabs.hand_framing_tool.desc4=If you wish to frame the tool in a Craftin item.nomilabs.hand_framing_tool.desc5=Then, once the tool is framed, right clicking any drawers in-world will frame them. item.nomilabs.hand_framing_tool.desc6=When right clicking any wood-type drawers in world, they will also be turned into framed drawers. +item.nomilabs.info_item.name=Information + item.nomilabs.pulsatingdust.name=Pulsating Dust item.nomilabs.pulsatingmesh.name=Pulsating Mesh @@ -592,6 +594,12 @@ tooltip.stabilized_matters.description2=§f§oIt looks oddly familiar.§r tooltip.nomilabs.capacitors.description=Ender IO Machine Upgrade tooltip.nomilabs.capacitors.level=§5Level: %s§r +tooltip.nomilabs.info.ae2-stuff.1=§cAE2 Stuff Pattern Encoders have been removed.§r +tooltip.nomilabs.info.ae2-stuff.2=§6Please use AE2 Pattern Terminals instead.§r +tooltip.nomilabs.info.ae2-stuff.3=§eAll Existing Items §l(including in Patterns),§r +tooltip.nomilabs.info.ae2-stuff.4=§eBlocks, and usages in Recipes,§r +tooltip.nomilabs.info.ae2-stuff.5=§ehave been replaced by AE2 Interfaces.§r + # Multiblocks tooltip.nomilabs.microverse_projector_1.description=§8A machine capable of stabilizing projection into microverses for basic micro miner missions.§r tooltip.nomilabs.microverse_projector_2.description=§8An advanced machine capable of stabilizing projection into microverses for complex missions into the deepest parts of space.§r diff --git a/src/main/resources/assets/nomilabs/models/item/info_item.json b/src/main/resources/assets/nomilabs/models/item/info_item.json new file mode 100644 index 00000000..97d5f03d --- /dev/null +++ b/src/main/resources/assets/nomilabs/models/item/info_item.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "nomilabs:items/info_item" + } +} diff --git a/src/main/resources/assets/nomilabs/textures/items/info_item.png b/src/main/resources/assets/nomilabs/textures/items/info_item.png new file mode 100644 index 00000000..4b919578 Binary files /dev/null and b/src/main/resources/assets/nomilabs/textures/items/info_item.png differ