diff --git a/src/main/java/com/lukasabbe/simplehud/config/Config.java b/src/main/java/com/lukasabbe/simplehud/config/Config.java index cf609f1..62f5fe9 100644 --- a/src/main/java/com/lukasabbe/simplehud/config/Config.java +++ b/src/main/java/com/lukasabbe/simplehud/config/Config.java @@ -23,10 +23,10 @@ public class Config { public Map HudActivatedList = getActiveHuds(); @SerialEntry - public HudPosition hudPosition = HudPosition.CENTER; + public HudPosition hudPositionElytra = HudPosition.CENTER; @SerialEntry - public SpeedEnum speedEnum = SpeedEnum.kmh; + public SpeedEnum speedEnumElytra = SpeedEnum.kmh; @SerialEntry public boolean ignoreSafeArea = false; diff --git a/src/main/java/com/lukasabbe/simplehud/config/ModMenu.java b/src/main/java/com/lukasabbe/simplehud/config/ModMenu.java new file mode 100644 index 0000000..97262ed --- /dev/null +++ b/src/main/java/com/lukasabbe/simplehud/config/ModMenu.java @@ -0,0 +1,64 @@ +package com.lukasabbe.simplehud.config; + +import com.terraformersmc.modmenu.api.ConfigScreenFactory; +import com.terraformersmc.modmenu.api.ModMenuApi; +import dev.isxander.yacl3.api.*; +import dev.isxander.yacl3.api.controller.TickBoxControllerBuilder; +import dev.isxander.yacl3.gui.controllers.TickBoxController; +import dev.isxander.yacl3.gui.controllers.cycling.EnumController; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; + +public class ModMenu implements ModMenuApi { + + @Override + public ConfigScreenFactory getModConfigScreenFactory() { + return this::createConfig; + } + + private Screen createConfig(Screen parent) { + Config instance = Config.HANDLER.instance(); + return YetAnotherConfigLib + .createBuilder() + .title(Component.translatable("simple_hud.config.title")) + .category(ConfigCategory + .createBuilder() + .name(Component.translatable("simple_hud.config.category.general.name")) + .tooltip(Component.translatable("simple_hud.config.category.general.tooltip")) + .group(toggleOptions()) + .build() + ) + .category(ConfigCategory + .createBuilder() + .name(Component.translatable("simple_hud.config.category.elytra_options.name")) + .option(Option + .createBuilder() + .name(Component.translatable("simple_hud.config.category.elytra_options.option.speed_enum.name")) + .description(OptionDescription.of(Component.translatable("simple_hud.config.category.elytra_options.option.speed_enum.description"))) + .binding(SpeedEnum.kmh, () -> instance.speedEnumElytra, newVal -> instance.speedEnumElytra = newVal) + .customController(opt -> new EnumController<>(opt, SpeedEnum.class)) + .build()) + .build()) + .save(() -> Config.HANDLER.save()) + .build().generateScreen(parent); + } + private OptionGroup toggleOptions(){ + var builder = OptionGroup + .createBuilder() + .name( Component.translatable("simple_hud.config.category.general.group.activated_huds.name")) + .description(OptionDescription.of(Component.translatable("simple_hud.config.category.general.group.activated_huds.description"))); + + Config instance = Config.HANDLER.instance(); + for(var transport : instance.HudActivatedList.entrySet()){ + builder.option(Option + .createBuilder() + .name(Component.translatable("simple_hud.config.category.general.group.activated_huds.option." + transport.getKey().split(":")[1] + ".name")) + .description(OptionDescription.of(Component.translatable("simple_hud.config.category.general.group.activated_huds.option." + transport.getKey().split(":")[1] + ".description"))) + .binding(true, transport::getValue, newVal -> instance.HudActivatedList.put(transport.getKey(), newVal)) + .controller(TickBoxControllerBuilder::create) + .build() + ); + } + return builder.build(); + } +} diff --git a/src/main/java/com/lukasabbe/simplehud/config/SpeedEnum.java b/src/main/java/com/lukasabbe/simplehud/config/SpeedEnum.java index bd5b428..a4ed289 100644 --- a/src/main/java/com/lukasabbe/simplehud/config/SpeedEnum.java +++ b/src/main/java/com/lukasabbe/simplehud/config/SpeedEnum.java @@ -9,6 +9,6 @@ public enum SpeedEnum implements NameableEnum { ms; @Override public Component getDisplayName() { - return null; + return Component.translatable("simple_hud.config.speed_enum." + name().toLowerCase()); } } diff --git a/src/main/java/com/lukasabbe/simplehud/huds/ElytraHud.java b/src/main/java/com/lukasabbe/simplehud/huds/ElytraHud.java index ce3e5ab..83691d4 100644 --- a/src/main/java/com/lukasabbe/simplehud/huds/ElytraHud.java +++ b/src/main/java/com/lukasabbe/simplehud/huds/ElytraHud.java @@ -5,9 +5,21 @@ import com.lukasabbe.simplehud.SimpleHudMod; import com.lukasabbe.simplehud.tools.ElytraTools; import net.minecraft.client.DeltaTracker; import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.renderer.RenderPipelines; import net.minecraft.resources.Identifier; +import net.minecraft.util.ARGB; +import net.minecraft.util.Mth; +import net.minecraft.world.item.Items; public class ElytraHud implements SimpleHud { + + Identifier compass = Identifier.fromNamespaceAndPath(Constants.MOD_ID, "textures/compass.png"); + Identifier compass_pointer = Identifier.fromNamespaceAndPath(Constants.MOD_ID, "textures/compass_pointer.png"); + Identifier green_arrow = Identifier.fromNamespaceAndPath(Constants.MOD_ID, "textures/green_arrow.png"); + Identifier red_arrow = Identifier.fromNamespaceAndPath(Constants.MOD_ID, "textures/red_arrow.png"); + Identifier off_green_arrow = Identifier.fromNamespaceAndPath(Constants.MOD_ID, "textures/off_green_arrow.png"); + Identifier off_red_arrow = Identifier.fromNamespaceAndPath(Constants.MOD_ID, "textures/off_red_arrow.png"); + @Override public void render(GuiGraphics graphics, DeltaTracker tracker) { if(!isHudActivated()) return; @@ -25,26 +37,121 @@ public class ElytraHud implements SimpleHud { float textScale = 0.6f; int whiteColor = 0xFFFFFFFF; + //Draw pitch int pitchTextY = 5; - renderCenteredScaledText(graphics, String.format("%d°", ElytraTools.getPitch()), x + textX, y + pitchTextY, whiteColor, textScale); + int pitch = ElytraTools.getPitch(); + renderCenteredScaledText(graphics, String.format("%d°", pitch), x + textX, y + pitchTextY, whiteColor, textScale); + //Draw speed int speedTextY = 15; renderCenteredScaledText(graphics, getSpeed(), x + textX, y + speedTextY, whiteColor, textScale); + //Draw coordinates int coordinatesTextY = 25; - String coordinatesText = String.format("%.0f:%.0f:%.0f", client.player.getX(), client.player.getY(), client.player.getZ()); - int maxAvailableWidth = 40; + String coordinatesText = String.format("%.0f:%.0f:%.0f", client.player.getX(), client.player.getY(), client.player.getZ()); int textWidth = client.font.width(coordinatesText); - float maxScale = (float) maxAvailableWidth / textWidth; float finalScale = Math.min(textScale, maxScale); - renderCenteredScaledText(graphics, coordinatesText, x + textX, y + coordinatesTextY, whiteColor, finalScale); + + //Draw elytra status + int itemX = 47; + int itemY = 5; + + int statusBarY = 30 + y; + int statusBarX = 50 + x; + int statusSize = 17; + int width = 2; + + float damagePercentage = ElytraTools.getDamagePercentage(); + final int statusBar = statusBarY - (int)(damagePercentage * statusSize); + float damagePercentageLeft = 1 - damagePercentage; + + drawScaledItem(graphics, x + itemX, y + itemY, Items.ELYTRA, 0.5f); + + graphics.fill(statusBarX, statusBarY, statusBarX + width, statusBar, ARGB.color(0xFF, ElytraTools.damageColor())); + if(damagePercentageLeft != 0) { + graphics.fill(statusBarX, statusBar, statusBarX + width,statusBar - (int)(damagePercentageLeft * statusSize), 0xFF3D3D3D); + } + + int textureCornerX = 0; + int textureCornerY = 0; + + //Draw up and down arrows + + int arrowWidth = 6; + int arrowHeight = 8; + + boolean isGoingUp = pitch > 0; + int greenAndRedArrowX = x + 56; + int greenArrowY = y + 10; + int redArrowY = y + 20; + + if(!isGoingUp){ + graphics.blit( + RenderPipelines.GUI_TEXTURED, + green_arrow, + greenAndRedArrowX, greenArrowY, + textureCornerX, textureCornerY, + arrowWidth, arrowHeight, + arrowWidth, arrowHeight + ); + graphics.blit( + RenderPipelines.GUI_TEXTURED, + off_red_arrow, + greenAndRedArrowX, redArrowY, + textureCornerX, textureCornerY, + arrowWidth, arrowHeight, + arrowWidth, arrowHeight + ); + }else { + graphics.blit( + RenderPipelines.GUI_TEXTURED, + off_green_arrow, + greenAndRedArrowX, greenArrowY, + textureCornerX, textureCornerY, + arrowWidth, arrowHeight, + arrowWidth, arrowHeight + ); + graphics.blit( + RenderPipelines.GUI_TEXTURED, + red_arrow, + greenAndRedArrowX, redArrowY, + textureCornerX, textureCornerY, + arrowWidth, arrowHeight, + arrowWidth, arrowHeight + ); + } + + //Compas background + + int compassWidth = 29; + int compassHeight = 29; + int compassX = x + 67; + int compassY = y + 3; + graphics.blit( + RenderPipelines.GUI_TEXTURED, + compass, + compassX, compassY, + textureCornerX, textureCornerY, + compassWidth, compassHeight, + compassWidth, compassHeight + ); + + double radians = ElytraTools.getRadians(); + + double radius = 5; + float centerX = compassX + 14; + float centerY = compassY + 14; + float endX = Math.round(centerX + (radius * -Mth.sin(radians))); + float endY = Math.round(centerY + (radius * Mth.cos(radians))); + + drawLine(graphics, centerX, centerY, endX, endY, (int) radius, compass_pointer); } private String getSpeed(){ - return switch (SimpleHudMod.configInstance.speedEnum){ + return switch (SimpleHudMod.configInstance.speedEnumElytra){ case kmh -> String.format("%.1f km/h", ElytraTools.getSpeedKmh()); case mph -> String.format("%.1f mph", ElytraTools.getSpeedMph()); case ms -> String.format("%.1f m/s", ElytraTools.getSpeedMs()); diff --git a/src/main/java/com/lukasabbe/simplehud/huds/SimpleHud.java b/src/main/java/com/lukasabbe/simplehud/huds/SimpleHud.java index c376611..eb40c78 100644 --- a/src/main/java/com/lukasabbe/simplehud/huds/SimpleHud.java +++ b/src/main/java/com/lukasabbe/simplehud/huds/SimpleHud.java @@ -8,6 +8,8 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.renderer.RenderPipelines; import net.minecraft.resources.Identifier; +import net.minecraft.util.Mth; +import net.minecraft.world.item.Item; public interface SimpleHud { Minecraft client = Minecraft.getInstance(); @@ -75,15 +77,41 @@ public interface SimpleHud { stack.popMatrix(); } + default void drawScaledItem(GuiGraphics context, int poxX, int posY, Item item, float scaled){ + var stack = context.pose(); + stack.pushMatrix(); + stack.translate(poxX,posY); + stack.scale(scaled,scaled); + stack.translate(-poxX,-posY); + context.renderFakeItem(item.getDefaultInstance(), poxX, posY); + stack.popMatrix(); + } + default int[] getCornerPos(){ int backPlateCenteredX = 50; int backPlateCenteredY = 60; int screenWidth = client.getWindow().getGuiScaledWidth(); int screenHeight = client.getWindow().getGuiScaledHeight(); - int[] pos = calculateHudPosition(screenWidth, screenHeight, SimpleHudMod.configInstance.hudPosition); + int[] pos = calculateHudPosition(screenWidth, screenHeight, SimpleHudMod.configInstance.hudPositionElytra); int x = pos[0] - backPlateCenteredX; int y = pos[1] - backPlateCenteredY; return new int[]{x, y}; } + + default void drawLine(GuiGraphics graphics, float posX, float posY, float endPosX, float endPosY, int points, Identifier texture){ + for (int i = 0; i <= points; i++){ + float progress = (float) i / points; + float x = Mth.lerp(progress, posX, endPosX); + float y = Mth.lerp(progress, posY, endPosY); + graphics.blit( + RenderPipelines.GUI_TEXTURED, + texture, + (int)x, (int)y, + 0, 0, + 1, 1, + 1,5 + ); + } + } } diff --git a/src/main/java/com/lukasabbe/simplehud/tools/ElytraTools.java b/src/main/java/com/lukasabbe/simplehud/tools/ElytraTools.java index 6749585..1c4c190 100644 --- a/src/main/java/com/lukasabbe/simplehud/tools/ElytraTools.java +++ b/src/main/java/com/lukasabbe/simplehud/tools/ElytraTools.java @@ -2,6 +2,8 @@ package com.lukasabbe.simplehud.tools; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.Items; import net.minecraft.world.phys.Vec3; import org.jspecify.annotations.Nullable; @@ -40,10 +42,31 @@ public class ElytraTools { return (int)player.getXRot(); } - public static int getYaw(){ + public static double getRadians(){ var player = getLocalPlayer(); if(player == null) return 0; - return (int)player.getYRot(); + float yaw = player.getViewYRot(Minecraft.getInstance().getFrameTimeNs()); + + float normalizedYaw = (yaw % 360); + if (normalizedYaw < 0) normalizedYaw += 360; + + return Math.toRadians(normalizedYaw); + } + + public static float getDamagePercentage(){ + var player = getLocalPlayer(); + if(player == null) return 0; + var chestItem = player.getItemBySlot(EquipmentSlot.CHEST); + if(!chestItem.is(Items.ELYTRA)) return 0; + return (1 - ((float) chestItem.getDamageValue() / chestItem.getMaxDamage())); + } + + public static int damageColor(){ + var player = getLocalPlayer(); + if(player == null) return 0; + var chestItem = player.getItemBySlot(EquipmentSlot.CHEST); + if(!chestItem.is(Items.ELYTRA)) return 0; + return chestItem.getBarColor(); } private static @Nullable LocalPlayer getLocalPlayer() { diff --git a/src/main/resources/assets/simplehud/icon.png b/src/main/resources/assets/simplehud/icon.png index 5f20026..ee355c1 100644 Binary files a/src/main/resources/assets/simplehud/icon.png and b/src/main/resources/assets/simplehud/icon.png differ diff --git a/src/main/resources/assets/simplehud/lang/en_us.json b/src/main/resources/assets/simplehud/lang/en_us.json new file mode 100644 index 0000000..d3659c4 --- /dev/null +++ b/src/main/resources/assets/simplehud/lang/en_us.json @@ -0,0 +1,15 @@ +{ + "simple_hud.config.title": "Simple HUD config menu", + "simple_hud.config.category.general.name": "General options", + "simple_hud.config.category.general.tooltip": "All general options for the mod", + "simple_hud.config.category.general.group.activated_huds.name": "Toggle HUD:s", + "simple_hud.config.category.general.group.activated_huds.description": "Toggle menu for all transport HUD:s", + "simple_hud.config.category.general.group.activated_huds.option.elytra_hud.name": "Elytra HUD", + "simple_hud.config.category.general.group.activated_huds.option.elytra_hud.description": "Elytra Hud toggle, if you don't want to see the an HUD when you fly.", + "simple_hud.config.category.elytra_options.name": "Elytra HUD options", + "simple_hud.config.category.elytra_options.option.speed_enum.name": "Speed unit", + "simple_hud.config.category.elytra_options.option.speed_enum.description": "You can change the speed unit to what you are used to", + "simple_hud.config.speed_enum.kmh": "km/h", + "simple_hud.config.speed_enum.mph": "MPH", + "simple_hud.config.speed_enum.ms": "m/s" +} \ No newline at end of file diff --git a/src/main/resources/assets/simplehud/textures/compass.png b/src/main/resources/assets/simplehud/textures/compass.png new file mode 100644 index 0000000..2a4bb25 Binary files /dev/null and b/src/main/resources/assets/simplehud/textures/compass.png differ diff --git a/src/main/resources/assets/simplehud/textures/compass_pointer.png b/src/main/resources/assets/simplehud/textures/compass_pointer.png new file mode 100644 index 0000000..dc84d6d Binary files /dev/null and b/src/main/resources/assets/simplehud/textures/compass_pointer.png differ diff --git a/src/main/resources/assets/simplehud/textures/green_arrow.png b/src/main/resources/assets/simplehud/textures/green_arrow.png new file mode 100644 index 0000000..a480f76 Binary files /dev/null and b/src/main/resources/assets/simplehud/textures/green_arrow.png differ diff --git a/src/main/resources/assets/simplehud/textures/off_green_arrow.png b/src/main/resources/assets/simplehud/textures/off_green_arrow.png new file mode 100644 index 0000000..87ca8ca Binary files /dev/null and b/src/main/resources/assets/simplehud/textures/off_green_arrow.png differ diff --git a/src/main/resources/assets/simplehud/textures/off_red_arrow.png b/src/main/resources/assets/simplehud/textures/off_red_arrow.png new file mode 100644 index 0000000..2ac7d11 Binary files /dev/null and b/src/main/resources/assets/simplehud/textures/off_red_arrow.png differ diff --git a/src/main/resources/assets/simplehud/textures/red_arrow.png b/src/main/resources/assets/simplehud/textures/red_arrow.png new file mode 100644 index 0000000..8a6d421 Binary files /dev/null and b/src/main/resources/assets/simplehud/textures/red_arrow.png differ diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 95f6d9b..6538cc0 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -12,6 +12,9 @@ "entrypoints": { "client": [ "com.lukasabbe.simplehud.SimpleHudMod" + ], + "modmenu": [ + "com.lukasabbe.simplehud.config.ModMenu" ] }, "mixins": [