diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarWidget.java index 51a214de0b3..c21994a418b 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarWidget.java @@ -3,9 +3,11 @@ import de.hysky.skyblocker.utils.EnumUtils; import de.hysky.skyblocker.utils.render.GuiHelper; import it.unimi.dsi.fastutil.booleans.BooleanConsumer; + import java.awt.Color; import java.util.List; import java.util.function.Consumer; + import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; @@ -28,6 +30,7 @@ public class EditBarWidget extends AbstractContainerWidget { private final EnumCyclingOption iconOption; private final EnumCyclingOption textOption; + private final EnumCyclingOption flowOption; private final BooleanOption showMaxOption; private final BooleanOption showOverflowOption; @@ -45,7 +48,7 @@ public class EditBarWidget extends AbstractContainerWidget { private int contentsWidth = 0; public EditBarWidget(int x, int y, Screen parent) { - super(x, y, 100, 99, Component.literal("Edit bar"), AbstractScrollArea.defaultSettings(4)); + super(x, y, 100, 110, Component.literal("Edit bar"), AbstractScrollArea.defaultSettings(4)); Font textRenderer = Minecraft.getInstance().font; @@ -59,32 +62,36 @@ public EditBarWidget(int x, int y, Screen parent) { textOption = new EnumCyclingOption<>(0, 22, getWidth(), translatable, StatusBar.TextPosition.class); contentsWidth = Math.max(contentsWidth, textRenderer.width(translatable) + textOption.getLongestOptionWidth() + 10); + translatable = Component.translatable("skyblocker.bars.config.flow"); + flowOption = new EnumCyclingOption<>(0, 33, getWidth(), translatable, StatusBar.FlowDirection.class); + contentsWidth = Math.max(contentsWidth, textRenderer.width(translatable) + textOption.getLongestOptionWidth() + 10); + translatable = Component.translatable("skyblocker.bars.config.showMax"); - showMaxOption = new BooleanOption(0, 33, getWidth(), translatable); + showMaxOption = new BooleanOption(0, 44, getWidth(), translatable); contentsWidth = Math.max(contentsWidth, textRenderer.width(translatable) + 9 + 10); translatable = Component.translatable("skyblocker.bars.config.showOverflow"); - showOverflowOption = new BooleanOption(0, 44, getWidth(), translatable); + showOverflowOption = new BooleanOption(0, 55, getWidth(), translatable); contentsWidth = Math.max(contentsWidth, textRenderer.width(translatable) + 9 + 10); // COLO(u)RS translatable = Component.translatable("skyblocker.bars.config.mainColor"); contentsWidth = Math.max(contentsWidth, textRenderer.width(translatable) + 9 + 10); - color1 = new ColorOption(0, 55, getWidth(), translatable, parent); + color1 = new ColorOption(0, 66, getWidth(), translatable, parent); translatable = Component.translatable("skyblocker.bars.config.overflowColor"); contentsWidth = Math.max(contentsWidth, textRenderer.width(translatable) + 9 + 10); - color2 = new ColorOption(0, 66, getWidth(), translatable, parent); + color2 = new ColorOption(0, 77, getWidth(), translatable, parent); translatable = Component.translatable("skyblocker.bars.config.textColor"); contentsWidth = Math.max(contentsWidth, textRenderer.width(translatable) + 9 + 10); - textColor = new ColorOption(0, 77, getWidth(), translatable, parent); + textColor = new ColorOption(0, 88, getWidth(), translatable, parent); translatable = Component.translatable("skyblocker.bars.config.hide"); contentsWidth = Math.max(contentsWidth, textRenderer.width(translatable) + 9 + 10); - hideOption = new RunnableOption(0, 88, getWidth(), translatable); + hideOption = new RunnableOption(0, 99, getWidth(), translatable); - options = List.of(iconOption, textOption, showMaxOption, showOverflowOption, color1, color2, textColor, hideOption); + options = List.of(iconOption, textOption, flowOption, showMaxOption, showOverflowOption, color1, color2, textColor, hideOption); setWidth(contentsWidth); } @@ -132,6 +139,8 @@ public void setStatusBar(StatusBar statusBar) { iconOption.setOnChange(statusBar::setIconPosition); textOption.setCurrent(statusBar.getTextPosition()); textOption.setOnChange(statusBar::setTextPosition); + flowOption.setCurrent(statusBar.getFlowDirection()); + flowOption.setOnChange(statusBar::setFlowDirection); color1.setCurrent(statusBar.getColors()[0].getRGB()); color1.setOnChange(color -> statusBar.getColors()[0] = color); @@ -203,7 +212,8 @@ public void onClick(MouseButtonEvent click, boolean doubled) { } @Override - protected void updateWidgetNarration(NarrationElementOutput builder) {} + protected void updateWidgetNarration(NarrationElementOutput builder) { + } } public static class EnumCyclingOption> extends AbstractWidget { @@ -275,7 +285,8 @@ protected void extractWidgetRenderState(GuiGraphicsExtractor graphics, int mouse Font textRenderer = Minecraft.getInstance().font; graphics.text(textRenderer, getMessage(), getX() + 1, getY() + 1, active ? -1 : CommonColors.GRAY, true); GuiHelper.border(graphics, getRight() - 10, getY() + 1, 9, 9, active ? -1 : CommonColors.GRAY); - if (current && active) graphics.fill(getRight() - 8, getY() + 3, getRight() - 3, getY() + 8, CommonColors.WHITE); + if (current && active) + graphics.fill(getRight() - 8, getY() + 3, getRight() - 3, getY() + 8, CommonColors.WHITE); } @Override diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java index 9fde3ea8fcd..6e791ae31f6 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java @@ -102,6 +102,7 @@ public Component getName() { private IconPosition iconPosition = IconPosition.LEFT; private TextPosition textPosition = TextPosition.BAR_CENTER; + private FlowDirection flowDirection = FlowDirection.LEFT_TO_RIGHT; public boolean showMax = false; public boolean showOverflow = false; @@ -149,14 +150,25 @@ public void extractBar(GuiGraphicsExtractor graphics) { //context.drawText(MinecraftClient.getInstance().textRenderer, gridX + " " + gridY + " s:" + size , x, y-9, Colors.WHITE, true); } - protected void extractBarFill(GuiGraphicsExtractor graphics, int barX, int barWith) { - GuiHelper.nineSliceColored(graphics, BAR_FILL, barX + 1, renderY + 2, (int) ((barWith - 2) * fill), 5, transparency(colors[0].getRGB())); + protected void extractBarFill(GuiGraphicsExtractor graphics, int barX, int barWidth) { + renderBarFill(graphics, barX, barWidth, fill, transparency(colors[0].getRGB())); if (hasOverflow() && overflowFill > 0) { - GuiHelper.nineSliceColored(graphics, BAR_FILL, barX + 1, renderY + 2, (int) ((barWith - 2) * Math.min(overflowFill, 1)), 5, transparency(colors[1].getRGB())); + renderBarFill(graphics, barX, barWidth, Math.min(overflowFill, 1), transparency(colors[1].getRGB())); } } + protected void renderBarFill(GuiGraphicsExtractor graphics, int barX, int barWidth, float fill, int argb) { + int fillWidth = (int) ((barWidth - 2) * fill); + int x = switch (flowDirection) { + case LEFT_TO_RIGHT -> barX + 1; + case RIGHT_TO_LEFT -> barX + barWidth - fillWidth - 1; + case FROM_MIDDLE -> barX + (barWidth - fillWidth) / 2; + }; + + GuiHelper.nineSliceColored(graphics, BAR_FILL, x, renderY + 2, fillWidth, 5, argb); + } + public void updateValues(float fill, float overflowFill, int value, @Nullable Integer max, @Nullable Integer overflow) { this.value = value; this.fill = Math.clamp(fill, 0, 1); @@ -335,6 +347,14 @@ public void setTextPosition(TextPosition textPosition) { this.textPosition = textPosition; } + public FlowDirection getFlowDirection() { + return flowDirection; + } + + public void setFlowDirection(FlowDirection flowDirection) { + this.flowDirection = flowDirection; + } + public enum IconPosition implements StringRepresentable { LEFT, RIGHT, @@ -370,6 +390,22 @@ public String toString() { } } + public enum FlowDirection implements StringRepresentable { + LEFT_TO_RIGHT, + RIGHT_TO_LEFT, + FROM_MIDDLE; + + @Override + public String getSerializedName() { + return name(); + } + + @Override + public String toString() { + return I18n.get("skyblocker.bars.config.flowDirection." + name()); + } + } + @FunctionalInterface public interface OnClick { void onClick(StatusBar statusBar, MouseButtonEvent click); @@ -390,7 +426,8 @@ public void loadFromJson(JsonObject object) { this.colors = newColors; } - if (object.has("text_color")) this.textColor = new Color(Integer.parseInt(object.get("text_color").getAsString(), 16)); + if (object.has("text_color")) + this.textColor = new Color(Integer.parseInt(object.get("text_color").getAsString(), 16)); String maybeAnchor = object.get("anchor").getAsString().trim(); this.anchor = maybeAnchor.equals("null") ? null : BarPositioner.BarAnchor.valueOf(maybeAnchor); @@ -407,10 +444,15 @@ public void loadFromJson(JsonObject object) { this.y = object.get("y").getAsFloat(); } // these are optional too, why not - if (object.has("icon_position")) this.iconPosition = IconPosition.valueOf(object.get("icon_position").getAsString().trim()); + if (object.has("icon_position")) + this.iconPosition = IconPosition.valueOf(object.get("icon_position").getAsString().trim()); // backwards compat teehee - if (object.has("show_text")) this.textPosition = object.get("show_text").getAsBoolean() ? TextPosition.BAR_CENTER : TextPosition.OFF; - if (object.has("text_position")) this.textPosition = TextPosition.valueOf(object.get("text_position").getAsString().trim()); + if (object.has("show_text")) + this.textPosition = object.get("show_text").getAsBoolean() ? TextPosition.BAR_CENTER : TextPosition.OFF; + if (object.has("text_position")) + this.textPosition = TextPosition.valueOf(object.get("text_position").getAsString().trim()); + if (object.has("flow_direction")) + this.flowDirection = FlowDirection.valueOf(object.get("flow_direction").getAsString().trim()); if (object.has("show_max")) this.showMax = object.get("show_max").getAsBoolean(); if (object.has("show_overflow")) this.showOverflow = object.get("show_overflow").getAsBoolean(); } @@ -439,6 +481,7 @@ public JsonObject toJson() { } object.addProperty("icon_position", iconPosition.getSerializedName()); object.addProperty("text_position", textPosition.getSerializedName()); + object.addProperty("flow_direction", flowDirection.getSerializedName()); object.addProperty("show_max", showMax); object.addProperty("show_overflow", showOverflow); object.addProperty("enabled", enabled); @@ -452,23 +495,24 @@ public ManaStatusBar(StatusBarType type) { } @Override - protected void extractBarFill(GuiGraphicsExtractor graphics, int barX, int barWith) { + protected void extractBarFill(GuiGraphicsExtractor graphics, int barX, int barWidth) { if (hasOverflow() && overflowFill > 0) { if (overflowFill > fill && SkyblockerConfigManager.get().uiAndVisuals.bars.intelligenceDisplay == UIAndVisualsConfig.IntelligenceDisplay.IN_FRONT) { - GuiHelper.nineSliceColored(graphics, BAR_FILL, barX + 1, getY() + 2, (int) ((barWith - 2) * Math.min(overflowFill, 1)), 5, transparency(getColors()[1].getRGB())); - GuiHelper.nineSliceColored(graphics, BAR_FILL, barX + 1, getY() + 2, (int) ((barWith - 2) * fill), 5, transparency(getColors()[0].getRGB())); + renderBarFill(graphics, barX, barWidth, Math.min(overflowFill, 1), transparency(getColors()[1].getRGB())); + renderBarFill(graphics, barX, barWidth, fill, transparency(getColors()[0].getRGB())); } else { - GuiHelper.nineSliceColored(graphics, BAR_FILL, barX + 1, getY() + 2, (int) ((barWith - 2) * fill), 5, transparency(getColors()[0].getRGB())); - GuiHelper.nineSliceColored(graphics, BAR_FILL, barX + 1, getY() + 2, (int) ((barWith - 2) * Math.min(overflowFill, 1)), 5, transparency(getColors()[1].getRGB())); + renderBarFill(graphics, barX, barWidth, fill, transparency(getColors()[0].getRGB())); + renderBarFill(graphics, barX, barWidth, Math.min(overflowFill, 1), transparency(getColors()[1].getRGB())); } } else { - GuiHelper.nineSliceColored(graphics, BAR_FILL, barX + 1, getY() + 2, (int) ((barWith - 2) * fill), 5, transparency(getColors()[0].getRGB())); + renderBarFill(graphics, barX, barWidth, fill, transparency(getColors()[0].getRGB())); } } } public static class ExperienceStatusBar extends StatusBar { private static final Identifier CLOCK_ICON = SkyblockerMod.id("bars/icons/rift_time"); + public ExperienceStatusBar(StatusBarType type) { super(type, time -> { if (Utils.isInTheRift()) { @@ -508,10 +552,9 @@ protected void extractBarFill(GuiGraphicsExtractor graphics, int barX, int barWi } else { fillColor = getColors()[0].getRGB(); } - - GuiHelper.nineSliceColored(graphics, BAR_FILL, barX + 1, getY() + 2, (int) ((barWidth - 2) * fill), 5, transparency(fillColor)); + renderBarFill(graphics, barX, barWidth, fill, transparency(fillColor)); if (hasOverflow() && overflowFill > 0) { - GuiHelper.nineSliceColored(graphics, BAR_FILL, barX + 1, getY() + 2, (int) ((barWidth - 2) * Math.min(overflowFill, 1)), 5, transparency(getColors()[1].getRGB())); + renderBarFill(graphics, barX, barWidth, Math.min(overflowFill, 1), transparency(getColors()[1].getRGB())); } } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index f676c2b91a2..e6f3e31635b 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -46,6 +46,10 @@ "skyblocker.bars.config.experience": "Experience", "skyblocker.bars.config.explanation": "Welcome to the status bars config screen!\n\nDrag and drop the bars to snap them to an anchor (white squares), existing bars or you can put them anywhere.\nYou can right click them to edit a bunch of properties.\nBy hovering your mouse between 2 bars (your cursor should change), you can resize them.\n\nEverything is saved when you leave.", "skyblocker.bars.config.explanationTitle": "What is this?", + "skyblocker.bars.config.flow": "Flow", + "skyblocker.bars.config.flowDirection.FROM_MIDDLE": "From Middle", + "skyblocker.bars.config.flowDirection.LEFT_TO_RIGHT": "Left to Right", + "skyblocker.bars.config.flowDirection.RIGHT_TO_LEFT": "Right to Left", "skyblocker.bars.config.health": "Health", "skyblocker.bars.config.hide": "Hide", "skyblocker.bars.config.icon": "Icon",