From 11e6aee70e3bd102a439f0dc1bb2eacd672f93dc Mon Sep 17 00:00:00 2001 From: micle Date: Wed, 14 Jan 2026 00:10:47 +0100 Subject: [PATCH] Reworked tooltip for totems to look better and be translatable via lang files. Implemented helper method for creating text components displaying keybind keys. --- .../item/totem/TotemItem.java | 67 +++++++++++-------- .../totem_of_reviving/util/LangAsset.java | 30 +++++++++ .../assets/totem_of_reviving/lang/en_us.json | 12 ++++ 3 files changed, 80 insertions(+), 29 deletions(-) diff --git a/src/main/java/dev/micle/totem_of_reviving/item/totem/TotemItem.java b/src/main/java/dev/micle/totem_of_reviving/item/totem/TotemItem.java index b921044..d9018a4 100644 --- a/src/main/java/dev/micle/totem_of_reviving/item/totem/TotemItem.java +++ b/src/main/java/dev/micle/totem_of_reviving/item/totem/TotemItem.java @@ -1,6 +1,6 @@ package dev.micle.totem_of_reviving.item.totem; -import dev.micle.totem_of_reviving.TotemOfReviving; +import com.mojang.blaze3d.platform.InputConstants; import dev.micle.totem_of_reviving.component.TotemData; import dev.micle.totem_of_reviving.setup.Config; import dev.micle.totem_of_reviving.setup.ModDataComponents; @@ -22,9 +22,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Rarity; import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.level.Level; -import org.apache.commons.codec.language.bm.Lang; import org.jetbrains.annotations.NotNull; -import org.lwjgl.glfw.GLFW; import javax.annotation.ParametersAreNonnullByDefault; import java.io.IOException; @@ -202,45 +200,56 @@ public abstract class TotemItem extends Item { @Override @ParametersAreNonnullByDefault public void appendHoverText(ItemStack stack, TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + Minecraft minecraft = Minecraft.getInstance(); TotemData totemData = getTotemData(stack); - Optional targetUUID = totemData.getTargetUUID(); - if (targetUUID.isEmpty()) { - tooltipComponents.add(Component.literal(ChatFormatting.RED + "Target: " + ChatFormatting.DARK_RED + "N/A")); - } else { - tooltipComponents.add(Component.literal(ChatFormatting.WHITE + "Target: " + ChatFormatting.GRAY + totemData.getTargetName())); - } + tooltipComponents.add(LangAsset.TOOLTIP_TOTEM_TARGET.getComponent( + totemData.getTargetUUID().isPresent() + ? Component.literal(totemData.getTargetName()).withStyle(ChatFormatting.GRAY) + : LangAsset.GENERAL_NA.getComponent().withStyle(ChatFormatting.RED) + ).withStyle(ChatFormatting.WHITE)); + + tooltipComponents.add(LangAsset.TOOLTIP_TOTEM_TARGET_COST.getComponent( + Component.literal(String.format("%d", getTargetCost(totemData))).withStyle( + getTargetCost(totemData) <= getMaxCharge() + ? ChatFormatting.GRAY + : ChatFormatting.RED + ) + ).withStyle(ChatFormatting.WHITE)); + + tooltipComponents.add(LangAsset.TOOLTIP_TOTEM_CHARGES.getComponent( + Component.literal(String.format("%d/%d", totemData.getCharge(), getMaxCharge())).withStyle(ChatFormatting.GRAY) + ).withStyle(ChatFormatting.WHITE)); tooltipComponents.add(Component.empty()); - - if (!canAffordTarget(totemData)) { - tooltipComponents.add(Component.literal(ChatFormatting.RED + "Charges: " + ChatFormatting.DARK_RED + "(" + totemData.getCharge() + "/" + getTargetCost(totemData) + ") " + - ChatFormatting.RED + "[Max: " + ChatFormatting.DARK_RED + getMaxCharge() + ChatFormatting.RED + "] [Multi: " + ChatFormatting.DARK_RED + getConfig().getChargeCostMultiplier() + ChatFormatting.RED + "]")); - } else { - tooltipComponents.add(Component.literal(ChatFormatting.WHITE + "Charges: " + ChatFormatting.GRAY + "(" + totemData.getCharge() + "/" + getTargetCost(totemData) + ") " + - ChatFormatting.WHITE + "[Max: " + ChatFormatting.GRAY + getMaxCharge() + ChatFormatting.WHITE + "] [Multi: " + ChatFormatting.GRAY + getConfig().getChargeCostMultiplier() + ChatFormatting.WHITE + "]")); + if (isChargeCostDynamic()) { + tooltipComponents.add(LangAsset.TOOLTIP_TOTEM_DYNAMIC_COST.getComponent( + Component.literal(String.format("%.2f", getConfig().getChargeCostMultiplier())).withStyle(ChatFormatting.GRAY) + ).withStyle(ChatFormatting.WHITE, ChatFormatting.ITALIC)); } - if (getConfig().getCanReviveMoreExpensiveTargets()) { - tooltipComponents.add(Component.literal(ChatFormatting.WHITE + "Can revive more expensive targets.")); + tooltipComponents.add(LangAsset.TOOLTIP_TOTEM_CAN_REVIVE_MORE_EXPENSIVE_TARGETS.getComponent().withStyle(ChatFormatting.WHITE, ChatFormatting.ITALIC)); } - if (getConfig().getCanReviveAcrossDimensions()) { - tooltipComponents.add(Component.literal(ChatFormatting.WHITE + "Can revive targets across dimensions.")); + tooltipComponents.add(LangAsset.TOOLTIP_TOTEM_CAN_REVIVE_ACROSS_DIMENSIONS.getComponent().withStyle(ChatFormatting.WHITE, ChatFormatting.ITALIC)); } tooltipComponents.add(Component.empty()); - if (GLFW.glfwGetKey(Minecraft.getInstance().getWindow().getWindow(), GLFW.GLFW_KEY_LEFT_SHIFT) == 1) { - tooltipComponents.add(Component.literal(ChatFormatting.GRAY + "Showing advanced tooltip.")); - tooltipComponents.add(Component.literal(ChatFormatting.WHITE + "[" + ChatFormatting.GRAY + "R-CLICK" + ChatFormatting.WHITE + "]")); - tooltipComponents.add(Component.literal(ChatFormatting.WHITE + "When second hand is empty: revive target.")); - tooltipComponents.add(Component.literal(ChatFormatting.WHITE + "When second hand is holding a reviving charge: charge totem.")); - tooltipComponents.add(Component.literal("")); - tooltipComponents.add(Component.literal(ChatFormatting.WHITE + "[" + ChatFormatting.GRAY + "L-SHIFT + R-CLICK" + ChatFormatting.WHITE + "]")); - tooltipComponents.add(Component.literal(ChatFormatting.WHITE + "Change target.")); + if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), minecraft.options.keyShift.getKey().getValue())) { + tooltipComponents.add(LangAsset.TOOLTIP_ADVANCED_TOOLTIP_SHOWN.getComponent().withStyle(ChatFormatting.WHITE, ChatFormatting.UNDERLINE)); + + tooltipComponents.add(LangAsset.createKeyText(true, new ChatFormatting[]{ChatFormatting.WHITE}, new ChatFormatting[]{ChatFormatting.GRAY}, minecraft.options.keyUse)); + tooltipComponents.add(LangAsset.TOOLTIP_TOTEM_REVIVE_INSTRUCTION.getComponent().withStyle(ChatFormatting.WHITE)); + tooltipComponents.add(LangAsset.TOOLTIP_TOTEM_CHARGE_INSTRUCTION.getComponent().withStyle(ChatFormatting.WHITE)); + tooltipComponents.add(Component.empty()); + + tooltipComponents.add(LangAsset.createKeyText(true, new ChatFormatting[]{ChatFormatting.WHITE}, new ChatFormatting[]{ChatFormatting.GRAY}, minecraft.options.keyShift, minecraft.options.keyUse)); + tooltipComponents.add(LangAsset.TOOLTIP_TOTEM_CHANGE_TARGET_INSTRUCTION.getComponent().withStyle(ChatFormatting.WHITE)); } else { - tooltipComponents.add(Component.literal(ChatFormatting.GRAY + "Hold [" + ChatFormatting.DARK_GRAY + "L-SHIFT" + ChatFormatting.GRAY + "] for advanced tooltip.")); + tooltipComponents.add(LangAsset.TOOLTIP_ADVANCED_TOOLTIP_HIDDEN.getComponent( + LangAsset.createKeyText(true, new ChatFormatting[]{ChatFormatting.WHITE}, new ChatFormatting[]{ChatFormatting.GRAY}, minecraft.options.keyShift) + )); } super.appendHoverText(stack, context, tooltipComponents, tooltipFlag); diff --git a/src/main/java/dev/micle/totem_of_reviving/util/LangAsset.java b/src/main/java/dev/micle/totem_of_reviving/util/LangAsset.java index eb6237f..eb1e2b8 100644 --- a/src/main/java/dev/micle/totem_of_reviving/util/LangAsset.java +++ b/src/main/java/dev/micle/totem_of_reviving/util/LangAsset.java @@ -1,10 +1,16 @@ package dev.micle.totem_of_reviving.util; import dev.micle.totem_of_reviving.TotemOfReviving; +import net.minecraft.ChatFormatting; +import net.minecraft.client.KeyMapping; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentUtils; import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.contents.TranslatableContents; +import java.util.ArrayList; +import java.util.List; + public enum LangAsset { ITEM_GROUP_MAIN("itemGroup", "main"), ITEM_STRAW_TOTEM("item", "straw_totem"), @@ -15,6 +21,18 @@ public enum LangAsset { ITEM_IRON_CHARGE("item", "iron_charge"), ITEM_DIAMOND_CHARGE("item", "diamond_charge"), ITEM_NETHERITE_CHARGE("item", "netherite_charge"), + TOOLTIP_TOTEM_TARGET("tooltip", "totem_target"), + TOOLTIP_TOTEM_TARGET_COST("tooltip", "totem_target_cost"), + TOOLTIP_TOTEM_CHARGES("tooltip", "totem_charges"), + TOOLTIP_TOTEM_DYNAMIC_COST("tooltip", "totem_dynamic_cost"), + TOOLTIP_TOTEM_CAN_REVIVE_MORE_EXPENSIVE_TARGETS("tooltip", "totem_can_revive_more_expensive_targets"), + TOOLTIP_TOTEM_CAN_REVIVE_ACROSS_DIMENSIONS("tooltip", "totem_can_revive_across_dimensions"), + TOOLTIP_TOTEM_REVIVE_INSTRUCTION("tooltip", "totem_revive_instruction"), + TOOLTIP_TOTEM_CHARGE_INSTRUCTION("tooltip", "totem_charge_instruction"), + TOOLTIP_TOTEM_CHANGE_TARGET_INSTRUCTION("tooltip", "totem_change_target_instructions"), + TOOLTIP_ADVANCED_TOOLTIP_HIDDEN("tooltip", "advanced_tooltip_hidden"), + TOOLTIP_ADVANCED_TOOLTIP_SHOWN("tooltip", "advanced_tooltip_shown"), + GENERAL_NA("general", "na"), MESSAGE_UNABLE_TO_FIND_PLAYER("message", "unable_to_find_player"), MESSAGE_PLAYER_IS_NOT_DEAD("message", "player_is_not_dead"), MESSAGE_PLAYER_IS_IN_ANOTHER_DIMENSION("message", "player_is_in_another_dimension"), @@ -39,4 +57,16 @@ public enum LangAsset { public MutableComponent getComponent(Object ...args) { return Component.translatable(String.format("%s.%s.%s", category, TotemOfReviving.MOD_ID, key), args); } + + public static Component createKeyText(boolean isEnclosed, ChatFormatting[] textFormat, ChatFormatting[] keyFormat, KeyMapping...keys) { + List textComponents = new ArrayList<>(); + textComponents.add(isEnclosed ? Component.literal("[").withStyle(textFormat) : Component.empty()); + for (int i = 0; i < keys.length; i++) { + if (i > 0) textComponents.add(Component.literal(" + ").withStyle(textFormat)); + textComponents.add(Component.literal(keys[i].getKey().getDisplayName().getString()).withStyle(keyFormat)); + } + textComponents.add(isEnclosed ? Component.literal("]").withStyle(textFormat) : Component.empty()); + + return ComponentUtils.formatList(textComponents, Component.empty()); + } } diff --git a/src/main/resources/assets/totem_of_reviving/lang/en_us.json b/src/main/resources/assets/totem_of_reviving/lang/en_us.json index 8141759..01a7793 100644 --- a/src/main/resources/assets/totem_of_reviving/lang/en_us.json +++ b/src/main/resources/assets/totem_of_reviving/lang/en_us.json @@ -8,6 +8,18 @@ "item.totem_of_reviving.iron_charge": "Iron reviving charge", "item.totem_of_reviving.diamond_charge": "Diamond reviving charge", "item.totem_of_reviving.netherite_charge": "Netherite reviving charge", + "tooltip.totem_of_reviving.totem_target": "Target -> %s", + "tooltip.totem_of_reviving.totem_target_cost": "Cost -> %s", + "tooltip.totem_of_reviving.totem_charges": "Charges -> %s", + "tooltip.totem_of_reviving.totem_dynamic_cost": "Dynamic cost (Multiplier: %s).", + "tooltip.totem_of_reviving.totem_can_revive_more_expensive_targets": "Can revive more expensive targets.", + "tooltip.totem_of_reviving.totem_can_revive_across_dimensions": "Can revive across dimensions.", + "tooltip.totem_of_reviving.totem_revive_instruction": "When second hand is empty: revive target.", + "tooltip.totem_of_reviving.totem_charge_instruction": "When second hand has a reviving charge: charge totem.", + "tooltip.totem_of_reviving.totem_change_target_instructions": "Change target.", + "tooltip.totem_of_reviving.advanced_tooltip_hidden": "Hold %s for advanced tooltip.", + "tooltip.totem_of_reviving.advanced_tooltip_shown": "Showing advanced tooltip:", + "general.totem_of_reviving.na": "N/A", "message.totem_of_reviving.unable_to_find_player": "Unable to find player!", "message.totem_of_reviving.player_is_not_dead": "%s is not dead!", "message.totem_of_reviving.player_is_in_another_dimension": "%s is in a different dimension!",