From 6593a3f089107dc4c0221d1794b9cc05f4fa942a Mon Sep 17 00:00:00 2001 From: froslanz Date: Sat, 24 Oct 2026 12:57:42 -0400 Subject: [PATCH] add Armor HUD module showing worn armor durability lists the four worn armor pieces helmet-to-boots, skipping empty slots. with Icons on (default) each row draws the item icon with its durability percentage beside it, vertically centered; with Icons off it draws the item's hover name plus the percentage as plain text. the percentage is colored by condition (green >= 60%, yellow >= 30%, red below) and shows a dash for items without durability. width/height track the drawn rows so the editor box matches, falling back to the constructor size when nothing is equipped --- .../features/modules/hud/ArmorHudModule.java | 80 +++++++++++++++++++ .../java/cc/fros/manager/ModuleManager.java | 2 + 2 files changed, 82 insertions(+) create mode 100644 src/main/java/cc/fros/features/modules/hud/ArmorHudModule.java diff --git a/src/main/java/cc/fros/features/modules/hud/ArmorHudModule.java b/src/main/java/cc/fros/features/modules/hud/ArmorHudModule.java new file mode 100644 index 0000000..496b926 --- /dev/null +++ b/src/main/java/cc/fros/features/modules/hud/ArmorHudModule.java @@ -0,0 +1,80 @@ +package cc.fros.features.modules.hud; + +import cc.fros.event.impl.render.Render2DEvent; +import cc.fros.features.modules.client.HudModule; +import cc.fros.features.settings.Setting; +import cc.fros.util.render.FrosFont; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.ItemStack; + +public class ArmorHudModule extends HudModule { + /** helmet first, boots last */ + private static final EquipmentSlot[] SLOTS = { + EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET + }; + + private static final int HEALTHY = 0x55FF55; + private static final int WORN = 0xFFFF55; + private static final int CRITICAL = 0xFF5555; + + public final Setting icons = bool("Icons", true); + + public ArmorHudModule() { + super("Armor", "Display armor durability", 70, 40); + } + + @Override + protected void render(Render2DEvent e) { + super.render(e); + if (nullCheck()) return; + + float x = getX(); + float y = getY(); + boolean showIcons = icons.getValue(); + int rowHeight = showIcons ? 16 : FrosFont.lineHeight(); + int rows = 0; + int textWidth = 0; + + for (EquipmentSlot slot : SLOTS) { + ItemStack stack = mc.player.getItemBySlot(slot); + if (stack.isEmpty()) continue; + + float rowY = y + rows * rowHeight; + float ratio = durability(stack); + String percent = ratio < 0f ? "\u2014" : Math.round(ratio * 100) + "%"; + int color = ratio < 0f ? -1 + : ratio >= 0.6f ? HEALTHY + : ratio >= 0.3f ? WORN + : CRITICAL; + + int textX; + int textY; + if (showIcons) { + e.getContext().renderItem(stack, (int) x, (int) rowY); + textX = (int) x + 19; + textY = (int) (rowY + 8 - FrosFont.visualCenter()); + } else { + Component name = stack.getHoverName(); + FrosFont.draw(e.getContext(), name, (int) x, (int) rowY, -1); + textX = (int) (x + FrosFont.width(name) + 4); + textY = (int) rowY; + } + FrosFont.draw(e.getContext(), percent, textX, textY, color); + textWidth = Math.max(textWidth, textX - (int) x + FrosFont.width(percent)); + rows++; + } + + if (rows > 0) { + setWidth(textWidth); + setHeight(rows * rowHeight); + } + } + + /** durability left as 0..1, or -1 for items without durability */ + private static float durability(ItemStack stack) { + int max = stack.getMaxDamage(); + if (max <= 0) return -1f; + return (max - stack.getDamageValue()) / (float) max; + } +} diff --git a/src/main/java/cc/fros/manager/ModuleManager.java b/src/main/java/cc/fros/manager/ModuleManager.java index 41d0209..8283381 100644 --- a/src/main/java/cc/fros/manager/ModuleManager.java +++ b/src/main/java/cc/fros/manager/ModuleManager.java @@ -18,6 +18,7 @@ import cc.fros.features.modules.combat.KillAuraModule; import cc.fros.features.modules.combat.CriticalsModule; import cc.fros.features.modules.combat.KeyPearlModule; import cc.fros.features.modules.hud.ArrayListHudModule; +import cc.fros.features.modules.hud.ArmorHudModule; import cc.fros.features.modules.hud.CoordinatesHudModule; import cc.fros.features.modules.hud.FpsHudModule; import cc.fros.features.modules.hud.PingHudModule; @@ -57,6 +58,7 @@ public class ModuleManager implements Jsonable, Util { register(new RadarHudModule()); register(new WelcomerHudModule()); register(new TimeHudModule()); + register(new ArmorHudModule()); register(new HudEditorModule()); register(new ClickGuiModule()); register(new NotificationsModule());