A mod that adds your armor to the hud modrinth.com/mod/simple-armor-hud
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

merge: fixed config screen and trim empty slots

+75 -95
+9 -3
README.md
··· 5 5 <h1 align="center">Simple armor hud</h1> 6 6 7 7 <p align="center"> 8 - <img src="https://img.shields.io/badge/for%20MC-1.17.x,%201.18.x,%201.19.x,%201.20.x-green" alt="Minecraft version"/> 9 8 <img src="https://img.shields.io/github/v/release/LegoRaft/simple-armor-hud?color=yellow" alt="Release"/> 10 9 <img src="https://img.shields.io/modrinth/dt/tJflAtvJ?label=modrinth" alt="Modrinth downloads"/> 11 10 <img src="https://img.shields.io/github/downloads/legoraft/simple-armor-hud/total" alt="Github downloads"/> ··· 15 14 This mod shows your armor above the foodbar in the in-game hud. It also moves armor up when underwater and down when in creative and has a few config options for compatibility with other mods. You can toggle the armor hud on or off with a keybind, configurable through the normal menu. 16 15 17 16 ### Features 18 - <img src="https://user-images.githubusercontent.com/50689727/130084592-5a35579a-f300-4c6e-b6ad-9b6bd620904c.png" alt="armor hud third person" width="640"/> <br> 17 + <img src="https://cdn.modrinth.com/data/tJflAtvJ/images/e9e59b541926f4ef4ab4081a2d5fb39ed7926711.png" alt="armor hud in third person" width="640"/> <br> 19 18 _Shows armor you're currently wearing_ 20 19 <img src="https://cdn.modrinth.com/data/tJflAtvJ/images/dcc817d1be3765a8af5ef581bff1abe909c77e47.png" alt="armor hud underwater" width="640"/><br> 21 20 _Moves armor up underwater_ ··· 24 23 If you have any bug reports or a suggestion for the mod leave them [here](https://github.com/LegoRaft/simple-armor-hud/issues). If you have any coding experience and want to help out with development, fork the repository and open a [pull request](https://github.com/legoraft/simple-armor-hud/pulls). 25 24 26 25 ### Translations 27 - This mod is available with english and dutch translations, if you know any other translations, create a [pull request](https://github.com/legoraft/simple-armor-hud/pulls) with a new [lang](https://github.com/legoraft/simple-armor-hud/tree/main/src/main/resources/assets/simple-armor-hud/lang) file with your translation. 26 + This mod currently supports the following languages: 27 + - English 28 + - Dutch 29 + - German 30 + - Vietnamese 31 + - Traditional Chinese 32 + 33 + If you see any missing languages or ar familiar translating, feel free to open a [pull request](https://github.com/legoraft/simple-armor-hud/pulls) and add your translation in a new [lang file](https://github.com/legoraft/simple-armor-hud/tree/main/src/main/resources/assets/simple-armor-hud/lang). The [`en_us.json`](https://github.com/legoraft/simple-armor-hud/blob/main/src/main/resources/assets/simple-armor-hud/lang/en_us.json) file is the source of truth for translation keys, so reference that one. 28 34 29 35 ### Dependencies 30 36 Simple armor hud requires the [Fabric API](https://modrinth.com/mod/fabric-api)
+11 -6
src/client/java/com/armorhud/config/config.java
··· 22 22 private static final Path CONFIG_PATH = FabricLoader.getInstance().getConfigDir().resolve("armorhud.properties"); 23 23 24 24 public enum Position { 25 - FOODBAR, 26 - HEALTHBAR, 27 - HOTBAR_LEFT, 28 - HOTBAR_RIGHT; 25 + FOODBAR("config.armorposition.foodbar"), 26 + HEALTHBAR("config.armorposition.healthbar"), 27 + HOTBAR_LEFT("config.armorposition.hotbar_left"), 28 + HOTBAR_RIGHT("config.armorposition.hotbar_right"); 29 + 30 + private final String key; 31 + Position(String key) { 32 + this.key = key; 33 + } 29 34 30 - public Component displayName() { 31 - return Component.translatable("config.armorposition." + name().toLowerCase()); 35 + public Component getDisplayName() { 36 + return Component.translatable(this.key); 32 37 } 33 38 } 34 39
+27 -61
src/client/java/com/armorhud/config/configScreen.java
··· 3 3 import net.fabricmc.api.EnvType; 4 4 import net.fabricmc.api.Environment; 5 5 import net.minecraft.client.Minecraft; 6 - import net.minecraft.client.gui.GuiGraphicsExtractor; 7 - import net.minecraft.client.gui.components.Button; 8 - import net.minecraft.client.gui.components.CycleButton; 9 - import net.minecraft.client.gui.components.OptionsList; 6 + import net.minecraft.client.OptionInstance; 10 7 import net.minecraft.client.gui.screens.Screen; 11 8 import net.minecraft.client.gui.screens.options.OptionsSubScreen; 12 - import net.minecraft.client.gui.layouts.*; 13 9 import net.minecraft.network.chat.Component; 14 10 15 11 @Environment(EnvType.CLIENT) ··· 21 17 this.parent = parent; 22 18 } 23 19 24 - public CycleButton<?> doubleHotbarToggle; 25 - public CycleButton<?> betterMountHudToggle; 26 - public CycleButton<?> armorHudToggle; 27 - public CycleButton<?> disableArmorBar; 28 - public CycleButton<?> armorPosition; 29 - public CycleButton<?> rightToLeftToggle; 30 - public CycleButton<?> trimEmptySlots; 31 - 32 - public Button doneButton; 33 - 34 20 @Override 35 - protected void init() { 36 - doubleHotbarToggle = CycleButton.onOffBuilder(config.DOUBLE_HOTBAR) 37 - .create(Component.translatable("config.doublehotbar"), ((button, value) -> config.DOUBLE_HOTBAR = !config.DOUBLE_HOTBAR)); 38 - 39 - betterMountHudToggle = CycleButton.onOffBuilder(config.BETTER_MOUNT_HUD) 40 - .create(Component.translatable("config.bettermounthud"), (button, value) -> config.BETTER_MOUNT_HUD = !config.BETTER_MOUNT_HUD); 41 - 42 - armorHudToggle = CycleButton.onOffBuilder(config.ARMOR_HUD) 43 - .create(Component.translatable("config.armorvisible"), (button, value) -> config.ARMOR_HUD = !config.ARMOR_HUD); 44 - 45 - disableArmorBar = CycleButton.onOffBuilder(config.DISABLE_ARMOR_BAR) 46 - .create(Component.translatable("config.disablearmorbar"), ((button, value) -> config.DISABLE_ARMOR_BAR = !config.DISABLE_ARMOR_BAR)); 47 - 48 - armorPosition = CycleButton.builder(config.Position::displayName, config.Position.valueOf(String.valueOf(config.position))).withValues(config.Position.values()) 49 - .create(Component.translatable("config.armorposition"), ((button, value) -> config.position = value)); 50 - 51 - rightToLeftToggle = CycleButton.onOffBuilder(config.RTL) 52 - .create(Component.translatable("config.righttoleft"), (button, value) -> config.RTL = !config.RTL); 53 - 54 - trimEmptySlots = CycleButton.onOffBuilder(config.TRIM_EMPTY_SLOTS) 55 - .create(Component.translatable("config.trimemptyslots"), ((button, value) -> config.TRIM_EMPTY_SLOTS = !config.TRIM_EMPTY_SLOTS)); 56 - 57 - doneButton = Button 58 - .builder(Component.translatable("config.done"), button -> onClose()) 59 - .bounds(width / 2 - 100, height - 25, 200, 20) 60 - .build(); 61 - 62 - OptionsList optionListWidget = this.addRenderableWidget(new OptionsList(this.minecraft, this.width, this)); 63 - optionListWidget.addHeader(Component.translatable("config.header.general")); 64 - optionListWidget.addSmall(armorHudToggle, disableArmorBar); 21 + protected void addOptions() { 22 + assert this.list != null; 65 23 66 - optionListWidget.addHeader(Component.translatable("config.header.compatibility")); 67 - optionListWidget.addSmall(betterMountHudToggle, doubleHotbarToggle); 68 - 69 - optionListWidget.addHeader(Component.translatable("config.header.display")); 70 - optionListWidget.addSmall(armorPosition, rightToLeftToggle); 71 - optionListWidget.addSmall(trimEmptySlots, null); 24 + OptionInstance<config.Position> armorPositionOptions = new OptionInstance<>( 25 + "config.armorposition", 26 + OptionInstance.noTooltip(), 27 + (component, value) -> value.getDisplayName(), 28 + new OptionInstance.Enum<>(java.util.List.of(config.Position.values()), null), 29 + config.position, 30 + value -> config.position = value 31 + ); 72 32 73 - addRenderableWidget(doneButton); 74 - } 33 + this.list.addHeader(Component.translatable("config.header.general")); 34 + this.list.addSmall( 35 + OptionInstance.createBoolean("config.armorvisible", config.ARMOR_HUD, v -> config.ARMOR_HUD = v), 36 + OptionInstance.createBoolean("config.disablearmorbar", config.DISABLE_ARMOR_BAR, v -> config.DISABLE_ARMOR_BAR = v) 37 + ); 75 38 76 - @Override 77 - protected void addOptions() { } 39 + this.list.addHeader(Component.translatable("config.header.compatibility")); 40 + this.list.addSmall( 41 + OptionInstance.createBoolean("config.doublehotbar", config.DOUBLE_HOTBAR, v -> config.DOUBLE_HOTBAR = v), 42 + OptionInstance.createBoolean("config.bettermounthud", config.BETTER_MOUNT_HUD, v -> config.BETTER_MOUNT_HUD = v) 43 + ); 78 44 79 - @Override 80 - public void extractRenderState(GuiGraphicsExtractor context, int mouseX, int mouseY, float delta) { 81 - context.centeredText(this.font, Component.translatable("config.title"), this.width / 2, 12, 0xffffff); 82 - super.extractRenderState(context, mouseX, mouseY, delta); 45 + this.list.addHeader(Component.translatable("config.header.display")); 46 + this.list.addSmall( 47 + armorPositionOptions, 48 + OptionInstance.createBoolean("config.righttoleft", config.RTL, v -> config.RTL = v), 49 + OptionInstance.createBoolean("config.trimemptyslots", config.TRIM_EMPTY_SLOTS, v -> config.TRIM_EMPTY_SLOTS = v) 50 + ); 83 51 } 84 52 85 53 @Override 86 54 public void onClose() { 87 - assert this.minecraft != null; 88 - 89 55 config.save(); 90 56 this.minecraft.setScreen(this.parent); 91 57 }
+28 -25
src/client/java/com/armorhud/mixin/client/armorHudMixin.java
··· 72 72 73 73 assert minecraft.player != null; 74 74 ArmorAccessor armorAccessor = armorHud.getArmorAccessor(); 75 + EquipmentSlot[] slots = EquipmentSlot.values(); 75 76 76 77 final int hungerWidth = 14; // Magic number to center 4 armor pieces 77 78 final int armorWidth = 15; 78 79 80 + int emptyArmorSlots = 0; 81 + if (config.TRIM_EMPTY_SLOTS) { 82 + for (EquipmentSlot slot : slots) { 83 + if (slot.isArmor()) { 84 + ItemStack stack = armorAccessor.getArmorPiece(minecraft.player, slot); 85 + if (stack.isEmpty()) { 86 + emptyArmorSlots++; 87 + } 88 + } 89 + } 90 + } 91 + 79 92 float hungerX = scaledWidth / 2f + startXPosition; 80 - float x = hungerX + hungerWidth + 2; 81 - 82 - EquipmentSlot[] slots = EquipmentSlot.values(); 93 + float x = hungerX + hungerWidth - (7 * emptyArmorSlots) + 2 - (armorWidth * 2); 83 94 84 95 if (config.RTL) { 96 + if ( config.TRIM_EMPTY_SLOTS ) { x -= (float) (( (float) armorWidth / 2 ) + 0.5); } 97 + x += armorWidth; 85 98 for ( int i = slots.length - 1; i > 0; i-- ) { 86 99 EquipmentSlot slot = slots[i]; 100 + if (!slot.isArmor()) continue; 101 + ItemStack armor = armorAccessor.getArmorPiece(minecraft.player, slot); 102 + 103 + if (config.TRIM_EMPTY_SLOTS && armor.isEmpty()) continue; 87 104 x -= armorWidth; 88 105 89 - if ( slot.isArmor() ) { 90 - renderArmorPiece(context, x, armorHeight, minecraft.player, armorAccessor.getArmorPiece(minecraft.player, slot)); 91 - } 106 + renderArmorPiece(context, x, armorHeight, minecraft.player, armor); 92 107 } 93 108 } else { 109 + if ( config.TRIM_EMPTY_SLOTS ) { x += ( (float) hungerWidth / 2 ); } 94 110 for ( EquipmentSlot slot : slots ) { 95 - x -= armorWidth; 111 + if ( !slot.isArmor() ) continue; 112 + ItemStack armor = armorAccessor.getArmorPiece(minecraft.player, slot); 96 113 97 - if ( slot.isArmor() ) { 98 - renderArmorPiece(context, x, armorHeight, minecraft.player, armorAccessor.getArmorPiece(minecraft.player, slot)); 99 - } 100 - } 101 - } 102 - 103 - /* Putting this on the backburner for a little while to implement other things - Legoraft 114 + if ( config.TRIM_EMPTY_SLOTS && armor.isEmpty() ) continue; 115 + x -= armorWidth; 104 116 105 - // counts empty slots to center condensed armor bar, don't like having to loop through the equip slots twice but idk how else to center this dynamically -dino 106 - int emptyArmorSlots = 0; 107 - if (config.TRIM_EMPTY_SLOTS) { 108 - for (int i = 2; i<6; i++) { // checks players armor slots only. probably makes stuff like trinkets incompatible -dino 109 - if(client.player.getEquippedStack(slots[i]).isEmpty()) { 110 - emptyArmorSlots++; 111 - } 112 - } 117 + renderArmorPiece(context, x, armorHeight, minecraft.player, armor); 118 + } 113 119 } 114 - 115 - float x = hungerX + hungerWidth - (7 * emptyArmorSlots) + 2; 116 - */ 117 120 } 118 121 119 122 @Unique