diff options
| author | viciscat <51047087+viciscat@users.noreply.github.com> | 2024-12-06 00:57:19 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-05 18:57:19 -0500 |
| commit | af5ec9fe170bbb8c0b0f492db2715dd3b9e35b0a (patch) | |
| tree | 2ac9ae00e156f798c789db6a96b586c5db5ce0ef /src/main/java | |
| parent | 3243e46b3ebab7b533147a4b40b8da641890ad7c (diff) | |
| download | Skyblocker-af5ec9fe170bbb8c0b0f492db2715dd3b9e35b0a.tar.gz Skyblocker-af5ec9fe170bbb8c0b0f492db2715dd3b9e35b0a.tar.bz2 Skyblocker-af5ec9fe170bbb8c0b0f492db2715dd3b9e35b0a.zip | |
Random status bar changes (#1009)
* Random status bar changes
* Add a hide button to the right-click menu
* More text/value customization
* Hopefully make text resizing easier on lower gui scales
* Make values show in config screen
* T A B S
* port
* use vanilla outline text renderer
might be faster since it only draws the text 2 times instead of 5
Diffstat (limited to 'src/main/java')
4 files changed, 1262 insertions, 1155 deletions
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 d39c67d7..f74d53da 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarWidget.java @@ -23,253 +23,305 @@ import java.util.function.Consumer; public class EditBarWidget extends ContainerWidget { - private final EnumCyclingOption<StatusBar.IconPosition> iconOption; - private final BooleanOption booleanOption; - - private final ColorOption color1; - private final ColorOption color2; - private final ColorOption textColor; - private final TextWidget nameWidget; - - private int contentsWidth = 0; - - public EditBarWidget(int x, int y, Screen parent) { - super(x, y, 100, 66, Text.literal("Edit bar")); - - TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; - - nameWidget = new TextWidget(Text.empty(), textRenderer); - - MutableText translatable = Text.translatable("skyblocker.bars.config.icon"); - contentsWidth = Math.max(contentsWidth, textRenderer.getWidth(translatable) + textRenderer.getWidth("RIGHT") + 10); - iconOption = new EnumCyclingOption<>(0, 11, getWidth(), translatable, StatusBar.IconPosition.class); - - translatable = Text.translatable("skyblocker.bars.config.showValue"); - contentsWidth = Math.max(contentsWidth, textRenderer.getWidth(translatable) + 9 + 10); - booleanOption = new BooleanOption(0, 22, getWidth(), translatable); - - // COLO(u)RS - translatable = Text.translatable("skyblocker.bars.config.mainColor"); - contentsWidth = Math.max(contentsWidth, textRenderer.getWidth(translatable) + 9 + 10); - color1 = new ColorOption(0, 33, getWidth(), translatable, parent); - - translatable = Text.translatable("skyblocker.bars.config.overflowColor"); - contentsWidth = Math.max(contentsWidth, textRenderer.getWidth(translatable) + 9 + 10); - color2 = new ColorOption(0, 44, getWidth(), translatable, parent); - - translatable = Text.translatable("skyblocker.bars.config.textColor"); - contentsWidth = Math.max(contentsWidth, textRenderer.getWidth(translatable) + 9 + 10); - textColor = new ColorOption(0, 55, getWidth(), translatable, parent); - - setWidth(contentsWidth); - } - - @Override - public List<? extends Element> children() { - return List.of(iconOption, booleanOption, color1, color2, textColor); - } - - public int insideMouseX = 0; - public int insideMouseY = 0; - - @Override - protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { - if (isHovered()) { - insideMouseX = mouseX; - insideMouseY = mouseY; - } else { - int i = mouseX - insideMouseX; - int j = mouseY - insideMouseY; - if (i * i + j * j > 30 * 30) visible = false; - } - TooltipBackgroundRenderer.render(context, getX(), getY(), getWidth(), getHeight(), 0, null); - MatrixStack matrices = context.getMatrices(); - matrices.push(); - matrices.translate(getX(), getY(), 0); - nameWidget.render(context, mouseX, mouseY, delta); - iconOption.renderWidget(context, mouseX - getX(), mouseY - getY(), delta); - booleanOption.renderWidget(context, mouseX - getX(), mouseY - getY(), delta); - color1.renderWidget(context, mouseX - getX(), mouseY - getY(), delta); - color2.renderWidget(context, mouseX - getX(), mouseY - getY(), delta); - textColor.renderWidget(context, mouseX - getX(), mouseY - getY(), delta); - matrices.pop(); - } - - @Override - protected void appendClickableNarrations(NarrationMessageBuilder builder) { - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (!visible) return false; - if (!isHovered()) visible = false; - return super.mouseClicked(mouseX - getX(), mouseY - getY(), button); - } - - public void setStatusBar(StatusBar statusBar) { - iconOption.setCurrent(statusBar.getIconPosition()); - iconOption.setOnChange(statusBar::setIconPosition); - booleanOption.setCurrent(statusBar.showText()); - booleanOption.setOnChange(statusBar::setShowText); - - color1.setCurrent(statusBar.getColors()[0].getRGB()); - color1.setOnChange(color -> statusBar.getColors()[0] = color); - - color2.active = statusBar.hasOverflow(); - if (color2.active) { - color2.setCurrent(statusBar.getColors()[1].getRGB()); - color2.setOnChange(color -> statusBar.getColors()[1] = color); - } - - if (statusBar.getTextColor() != null) { - textColor.setCurrent(statusBar.getTextColor().getRGB()); - } - textColor.setOnChange(statusBar::setTextColor); - - MutableText formatted = statusBar.getName().copy().formatted(Formatting.BOLD); - nameWidget.setMessage(formatted); - setWidth(Math.max(MinecraftClient.getInstance().textRenderer.getWidth(formatted), contentsWidth)); - } - - @Override - public void setWidth(int width) { - super.setWidth(width); - iconOption.setWidth(width); - booleanOption.setWidth(width); - color1.setWidth(width); - color2.setWidth(width); - textColor.setWidth(width); - nameWidget.setWidth(width); - - } - - public static class EnumCyclingOption<T extends Enum<T>> extends ClickableWidget { - - private T current; - private final T[] values; - private Consumer<T> onChange = null; - - public EnumCyclingOption(int x, int y, int width, Text message, Class<T> enumClass) { - super(x, y, width, 11, message); - values = enumClass.getEnumConstants(); - current = values[0]; - } - - @Override - protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { - if (isMouseOver(mouseX, mouseY)) { - context.fill(getX(), getY(), getRight(), getBottom(), 0x20FFFFFF); - } - TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; - context.drawText(textRenderer, getMessage(), getX() + 1, getY() + 1, -1, true); - String string = current.toString(); - context.drawText(textRenderer, string, getRight() - textRenderer.getWidth(string) - 1, getY() + 1, -1, true); - } - - public void setCurrent(T current) { - this.current = current; - } - - @Override - public void onClick(double mouseX, double mouseY) { - current = values[(current.ordinal() + 1) % values.length]; - if (onChange != null) onChange.accept(current); - super.onClick(mouseX, mouseY); - } - - @Override - protected void appendClickableNarrations(NarrationMessageBuilder builder) { - } - - public void setOnChange(Consumer<T> onChange) { - this.onChange = onChange; - } - } - - public static class BooleanOption extends ClickableWidget { - - private boolean current = false; - private BooleanConsumer onChange = null; - - public BooleanOption(int x, int y, int width, Text message) { - super(x, y, width, 11, message); - } - - @Override - protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { - if (isMouseOver(mouseX, mouseY)) { - context.fill(getX(), getY(), getRight(), getBottom(), 0x20FFFFFF); - } - TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; - context.drawText(textRenderer, getMessage(), getX() + 1, getY() + 1, -1, true); - context.drawBorder(getRight() - 10, getY() + 1, 9, 9, -1); - if (current) context.fill(getRight() - 8, getY() + 3, getRight() - 3, getY() + 8, -1); - } - - @Override - public void onClick(double mouseX, double mouseY) { - current = !current; - if (onChange != null) onChange.accept(current); - super.onClick(mouseX, mouseY); - } - - @Override - protected void appendClickableNarrations(NarrationMessageBuilder builder) { - } - - public void setCurrent(boolean current) { - this.current = current; - } - - public void setOnChange(BooleanConsumer onChange) { - this.onChange = onChange; - } - } - - public static class ColorOption extends ClickableWidget { - - public void setCurrent(int current) { - this.current = current; - } - - private int current = 0; - private Consumer<Color> onChange = null; - private final Screen parent; - - public ColorOption(int x, int y, int width, Text message, Screen parent) { - super(x, y, width, 11, message); - this.parent = parent; - } - - @Override - protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { - if (isMouseOver(mouseX, mouseY)) { - context.fill(getX(), getY(), getRight(), getBottom(), 0x20FFFFFF); - } - TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; - context.drawText(textRenderer, getMessage(), getX() + 1, getY() + 1, active ? -1 : Colors.GRAY, true); - context.drawBorder(getRight() - 10, getY() + 1, 9, 9, active ? -1 : Colors.GRAY); - context.fill(getRight() - 8, getY() + 3, getRight() - 3, getY() + 8, active ? current : Colors.GRAY); - } - - @Override - public void onClick(double mouseX, double mouseY) { - super.onClick(mouseX, mouseY); - MinecraftClient.getInstance().setScreen(new EditBarColorPopup(Text.literal("Edit ").append(getMessage()), parent, this::set)); - } - - private void set(Color color) { - current = color.getRGB(); - if (onChange != null) onChange.accept(color); - } - - @Override - protected void appendClickableNarrations(NarrationMessageBuilder builder) { - - } - - public void setOnChange(Consumer<Color> onChange) { - this.onChange = onChange; - } - } + private final EnumCyclingOption<StatusBar.IconPosition> iconOption; + private final EnumCyclingOption<StatusBar.TextPosition> textOption; + + private final ColorOption color1; + private final ColorOption color2; + private final ColorOption textColor; + private final TextWidget nameWidget; + private final RunnableOption hideOption; + + private final List<? extends ClickableWidget> options; + + private int contentsWidth = 0; + + public EditBarWidget(int x, int y, Screen parent) { + super(x, y, 100, 77, Text.literal("Edit bar")); + + TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; + + nameWidget = new TextWidget(Text.empty(), textRenderer); + + MutableText translatable = Text.translatable("skyblocker.bars.config.icon"); + iconOption = new EnumCyclingOption<>(0, 11, getWidth(), translatable, StatusBar.IconPosition.class); + contentsWidth = Math.max(contentsWidth, textRenderer.getWidth(translatable) + iconOption.getLongestOptionWidth() + 10); + + translatable = Text.translatable("skyblocker.bars.config.text"); + textOption = new EnumCyclingOption<>(0, 22, getWidth(), translatable, StatusBar.TextPosition.class); + contentsWidth = Math.max(contentsWidth, textRenderer.getWidth(translatable) + textOption.getLongestOptionWidth() + 10); + + // COLO(u)RS + translatable = Text.translatable("skyblocker.bars.config.mainColor"); + contentsWidth = Math.max(contentsWidth, textRenderer.getWidth(translatable) + 9 + 10); + color1 = new ColorOption(0, 33, getWidth(), translatable, parent); + + translatable = Text.translatable("skyblocker.bars.config.overflowColor"); + contentsWidth = Math.max(contentsWidth, textRenderer.getWidth(translatable) + 9 + 10); + color2 = new ColorOption(0, 44, getWidth(), translatable, parent); + + translatable = Text.translatable("skyblocker.bars.config.textColor"); + contentsWidth = Math.max(contentsWidth, textRenderer.getWidth(translatable) + 9 + 10); + textColor = new ColorOption(0, 55, getWidth(), translatable, parent); + + translatable = Text.translatable("skyblocker.bars.config.hide"); + contentsWidth = Math.max(contentsWidth, textRenderer.getWidth(translatable) + 9 + 10); + hideOption = new RunnableOption(0, 66, getWidth(), translatable); + + options = List.of(iconOption, textOption, color1, color2, textColor, hideOption); + + setWidth(contentsWidth); + } + + @Override + public List<? extends Element> children() { + return options; + } + + public int insideMouseX = 0; + public int insideMouseY = 0; + + @Override + protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + if (isHovered()) { + insideMouseX = mouseX; + insideMouseY = mouseY; + } else { + int i = mouseX - insideMouseX; + int j = mouseY - insideMouseY; + if (i * i + j * j > 30 * 30) visible = false; + } + MatrixStack matrices = context.getMatrices(); + matrices.push(); + matrices.translate(getX(), getY(), 200.f); + TooltipBackgroundRenderer.render(context, 0, 0, getWidth(), getHeight(), 0, null); + nameWidget.render(context, mouseX, mouseY, delta); + for (ClickableWidget option : options) option.render(context, mouseX - getX(), mouseY - getY(), delta); + matrices.pop(); + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) { + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (!visible) return false; + if (!isHovered()) visible = false; + return super.mouseClicked(mouseX - getX(), mouseY - getY(), button); + } + + public void setStatusBar(StatusBar statusBar) { + iconOption.setCurrent(statusBar.getIconPosition()); + iconOption.setOnChange(statusBar::setIconPosition); + textOption.setCurrent(statusBar.getTextPosition()); + textOption.setOnChange(statusBar::setTextPosition); + + color1.setCurrent(statusBar.getColors()[0].getRGB()); + color1.setOnChange(color -> statusBar.getColors()[0] = color); + + color2.active = statusBar.hasOverflow(); + if (color2.active) { + color2.setCurrent(statusBar.getColors()[1].getRGB()); + color2.setOnChange(color -> statusBar.getColors()[1] = color); + } + + if (statusBar.getTextColor() != null) { + textColor.setCurrent(statusBar.getTextColor().getRGB()); + } + textColor.setOnChange(statusBar::setTextColor); + hideOption.active = statusBar.anchor != null; + hideOption.setRunnable(() -> { + if (statusBar.anchor != null) + FancyStatusBars.barPositioner.removeBar(statusBar.anchor, statusBar.gridY, statusBar); + FancyStatusBars.updatePositions(); + }); + + MutableText formatted = statusBar.getName().copy().formatted(Formatting.BOLD); + nameWidget.setMessage(formatted); + setWidth(Math.max(MinecraftClient.getInstance().textRenderer.getWidth(formatted), contentsWidth)); + } + + @Override + public void setWidth(int width) { + super.setWidth(width); + for (ClickableWidget option : options) option.setWidth(width); + nameWidget.setWidth(width); + + } + + public class RunnableOption extends ClickableWidget { + + private Runnable runnable; + + public RunnableOption(int x, int y, int width, Text message) { + super(x, y, width, 11, message); + } + + public void setRunnable(Runnable runnable) { + this.runnable = runnable; + } + + @Override + protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + if (isMouseOver(mouseX, mouseY)) { + context.fill(getX(), getY(), getRight(), getBottom(), 0x20FFFFFF); + } + TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; + context.drawText(textRenderer, getMessage(), getX() + 1, getY() + 1, active ? -1: Colors.GRAY, true); + } + + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + EditBarWidget.this.visible = false; + if (runnable != null) runnable.run(); + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) {} + } + + public static class EnumCyclingOption<T extends Enum<T>> extends ClickableWidget { + + private T current; + private final T[] values; + private Consumer<T> onChange = null; + + public EnumCyclingOption(int x, int y, int width, Text message, Class<T> enumClass) { + super(x, y, width, 11, message); + values = enumClass.getEnumConstants(); + current = values[0]; + } + + @Override + protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + if (isMouseOver(mouseX, mouseY)) { + context.fill(getX(), getY(), getRight(), getBottom(), 0x20FFFFFF); + } + TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; + context.drawText(textRenderer, getMessage(), getX() + 1, getY() + 1, -1, true); + String string = current.toString(); + context.drawText(textRenderer, string, getRight() - textRenderer.getWidth(string) - 1, getY() + 1, -1, true); + } + + public void setCurrent(T current) { + this.current = current; + } + + @Override + public void onClick(double mouseX, double mouseY) { + current = values[(current.ordinal() + 1) % values.length]; + if (onChange != null) onChange.accept(current); + super.onClick(mouseX, mouseY); + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) { + } + + public void setOnChange(Consumer<T> onChange) { + this.onChange = onChange; + } + + int getLongestOptionWidth() { + int m = 0; + for (T value : values) { + int i = MinecraftClient.getInstance().textRenderer.getWidth(value.toString()); + m = Math.max(m, i); + } + return m; + } + } + + /** + * Unused but could always come in handy I guess + */ + @SuppressWarnings("unused") + public static class BooleanOption extends ClickableWidget { + + private boolean current = false; + private BooleanConsumer onChange = null; + + public BooleanOption(int x, int y, int width, Text message) { + super(x, y, width, 11, message); + } + + @Override + protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + if (isMouseOver(mouseX, mouseY)) { + context.fill(getX(), getY(), getRight(), getBottom(), 0x20FFFFFF); + } + TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; + context.drawText(textRenderer, getMessage(), getX() + 1, getY() + 1, -1, true); + context.drawBorder(getRight() - 10, getY() + 1, 9, 9, -1); + if (current) context.fill(getRight() - 8, getY() + 3, getRight() - 3, getY() + 8, -1); + } + + @Override + public void onClick(double mouseX, double mouseY) { + current = !current; + if (onChange != null) onChange.accept(current); + super.onClick(mouseX, mouseY); + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) { + } + + public void setCurrent(boolean current) { + this.current = current; + } + + public void setOnChange(BooleanConsumer onChange) { + this.onChange = onChange; + } + } + + public static class ColorOption extends ClickableWidget { + + public void setCurrent(int current) { + this.current = current; + } + + private int current = 0; + private Consumer<Color> onChange = null; + private final Screen parent; + + public ColorOption(int x, int y, int width, Text message, Screen parent) { + super(x, y, width, 11, message); + this.parent = parent; + } + + @Override + protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + if (isMouseOver(mouseX, mouseY)) { + context.fill(getX(), getY(), getRight(), getBottom(), 0x20FFFFFF); + } + TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; + context.drawText(textRenderer, getMessage(), getX() + 1, getY() + 1, active ? -1 : Colors.GRAY, true); + context.drawBorder(getRight() - 10, getY() + 1, 9, 9, active ? -1 : Colors.GRAY); + context.fill(getRight() - 8, getY() + 3, getRight() - 3, getY() + 8, active ? current : Colors.GRAY); + } + + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + MinecraftClient.getInstance().setScreen(new EditBarColorPopup(Text.literal("Edit ").append(getMessage()), parent, this::set)); + } + + private void set(Color color) { + current = color.getRGB(); + if (onChange != null) onChange.accept(color); + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) { + + } + + public void setOnChange(Consumer<Color> onChange) { + this.onChange = onChange; + } + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java index 46685468..cc6a3571 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java @@ -33,288 +33,298 @@ import java.util.*; import java.util.concurrent.CompletableFuture; public class FancyStatusBars { - private static final Path FILE = SkyblockerMod.CONFIG_DIR.resolve("status_bars.json"); - private static final Logger LOGGER = LoggerFactory.getLogger(FancyStatusBars.class); + private static final Path FILE = SkyblockerMod.CONFIG_DIR.resolve("status_bars.json"); + private static final Logger LOGGER = LoggerFactory.getLogger(FancyStatusBars.class); - private final MinecraftClient client = MinecraftClient.getInstance(); - private final StatusBarTracker statusBarTracker = SkyblockerMod.getInstance().statusBarTracker; + private final MinecraftClient client = MinecraftClient.getInstance(); + private final StatusBarTracker statusBarTracker = SkyblockerMod.getInstance().statusBarTracker; - public static BarPositioner barPositioner = new BarPositioner(); - public static Map<String, StatusBar> statusBars = new HashMap<>(); + public static BarPositioner barPositioner = new BarPositioner(); + public static Map<String, StatusBar> statusBars = new HashMap<>(); - public static boolean isHealthFancyBarVisible() { - StatusBar health = statusBars.get("health"); - return health.anchor != null || health.inMouse; - } + public static boolean isHealthFancyBarVisible() { + StatusBar health = statusBars.get("health"); + return health.anchor != null || health.inMouse; + } - public static boolean isExperienceFancyBarVisible() { - StatusBar experience = statusBars.get("experience"); - return experience.anchor != null || experience.inMouse; - } + public static boolean isExperienceFancyBarVisible() { + StatusBar experience = statusBars.get("experience"); + return experience.anchor != null || experience.inMouse; + } - @SuppressWarnings("deprecation") + @SuppressWarnings("deprecation") @Init - public static void init() { - statusBars.put("health", new StatusBar(Identifier.of(SkyblockerMod.NAMESPACE, "bars/icons/health"), - new Color[]{new Color(255, 0, 0), new Color(255, 220, 0)}, - true, new Color(255, 85, 85), Text.translatable("skyblocker.bars.config.health"))); - statusBars.put("intelligence", new StatusBar(Identifier.of(SkyblockerMod.NAMESPACE, "bars/icons/intelligence"), - new Color[]{new Color(0, 255, 255), new Color(180, 0, 255)}, - true, new Color(85, 255, 255), Text.translatable("skyblocker.bars.config.intelligence"))); - statusBars.put("defense", new StatusBar(Identifier.of(SkyblockerMod.NAMESPACE, "bars/icons/defense"), - new Color[]{new Color(255, 255, 255)}, - false, new Color(185, 185, 185), Text.translatable("skyblocker.bars.config.defense"))); - statusBars.put("experience", new StatusBar(Identifier.of(SkyblockerMod.NAMESPACE, "bars/icons/experience"), - new Color[]{new Color(100, 230, 70)}, - false, new Color(128, 255, 32), Text.translatable("skyblocker.bars.config.experience"))); - statusBars.put("speed", new StatusBar(Identifier.of(SkyblockerMod.NAMESPACE, "bars/icons/speed"), - new Color[]{new Color(255, 255, 255)}, - false, new Color(185, 185, 185), Text.translatable("skyblocker.bars.config.speed"))); - - // Fetch from old status bar config - int[] counts = new int[3]; // counts for RIGHT, LAYER1, LAYER2 - StatusBar health = statusBars.get("health"); - UIAndVisualsConfig.LegacyBarPositions barPositions = SkyblockerConfigManager.get().uiAndVisuals.bars.barPositions; - initBarPosition(health, counts, barPositions.healthBarPosition); - StatusBar intelligence = statusBars.get("intelligence"); - initBarPosition(intelligence, counts, barPositions.manaBarPosition); - StatusBar defense = statusBars.get("defense"); - initBarPosition(defense, counts, barPositions.defenceBarPosition); - StatusBar experience = statusBars.get("experience"); - initBarPosition(experience, counts, barPositions.experienceBarPosition); - StatusBar speed = statusBars.get("speed"); - initBarPosition(speed, counts, UIAndVisualsConfig.LegacyBarPosition.RIGHT); - - CompletableFuture.supplyAsync(FancyStatusBars::loadBarConfig).thenAccept(object -> { - if (object != null) { - for (String s : object.keySet()) { - if (statusBars.containsKey(s)) { - try { - statusBars.get(s).loadFromJson(object.get(s).getAsJsonObject()); - } catch (Exception e) { - LOGGER.error("[Skyblocker] Failed to load {} status bar", s, e); - } - } else { - LOGGER.warn("[Skyblocker] Unknown status bar: {}", s); - } - } - } - placeBarsInPositioner(); - configLoaded = true; - }).exceptionally(throwable -> { - LOGGER.error("[Skyblocker] Failed reading status bars config", throwable); - return null; - }); - ClientLifecycleEvents.CLIENT_STOPPING.register((client) -> { - saveBarConfig(); - GLFW.glfwDestroyCursor(StatusBarsConfigScreen.RESIZE_CURSOR); - }); - - ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register( - ClientCommandManager.literal(SkyblockerMod.NAMESPACE) - .then(ClientCommandManager.literal("bars").executes(Scheduler.queueOpenScreenCommand(StatusBarsConfigScreen::new))))); - } - - /** - * Loads the bar position from the old config. Should be used to initialize new bars too. - * @param bar the bar to load the position for - * @param counts the counts for each bar position (LAYER1, LAYER2, RIGHT) - * @param position the position to load - */ - private static void initBarPosition(StatusBar bar, int[] counts, UIAndVisualsConfig.LegacyBarPosition position) { - switch (position) { - case RIGHT: - bar.anchor = BarPositioner.BarAnchor.HOTBAR_RIGHT; - bar.gridY = 0; - bar.gridX = counts[position.ordinal()]++; - break; - case LAYER1: - bar.anchor = BarPositioner.BarAnchor.HOTBAR_TOP; - bar.gridY = 0; - bar.gridX = counts[position.ordinal()]++; - break; - case LAYER2: - bar.anchor = BarPositioner.BarAnchor.HOTBAR_TOP; - bar.gridY = 1; - bar.gridX = counts[position.ordinal()]++; - break; - } - } - - private static boolean configLoaded = false; - - private static void placeBarsInPositioner() { - List<StatusBar> original = statusBars.values().stream().toList(); - - for (BarPositioner.BarAnchor barAnchor : BarPositioner.BarAnchor.allAnchors()) { - List<StatusBar> barList = new ArrayList<>(original.stream().filter(bar -> bar.anchor == barAnchor).toList()); - if (barList.isEmpty()) continue; - barList.sort((a, b) -> a.gridY == b.gridY ? Integer.compare(a.gridX, b.gridX) : Integer.compare(a.gridY, b.gridY)); - - int y = -1; - int rowNum = -1; - for (StatusBar statusBar : barList) { - if (statusBar.gridY > y) { - barPositioner.addRow(barAnchor); - rowNum++; - y = statusBar.gridY; - } - barPositioner.addBar(barAnchor, rowNum, statusBar); - } - } - } - - public static JsonObject loadBarConfig() { - try (BufferedReader reader = Files.newBufferedReader(FILE)) { - return SkyblockerMod.GSON.fromJson(reader, JsonObject.class); - } catch (NoSuchFileException e) { - LOGGER.warn("[Skyblocker] No status bar config file found, using defaults"); - } catch (Exception e) { - LOGGER.error("[Skyblocker] Failed to load status bars config", e); - } - return null; - } - - public static void saveBarConfig() { - JsonObject output = new JsonObject(); - statusBars.forEach((s, statusBar) -> output.add(s, statusBar.toJson())); - try (BufferedWriter writer = Files.newBufferedWriter(FILE)) { - SkyblockerMod.GSON.toJson(output, writer); - LOGGER.info("[Skyblocker] Saved status bars config"); - } catch (IOException e) { - LOGGER.error("[Skyblocker] Failed to save status bars config", e); - } - } - - public static void updatePositions() { - if (!configLoaded) return; - final int width = MinecraftClient.getInstance().getWindow().getScaledWidth(); - final int height = MinecraftClient.getInstance().getWindow().getScaledHeight(); - - for (BarPositioner.BarAnchor barAnchor : BarPositioner.BarAnchor.allAnchors()) { - ScreenPos anchorPosition = barAnchor.getAnchorPosition(width, height); - BarPositioner.SizeRule sizeRule = barAnchor.getSizeRule(); - - int targetSize = sizeRule.targetSize(); - boolean visibleHealthMove = barAnchor == BarPositioner.BarAnchor.HOTBAR_TOP && !isHealthFancyBarVisible(); - if (visibleHealthMove) { - targetSize /= 2; - } - - if (sizeRule.isTargetSize()) { - for (int row = 0; row < barPositioner.getRowCount(barAnchor); row++) { - LinkedList<StatusBar> barRow = barPositioner.getRow(barAnchor, row); - if (barRow.isEmpty()) continue; - - // FIX SIZES - int totalSize = 0; - for (StatusBar statusBar : barRow) - totalSize += (statusBar.size = Math.clamp(statusBar.size, sizeRule.minSize(), sizeRule.maxSize())); - - whileLoop: - while (totalSize != targetSize) { - if (totalSize > targetSize) { - for (StatusBar statusBar : barRow) { - if (statusBar.size > sizeRule.minSize()) { - statusBar.size--; - totalSize--; - if (totalSize == targetSize) break whileLoop; - } - } - } else { - for (StatusBar statusBar : barRow) { - if (statusBar.size < sizeRule.maxSize()) { - statusBar.size++; - totalSize++; - if (totalSize == targetSize) break whileLoop; - } - } - } - } - - } - } - - for (int row = 0; row < barPositioner.getRowCount(barAnchor); row++) { - List<StatusBar> barRow = barPositioner.getRow(barAnchor, row); - if (barRow.isEmpty()) continue; - - - // Update the positions - float widthPerSize; - if (sizeRule.isTargetSize()) - widthPerSize = (float) sizeRule.totalWidth() / targetSize; - else - widthPerSize = sizeRule.widthPerSize(); - - if (visibleHealthMove) widthPerSize /= 2; - - int currSize = 0; - int rowSize = barRow.size(); - for (int i = 0; i < rowSize; i++) { - // A bit of a padding - int offsetX = 0; - int lessWidth = 0; - if (rowSize > 1) { // Technically bars in the middle of 3+ bars will be smaller than the 2 side ones but shh - if (i == 0) lessWidth = 1; - else if (i == rowSize - 1) { - lessWidth = 1; - offsetX = 1; - } else { - lessWidth = 2; - offsetX = 1; - } - } - StatusBar statusBar = barRow.get(i); - statusBar.size = Math.clamp(statusBar.size, sizeRule.minSize(), sizeRule.maxSize()); - - float x = barAnchor.isRight() ? - anchorPosition.x() + (visibleHealthMove ? sizeRule.totalWidth() / 2.f : 0) + currSize * widthPerSize : - anchorPosition.x() - currSize * widthPerSize - statusBar.size * widthPerSize; - statusBar.setX(MathHelper.ceil(x) + offsetX); - - int y = barAnchor.isUp() ? - anchorPosition.y() - (row + 1) * (statusBar.getHeight() + 1) : - anchorPosition.y() + row * (statusBar.getHeight() + 1); - statusBar.setY(y); - - statusBar.setWidth(MathHelper.floor(statusBar.size * widthPerSize) - lessWidth); - currSize += statusBar.size; - statusBar.gridX = i; - statusBar.gridY = row; - - } - } - - } - } - - public static boolean isEnabled() { - return SkyblockerConfigManager.get().uiAndVisuals.bars.enableBars && !Utils.isInTheRift(); - } - - public boolean render(DrawContext context, int scaledWidth, int scaledHeight) { - var player = client.player; - if (!isEnabled() || player == null) - return false; - - Collection<StatusBar> barCollection = statusBars.values(); - for (StatusBar statusBar : barCollection) { - if (statusBar.anchor != null) statusBar.render(context, -1, -1, client.getRenderTickCounter().getLastFrameDuration()); - } - for (StatusBar statusBar : barCollection) { - if (statusBar.anchor != null && statusBar.showText()) statusBar.renderText(context); - } - StatusBarTracker.Resource health = statusBarTracker.getHealth(); - statusBars.get("health").updateValues(health.value() / (float) health.max(), health.overflow() / (float) health.max(), health.value()); - - StatusBarTracker.Resource intelligence = statusBarTracker.getMana(); - statusBars.get("intelligence") |
