From ca2c617e036dbfc07243faf06f0b77a03636134d Mon Sep 17 00:00:00 2001 From: vicisacat Date: Tue, 26 Mar 2024 17:50:20 +0100 Subject: [PATCH 01/25] testing things --- .../skyblocker/skyblock/FancyStatusBars.java | 13 +++++++++++++ .../textures/gui/sprites/bars/bar_test.png | Bin 0 -> 170 bytes 2 files changed, 13 insertions(+) create mode 100644 src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_test.png diff --git a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java index 3456d1adbc..c1632732f9 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java @@ -6,8 +6,12 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.texture.Sprite; +import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.Identifier; +import java.util.function.Supplier; + public class FancyStatusBars { private static final Identifier BARS = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/bars.png"); @@ -38,6 +42,9 @@ private int fill(int value, int max) { return (100 * value) / max; } + private static final Identifier TEST = new Identifier(SkyblockerMod.NAMESPACE, "bars/bar_test"); + private static final Supplier SUPPLIER = () -> MinecraftClient.getInstance().getGuiAtlasManager().getSprite(TEST); + public boolean render(DrawContext context, int scaledWidth, int scaledHeight) { var player = client.player; if (!SkyblockerConfigManager.get().general.bars.enableBars || player == null || Utils.isInTheRift()) @@ -77,6 +84,12 @@ public boolean render(DrawContext context, int scaledWidth, int scaledHeight) { for (var bar : bars) { bar.drawText(context); } + MatrixStack matrices = context.getMatrices(); + matrices.push(); + matrices.translate(50, 50, 0); + matrices.scale(2,2,1); + context.drawSprite(0, 0, 0, 60, 5, SUPPLIER.get(), 1, 0.25f, 0.25f, 1); + matrices.pop(); return true; } diff --git a/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_test.png b/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_test.png new file mode 100644 index 0000000000000000000000000000000000000000..cde2a16f6408e1c3b9206ca7af00ee8eeebe489b GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^HbBhE!3HEHJNw0f6k~CayA#8@b22Z19F}xPUq=Rp zjs4tz5?O(K&H|6fVg?4j!ywFfJby(BP|)7f#WBRfKRJb=>CBp@{|Z$*nqOX4Gcanh ziH^R_A}V!n!Ooq1jfKb0DJv_LB{pO}K4u#5>;t>P{=N-1HjRP|RcA$Jin^{T0~*EP M>FVdQ&MBb@0ASfPBme*a literal 0 HcmV?d00001 From 897b3021fbc1aca4b481c741fbe873bd7e5b197f Mon Sep 17 00:00:00 2001 From: vicisacat Date: Thu, 28 Mar 2024 13:43:10 +0100 Subject: [PATCH 02/25] colored nine-slice --- .../mixin/accessor/DrawContextInvoker.java | 3 + .../skyblocker/utils/render/RenderHelper.java | 71 +++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/src/main/java/de/hysky/skyblocker/mixin/accessor/DrawContextInvoker.java b/src/main/java/de/hysky/skyblocker/mixin/accessor/DrawContextInvoker.java index 8dcccf3411..bb201dce85 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/accessor/DrawContextInvoker.java +++ b/src/main/java/de/hysky/skyblocker/mixin/accessor/DrawContextInvoker.java @@ -4,6 +4,7 @@ import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.tooltip.TooltipComponent; import net.minecraft.client.gui.tooltip.TooltipPositioner; +import net.minecraft.util.Identifier; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; @@ -14,4 +15,6 @@ public interface DrawContextInvoker { @Invoker void invokeDrawTooltip(TextRenderer textRenderer, List components, int x, int y, TooltipPositioner positioner); + @Invoker + void invokeDrawTexturedQuad(Identifier texture, int x1, int x2, int y1, int y2, int z, float u1, float u2, float v1, float v2, float red, float green, float blue, float alpha); } diff --git a/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java b/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java index e39b5364bf..da179d0e3e 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java @@ -4,6 +4,7 @@ import com.mojang.logging.LogUtils; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.mixin.accessor.BeaconBlockEntityRendererInvoker; +import de.hysky.skyblocker.mixin.accessor.DrawContextInvoker; import de.hysky.skyblocker.utils.render.culling.OcclusionCulling; import de.hysky.skyblocker.utils.render.title.Title; import de.hysky.skyblocker.utils.render.title.TitleContainer; @@ -12,8 +13,11 @@ import net.fabricmc.fabric.api.event.Event; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.render.*; import net.minecraft.client.render.VertexFormat.DrawMode; +import net.minecraft.client.texture.Scaling; +import net.minecraft.client.texture.Sprite; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.sound.SoundEvents; import net.minecraft.text.OrderedText; @@ -28,6 +32,7 @@ import org.lwjgl.opengl.GL11; import org.slf4j.Logger; +import java.awt.*; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; @@ -370,6 +375,72 @@ public static boolean pointIsInArea(double x, double y, double x1, double y1, do return x >= x1 && x <= x2 && y >= y1 && y <= y2; } + private static void drawSprite(DrawContext context, Sprite sprite, int i, int j, int k, int l, int x, int y, int z, int width, int height, float red, float green, float blue, float alpha) { + if (width == 0 || height == 0) { + return; + } + ((DrawContextInvoker) context).invokeDrawTexturedQuad(sprite.getAtlasId(), x, x + width, y, y + height, z, sprite.getFrameU((float)k / (float)i), sprite.getFrameU((float)(k + width) / (float)i), sprite.getFrameV((float)l / (float)j), sprite.getFrameV((float)(l + height) / (float)j), red, green, blue, alpha); + } + private static void drawSpriteTiled(DrawContext context, Sprite sprite, int x, int y, int z, int width, int height, int i, int j, int tileWidth, int tileHeight, int k, int l, float red, float green, float blue, float alpha) { + if (width <= 0 || height <= 0) { + return; + } + if (tileWidth <= 0 || tileHeight <= 0) { + throw new IllegalArgumentException("Tiled sprite texture size must be positive, got " + tileWidth + "x" + tileHeight); + } + for (int m = 0; m < width; m += tileWidth) { + int n = Math.min(tileWidth, width - m); + for (int o = 0; o < height; o += tileHeight) { + int p = Math.min(tileHeight, height - o); + drawSprite(context, sprite, k, l, i, j, x + m, y + o, z, n, p, red, green, blue, alpha); + } + } + } + + public static void renderNineSliceColored(DrawContext context, Identifier texture, int x, int y, int width, int height, float red, float green, float blue, float alpha) { + Sprite sprite = MinecraftClient.getInstance().getGuiAtlasManager().getSprite(texture); + Scaling scaling = MinecraftClient.getInstance().getGuiAtlasManager().getScaling(sprite); + if (!(scaling instanceof Scaling.NineSlice nineSlice)) return; + Scaling.NineSlice.Border border = nineSlice.border(); + int z = 0; + + int i = Math.min(border.left(), width / 2); + int j = Math.min(border.right(), width / 2); + int k = Math.min(border.top(), height / 2); + int l = Math.min(border.bottom(), height / 2); + if (width == nineSlice.width() && height == nineSlice.height()) { + drawSprite(context, sprite, nineSlice.width(), nineSlice.height(), 0, 0, x, y, z, width, height, red, green, blue, alpha); + return; + } + if (height == nineSlice.height()) { + drawSprite(context, sprite, nineSlice.width(), nineSlice.height(), 0, 0, x, y, z, i, height, red, green, blue, alpha); + drawSpriteTiled(context, sprite, x + i, y, z, width - j - i, height, i, 0, nineSlice.width() - j - i, nineSlice.height(), nineSlice.width(), nineSlice.height(), red, green, blue, alpha); + drawSprite(context, sprite, nineSlice.width(), nineSlice.height(), nineSlice.width() - j, 0, x + width - j, y, z, j, height, red, green, blue, alpha); + return; + } + if (width == nineSlice.width()) { + drawSprite(context, sprite, nineSlice.width(), nineSlice.height(), 0, 0, x, y, z, width, k, red, green, blue, alpha); + drawSpriteTiled(context, sprite, x, y + k, z, width, height - l - k, 0, k, nineSlice.width(), nineSlice.height() - l - k, nineSlice.width(), nineSlice.height(), red, green, blue, alpha); + drawSprite(context, sprite, nineSlice.width(), nineSlice.height(), 0, nineSlice.height() - l, x, y + height - l, z, width, l, red, green, blue, alpha); + return; + } + drawSprite(context, sprite, nineSlice.width(), nineSlice.height(), 0, 0, x, y, z, i, k, red, green, blue, alpha); + drawSpriteTiled(context, sprite, x + i, y, z, width - j - i, k, i, 0, nineSlice.width() - j - i, k, nineSlice.width(), nineSlice.height(), red, green, blue, alpha); + drawSprite(context, sprite, nineSlice.width(), nineSlice.height(), nineSlice.width() - j, 0, x + width - j, y, z, j, k, red, green, blue, alpha); + drawSprite(context, sprite, nineSlice.width(), nineSlice.height(), 0, nineSlice.height() - l, x, y + height - l, z, i, l, red, green, blue, alpha); + drawSpriteTiled(context, sprite, x + i, y + height - l, z, width - j - i, l, i, nineSlice.height() - l, nineSlice.width() - j - i, l, nineSlice.width(), nineSlice.height(), red, green, blue, alpha); + drawSprite(context, sprite, nineSlice.width(), nineSlice.height(), nineSlice.width() - j, nineSlice.height() - l, x + width - j, y + height - l, z, j, l, red, green, blue, alpha); + drawSpriteTiled(context, sprite, x, y + k, z, i, height - l - k, 0, k, i, nineSlice.height() - l - k, nineSlice.width(), nineSlice.height(), red, green, blue, alpha); + drawSpriteTiled(context, sprite, x + i, y + k, z, width - j - i, height - l - k, i, k, nineSlice.width() - j - i, nineSlice.height() - l - k, nineSlice.width(), nineSlice.height(), red, green, blue, alpha); + drawSpriteTiled(context, sprite, x + width - j, y + k, z, i, height - l - k, nineSlice.width() - j, k, j, nineSlice.height() - l - k, nineSlice.width(), nineSlice.height(), red, green, blue, alpha); + } + + private static final float[] colorBuffer = new float[4]; + public static void renderNineSliceColored(DrawContext context, Identifier texture, int x, int y, int width, int height, Color color) { + color.getComponents(colorBuffer); + renderNineSliceColored(context, texture, x, y, width, height, colorBuffer[0],colorBuffer[1],colorBuffer[2],colorBuffer[3]); + } + // TODO Get rid of reflection once the new Sodium is released private static MethodHandle getDeferredRenderTaskHandle() { try { From 0d5b04f9a5f57be03c79b76ff9b730951b5f959f Mon Sep 17 00:00:00 2001 From: vicisacat Date: Sun, 31 Mar 2024 14:51:18 +0200 Subject: [PATCH 03/25] progress ig --- .../skyblocker/skyblock/FancyStatusBars.java | 53 ++++--- .../skyblock/fancybars/BarGrid.java | 93 ++++++++++++ .../skyblock/fancybars/StatusBar.java | 136 ++++++++++++++++++ .../fancybars/StatusBarsConfigScreen.java | 44 ++++++ .../textures/gui/sprites/bars/bar_back.png | Bin 0 -> 196 bytes .../gui/sprites/bars/bar_back.png.mcmeta | 10 ++ .../textures/gui/sprites/bars/bar_fill.png | Bin 0 -> 179 bytes .../gui/sprites/bars/bar_fill.png.mcmeta | 10 ++ .../textures/gui/sprites/bars/bar_test.png | Bin 170 -> 0 bytes 9 files changed, 325 insertions(+), 21 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java create mode 100644 src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_back.png create mode 100644 src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_back.png.mcmeta create mode 100644 src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_fill.png create mode 100644 src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_fill.png.mcmeta delete mode 100644 src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_test.png diff --git a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java index c1632732f9..7744626bac 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java @@ -2,7 +2,10 @@ import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.skyblock.fancybars.BarGrid; +import de.hysky.skyblocker.skyblock.fancybars.StatusBar; import de.hysky.skyblocker.utils.Utils; +import de.hysky.skyblocker.utils.render.RenderHelper; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; @@ -10,6 +13,11 @@ import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.Identifier; +import java.awt.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.function.Supplier; public class FancyStatusBars { @@ -18,11 +26,11 @@ public class FancyStatusBars { private final MinecraftClient client = MinecraftClient.getInstance(); private final StatusBarTracker statusBarTracker = SkyblockerMod.getInstance().statusBarTracker; - private final StatusBar[] bars = new StatusBar[]{ - new StatusBar(0, 16733525, 2), // Health Bar - new StatusBar(1, 5636095, 2), // Intelligence Bar - new StatusBar(2, 12106180, 1), // Defence Bar - new StatusBar(3, 8453920, 1), // Experience Bar + private final OldStatusBar[] bars = new OldStatusBar[]{ + new OldStatusBar(0, 16733525, 2, new Color[]{new Color(255, 0, 0), new Color(255, 220, 0)}), // Health Bar + new OldStatusBar(1, 5636095, 2, new Color[]{new Color(0, 255, 255), new Color(180, 0, 255)}), // Intelligence Bar + new OldStatusBar(2, 12106180, 1, new Color[]{new Color(255, 255, 255)}), // Defence Bar + new OldStatusBar(3, 8453920, 1, new Color[]{new Color(100, 220, 70)}), // Experience Bar }; // Positions to show the bars @@ -31,6 +39,16 @@ public class FancyStatusBars { private final int[] anchorsX = new int[3]; private final int[] anchorsY = new int[3]; + public static BarGrid barGrid = new BarGrid(); + public static Map statusBars = new HashMap<>(); + + static { + statusBars.put("health", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(255, 0, 0), new Color(255, 220, 0)}, true, null)); + statusBars.put("intelligence", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(0, 255, 255), new Color(180, 0, 255)}, true, null)); + statusBars.put("defense", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(255, 255, 255)}, false, null)); + statusBars.put("experience", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(100, 220, 70)}, false, null)); + } + public FancyStatusBars() { moveBar(0, 0); moveBar(1, 0); @@ -42,8 +60,9 @@ private int fill(int value, int max) { return (100 * value) / max; } - private static final Identifier TEST = new Identifier(SkyblockerMod.NAMESPACE, "bars/bar_test"); - private static final Supplier SUPPLIER = () -> MinecraftClient.getInstance().getGuiAtlasManager().getSprite(TEST); + private static final Identifier BAR_FILL = new Identifier(SkyblockerMod.NAMESPACE, "bars/bar_fill"); + private static final Identifier BAR_BACK = new Identifier(SkyblockerMod.NAMESPACE, "bars/bar_back"); + private static final Supplier SUPPLIER = () -> MinecraftClient.getInstance().getGuiAtlasManager().getSprite(BAR_FILL); public boolean render(DrawContext context, int scaledWidth, int scaledHeight) { var player = client.player; @@ -129,8 +148,9 @@ public void moveBar(int bar, int location) { } } - private class StatusBar { + private class OldStatusBar { public final int[] fill; + private final Color[] colors; public int offsetX; private final int v; private final int text_color; @@ -138,13 +158,14 @@ private class StatusBar { public int bar_width; public Object text; - private StatusBar(int i, int textColor, int fillNum) { + private OldStatusBar(int i, int textColor, int fillNum, Color[] colors) { this.v = i * 9; this.text_color = textColor; this.fill = new int[fillNum]; this.fill[0] = 100; this.anchorNum = 0; this.text = ""; + this.colors = colors; } public void update(StatusBarTracker.Resource resource) { @@ -163,23 +184,13 @@ public void draw(DrawContext context) { context.drawTexture(BARS, anchorsX[anchorNum] + offsetX, anchorsY[anchorNum], 0, v, 9, 9); // Draw the background for the bar - context.drawTexture(BARS, anchorsX[anchorNum] + offsetX + 10, anchorsY[anchorNum], 10, v, 2, 9); - for (int i = 2; i < bar_width - 2; i += 58) { - context.drawTexture(BARS, anchorsX[anchorNum] + offsetX + 10 + i, anchorsY[anchorNum], 12, v, Math.min(58, bar_width - 2 - i), 9); - } - context.drawTexture(BARS, anchorsX[anchorNum] + offsetX + 10 + bar_width - 2, anchorsY[anchorNum], 70, v, 2, 9); + context.drawGuiTexture(BAR_BACK, anchorsX[anchorNum]+ offsetX+10, anchorsY[anchorNum]+1, bar_width, 7); // Draw the filled part of the bar for (int i = 0; i < fill.length; i++) { int fill_width = this.fill[i] * (bar_width - 2) / 100; if (fill_width >= 1) { - context.drawTexture(BARS, anchorsX[anchorNum] + offsetX + 11, anchorsY[anchorNum], 72 + i * 60, v, 1, 9); - } - for (int j = 1; j < fill_width - 1; j += 58) { - context.drawTexture(BARS, anchorsX[anchorNum] + offsetX + 11 + j, anchorsY[anchorNum], 73 + i * 60, v, Math.min(58, fill_width - 1 - j), 9); - } - if (fill_width == bar_width - 2) { - context.drawTexture(BARS, anchorsX[anchorNum] + offsetX + 11 + fill_width - 1, anchorsY[anchorNum], 131 + i * 60, v, 1, 9); + RenderHelper.renderNineSliceColored(context, BAR_FILL, anchorsX[anchorNum] + offsetX + 11, anchorsY[anchorNum]+2, fill_width, 5, colors[i]); } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java new file mode 100644 index 0000000000..b85f85e121 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java @@ -0,0 +1,93 @@ +package de.hysky.skyblocker.skyblock.fancybars; + +import java.util.LinkedList; +import java.util.List; + +public class BarGrid { + private final LinkedList> top = new LinkedList<>(); + private final LinkedList> bottomLeft = new LinkedList<>(); + private final LinkedList> bottomRight = new LinkedList<>(); + + public BarGrid() {} + + public void add(int row, StatusBar bar, boolean right) { + if (row > 0) + top.get(row).add(bar); + else if (row < 0) { + if (right) { + bottomRight.get(Math.abs(row)).add(bar); + } else { + bottomLeft.get(Math.abs(row)).add(bar); + } + } + } + + public void add(int x, int y, StatusBar bar) { + if (y > 0) { + if (x < 1) throw new IllegalArgumentException("x can't be negative, x: " + x); + LinkedList statusBars = top.get(y-1); + statusBars.add(Math.min(x-1, statusBars.size()), bar); + bar.gridY = y; + bar.gridX = statusBars.indexOf(bar)+1; + } else if (y < 0) { + LinkedList statusBars = (x < 0? bottomLeft: bottomRight).get(Math.abs(y)-1); + statusBars.add(Math.min(Math.abs(x)-1, statusBars.size()), bar); + bar.gridY = y; + bar.gridX = -(statusBars.indexOf(bar)+1); + } + } + + public List getRow(int row, boolean right) { + if (row > 0) { + return top.get(row-1); + } else { + return (right ? bottomRight: bottomLeft).get(Math.abs(row)-1); + } + } + + public void addRow(int row, boolean right) { + if (row>0) { + top.add(row-1, new LinkedList<>()); + } else if (row<0) { + (right ? bottomRight: bottomLeft).add(Math.abs(row)-1, new LinkedList<>()); + } + } + + public void remove(int x, int y) { + if (y > 0) { + if (x < 1) throw new IllegalArgumentException("x can't be negative, x: " + x); + LinkedList statusBars = top.get(y-1); + StatusBar remove = statusBars.remove(x-1); + for (int i = x-1; i < statusBars.size(); i++) { + statusBars.get(i).gridX--; + } + remove.gridX = 0; + remove.gridY = 0; + if (statusBars.isEmpty()) { + top.remove(y - 1); + for (int i = y-1; i < top.size(); i++) { + for (StatusBar bar : top.get(i)) { + bar.gridY--; + } + } + } + } else if (y < 0) { + LinkedList> bottom = x < 0 ? bottomLeft : bottomRight; + LinkedList statusBars = bottom.get(Math.abs(y)-1); + StatusBar remove = statusBars.remove(Math.abs(x) - 1); + for (int i = Math.abs(x)-1; i < statusBars.size(); i++) { + statusBars.get(i).gridX--; + } + remove.gridX = 0; + remove.gridY = 0; + if (statusBars.isEmpty()) { + bottom.remove(Math.abs(y) - 1); + for (int i = Math.abs(y)-1; i < bottom.size(); i++) { + for (StatusBar bar : bottom.get(i)) { + bar.gridY--; + } + } + } + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java new file mode 100644 index 0000000000..9c688051a4 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java @@ -0,0 +1,136 @@ +package de.hysky.skyblocker.skyblock.fancybars; + +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.utils.render.RenderHelper; +import net.minecraft.client.gui.*; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.widget.ClickableWidget; +import net.minecraft.client.gui.widget.Widget; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; +import java.util.function.Consumer; + +public class StatusBar implements Widget, Drawable, Element, Selectable { + + private static final Identifier BAR_FILL = new Identifier(SkyblockerMod.NAMESPACE, "bars/bar_fill"); + private static final Identifier BAR_BACK = new Identifier(SkyblockerMod.NAMESPACE, "bars/bar_back"); + + private final Identifier icon; + private final Color[] colors; + private final boolean hasOverflow; + private final @Nullable Color textColor; + + private @Nullable Consumer onClick = null; + public int gridX = 0; + public int gridY = 0; + + public float size = 1; + private int width = 0; + + public float fill = 0; + public float overflowFill = 0; + + private int x = 0; + private int y = 0; + + public StatusBar(Identifier icon, Color[] colors, boolean hasOverflow, @Nullable Color textColor) { + this.icon = icon; + this.colors = colors; + this.hasOverflow = hasOverflow; + this.textColor = textColor; + } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + context.drawGuiTexture(icon, x, y, 9, 9); + context.drawGuiTexture(BAR_BACK, x + 10, y + 1, width - 10, 7); + RenderHelper.renderNineSliceColored(context, BAR_FILL, x + 11, y + 2, (int) ((width - 12) * fill), 5, colors[0]); + if (hasOverflow) { + RenderHelper.renderNineSliceColored(context, BAR_FILL, x + 11, y + 2, (int) ((width - 12) * overflowFill), 5, colors[1]); + } + } + + // GUI shenanigans + + @Override + public void setX(int x) { + this.x = x; + } + + @Override + public void setY(int y) { + this.y = y; + } + + @Override + public int getX() { + return x; + } + + @Override + public int getY() { + return y; + } + + @Override + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + + @Override + public int getHeight() { + return 9; + } + + @Override + public ScreenRect getNavigationFocus() { + return Widget.super.getNavigationFocus(); + } + + @Override + public boolean isMouseOver(double mouseX, double mouseY) { + return mouseX >= x && mouseX <= x + getWidth() && mouseY >= y && mouseY <= y + getHeight(); + } + + @Override + public void forEachChild(Consumer consumer) {} + + @Override + public void setFocused(boolean focused) { + + } + + @Override + public boolean isFocused() { + return false; + } + + @Override + public SelectionType getType() { + return SelectionType.NONE; + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (!isMouseOver(mouseX, mouseY)) return false; + if (onClick != null) { + onClick.accept(this); + } + return true; + } + + public void setOnClick(@Nullable Consumer onClick) { + this.onClick = onClick; + } + + @Override + public void appendNarrations(NarrationMessageBuilder builder) { + + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java new file mode 100644 index 0000000000..1f0b7ffe79 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java @@ -0,0 +1,44 @@ +package de.hysky.skyblocker.skyblock.fancybars; + +import de.hysky.skyblocker.skyblock.FancyStatusBars; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.Nullable; + +public class StatusBarsConfigScreen extends Screen { + + private static final Identifier HOTBAR_TEXTURE = new Identifier("hud/hotbar"); + + private @Nullable StatusBar cursorBar = null; + protected StatusBarsConfigScreen(Text title) { + super(title); + } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + super.render(context, mouseX, mouseY, delta); + context.drawGuiTexture(HOTBAR_TEXTURE, width/2 - 91, height-22, 182, 22); + if (cursorBar != null) { + cursorBar.setX(mouseX); + cursorBar.setY(mouseY); + cursorBar.render(context, mouseX, mouseY, delta); + } + } + + @Override + protected void init() { + super.init(); + FancyStatusBars.statusBars.values().forEach(this::setup); + } + + private void setup(StatusBar statusBar) { + this.addDrawableChild(statusBar); + statusBar.setOnClick(this::onClick); + } + + private void onClick(StatusBar statusBar) { + + } +} diff --git a/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_back.png b/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_back.png new file mode 100644 index 0000000000000000000000000000000000000000..150d6ad6715258a82b0537d694a39dab991b0387 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^6+q0+!3-q7oU8l-q!^2X+?^QKos)S9^91;WxB_Vn4GmFIQ6R(ZuBj79T}hB%@c;k+8631$f(+p-@Q5sCVBk9p z!i>lBSEK+14Lw~PLoED{URub=U?6bF!Ry=oogL>cxa_q)$gX5ERc7JFF6+pa-{;ns g8ZUQBp1Zz{J64|Q=}+&=Q9#WMp00i_>zopr02JjrA^-pY literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_back.png.mcmeta b/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_back.png.mcmeta new file mode 100644 index 0000000000..4744012e33 --- /dev/null +++ b/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_back.png.mcmeta @@ -0,0 +1,10 @@ +{ + "gui": { + "scaling": { + "type": "nine_slice", + "width": 120, + "height": 7, + "border": 3 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_fill.png b/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_fill.png new file mode 100644 index 0000000000000000000000000000000000000000..714ae67547b7a140a83ac0551e103b1b8fe03352 GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^6+q0&!3-pKvfcO(q!^2X+?^QKos)S9^91;WxMpS*{Qv*|#EBC?fpw;n=YZ6e1o;I61sNQ)R(=8UISV`@iy0XB z4uUY_j)~cCfr1L2E{-7@!O00}5&{fcrWHCcFf(6fXl&dhDRYCFL1G5uv=dD6<E Q1gd55boFyt=akR{0N|fAK>z>% literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_fill.png.mcmeta b/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_fill.png.mcmeta new file mode 100644 index 0000000000..8a9af80921 --- /dev/null +++ b/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_fill.png.mcmeta @@ -0,0 +1,10 @@ +{ + "gui": { + "scaling": { + "type": "nine_slice", + "width": 120, + "height": 5, + "border": 2 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_test.png b/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/bar_test.png deleted file mode 100644 index cde2a16f6408e1c3b9206ca7af00ee8eeebe489b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^HbBhE!3HEHJNw0f6k~CayA#8@b22Z19F}xPUq=Rp zjs4tz5?O(K&H|6fVg?4j!ywFfJby(BP|)7f#WBRfKRJb=>CBp@{|Z$*nqOX4Gcanh ziH^R_A}V!n!Ooq1jfKb0DJv_LB{pO}K4u#5>;t>P{=N-1HjRP|RcA$Jin^{T0~*EP M>FVdQ&MBb@0ASfPBme*a From 81ee919672b3628c58e6499c806bac14d6b40ec4 Mon Sep 17 00:00:00 2001 From: vicisacat Date: Tue, 2 Apr 2024 17:23:55 +0200 Subject: [PATCH 04/25] idk again --- .../fancybars/StatusBarsConfigScreen.java | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java index 1f0b7ffe79..2d80e764b5 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java @@ -2,15 +2,24 @@ import de.hysky.skyblocker.skyblock.FancyStatusBars; import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.ScreenPos; +import net.minecraft.client.gui.ScreenRect; +import net.minecraft.client.gui.navigation.NavigationAxis; +import net.minecraft.client.gui.navigation.NavigationDirection; import net.minecraft.client.gui.screen.Screen; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import org.jetbrains.annotations.Nullable; +import java.util.HashMap; +import java.util.Map; + public class StatusBarsConfigScreen extends Screen { private static final Identifier HOTBAR_TEXTURE = new Identifier("hud/hotbar"); + private final Map meaningFullName = new HashMap<>(); + private @Nullable StatusBar cursorBar = null; protected StatusBarsConfigScreen(Text title) { super(title); @@ -24,6 +33,23 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { cursorBar.setX(mouseX); cursorBar.setY(mouseY); cursorBar.render(context, mouseX, mouseY, delta); + + for (ScreenRect screenRect : meaningFullName.keySet()) { + for (NavigationDirection value : NavigationDirection.values()) { + boolean overlaps = screenRect.getBorder(value).overlaps(new ScreenRect(new ScreenPos(mouseX - 1, mouseY - 1), 3, 3)); + if (overlaps) { + int[] ints = meaningFullName.get(screenRect); + if (ints[0] != cursorBar.gridX || ints[1] != cursorBar.gridY) { + FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY); + if (value.getAxis().equals(NavigationAxis.VERTICAL)) { + if (value.isPositive()) { + FancyStatusBars.barGrid.addRow(ints[1]+1, ints[0]>0); + } + } + } + } + } + } } } @@ -39,6 +65,13 @@ private void setup(StatusBar statusBar) { } private void onClick(StatusBar statusBar) { - + cursorBar = statusBar; + meaningFullName.clear(); + FancyStatusBars.barGrid.remove(statusBar.gridX, statusBar.gridY); + FancyStatusBars.statusBars.values().forEach(statusBar1 -> { + meaningFullName.put( + new ScreenRect(new ScreenPos(statusBar1.getX(), statusBar1.getY()), statusBar1.getWidth(), statusBar1.getHeight()), + new int[]{statusBar1.gridX, statusBar1.gridY}); + }); } } From a6ac00af3844d5f59c1f528a901c94e91e58889d Mon Sep 17 00:00:00 2001 From: vicisacat Date: Wed, 3 Apr 2024 15:33:12 +0200 Subject: [PATCH 05/25] progress ig --- .../skyblocker/skyblock/FancyStatusBars.java | 77 +++++++++++++++++++ .../skyblock/fancybars/BarGrid.java | 5 ++ .../skyblock/fancybars/StatusBar.java | 2 +- .../fancybars/StatusBarsConfigScreen.java | 13 +++- 4 files changed, 95 insertions(+), 2 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java index 7744626bac..a5cbab1f6b 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java @@ -47,6 +47,83 @@ public class FancyStatusBars { statusBars.put("intelligence", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(0, 255, 255), new Color(180, 0, 255)}, true, null)); statusBars.put("defense", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(255, 255, 255)}, false, null)); statusBars.put("experience", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(100, 220, 70)}, false, null)); + + barGrid.addRow(1, false); + barGrid.add(1, 1, statusBars.get("health")); + barGrid.add(2, 1, statusBars.get("intelligence")); + barGrid.addRow(2, false); + barGrid.add(1, 2, statusBars.get("experience")); + barGrid.addRow(-1, true); + barGrid.add(1, -1, statusBars.get("defense")); + } + + public static void updatePositions() { + final float hotbarSize = 182; + final int width = MinecraftClient.getInstance().getWindow().getScaledWidth(); + final int height = MinecraftClient.getInstance().getWindow().getScaledHeight(); + + // THE TOP + for (int i = 0; i < barGrid.getTopSize(); i++) { + List row = barGrid.getRow(i + 1, false); + if (row.isEmpty()) continue; + int totalSize = 0; + for (StatusBar bar : row) { + totalSize += bar.size; + } + + // Fix sizing + whileLoop: while (totalSize != 12) { + if (totalSize > 12) { + for (StatusBar bar : row) { + bar.size--; + totalSize--; + if (totalSize == 12) break whileLoop; + } + } else { + for (StatusBar bar : row) { + bar.size++; + totalSize++; + if (totalSize == 12) break whileLoop; + } + } + } + + int x = width/2 - 91; + int y = height - 33 - 10*i; + for (StatusBar bar : row) { + bar.setX(x); + bar.setY(y); + bar.setWidth((int) ((bar.size / 12.f)*hotbarSize)); + x += bar.getWidth(); + } + } + + // BOTTOM LEFT + for (int i = 0; i < barGrid.getBottomLeftSize(); i++) { + List row = barGrid.getRow(-(i + 1), false); + if (row.isEmpty()) continue; + int x = width/2 - 91 - 2; + int y = height - 15-10*i; + for (StatusBar bar : row) { + bar.setY(y); + bar.setWidth(bar.size*25); + x -= bar.getWidth(); + bar.setX(x); + } + } + // BOTTOM RIGHT + for (int i = 0; i < barGrid.getBottomRightSize(); i++) { + List row = barGrid.getRow(-(i + 1), true); + if (row.isEmpty()) continue; + int x = width/2 + 91 + 2; + int y = height - 15-10*i; + for (StatusBar bar : row) { + bar.setX(x); + bar.setY(y); + bar.setWidth(bar.size*25); + x += bar.getWidth(); + } + } } public FancyStatusBars() { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java index b85f85e121..5e774d4a56 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java @@ -90,4 +90,9 @@ public void remove(int x, int y) { } } } + + public int getTopSize() {return top.size();} + + public int getBottomLeftSize() {return bottomLeft.size();} + public int getBottomRightSize() {return bottomRight.size();} } 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 9c688051a4..a15660f095 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java @@ -26,7 +26,7 @@ public class StatusBar implements Widget, Drawable, Element, Selectable { public int gridX = 0; public int gridY = 0; - public float size = 1; + public int size = 1; private int width = 0; public float fill = 0; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java index 2d80e764b5..0a08a19918 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java @@ -34,7 +34,7 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { cursorBar.setY(mouseY); cursorBar.render(context, mouseX, mouseY, delta); - for (ScreenRect screenRect : meaningFullName.keySet()) { + mainLoop: for (ScreenRect screenRect : meaningFullName.keySet()) { for (NavigationDirection value : NavigationDirection.values()) { boolean overlaps = screenRect.getBorder(value).overlaps(new ScreenRect(new ScreenPos(mouseX - 1, mouseY - 1), 3, 3)); if (overlaps) { @@ -44,8 +44,19 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { if (value.getAxis().equals(NavigationAxis.VERTICAL)) { if (value.isPositive()) { FancyStatusBars.barGrid.addRow(ints[1]+1, ints[0]>0); + FancyStatusBars.barGrid.add(1, ints[1] + 1, cursorBar); + } else { + FancyStatusBars.barGrid.addRow(ints[1], ints[0]>0); + FancyStatusBars.barGrid.add(1, ints[1], cursorBar); + } + } else { + if (value.isPositive()) { + FancyStatusBars.barGrid.add(ints[0] + 1, ints[1], cursorBar); + } else { + FancyStatusBars.barGrid.add(ints[0], ints[1], cursorBar); } } + break mainLoop; } } } From 3fe321f463fc728374e6f3423c6ac9eef31be184 Mon Sep 17 00:00:00 2001 From: vicisacat Date: Wed, 10 Apr 2024 18:19:29 +0200 Subject: [PATCH 06/25] more progress --- .../de/hysky/skyblocker/SkyblockerMod.java | 1 + .../skyblocker/skyblock/FancyStatusBars.java | 28 +++++++++++-- .../skyblock/fancybars/BarGrid.java | 3 +- .../skyblock/fancybars/StatusBar.java | 38 +++++++++++++++++- .../fancybars/StatusBarsConfigScreen.java | 39 ++++++++++++++++--- 5 files changed, 98 insertions(+), 11 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index 091e8548be..6d86c88da9 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -172,6 +172,7 @@ public void onInitializeClient() { Debug.init(); Kuudra.init(); RenderHelper.init(); + FancyStatusBars.init(); containerSolverManager.init(); statusBarTracker.init(); BeaconHighlighter.init(); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java index a5cbab1f6b..6995c4d297 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java @@ -1,11 +1,17 @@ package de.hysky.skyblocker.skyblock; +import com.mojang.brigadier.Command; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.fancybars.BarGrid; import de.hysky.skyblocker.skyblock.fancybars.StatusBar; +import de.hysky.skyblocker.skyblock.fancybars.StatusBarsConfigScreen; import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.render.RenderHelper; +import de.hysky.skyblocker.utils.scheduler.Scheduler; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; @@ -43,11 +49,13 @@ public class FancyStatusBars { public static Map statusBars = new HashMap<>(); static { - statusBars.put("health", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(255, 0, 0), new Color(255, 220, 0)}, true, null)); - statusBars.put("intelligence", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(0, 255, 255), new Color(180, 0, 255)}, true, null)); - statusBars.put("defense", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(255, 255, 255)}, false, null)); - statusBars.put("experience", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(100, 220, 70)}, false, null)); + statusBars.put("health", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(255, 0, 0), new Color(255, 220, 0)}, true, null, "health")); + statusBars.put("intelligence", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(0, 255, 255), new Color(180, 0, 255)}, true, null, "intelligence")); + statusBars.put("defense", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(255, 255, 255)}, false, null, "defense")); + statusBars.put("experience", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(100, 220, 70)}, false, null, "experience")); + } + public static void init() { barGrid.addRow(1, false); barGrid.add(1, 1, statusBars.get("health")); barGrid.add(2, 1, statusBars.get("intelligence")); @@ -55,6 +63,10 @@ public class FancyStatusBars { barGrid.add(1, 2, statusBars.get("experience")); barGrid.addRow(-1, true); barGrid.add(1, -1, statusBars.get("defense")); + + ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register( + ClientCommandManager.literal("skyblocker") + .then(ClientCommandManager.literal("bar_test").executes(Scheduler.queueOpenScreenCommand(StatusBarsConfigScreen::new))))); } public static void updatePositions() { @@ -62,6 +74,14 @@ public static void updatePositions() { final int width = MinecraftClient.getInstance().getWindow().getScaledWidth(); final int height = MinecraftClient.getInstance().getWindow().getScaledHeight(); + for (StatusBar value : statusBars.values()) { + if (value.gridX == 0 || value.gridY == 0) { + value.setX(-1); + value.setY(-1); + value.setWidth(0); + } + } + // THE TOP for (int i = 0; i < barGrid.getTopSize(); i++) { List row = barGrid.getRow(i + 1, false); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java index 5e774d4a56..932192400c 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java @@ -33,7 +33,7 @@ public void add(int x, int y, StatusBar bar) { LinkedList statusBars = (x < 0? bottomLeft: bottomRight).get(Math.abs(y)-1); statusBars.add(Math.min(Math.abs(x)-1, statusBars.size()), bar); bar.gridY = y; - bar.gridX = -(statusBars.indexOf(bar)+1); + bar.gridX = (int) ((statusBars.indexOf(bar)+1) * Math.signum(x)); } } @@ -54,6 +54,7 @@ public void addRow(int row, boolean right) { } public void remove(int x, int y) { + System.out.println("Removing x: " + x + " y: " + y); if (y > 0) { if (x < 1) throw new IllegalArgumentException("x can't be negative, x: " + x); LinkedList statusBars = top.get(y-1); 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 a15660f095..3b6453a0c5 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java @@ -2,11 +2,14 @@ import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.utils.render.RenderHelper; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.*; import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; import net.minecraft.client.gui.widget.ClickableWidget; import net.minecraft.client.gui.widget.Widget; +import net.minecraft.util.Colors; import net.minecraft.util.Identifier; +import org.apache.commons.lang3.builder.ToStringBuilder; import org.jetbrains.annotations.Nullable; import java.awt.*; @@ -21,6 +24,7 @@ public class StatusBar implements Widget, Drawable, Element, Selectable { private final Color[] colors; private final boolean hasOverflow; private final @Nullable Color textColor; + private final String name; private @Nullable Consumer onClick = null; public int gridX = 0; @@ -35,21 +39,41 @@ public class StatusBar implements Widget, Drawable, Element, Selectable { private int x = 0; private int y = 0; - public StatusBar(Identifier icon, Color[] colors, boolean hasOverflow, @Nullable Color textColor) { + public StatusBar(Identifier icon, Color[] colors, boolean hasOverflow, @Nullable Color textColor, String name) { this.icon = icon; this.colors = colors; this.hasOverflow = hasOverflow; this.textColor = textColor; + this.name = name; + } + + public StatusBar(Identifier icon, Color[] colors, boolean hasOverflow, @Nullable Color textColor){ + this(icon, colors, hasOverflow, textColor, "no name"); } @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { + if (width <= 0) return; context.drawGuiTexture(icon, x, y, 9, 9); context.drawGuiTexture(BAR_BACK, x + 10, y + 1, width - 10, 7); RenderHelper.renderNineSliceColored(context, BAR_FILL, x + 11, y + 2, (int) ((width - 12) * fill), 5, colors[0]); if (hasOverflow) { RenderHelper.renderNineSliceColored(context, BAR_FILL, x + 11, y + 2, (int) ((width - 12) * overflowFill), 5, colors[1]); } + context.drawText(MinecraftClient.getInstance().textRenderer, gridX + " ; " + gridY , x, y-9, Colors.WHITE, true); + } + + public void renderCursor(DrawContext context, int mouseX, int mouseY, float delta) { + int temp_x = x; + int temp_y = y; + int temp_width = width; + x = mouseX; + y = mouseY; + width = 100; + render(context, mouseX, mouseY, delta); + x = temp_x; + y = temp_y; + width = temp_width; } // GUI shenanigans @@ -133,4 +157,16 @@ public void setOnClick(@Nullable Consumer onClick) { public void appendNarrations(NarrationMessageBuilder builder) { } + + @Override + public String toString() { + return new ToStringBuilder(this) + .append("gridX", gridX) + .append("gridY", gridY) + .append("size", size) + .append("x", x) + .append("y", y) + .append("width", width) + .toString(); + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java index 0a08a19918..c1605303ec 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java @@ -21,18 +21,20 @@ public class StatusBarsConfigScreen extends Screen { private final Map meaningFullName = new HashMap<>(); private @Nullable StatusBar cursorBar = null; - protected StatusBarsConfigScreen(Text title) { - super(title); + public StatusBarsConfigScreen() { + super(Text.of("Status Bars Config")); + FancyStatusBars.updatePositions(); } @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { + for (ScreenRect screenRect : meaningFullName.keySet()) { + context.fillGradient(screenRect.position().x(), screenRect.position().y(), screenRect.position().x() + screenRect.width(), screenRect.position().y() + screenRect.height(), 0xFFFF0000, 0xFF0000FF); + } super.render(context, mouseX, mouseY, delta); context.drawGuiTexture(HOTBAR_TEXTURE, width/2 - 91, height-22, 182, 22); if (cursorBar != null) { - cursorBar.setX(mouseX); - cursorBar.setY(mouseY); - cursorBar.render(context, mouseX, mouseY, delta); + cursorBar.renderCursor(context, mouseX, mouseY, delta); mainLoop: for (ScreenRect screenRect : meaningFullName.keySet()) { for (NavigationDirection value : NavigationDirection.values()) { @@ -40,6 +42,8 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { if (overlaps) { int[] ints = meaningFullName.get(screenRect); if (ints[0] != cursorBar.gridX || ints[1] != cursorBar.gridY) { + System.out.println("Moving " + cursorBar); + System.out.println(ints[0] + " " + ints[1]); FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY); if (value.getAxis().equals(NavigationAxis.VERTICAL)) { if (value.isPositive()) { @@ -56,8 +60,11 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { FancyStatusBars.barGrid.add(ints[0], ints[1], cursorBar); } } + FancyStatusBars.updatePositions(); + System.out.println("After " + cursorBar); break mainLoop; } + break; } } } @@ -75,14 +82,36 @@ private void setup(StatusBar statusBar) { statusBar.setOnClick(this::onClick); } + @Override + public void removed() { + super.removed(); + FancyStatusBars.statusBars.values().forEach(statusBar -> statusBar.setOnClick(null)); + } + + @Override + public boolean shouldPause() { + return false; + } + private void onClick(StatusBar statusBar) { cursorBar = statusBar; meaningFullName.clear(); FancyStatusBars.barGrid.remove(statusBar.gridX, statusBar.gridY); + FancyStatusBars.updatePositions(); FancyStatusBars.statusBars.values().forEach(statusBar1 -> { meaningFullName.put( new ScreenRect(new ScreenPos(statusBar1.getX(), statusBar1.getY()), statusBar1.getWidth(), statusBar1.getHeight()), new int[]{statusBar1.gridX, statusBar1.gridY}); }); } + + @Override + public boolean mouseReleased(double mouseX, double mouseY, int button) { + if (cursorBar != null) { + cursorBar = null; + FancyStatusBars.updatePositions(); + return true; + } + return super.mouseReleased(mouseX, mouseY, button); + } } From 94f72e832a2c166c8bbd61480b75803f4c6b1071 Mon Sep 17 00:00:00 2001 From: vicisacat Date: Fri, 12 Apr 2024 17:16:39 +0200 Subject: [PATCH 07/25] guess what? progress! --- .../skyblocker/skyblock/FancyStatusBars.java | 18 +++- .../fancybars/StatusBarsConfigScreen.java | 99 +++++++++++++++---- 2 files changed, 94 insertions(+), 23 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java index 6995c4d297..a29d3f60f8 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java @@ -110,25 +110,33 @@ public static void updatePositions() { int x = width/2 - 91; int y = height - 33 - 10*i; - for (StatusBar bar : row) { + for (int j = 0; j < row.size(); j++) { + StatusBar bar = row.get(j); bar.setX(x); bar.setY(y); bar.setWidth((int) ((bar.size / 12.f)*hotbarSize)); x += bar.getWidth(); + bar.gridY = i+1; + bar.gridX = j+1; } } + final int maxSize = 3; // BOTTOM LEFT for (int i = 0; i < barGrid.getBottomLeftSize(); i++) { List row = barGrid.getRow(-(i + 1), false); if (row.isEmpty()) continue; int x = width/2 - 91 - 2; int y = height - 15-10*i; - for (StatusBar bar : row) { + for (int j = 0; j < row.size(); j++) { + StatusBar bar = row.get(j); + bar.size = Math.min(bar.size, maxSize); bar.setY(y); bar.setWidth(bar.size*25); x -= bar.getWidth(); bar.setX(x); + bar.gridX = -j-1; + bar.gridY = -i-1; } } // BOTTOM RIGHT @@ -137,11 +145,15 @@ public static void updatePositions() { if (row.isEmpty()) continue; int x = width/2 + 91 + 2; int y = height - 15-10*i; - for (StatusBar bar : row) { + for (int j = 0; j < row.size(); j++) { + StatusBar bar = row.get(j); + bar.size = Math.min(bar.size, maxSize); bar.setX(x); bar.setY(y); bar.setWidth(bar.size*25); x += bar.getWidth(); + bar.gridX = j+1; + bar.gridY = -i-1; } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java index c1605303ec..23b5b71cb5 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java @@ -11,7 +11,9 @@ import net.minecraft.util.Identifier; import org.jetbrains.annotations.Nullable; +import java.util.Collection; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; public class StatusBarsConfigScreen extends Screen { @@ -21,60 +23,100 @@ public class StatusBarsConfigScreen extends Screen { private final Map meaningFullName = new HashMap<>(); private @Nullable StatusBar cursorBar = null; + public StatusBarsConfigScreen() { super(Text.of("Status Bars Config")); FancyStatusBars.updatePositions(); } + private final int[] currentCoords = new int[]{0, 0}; + @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { for (ScreenRect screenRect : meaningFullName.keySet()) { context.fillGradient(screenRect.position().x(), screenRect.position().y(), screenRect.position().x() + screenRect.width(), screenRect.position().y() + screenRect.height(), 0xFFFF0000, 0xFF0000FF); } super.render(context, mouseX, mouseY, delta); - context.drawGuiTexture(HOTBAR_TEXTURE, width/2 - 91, height-22, 182, 22); + context.drawGuiTexture(HOTBAR_TEXTURE, width / 2 - 91, height - 22, 182, 22); if (cursorBar != null) { cursorBar.renderCursor(context, mouseX, mouseY, delta); + ScreenRect mouseRect = new ScreenRect(new ScreenPos(mouseX - 1, mouseY - 1), 3, 3); - mainLoop: for (ScreenRect screenRect : meaningFullName.keySet()) { + if (FancyStatusBars.barGrid.getTopSize() == 0 && topBarZone.overlaps(mouseRect) && currentCoords[1] != 1) { + FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY); + FancyStatusBars.barGrid.addRow(1, true); + FancyStatusBars.barGrid.add(1, 1, cursorBar); + currentCoords[1] = 1; + FancyStatusBars.updatePositions(); + } else if (FancyStatusBars.barGrid.getBottomLeftSize() == 0 && bottomLeftBarZone.overlaps(mouseRect) && (currentCoords[0] != -1 || currentCoords[1] != -1)) { + FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY); + FancyStatusBars.barGrid.addRow(-1, false); + FancyStatusBars.barGrid.add(-1, -1, cursorBar); + currentCoords[0] = -1; + currentCoords[1] = -1; + FancyStatusBars.updatePositions(); + } else if (FancyStatusBars.barGrid.getBottomRightSize() == 0 && bottomRightBarZone.overlaps(mouseRect) && (currentCoords[0] != 1 || currentCoords[1] != -1)) { + FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY); + FancyStatusBars.barGrid.addRow(-1, true); + FancyStatusBars.barGrid.add(1, -1, cursorBar); + currentCoords[0] = 1; + currentCoords[1] = -1; + FancyStatusBars.updatePositions(); + } else rectLoop:for (ScreenRect screenRect : meaningFullName.keySet()) { for (NavigationDirection value : NavigationDirection.values()) { - boolean overlaps = screenRect.getBorder(value).overlaps(new ScreenRect(new ScreenPos(mouseX - 1, mouseY - 1), 3, 3)); + boolean overlaps = screenRect.getBorder(value).add(value).overlaps(mouseRect); + if (overlaps) { int[] ints = meaningFullName.get(screenRect); - if (ints[0] != cursorBar.gridX || ints[1] != cursorBar.gridY) { + if (ints[0] != currentCoords[0] || ints[1] != currentCoords[1]) { + currentCoords[0] = ints[0]; + currentCoords[1] = ints[1]; System.out.println("Moving " + cursorBar); System.out.println(ints[0] + " " + ints[1]); FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY); + + int offset; if (value.getAxis().equals(NavigationAxis.VERTICAL)) { - if (value.isPositive()) { - FancyStatusBars.barGrid.addRow(ints[1]+1, ints[0]>0); - FancyStatusBars.barGrid.add(1, ints[1] + 1, cursorBar); + if (!value.isPositive()) { + offset = ints[1] > 0 ? 1 : 0; } else { - FancyStatusBars.barGrid.addRow(ints[1], ints[0]>0); - FancyStatusBars.barGrid.add(1, ints[1], cursorBar); + offset = ints[1] > 0 ? 0 : -1; } + + FancyStatusBars.barGrid.addRow(ints[1] + offset, ints[0] > 0); + FancyStatusBars.barGrid.add(ints[0] < 0 ? -1 : 1, ints[1] + offset, cursorBar); } else { if (value.isPositive()) { - FancyStatusBars.barGrid.add(ints[0] + 1, ints[1], cursorBar); + offset = ints[0] > 0 ? 1 : 0; } else { - FancyStatusBars.barGrid.add(ints[0], ints[1], cursorBar); + offset = ints[0] > 0 ? 0 : -1; } + + FancyStatusBars.barGrid.add(ints[0] + offset, ints[1], cursorBar); } FancyStatusBars.updatePositions(); System.out.println("After " + cursorBar); - break mainLoop; } - break; + break rectLoop; } } } } } + private ScreenRect topBarZone = new ScreenRect(0, 0, 0, 0); + private ScreenRect bottomLeftBarZone = new ScreenRect(0, 0, 0, 0); + private ScreenRect bottomRightBarZone = new ScreenRect(0, 0, 0, 0); + @Override protected void init() { super.init(); - FancyStatusBars.statusBars.values().forEach(this::setup); + Collection values = FancyStatusBars.statusBars.values(); + values.forEach(this::setup); + checkZeroCoordinates(values); + topBarZone = new ScreenRect(width / 2 - 91, height - 22 - 15, 182, 15); + bottomLeftBarZone = new ScreenRect(width / 2 - 91 - 20, height - 22, 20, 22); + bottomRightBarZone = new ScreenRect(width / 2 + 91, height - 22, 20, 22); } private void setup(StatusBar statusBar) { @@ -82,10 +124,23 @@ private void setup(StatusBar statusBar) { statusBar.setOnClick(this::onClick); } + private static void checkZeroCoordinates(Iterable bars) { + int offset = 0; + for (StatusBar statusBar : bars) { + if (statusBar.gridX == 0 || statusBar.gridY == 0) { + statusBar.setX(5); + statusBar.setY(5 + offset); + statusBar.setWidth(30); + offset += statusBar.getHeight(); + } + } + } + @Override public void removed() { super.removed(); FancyStatusBars.statusBars.values().forEach(statusBar -> statusBar.setOnClick(null)); + FancyStatusBars.updatePositions(); } @Override @@ -95,14 +150,16 @@ public boolean shouldPause() { private void onClick(StatusBar statusBar) { cursorBar = statusBar; - meaningFullName.clear(); FancyStatusBars.barGrid.remove(statusBar.gridX, statusBar.gridY); FancyStatusBars.updatePositions(); - FancyStatusBars.statusBars.values().forEach(statusBar1 -> { - meaningFullName.put( - new ScreenRect(new ScreenPos(statusBar1.getX(), statusBar1.getY()), statusBar1.getWidth(), statusBar1.getHeight()), - new int[]{statusBar1.gridX, statusBar1.gridY}); - }); + updateScreenRects(); + } + + private void updateScreenRects() { + meaningFullName.clear(); + FancyStatusBars.statusBars.values().forEach(statusBar1 -> meaningFullName.put( + new ScreenRect(new ScreenPos(statusBar1.getX(), statusBar1.getY()), statusBar1.getWidth(), statusBar1.getHeight()), + new int[]{statusBar1.gridX, statusBar1.gridY})); } @Override @@ -110,6 +167,8 @@ public boolean mouseReleased(double mouseX, double mouseY, int button) { if (cursorBar != null) { cursorBar = null; FancyStatusBars.updatePositions(); + checkZeroCoordinates(FancyStatusBars.statusBars.values()); + updateScreenRects(); return true; } return super.mouseReleased(mouseX, mouseY, button); From 3581365e654306cf08d0c4284ddfa454befd519d Mon Sep 17 00:00:00 2001 From: vicisacat Date: Sat, 13 Apr 2024 00:00:50 +0200 Subject: [PATCH 08/25] ssergorp --- .../skyblocker/config/SkyblockerConfig.java | 3 + .../config/categories/GeneralCategory.java | 7 ++ .../mixin/accessor/WindowAccessor.java | 11 +++ .../skyblocker/skyblock/FancyStatusBars.java | 49 +++++++---- .../skyblock/fancybars/StatusBar.java | 26 +++++- .../fancybars/StatusBarsConfigScreen.java | 78 +++++++++++++----- .../gui/sprites/bars/icons/defense.png | Bin 0 -> 198 bytes .../gui/sprites/bars/icons/experience.png | Bin 0 -> 243 bytes .../gui/sprites/bars/icons/health.png | Bin 0 -> 197 bytes .../gui/sprites/bars/icons/intelligence.png | Bin 0 -> 194 bytes src/main/resources/skyblocker.mixins.json | 1 + 11 files changed, 139 insertions(+), 36 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/mixin/accessor/WindowAccessor.java create mode 100644 src/main/resources/assets/skyblocker/textures/gui/sprites/bars/icons/defense.png create mode 100644 src/main/resources/assets/skyblocker/textures/gui/sprites/bars/icons/experience.png create mode 100644 src/main/resources/assets/skyblocker/textures/gui/sprites/bars/icons/health.png create mode 100644 src/main/resources/assets/skyblocker/textures/gui/sprites/bars/icons/intelligence.png diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index 86405f586c..20124e4bef 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java @@ -163,6 +163,9 @@ public static class General { @SerialEntry public boolean fancyCraftingTable = true; + @SerialEntry + public boolean oldBars = false; + @SerialEntry public boolean backpackPreviewWithoutShift = false; diff --git a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java index dbfbbb10d1..0c6a3d7594 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java @@ -27,6 +27,13 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig newValue -> config.general.enableTips = newValue) .controller(ConfigUtils::createBooleanController) .build()) + .option(Option.createBuilder() + .name(Text.literal("old bars")) + .binding(defaults.general.oldBars, + () -> config.general.oldBars, + newValue -> config.general.oldBars = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) .option(Option.createBuilder() .name(Text.translatable("text.autoconfig.skyblocker.option.general.acceptReparty")) .binding(defaults.general.acceptReparty, diff --git a/src/main/java/de/hysky/skyblocker/mixin/accessor/WindowAccessor.java b/src/main/java/de/hysky/skyblocker/mixin/accessor/WindowAccessor.java new file mode 100644 index 0000000000..ffbf34879a --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/mixin/accessor/WindowAccessor.java @@ -0,0 +1,11 @@ +package de.hysky.skyblocker.mixin.accessor; + +import net.minecraft.client.util.Window; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(Window.class) +public interface WindowAccessor { + @Accessor("handle") + long getHandle(); +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java index a29d3f60f8..1a58286366 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java @@ -1,7 +1,5 @@ package de.hysky.skyblocker.skyblock; -import com.mojang.brigadier.Command; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.fancybars.BarGrid; @@ -10,6 +8,7 @@ import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.render.RenderHelper; import de.hysky.skyblocker.utils.scheduler.Scheduler; +import jdk.jshell.EvalException; import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.minecraft.client.MinecraftClient; @@ -20,7 +19,7 @@ import net.minecraft.util.Identifier; import java.awt.*; -import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -48,14 +47,13 @@ public class FancyStatusBars { public static BarGrid barGrid = new BarGrid(); public static Map statusBars = new HashMap<>(); - static { - statusBars.put("health", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(255, 0, 0), new Color(255, 220, 0)}, true, null, "health")); - statusBars.put("intelligence", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(0, 255, 255), new Color(180, 0, 255)}, true, null, "intelligence")); - statusBars.put("defense", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(255, 255, 255)}, false, null, "defense")); - statusBars.put("experience", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "temp"), new Color[]{new Color(100, 220, 70)}, false, null, "experience")); - } - public static void init() { + statusBars.put("health", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "bars/icons/health"), new Color[]{new Color(255, 0, 0), new Color(255, 220, 0)}, true, null, "health")); + statusBars.put("intelligence", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "bars/icons/intelligence"), new Color[]{new Color(0, 255, 255), new Color(180, 0, 255)}, true, null, "intelligence")); + statusBars.put("defense", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "bars/icons/defense"), new Color[]{new Color(255, 255, 255)}, false, null, "defense")); + statusBars.put("experience", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "bars/icons/experience"), new Color[]{new Color(100, 220, 70)}, false, null, "experience")); + + barGrid.addRow(1, false); barGrid.add(1, 1, statusBars.get("health")); barGrid.add(2, 1, statusBars.get("intelligence")); @@ -95,14 +93,18 @@ public static void updatePositions() { whileLoop: while (totalSize != 12) { if (totalSize > 12) { for (StatusBar bar : row) { - bar.size--; - totalSize--; + if (bar.size > 2) { // TODO: this can cause infinite looping if we add more than 6 bars + bar.size--; + totalSize--; + } if (totalSize == 12) break whileLoop; } } else { for (StatusBar bar : row) { - bar.size++; - totalSize++; + if (bar.size < 12) { + bar.size++; + totalSize++; + } if (totalSize == 12) break whileLoop; } } @@ -177,6 +179,25 @@ public boolean render(DrawContext context, int scaledWidth, int scaledHeight) { var player = client.player; if (!SkyblockerConfigManager.get().general.bars.enableBars || player == null || Utils.isInTheRift()) return false; + + if (!SkyblockerConfigManager.get().general.oldBars) { + Collection barCollection = statusBars.values(); + for (StatusBar value : barCollection) { + value.render(context, -1, -1, client.getLastFrameDuration()); + } + for (StatusBar statusBar : barCollection) { + 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").updateValues(intelligence.value() / (float) intelligence.max(), intelligence.overflow() / (float) intelligence.max(), intelligence.value()); + int defense = statusBarTracker.getDefense(); + statusBars.get("defense").updateValues(defense / (defense + 100.f), 0, defense); + statusBars.get("experience").updateValues(player.experienceProgress, 0, player.experienceLevel); + return true; + } anchorsX[0] = scaledWidth / 2 - 91; anchorsY[0] = scaledHeight - 33; anchorsX[1] = anchorsX[0]; 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 3b6453a0c5..6d321a90c7 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java @@ -3,6 +3,7 @@ import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.utils.render.RenderHelper; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.*; import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; import net.minecraft.client.gui.widget.ClickableWidget; @@ -36,6 +37,8 @@ public class StatusBar implements Widget, Drawable, Element, Selectable { public float fill = 0; public float overflowFill = 0; + private Object text = ""; + private int x = 0; private int y = 0; @@ -57,12 +60,32 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { context.drawGuiTexture(icon, x, y, 9, 9); context.drawGuiTexture(BAR_BACK, x + 10, y + 1, width - 10, 7); RenderHelper.renderNineSliceColored(context, BAR_FILL, x + 11, y + 2, (int) ((width - 12) * fill), 5, colors[0]); - if (hasOverflow) { + if (hasOverflow && overflowFill > 0) { RenderHelper.renderNineSliceColored(context, BAR_FILL, x + 11, y + 2, (int) ((width - 12) * overflowFill), 5, colors[1]); } context.drawText(MinecraftClient.getInstance().textRenderer, gridX + " ; " + gridY , x, y-9, Colors.WHITE, true); } + public void updateValues(float fill, float overflowFill, Object text) { + this.text = text; + this.fill = fill; + this.overflowFill = overflowFill; + } + + public void renderText(DrawContext context) { + TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; + String text = this.text.toString(); + int x = this.x + 11 + (width - textRenderer.getWidth(text) - 12) / 2; + int y = this.y - 3; + + final int[] offsets = new int[]{-1, 1}; + for (int i : offsets) { + context.drawText(textRenderer, text, x + i, y, 0, false); + context.drawText(textRenderer, text, x, y + i, 0, false); + } + context.drawText(textRenderer, text, x, y, (textColor == null ? colors[0]: textColor).getRGB(), false); + } + public void renderCursor(DrawContext context, int mouseX, int mouseY, float delta) { int temp_x = x; int temp_y = y; @@ -161,6 +184,7 @@ public void appendNarrations(NarrationMessageBuilder builder) { @Override public String toString() { return new ToStringBuilder(this) + .append("name", name) .append("gridX", gridX) .append("gridY", gridY) .append("size", size) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java index 23b5b71cb5..8c6590293b 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java @@ -1,6 +1,8 @@ package de.hysky.skyblocker.skyblock.fancybars; +import de.hysky.skyblocker.mixin.accessor.WindowAccessor; import de.hysky.skyblocker.skyblock.FancyStatusBars; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.ScreenPos; import net.minecraft.client.gui.ScreenRect; @@ -8,8 +10,10 @@ import net.minecraft.client.gui.navigation.NavigationDirection; import net.minecraft.client.gui.screen.Screen; import net.minecraft.text.Text; +import net.minecraft.util.Colors; import net.minecraft.util.Identifier; import org.jetbrains.annotations.Nullable; +import org.lwjgl.glfw.GLFW; import java.util.Collection; import java.util.HashMap; @@ -20,6 +24,8 @@ public class StatusBarsConfigScreen extends Screen { private static final Identifier HOTBAR_TEXTURE = new Identifier("hud/hotbar"); + private final long RESIZE_CURSOR = GLFW.glfwCreateStandardCursor(GLFW.GLFW_HRESIZE_CURSOR); + private final Map meaningFullName = new HashMap<>(); private @Nullable StatusBar cursorBar = null; @@ -31,6 +37,7 @@ public StatusBarsConfigScreen() { private final int[] currentCoords = new int[]{0, 0}; + @SuppressWarnings("UnreachableCode") // IntelliJ big stupid @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { for (ScreenRect screenRect : meaningFullName.keySet()) { @@ -38,9 +45,14 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { } super.render(context, mouseX, mouseY, delta); context.drawGuiTexture(HOTBAR_TEXTURE, width / 2 - 91, height - 22, 182, 22); + ScreenRect mouseRect = new ScreenRect(new ScreenPos(mouseX - 1, mouseY - 1), 3, 3); + assert client != null; + WindowAccessor window = (WindowAccessor) (Object) client.getWindow(); + assert window != null; if (cursorBar != null) { cursorBar.renderCursor(context, mouseX, mouseY, delta); - ScreenRect mouseRect = new ScreenRect(new ScreenPos(mouseX - 1, mouseY - 1), 3, 3); + context.drawText(textRenderer, currentCoords[0] + " " + currentCoords[1], 100, 5, Colors.WHITE, true); + if (FancyStatusBars.barGrid.getTopSize() == 0 && topBarZone.overlaps(mouseRect) && currentCoords[1] != 1) { FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY); @@ -63,36 +75,43 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { currentCoords[1] = -1; FancyStatusBars.updatePositions(); } else rectLoop:for (ScreenRect screenRect : meaningFullName.keySet()) { - for (NavigationDirection value : NavigationDirection.values()) { - boolean overlaps = screenRect.getBorder(value).add(value).overlaps(mouseRect); + for (NavigationDirection direction : NavigationDirection.values()) { + boolean overlaps = screenRect.getBorder(direction).add(direction).overlaps(mouseRect); if (overlaps) { int[] ints = meaningFullName.get(screenRect); - if (ints[0] != currentCoords[0] || ints[1] != currentCoords[1]) { - currentCoords[0] = ints[0]; - currentCoords[1] = ints[1]; + int offsetX = 0; + int offsetY = 0; + final boolean vertical = direction.getAxis().equals(NavigationAxis.VERTICAL); + if (vertical) { + if (!direction.isPositive()) { + offsetY = ints[1] > 0 ? 1 : 0; + } else { + offsetY = ints[1] > 0 ? 0 : -1; + } + } else { + if (direction.isPositive()) { + offsetX = ints[0] > 0 ? 1 : 0; + } else { + offsetX = ints[0] > 0 ? 0 : -1; + } + } + context.drawText(textRenderer, ints[0] + offsetX + " " + ints[1] + offsetY, 100, 15, Colors.WHITE, true); + if (ints[0] + offsetX != currentCoords[0] || ints[1] + offsetY != currentCoords[1]) { + currentCoords[0] = ints[0] + offsetX; + currentCoords[1] = ints[1] + offsetY; System.out.println("Moving " + cursorBar); System.out.println(ints[0] + " " + ints[1]); FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY); - int offset; - if (value.getAxis().equals(NavigationAxis.VERTICAL)) { - if (!value.isPositive()) { - offset = ints[1] > 0 ? 1 : 0; - } else { - offset = ints[1] > 0 ? 0 : -1; - } - FancyStatusBars.barGrid.addRow(ints[1] + offset, ints[0] > 0); - FancyStatusBars.barGrid.add(ints[0] < 0 ? -1 : 1, ints[1] + offset, cursorBar); + if (vertical) { + + FancyStatusBars.barGrid.addRow(ints[1] + offsetY, ints[0] > 0); + FancyStatusBars.barGrid.add(ints[0] < 0 ? -1 : 1, ints[1] + offsetY, cursorBar); } else { - if (value.isPositive()) { - offset = ints[0] > 0 ? 1 : 0; - } else { - offset = ints[0] > 0 ? 0 : -1; - } - FancyStatusBars.barGrid.add(ints[0] + offset, ints[1], cursorBar); + FancyStatusBars.barGrid.add(ints[0] + offsetX, ints[1], cursorBar); } FancyStatusBars.updatePositions(); System.out.println("After " + cursorBar); @@ -101,6 +120,19 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { } } } + } else { + rectLoop:for (ScreenRect screenRect : meaningFullName.keySet()) { + for (NavigationDirection direction : new NavigationDirection[]{NavigationDirection.LEFT, NavigationDirection.RIGHT}) { + boolean overlaps = screenRect.getBorder(direction).add(direction).overlaps(mouseRect); + + if (overlaps) { + GLFW.glfwSetCursor(window.getHandle(), RESIZE_CURSOR); + break rectLoop; + } else { + GLFW.glfwSetCursor(window.getHandle(), 0); + } + } + } } } @@ -114,6 +146,7 @@ protected void init() { Collection values = FancyStatusBars.statusBars.values(); values.forEach(this::setup); checkZeroCoordinates(values); + updateScreenRects(); topBarZone = new ScreenRect(width / 2 - 91, height - 22 - 15, 182, 15); bottomLeftBarZone = new ScreenRect(width / 2 - 91 - 20, height - 22, 20, 22); bottomRightBarZone = new ScreenRect(width / 2 + 91, height - 22, 20, 22); @@ -136,11 +169,14 @@ private static void checkZeroCoordinates(Iterable bars) { } } + @SuppressWarnings("UnreachableCode") @Override public void removed() { super.removed(); FancyStatusBars.statusBars.values().forEach(statusBar -> statusBar.setOnClick(null)); FancyStatusBars.updatePositions(); + GLFW.glfwSetCursor(((WindowAccessor) (Object) client.getWindow()).getHandle(), 0); + GLFW.glfwDestroyCursor(RESIZE_CURSOR); // Does it explode if I don't do that?? idk aaaaaaaaa } @Override diff --git a/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/icons/defense.png b/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/icons/defense.png new file mode 100644 index 0000000000000000000000000000000000000000..4dd1314154e3e0b781d19d3725c886bb998ca103 GIT binary patch literal 198 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>3?#4ne^UZdjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCim11AIbUf%LQIpLXm#l9^QiWT!Lel>sT%k|4j}|3JX-dmCRcP=K?*BeIx* zf$uN~Gak=hkpdLd_jGX#kqFQ2apYn!;5lUU`u}~Kw>z5*12ounH!L?`@Qj|(W3qRB hYX0nH)7(4%GD;RP%&43EUIVC=!PC{xWt~$(698T}JfZ*q literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/icons/experience.png b/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/icons/experience.png new file mode 100644 index 0000000000000000000000000000000000000000..c1ba7d0c2f265002ffafac3d0c92534643460c61 GIT binary patch literal 243 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>3?#4ne^UZdjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCilo1AIbUzy9yP@gyqHhFMpUY5S9?6aV`&HaI132v9GzPT1gMIlhaf)@J|zI*)N8V{7h&+n!UMSZrfW7R<}$%zF1+)>U$U9^1|%O$WD@{VjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCf`#@Q5sCVBk9p!i>lBSEK+1qdZ+4Lo|Y0doBt#DDXHpYnS{t{BddO3`Hr8 zt?gC&c3(1i(!^5ha!q5O=Vm>x>=RMhyXOh62z6s=$zG)ybuVD{tb#9}PrfQP4^HmM n`}z2{T2p-E$^3*(EDge6b{SZybS5VNZDH_q^>bP0l+XkKH@HIy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/icons/intelligence.png b/src/main/resources/assets/skyblocker/textures/gui/sprites/bars/icons/intelligence.png new file mode 100644 index 0000000000000000000000000000000000000000..0f3872b9c23b3a45104e80ee505457719e7ad702 GIT binary patch literal 194 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>3?#4ne^UZdjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCim11AIbUfwb`R|0jO^7hbg+$PRp(atcVXmIV0){|5qw-`n_tfdZTb9+AZi z419+{nDKc2iWH!rwx^3@h(x&Uv4gw}20VuxE^YXK=BQ0mOKDNr#VrpUMTM2ZayM|W dY2*|q)hm}UoVl$Vxe}<2!PC{xWt~$(695D@JL&)c literal 0 HcmV?d00001 diff --git a/src/main/resources/skyblocker.mixins.json b/src/main/resources/skyblocker.mixins.json index 99d9faaa31..a483c0f049 100644 --- a/src/main/resources/skyblocker.mixins.json +++ b/src/main/resources/skyblocker.mixins.json @@ -49,6 +49,7 @@ "accessor.ScreenAccessor", "accessor.SkullBlockEntityAccessor", "accessor.SlotAccessor", + "accessor.WindowAccessor", "accessor.WorldRendererAccessor", "discordipc.ConnectionMixin" ], From b791e38cbd36360935164e337fa992bf514cbb36 Mon Sep 17 00:00:00 2001 From: vicisacat Date: Sun, 14 Apr 2024 17:36:21 +0200 Subject: [PATCH 09/25] it works so cool --- .../hysky/skyblocker/mixin/WindowMixin.java | 16 + .../skyblocker/skyblock/FancyStatusBars.java | 205 ++++++++++--- .../skyblock/auction/EditBidPopup.java | 13 +- .../skyblock/fancybars/BarGrid.java | 37 +++ .../skyblock/fancybars/EditBarColorPopup.java | 117 ++++++++ .../skyblock/fancybars/EditBarWidget.java | 274 ++++++++++++++++++ .../skyblock/fancybars/StatusBar.java | 194 +++++++++++-- .../fancybars/StatusBarsConfigScreen.java | 217 +++++++++++--- .../utils/render/gui/AbstractPopupScreen.java | 37 +++ .../assets/skyblocker/lang/en_us.json | 10 + src/main/resources/skyblocker.mixins.json | 1 + 11 files changed, 1008 insertions(+), 113 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/mixin/WindowMixin.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarColorPopup.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarWidget.java diff --git a/src/main/java/de/hysky/skyblocker/mixin/WindowMixin.java b/src/main/java/de/hysky/skyblocker/mixin/WindowMixin.java new file mode 100644 index 0000000000..92ca967d12 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/mixin/WindowMixin.java @@ -0,0 +1,16 @@ +package de.hysky.skyblocker.mixin; + +import de.hysky.skyblocker.skyblock.FancyStatusBars; +import net.minecraft.client.util.Window; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Window.class) +public class WindowMixin { + @Inject(method = "setScaleFactor", at = @At("TAIL")) + public void onScaleFactorChange(double scaleFactor, CallbackInfo ci) { + FancyStatusBars.updatePositions(); + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java index 1a58286366..6bf012ff20 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java @@ -1,5 +1,6 @@ package de.hysky.skyblocker.skyblock; +import com.google.gson.JsonObject; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.fancybars.BarGrid; @@ -8,25 +9,37 @@ import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.render.RenderHelper; import de.hysky.skyblocker.utils.scheduler.Scheduler; -import jdk.jshell.EvalException; import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.texture.Sprite; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.Text; import net.minecraft.util.Identifier; +import net.minecraft.util.math.MathHelper; +import org.lwjgl.glfw.GLFW; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.awt.*; -import java.util.Collection; -import java.util.HashMap; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.util.*; import java.util.List; -import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; public class FancyStatusBars { private static final Identifier BARS = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/bars.png"); + 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; @@ -48,26 +61,138 @@ public class FancyStatusBars { public static Map statusBars = new HashMap<>(); public static void init() { - statusBars.put("health", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "bars/icons/health"), new Color[]{new Color(255, 0, 0), new Color(255, 220, 0)}, true, null, "health")); - statusBars.put("intelligence", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "bars/icons/intelligence"), new Color[]{new Color(0, 255, 255), new Color(180, 0, 255)}, true, null, "intelligence")); - statusBars.put("defense", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "bars/icons/defense"), new Color[]{new Color(255, 255, 255)}, false, null, "defense")); - statusBars.put("experience", new StatusBar(new Identifier(SkyblockerMod.NAMESPACE, "bars/icons/experience"), new Color[]{new Color(100, 220, 70)}, false, null, "experience")); - - - barGrid.addRow(1, false); + statusBars.put("health", new StatusBar(new Identifier(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(new Identifier(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(new Identifier(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(new Identifier(SkyblockerMod.NAMESPACE, "bars/icons/experience"), + new Color[]{new Color(100, 230, 70)}, + false, new Color(128, 255, 32), Text.translatable("skyblocker.bars.config.experience"))); + + // Default positions + StatusBar health = statusBars.get("health"); + health.gridX = 1; + health.gridY = 1; + StatusBar intelligence = statusBars.get("intelligence"); + intelligence.gridX = 2; + intelligence.gridY = 1; + StatusBar defense = statusBars.get("defense"); + defense.gridX = 1; + defense.gridY = -1; + StatusBar experience = statusBars.get("experience"); + experience.gridX = 1; + experience.gridY = 2; + + 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); + } + } + } + placeBarsInGrid(); + configLoaded = true; + }); + ClientLifecycleEvents.CLIENT_STOPPING.register((client) -> { + saveBarConfig(); + GLFW.glfwDestroyCursor(StatusBarsConfigScreen.RESIZE_CURSOR); + }); + /*barGrid.addRow(1, false); barGrid.add(1, 1, statusBars.get("health")); barGrid.add(2, 1, statusBars.get("intelligence")); barGrid.addRow(2, false); barGrid.add(1, 2, statusBars.get("experience")); barGrid.addRow(-1, true); - barGrid.add(1, -1, statusBars.get("defense")); + barGrid.add(1, -1, statusBars.get("defense"));*/ + //placeBarsInGrid(); ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register( ClientCommandManager.literal("skyblocker") .then(ClientCommandManager.literal("bar_test").executes(Scheduler.queueOpenScreenCommand(StatusBarsConfigScreen::new))))); } + private static boolean configLoaded = false; + + private static void placeBarsInGrid() { + List original = statusBars.values().stream().toList(); + + // TOP + List barList = new ArrayList<>(original.stream().filter(statusBar -> statusBar.gridY > 0).toList()); + barList.sort((a, b) -> a.gridY == b.gridY ? Integer.compare(a.gridX, b.gridX) : Integer.compare(a.gridY, b.gridY)); + + int y = 0; + int rowNum = 0; + for (StatusBar statusBar : barList) { + if (statusBar.gridY > y) { + barGrid.addRowToEnd(true, false); + rowNum++; + y = statusBar.gridY; + } + barGrid.addToEndOfRow(rowNum, false, statusBar); + } + + // BOTTOM LEFT + barList.clear(); + barList.addAll(original.stream().filter(statusBar -> statusBar.gridY < 0 && statusBar.gridX < 0).toList()); + barList.sort((a, b) -> a.gridY == b.gridY ? -Integer.compare(a.gridX, b.gridX) : -Integer.compare(a.gridY, b.gridY)); + doBottom(false, barList); + + // BOTTOM RIGHT + barList.clear(); + barList.addAll(original.stream().filter(statusBar -> statusBar.gridY < 0 && statusBar.gridX > 0).toList()); + barList.sort((a, b) -> a.gridY == b.gridY ? Integer.compare(a.gridX, b.gridX) : -Integer.compare(a.gridY, b.gridY)); + doBottom(true, barList); + } + + private static void doBottom(boolean right, List barList) { + int y = 0; + int rowNum = 0; + for (StatusBar statusBar : barList) { + if (statusBar.gridY < y) { + barGrid.addRowToEnd(false, right); + rowNum--; + y = statusBar.gridY; + } + barGrid.addToEndOfRow(rowNum, right, 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 float hotbarSize = 182; final int width = MinecraftClient.getInstance().getWindow().getScaledWidth(); final int height = MinecraftClient.getInstance().getWindow().getScaledHeight(); @@ -83,6 +208,7 @@ public static void updatePositions() { // THE TOP for (int i = 0; i < barGrid.getTopSize(); i++) { List row = barGrid.getRow(i + 1, false); + System.out.println(row); if (row.isEmpty()) continue; int totalSize = 0; for (StatusBar bar : row) { @@ -90,10 +216,11 @@ public static void updatePositions() { } // Fix sizing - whileLoop: while (totalSize != 12) { + whileLoop: + while (totalSize != 12) { if (totalSize > 12) { for (StatusBar bar : row) { - if (bar.size > 2) { // TODO: this can cause infinite looping if we add more than 6 bars + if (bar.size > bar.getMinimumSize()) { // TODO: this can cause infinite looping if we add more than 6 bars bar.size--; totalSize--; } @@ -101,7 +228,7 @@ public static void updatePositions() { } } else { for (StatusBar bar : row) { - if (bar.size < 12) { + if (bar.size < bar.getMaximumSize()) { bar.size++; totalSize++; } @@ -110,52 +237,52 @@ public static void updatePositions() { } } - int x = width/2 - 91; - int y = height - 33 - 10*i; + int x = width / 2 - 91; + int y = height - 33 - 10 * i; + int size = 0; for (int j = 0; j < row.size(); j++) { StatusBar bar = row.get(j); - bar.setX(x); + bar.setX(x + (int) ((size / 12.d) * hotbarSize)); bar.setY(y); - bar.setWidth((int) ((bar.size / 12.f)*hotbarSize)); - x += bar.getWidth(); - bar.gridY = i+1; - bar.gridX = j+1; + bar.setWidth((int) ((bar.size / 12.d) * hotbarSize)); + size += bar.size; + bar.gridY = i + 1; + bar.gridX = j + 1; } } - final int maxSize = 3; // BOTTOM LEFT for (int i = 0; i < barGrid.getBottomLeftSize(); i++) { List row = barGrid.getRow(-(i + 1), false); if (row.isEmpty()) continue; - int x = width/2 - 91 - 2; - int y = height - 15-10*i; + int x = width / 2 - 91 - 2; + int y = height - 15 - 10 * (barGrid.getBottomLeftSize() - i - 1); for (int j = 0; j < row.size(); j++) { StatusBar bar = row.get(j); - bar.size = Math.min(bar.size, maxSize); + bar.size = MathHelper.clamp(bar.size, bar.getMinimumSize(), bar.getMaximumSize()); bar.setY(y); - bar.setWidth(bar.size*25); + bar.setWidth(bar.size * 25); x -= bar.getWidth(); bar.setX(x); - bar.gridX = -j-1; - bar.gridY = -i-1; + bar.gridX = -j - 1; + bar.gridY = -i - 1; } } // BOTTOM RIGHT for (int i = 0; i < barGrid.getBottomRightSize(); i++) { List row = barGrid.getRow(-(i + 1), true); if (row.isEmpty()) continue; - int x = width/2 + 91 + 2; - int y = height - 15-10*i; + int x = width / 2 + 91 + 2; + int y = height - 15 - 10 * (barGrid.getBottomRightSize() - i - 1); for (int j = 0; j < row.size(); j++) { StatusBar bar = row.get(j); - bar.size = Math.min(bar.size, maxSize); + bar.size = MathHelper.clamp(bar.size, bar.getMinimumSize(), bar.getMaximumSize()); bar.setX(x); bar.setY(y); - bar.setWidth(bar.size*25); + bar.setWidth(bar.size * 25); x += bar.getWidth(); - bar.gridX = j+1; - bar.gridY = -i-1; + bar.gridX = j + 1; + bar.gridY = -i - 1; } } } @@ -186,7 +313,7 @@ public boolean render(DrawContext context, int scaledWidth, int scaledHeight) { value.render(context, -1, -1, client.getLastFrameDuration()); } for (StatusBar statusBar : barCollection) { - statusBar.renderText(context); + if (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()); @@ -236,7 +363,7 @@ public boolean render(DrawContext context, int scaledWidth, int scaledHeight) { MatrixStack matrices = context.getMatrices(); matrices.push(); matrices.translate(50, 50, 0); - matrices.scale(2,2,1); + matrices.scale(2, 2, 1); context.drawSprite(0, 0, 0, 60, 5, SUPPLIER.get(), 1, 0.25f, 0.25f, 1); matrices.pop(); return true; @@ -314,13 +441,13 @@ public void draw(DrawContext context) { context.drawTexture(BARS, anchorsX[anchorNum] + offsetX, anchorsY[anchorNum], 0, v, 9, 9); // Draw the background for the bar - context.drawGuiTexture(BAR_BACK, anchorsX[anchorNum]+ offsetX+10, anchorsY[anchorNum]+1, bar_width, 7); + context.drawGuiTexture(BAR_BACK, anchorsX[anchorNum] + offsetX + 10, anchorsY[anchorNum] + 1, bar_width, 7); // Draw the filled part of the bar for (int i = 0; i < fill.length; i++) { int fill_width = this.fill[i] * (bar_width - 2) / 100; if (fill_width >= 1) { - RenderHelper.renderNineSliceColored(context, BAR_FILL, anchorsX[anchorNum] + offsetX + 11, anchorsY[anchorNum]+2, fill_width, 5, colors[i]); + RenderHelper.renderNineSliceColored(context, BAR_FILL, anchorsX[anchorNum] + offsetX + 11, anchorsY[anchorNum] + 2, fill_width, 5, colors[i]); } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java index 6b90b86ce0..9d4608035c 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java @@ -34,18 +34,7 @@ protected void init() { super.init(); layout = DirectionalLayoutWidget.vertical(); layout.spacing(8).getMainPositioner().alignHorizontalCenter(); - textFieldWidget = new TextFieldWidget(textRenderer, 120, 15, Text.empty()) { - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (!super.keyPressed(keyCode, scanCode, modifiers)) { - if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) { - done(null); - return true; - } - } else return true; - return false; - } - }; + textFieldWidget = new EnterConfirmTextFieldWidget(textRenderer, 120, 15, Text.empty(), () -> done(null)); textFieldWidget.setTextPredicate(this::isStringGood); layout.add(new TextWidget(Text.literal("- Set Bid -").fillStyle(Style.EMPTY.withBold(true)), textRenderer)); layout.add(textFieldWidget); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java index 932192400c..384250f9c5 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java @@ -53,6 +53,28 @@ public void addRow(int row, boolean right) { } } + public void addRowToEnd(boolean top, boolean right) { + if (top) { + this.top.add(new LinkedList<>()); + } else { + (right ? bottomRight: bottomLeft).add(new LinkedList<>()); + } + } + + public void addToEndOfRow(int row, boolean right, StatusBar bar) { + if (row>0) { + LinkedList statusBars = top.get(row - 1); + statusBars.add(bar); + bar.gridY = row; + bar.gridX = statusBars.indexOf(bar)+1; + } else if (row<0) { + LinkedList statusBars = (right? bottomRight: bottomLeft).get(Math.abs(row)-1); + statusBars.add(bar); + bar.gridY = row; + bar.gridX = (statusBars.indexOf(bar)+1) * (right ? 1: -1); + } + } + public void remove(int x, int y) { System.out.println("Removing x: " + x + " y: " + y); if (y > 0) { @@ -92,6 +114,21 @@ public void remove(int x, int y) { } } + public boolean coordinatesExist(int x, int y) { + if (x == 0 || y == 0) return false; + if (y > 0) { + if (y > getTopSize()) return false; + return x <= getRow(y, false).size(); + } else { + if (Math.abs(y) > (x < 0 ? getBottomLeftSize(): getBottomRightSize())) return false; + return Math.abs(x) <= getRow(y, x > 0).size(); + } + } + + public StatusBar getBar(int x, int y) { + return getRow(y, x>0).get(Math.abs(x)-1); + } + public int getTopSize() {return top.size();} public int getBottomLeftSize() {return bottomLeft.size();} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarColorPopup.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarColorPopup.java new file mode 100644 index 0000000000..a3ce4e43fc --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarColorPopup.java @@ -0,0 +1,117 @@ +package de.hysky.skyblocker.skyblock.fancybars; + +import de.hysky.skyblocker.utils.render.gui.AbstractPopupScreen; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.widget.*; +import net.minecraft.text.Style; +import net.minecraft.text.Text; + +import java.awt.*; +import java.util.List; +import java.util.function.Consumer; + +public class EditBarColorPopup extends AbstractPopupScreen { + + private final Consumer setColor; + + private DirectionalLayoutWidget layout = DirectionalLayoutWidget.vertical(); + private BasicColorSelector colorSelector; + + protected EditBarColorPopup(Text title, Screen backgroundScreen, Consumer setColor) { + super(title, backgroundScreen); + this.setColor = setColor; + } + + @Override + protected void init() { + super.init(); + layout = DirectionalLayoutWidget.vertical(); + layout.spacing(8).getMainPositioner().alignHorizontalCenter(); + layout.add(new TextWidget(title.copy().fillStyle(Style.EMPTY.withBold(true)), MinecraftClient.getInstance().textRenderer)); + colorSelector = new BasicColorSelector(0, 0, 150, () -> done(null)); + layout.add(colorSelector); + + DirectionalLayoutWidget horizontal = DirectionalLayoutWidget.horizontal(); + ButtonWidget buttonWidget = ButtonWidget.builder(Text.literal("Cancel"), button -> close()).width(80).build(); + horizontal.add(buttonWidget); + horizontal.add(ButtonWidget.builder(Text.literal("Done"), this::done).width(80).build()); + + layout.add(horizontal); + layout.forEachChild(this::addDrawableChild); + this.layout.refreshPositions(); + SimplePositioningWidget.setPos(layout, this.getNavigationFocus()); + } + + private void done(Object object) { + if (colorSelector.validColor) setColor.accept(new Color(colorSelector.getColor())); + close(); + } + + @Override + public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) { + super.renderBackground(context, mouseX, mouseY, delta); + drawPopupBackground(context, layout.getX(), layout.getY(), layout.getWidth(), layout.getHeight()); + } + + private static class BasicColorSelector extends ContainerWidget { + + private final EnterConfirmTextFieldWidget textFieldWidget; + + public BasicColorSelector(int x, int y, int width, Runnable onEnter) { + super(x, y, width, 15, Text.literal("edit color")); + textFieldWidget = new EnterConfirmTextFieldWidget(MinecraftClient.getInstance().textRenderer, getX() + 16, getY(), width - 16, 15, Text.empty(), onEnter); + textFieldWidget.setChangedListener(this::onTextChange); + textFieldWidget.setTextPredicate(s -> s.length() <= 6); + } + + @Override + public List children() { + return List.of(textFieldWidget); + } + + public int getColor() { + return color; + } + + private int color = 0xFF000000; + private boolean validColor = false; + + private void onTextChange(String text) { + try { + color = Integer.parseInt(text, 16) | 0xFF000000; + validColor = true; + } catch (NumberFormatException e) { + color = 0; + validColor = false; + } + } + + @Override + protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + context.drawBorder(getX(), getY(), 15, 15, validColor ? -1 : 0xFFDD0000); + context.fill(getX() + 1, getY() + 1, getX() + 14, getY() + 14, color); + textFieldWidget.renderWidget(context, mouseX, mouseY, delta); + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) { + + } + + @Override + public void setX(int x) { + super.setX(x); + textFieldWidget.setX(getX()+16); + } + + @Override + public void setY(int y) { + super.setY(y); + textFieldWidget.setY(getY()); + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarWidget.java new file mode 100644 index 0000000000..54af7a0308 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarWidget.java @@ -0,0 +1,274 @@ +package de.hysky.skyblocker.skyblock.fancybars; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.tooltip.TooltipBackgroundRenderer; +import net.minecraft.client.gui.widget.ClickableWidget; +import net.minecraft.client.gui.widget.ContainerWidget; +import net.minecraft.client.gui.widget.TextWidget; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.Colors; +import net.minecraft.util.Formatting; + +import java.awt.*; +import java.util.List; +import java.util.function.Consumer; + +public class EditBarWidget extends ContainerWidget { + + private final EnumCyclingOption 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 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); + 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> extends ClickableWidget { + + private T current; + private final T[] values; + private Consumer onChange = null; + + public EnumCyclingOption(int x, int y, int width, Text message, Class 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 onChange) { + this.onChange = onChange; + } + } + + public static class BooleanOption extends ClickableWidget { + + private boolean current = false; + private Consumer 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(Consumer onChange) { + this.onChange = onChange; + } + } + + public static class ColorOption extends ClickableWidget { + + public void setCurrent(int current) { + this.current = current; + } + + private int current = 0; + private Consumer 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 onChange) { + this.onChange = onChange; + } + } +} 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 6d321a90c7..ea4a03888f 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java @@ -1,5 +1,8 @@ package de.hysky.skyblocker.skyblock.fancybars; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.utils.render.RenderHelper; import net.minecraft.client.MinecraftClient; @@ -8,7 +11,7 @@ import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; import net.minecraft.client.gui.widget.ClickableWidget; import net.minecraft.client.gui.widget.Widget; -import net.minecraft.util.Colors; +import net.minecraft.text.Text; import net.minecraft.util.Identifier; import org.apache.commons.lang3.builder.ToStringBuilder; import org.jetbrains.annotations.Nullable; @@ -21,13 +24,66 @@ public class StatusBar implements Widget, Drawable, Element, Selectable { private static final Identifier BAR_FILL = new Identifier(SkyblockerMod.NAMESPACE, "bars/bar_fill"); private static final Identifier BAR_BACK = new Identifier(SkyblockerMod.NAMESPACE, "bars/bar_back"); + + /* public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.INT.fieldOf("size").forGetter(bar -> bar.size), + Codec.INT.fieldOf("x").forGetter(bar -> bar.gridX), + Codec.INT.fieldOf("y").forGetter(bar -> bar.gridY), + Codec.STRING.listOf().fieldOf("colors").xmap( + strings -> strings.stream().map(s -> Integer.parseInt(s, 16)).map(Color::new).toArray(Color[]::new), + colors -> Arrays.stream(colors).map(color -> Integer.toHexString(color.getRGB())).toList()) + .forGetter(StatusBar::getColors), + Codec.STRING.optionalFieldOf("text_color").xmap( + s -> { + if (s.isPresent()) { + return Optional.of(new Color(Integer.parseInt(s.get(), 16))); + } else return Optional.empty(); + }, + o -> o.map(object -> Integer.toHexString(((Color) object).getRGB()))) + .forGetter(bar -> { + if (bar.getTextColor() != null) { + return Optional.of(bar.getTextColor()); + } else return Optional.empty(); + }), + Codec.BOOL.optionalFieldOf("show_text", true).forGetter(StatusBar::showText), + Codec.STRING.fieldOf("icon_position").xmap( + IconPosition::valueOf, + Enum::toString + ).forGetter(bar -> bar.iconPosition) + ) + + .apply(instance, ));*/ + private final Identifier icon; - private final Color[] colors; + + public Color[] getColors() { + return colors; + } + + public boolean hasOverflow() { + return hasOverflow; + } + + public @Nullable Color getTextColor() { + return textColor; + } + + private Color[] colors; private final boolean hasOverflow; - private final @Nullable Color textColor; - private final String name; - private @Nullable Consumer onClick = null; + public void setTextColor(@Nullable Color textColor) { + this.textColor = textColor; + } + + private @Nullable Color textColor; + + public Text getName() { + return name; + } + + private final Text name; + + private @Nullable OnClick onClick = null; public int gridX = 0; public int gridY = 0; @@ -37,12 +93,15 @@ public class StatusBar implements Widget, Drawable, Element, Selectable { public float fill = 0; public float overflowFill = 0; - private Object text = ""; + private Object value = ""; private int x = 0; private int y = 0; - public StatusBar(Identifier icon, Color[] colors, boolean hasOverflow, @Nullable Color textColor, String name) { + private IconPosition iconPosition = IconPosition.LEFT; + private boolean showText = true; + + public StatusBar(Identifier icon, Color[] colors, boolean hasOverflow, @Nullable Color textColor, Text name) { this.icon = icon; this.colors = colors; this.hasOverflow = hasOverflow; @@ -50,32 +109,42 @@ public StatusBar(Identifier icon, Color[] colors, boolean hasOverflow, @Nullable this.name = name; } - public StatusBar(Identifier icon, Color[] colors, boolean hasOverflow, @Nullable Color textColor){ - this(icon, colors, hasOverflow, textColor, "no name"); + public StatusBar(Identifier icon, Color[] colors, boolean hasOverflow, @Nullable Color textColor) { + this(icon, colors, hasOverflow, textColor, Text.empty()); } @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { if (width <= 0) return; - context.drawGuiTexture(icon, x, y, 9, 9); - context.drawGuiTexture(BAR_BACK, x + 10, y + 1, width - 10, 7); - RenderHelper.renderNineSliceColored(context, BAR_FILL, x + 11, y + 2, (int) ((width - 12) * fill), 5, colors[0]); + switch (iconPosition) { + case LEFT -> context.drawGuiTexture(icon, x, y, 9, 9); + case RIGHT -> context.drawGuiTexture(icon, x + width - 9, y, 9, 9); + } + + int barWith = iconPosition.equals(IconPosition.OFF) ? width : width - 10; + int barX = iconPosition.equals(IconPosition.LEFT) ? x + 10 : x; + context.drawGuiTexture(BAR_BACK, barX, y + 1, barWith, 7); + RenderHelper.renderNineSliceColored(context, BAR_FILL, barX + 1, y + 2, (int) ((barWith - 2) * fill), 5, colors[0]); + + if (hasOverflow && overflowFill > 0) { - RenderHelper.renderNineSliceColored(context, BAR_FILL, x + 11, y + 2, (int) ((width - 12) * overflowFill), 5, colors[1]); + RenderHelper.renderNineSliceColored(context, BAR_FILL, barX + 1, y + 2, (int) ((barWith - 2) * overflowFill), 5, colors[1]); } - context.drawText(MinecraftClient.getInstance().textRenderer, gridX + " ; " + gridY , x, y-9, Colors.WHITE, true); + //context.drawText(MinecraftClient.getInstance().textRenderer, gridX + " " + gridY + " s:" + size , x, y-9, Colors.WHITE, true); } public void updateValues(float fill, float overflowFill, Object text) { - this.text = text; + this.value = text; this.fill = fill; this.overflowFill = overflowFill; } public void renderText(DrawContext context) { TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; - String text = this.text.toString(); - int x = this.x + 11 + (width - textRenderer.getWidth(text) - 12) / 2; + int barWith = iconPosition.equals(IconPosition.OFF) ? width : width - 10; + int barX = iconPosition.equals(IconPosition.LEFT) ? x + 10 : x; + String text = this.value.toString(); + int x = barX + (barWith - textRenderer.getWidth(text)) / 2; int y = this.y - 3; final int[] offsets = new int[]{-1, 1}; @@ -83,7 +152,7 @@ public void renderText(DrawContext context) { context.drawText(textRenderer, text, x + i, y, 0, false); context.drawText(textRenderer, text, x, y + i, 0, false); } - context.drawText(textRenderer, text, x, y, (textColor == null ? colors[0]: textColor).getRGB(), false); + context.drawText(textRenderer, text, x, y, (textColor == null ? colors[0] : textColor).getRGB(), false); } public void renderCursor(DrawContext context, int mouseX, int mouseY, float delta) { @@ -135,6 +204,14 @@ public int getHeight() { return 9; } + public int getMinimumSize() { + return 2; + } + + public int getMaximumSize() { + return gridY < 0 ? 6 : 12; + } + @Override public ScreenRect getNavigationFocus() { return Widget.super.getNavigationFocus(); @@ -146,11 +223,11 @@ public boolean isMouseOver(double mouseX, double mouseY) { } @Override - public void forEachChild(Consumer consumer) {} + public void forEachChild(Consumer consumer) { + } @Override public void setFocused(boolean focused) { - } @Override @@ -167,18 +244,17 @@ public SelectionType getType() { public boolean mouseClicked(double mouseX, double mouseY, int button) { if (!isMouseOver(mouseX, mouseY)) return false; if (onClick != null) { - onClick.accept(this); + onClick.onClick(this, button, (int) mouseX, (int) mouseY); } return true; } - public void setOnClick(@Nullable Consumer onClick) { + public void setOnClick(@Nullable OnClick onClick) { this.onClick = onClick; } @Override public void appendNarrations(NarrationMessageBuilder builder) { - } @Override @@ -193,4 +269,76 @@ public String toString() { .append("width", width) .toString(); } + + public IconPosition getIconPosition() { + return iconPosition; + } + + public void setIconPosition(IconPosition iconPosition) { + this.iconPosition = iconPosition; + } + + public boolean showText() { + return showText; + } + + public void setShowText(boolean showText) { + this.showText = showText; + } + + public enum IconPosition { + LEFT, + RIGHT, + OFF + } + + @FunctionalInterface + public interface OnClick { + + void onClick(StatusBar statusBar, int button, int mouseX, int mouseY); + } + + public void loadFromJson(JsonObject object) { + // Make colors optional, so it's easy to reset to default + if (object.has("colors")) { + JsonArray colors1 = object.get("colors").getAsJsonArray(); + if (colors1.size() < 2 && hasOverflow) { + throw new IllegalStateException("Missing second color of bar that has overflow"); + } + Color[] newColors = new Color[colors1.size()]; + for (int i = 0; i < colors1.size(); i++) { + JsonElement jsonElement = colors1.get(i); + newColors[i] = new Color(Integer.parseInt(jsonElement.getAsString(), 16)); + } + this.colors = newColors; + } + + if (object.has("text_color")) this.textColor = new Color(Integer.parseInt(object.get("text_color").getAsString(), 16)); + + this.size = object.get("size").getAsInt(); + this.gridX = object.get("x").getAsInt(); + this.gridY = object.get("y").getAsInt(); + // these are optional too, why not + if (object.has("icon_position")) this.iconPosition = IconPosition.valueOf(object.get("icon_position").getAsString()); + if (object.has("show_text")) this.showText = object.get("show_text").getAsBoolean(); + + } + + public JsonObject toJson() { + JsonObject object = new JsonObject(); + JsonArray colors1 = new JsonArray(); + for (Color color : colors) { + colors1.add(Integer.toHexString(color.getRGB()).substring(2)); + } + object.add("colors", colors1); + if (textColor != null) { + object.addProperty("text_color", Integer.toHexString(textColor.getRGB()).substring(2)); + } + object.addProperty("size", size); + object.addProperty("x", gridX); + object.addProperty("y", gridY); + object.addProperty("icon_position", iconPosition.toString()); + object.addProperty("show_text", showText); + return object; + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java index 8c6590293b..3bcc20113b 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java @@ -2,7 +2,9 @@ import de.hysky.skyblocker.mixin.accessor.WindowAccessor; import de.hysky.skyblocker.skyblock.FancyStatusBars; -import net.minecraft.client.MinecraftClient; +import it.unimi.dsi.fastutil.Pair; +import it.unimi.dsi.fastutil.objects.ObjectBooleanMutablePair; +import it.unimi.dsi.fastutil.objects.ObjectObjectMutablePair; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.ScreenPos; import net.minecraft.client.gui.ScreenRect; @@ -17,16 +19,16 @@ import java.util.Collection; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; public class StatusBarsConfigScreen extends Screen { private static final Identifier HOTBAR_TEXTURE = new Identifier("hud/hotbar"); - private final long RESIZE_CURSOR = GLFW.glfwCreateStandardCursor(GLFW.GLFW_HRESIZE_CURSOR); + public static final long RESIZE_CURSOR = GLFW.glfwCreateStandardCursor(GLFW.GLFW_HRESIZE_CURSOR); private final Map meaningFullName = new HashMap<>(); + private static final int HOTBAR_WIDTH = 182; private @Nullable StatusBar cursorBar = null; @@ -35,7 +37,14 @@ public StatusBarsConfigScreen() { FancyStatusBars.updatePositions(); } - private final int[] currentCoords = new int[]{0, 0}; + private final int[] currentCursorCoords = new int[]{0, 0}; + + private final Pair resizeHover = new ObjectBooleanMutablePair<>(new int[]{0, 0}, false); + + private final Pair resizedBars = ObjectObjectMutablePair.of(new int[]{0, 0}, new int[]{0, 0}); + private boolean resizing = false; + + private EditBarWidget editBarWidget; @SuppressWarnings("UnreachableCode") // IntelliJ big stupid @Override @@ -44,45 +53,47 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { context.fillGradient(screenRect.position().x(), screenRect.position().y(), screenRect.position().x() + screenRect.width(), screenRect.position().y() + screenRect.height(), 0xFFFF0000, 0xFF0000FF); } super.render(context, mouseX, mouseY, delta); - context.drawGuiTexture(HOTBAR_TEXTURE, width / 2 - 91, height - 22, 182, 22); + context.drawGuiTexture(HOTBAR_TEXTURE, width / 2 - HOTBAR_WIDTH / 2, height - 22, HOTBAR_WIDTH, 22); + editBarWidget.render(context, mouseX, mouseY, delta); + ScreenRect mouseRect = new ScreenRect(new ScreenPos(mouseX - 1, mouseY - 1), 3, 3); assert client != null; WindowAccessor window = (WindowAccessor) (Object) client.getWindow(); assert window != null; if (cursorBar != null) { cursorBar.renderCursor(context, mouseX, mouseY, delta); - context.drawText(textRenderer, currentCoords[0] + " " + currentCoords[1], 100, 5, Colors.WHITE, true); + context.drawText(textRenderer, currentCursorCoords[0] + " " + currentCursorCoords[1], 100, 5, Colors.WHITE, true); - if (FancyStatusBars.barGrid.getTopSize() == 0 && topBarZone.overlaps(mouseRect) && currentCoords[1] != 1) { + if (FancyStatusBars.barGrid.getTopSize() == 0 && topBarZone.overlaps(mouseRect) && currentCursorCoords[1] != 1) { FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY); FancyStatusBars.barGrid.addRow(1, true); FancyStatusBars.barGrid.add(1, 1, cursorBar); - currentCoords[1] = 1; + currentCursorCoords[1] = 1; FancyStatusBars.updatePositions(); - } else if (FancyStatusBars.barGrid.getBottomLeftSize() == 0 && bottomLeftBarZone.overlaps(mouseRect) && (currentCoords[0] != -1 || currentCoords[1] != -1)) { + } else if (FancyStatusBars.barGrid.getBottomLeftSize() == 0 && bottomLeftBarZone.overlaps(mouseRect) && (currentCursorCoords[0] != -1 || currentCursorCoords[1] != -1)) { FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY); FancyStatusBars.barGrid.addRow(-1, false); FancyStatusBars.barGrid.add(-1, -1, cursorBar); - currentCoords[0] = -1; - currentCoords[1] = -1; + currentCursorCoords[0] = -1; + currentCursorCoords[1] = -1; FancyStatusBars.updatePositions(); - } else if (FancyStatusBars.barGrid.getBottomRightSize() == 0 && bottomRightBarZone.overlaps(mouseRect) && (currentCoords[0] != 1 || currentCoords[1] != -1)) { + } else if (FancyStatusBars.barGrid.getBottomRightSize() == 0 && bottomRightBarZone.overlaps(mouseRect) && (currentCursorCoords[0] != 1 || currentCursorCoords[1] != -1)) { FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY); FancyStatusBars.barGrid.addRow(-1, true); FancyStatusBars.barGrid.add(1, -1, cursorBar); - currentCoords[0] = 1; - currentCoords[1] = -1; + currentCursorCoords[0] = 1; + currentCursorCoords[1] = -1; FancyStatusBars.updatePositions(); } else rectLoop:for (ScreenRect screenRect : meaningFullName.keySet()) { for (NavigationDirection direction : NavigationDirection.values()) { - boolean overlaps = screenRect.getBorder(direction).add(direction).overlaps(mouseRect); + boolean overlaps = screenRect.getBorder(direction).add(direction).overlaps(mouseRect); if (overlaps) { int[] ints = meaningFullName.get(screenRect); + final boolean vertical = direction.getAxis().equals(NavigationAxis.VERTICAL); int offsetX = 0; int offsetY = 0; - final boolean vertical = direction.getAxis().equals(NavigationAxis.VERTICAL); if (vertical) { if (!direction.isPositive()) { offsetY = ints[1] > 0 ? 1 : 0; @@ -97,11 +108,9 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { } } context.drawText(textRenderer, ints[0] + offsetX + " " + ints[1] + offsetY, 100, 15, Colors.WHITE, true); - if (ints[0] + offsetX != currentCoords[0] || ints[1] + offsetY != currentCoords[1]) { - currentCoords[0] = ints[0] + offsetX; - currentCoords[1] = ints[1] + offsetY; - System.out.println("Moving " + cursorBar); - System.out.println(ints[0] + " " + ints[1]); + if (ints[0] + offsetX != currentCursorCoords[0] || ints[1] + offsetY != currentCursorCoords[1]) { + currentCursorCoords[0] = ints[0] + offsetX; + currentCursorCoords[1] = ints[1] + offsetY; FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY); @@ -114,22 +123,99 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { FancyStatusBars.barGrid.add(ints[0] + offsetX, ints[1], cursorBar); } FancyStatusBars.updatePositions(); - System.out.println("After " + cursorBar); } break rectLoop; } } } } else { - rectLoop:for (ScreenRect screenRect : meaningFullName.keySet()) { - for (NavigationDirection direction : new NavigationDirection[]{NavigationDirection.LEFT, NavigationDirection.RIGHT}) { - boolean overlaps = screenRect.getBorder(direction).add(direction).overlaps(mouseRect); + // RESIZING STATE + if (resizing) { + int middleX; + boolean bottom; - if (overlaps) { - GLFW.glfwSetCursor(window.getHandle(), RESIZE_CURSOR); - break rectLoop; - } else { - GLFW.glfwSetCursor(window.getHandle(), 0); + int[] left = resizedBars.left(); + int[] right = resizedBars.right(); + boolean hasRight = right[0] != 0; + boolean hasLeft = left[0] != 0; + if (!hasRight) { + StatusBar bar = FancyStatusBars.barGrid.getBar(left[0], left[1]); + middleX = bar.getX() + bar.getWidth(); + bottom = bar.gridY < 0; + } else { + middleX = FancyStatusBars.barGrid.getBar(right[0], right[1]).getX(); + bottom = right[1] < 0; + } + int i = bottom ? 20 : 10; + boolean doResize = true; + StatusBar rightBar = null; + StatusBar leftBar = null; + + context.drawText(textRenderer, Integer.toString(mouseX - middleX), 100, 25, -1, true); + + if (mouseX < middleX) { + if (middleX - mouseX > i) { + + if (hasRight) { + rightBar = FancyStatusBars.barGrid.getBar(right[0], right[1]); + if (rightBar.size + 1 > rightBar.getMaximumSize()) doResize = false; + } + if (hasLeft) { + leftBar = FancyStatusBars.barGrid.getBar(left[0], left[1]); + if (leftBar.size - 1 < leftBar.getMinimumSize()) doResize = false; + } + + if (doResize) { + if (hasRight) rightBar.size++; + if (hasLeft) leftBar.size--; + FancyStatusBars.updatePositions(); + } + } + } else { + if (mouseX - middleX > i) { + + if (hasRight) { + rightBar = FancyStatusBars.barGrid.getBar(right[0], right[1]); + if (rightBar.size - 1 < rightBar.getMinimumSize()) doResize = false; + } + if (hasLeft) { + leftBar = FancyStatusBars.barGrid.getBar(left[0], left[1]); + if (leftBar.size + 1 > leftBar.getMaximumSize()) doResize = false; + } + context.drawText(textRenderer, leftBar.size + " " + leftBar.getMaximumSize(), 100, 35, -1, true); + + if (doResize) { + if (hasRight) rightBar.size--; + if (hasLeft) leftBar.size++; + FancyStatusBars.updatePositions(); + } + } + } + GLFW.glfwSetCursor(window.getHandle(), RESIZE_CURSOR); + } + // NOT RESIZING STATE + else { + rectLoop: + for (ScreenRect screenRect : meaningFullName.keySet()) { + for (NavigationDirection direction : new NavigationDirection[]{NavigationDirection.LEFT, NavigationDirection.RIGHT}) { + boolean overlaps = screenRect.getBorder(direction).add(direction).overlaps(mouseRect); + + if (overlaps && !editBarWidget.isMouseOver(mouseX, mouseY)) { + int[] ints = meaningFullName.get(screenRect); + boolean left = direction.equals(NavigationDirection.LEFT); + if ((ints[0] == 1 && left) || (ints[0] == -1 && !left) || (!left && ints[1] > 0 && ints[0] == FancyStatusBars.barGrid.getRow(ints[1], true).size())) { + break; + } + resizeHover.first()[0] = ints[0]; + resizeHover.first()[1] = ints[1]; + resizeHover.right(!left); + GLFW.glfwSetCursor(window.getHandle(), RESIZE_CURSOR); + break rectLoop; + } else { + resizeHover.first()[0] = 0; + resizeHover.first()[1] = 0; + GLFW.glfwSetCursor(window.getHandle(), 0); + } } } } @@ -143,13 +229,16 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { @Override protected void init() { super.init(); + editBarWidget = new EditBarWidget(0, 0, this); + editBarWidget.visible = false; + addSelectableChild(editBarWidget); // rendering separately to have it above hotbar Collection values = FancyStatusBars.statusBars.values(); values.forEach(this::setup); checkZeroCoordinates(values); updateScreenRects(); - topBarZone = new ScreenRect(width / 2 - 91, height - 22 - 15, 182, 15); - bottomLeftBarZone = new ScreenRect(width / 2 - 91 - 20, height - 22, 20, 22); - bottomRightBarZone = new ScreenRect(width / 2 + 91, height - 22, 20, 22); + topBarZone = new ScreenRect(width / 2 - HOTBAR_WIDTH / 2, height - 22 - 15, HOTBAR_WIDTH, 15); + bottomLeftBarZone = new ScreenRect(width / 2 - HOTBAR_WIDTH / 2 - 20, height - 22, 20, 22); + bottomRightBarZone = new ScreenRect(width / 2 + HOTBAR_WIDTH / 2, height - 22, 20, 22); } private void setup(StatusBar statusBar) { @@ -175,8 +264,9 @@ public void removed() { super.removed(); FancyStatusBars.statusBars.values().forEach(statusBar -> statusBar.setOnClick(null)); FancyStatusBars.updatePositions(); + assert client != null; GLFW.glfwSetCursor(((WindowAccessor) (Object) client.getWindow()).getHandle(), 0); - GLFW.glfwDestroyCursor(RESIZE_CURSOR); // Does it explode if I don't do that?? idk aaaaaaaaa + FancyStatusBars.saveBarConfig(); } @Override @@ -184,11 +274,20 @@ public boolean shouldPause() { return false; } - private void onClick(StatusBar statusBar) { - cursorBar = statusBar; - FancyStatusBars.barGrid.remove(statusBar.gridX, statusBar.gridY); - FancyStatusBars.updatePositions(); - updateScreenRects(); + private void onClick(StatusBar statusBar, int button, int mouseX, int mouseY) { + if (button == 0) { + cursorBar = statusBar; + FancyStatusBars.barGrid.remove(statusBar.gridX, statusBar.gridY); + FancyStatusBars.updatePositions(); + updateScreenRects(); + } else if (button == 1) { + int x = Math.min(mouseX - 1, width - editBarWidget.getWidth()); + int y = Math.min(mouseY - 1, height - editBarWidget.getHeight()); + editBarWidget.visible = true; + editBarWidget.setStatusBar(statusBar); + editBarWidget.setX(x); + editBarWidget.setY(y); + } } private void updateScreenRects() { @@ -206,7 +305,47 @@ public boolean mouseReleased(double mouseX, double mouseY, int button) { checkZeroCoordinates(FancyStatusBars.statusBars.values()); updateScreenRects(); return true; + } else if (resizing) { + resizing = false; + resizedBars.left()[0] = 0; + resizedBars.left()[1] = 0; + resizedBars.right()[0] = 0; + resizedBars.right()[1] = 0; + updateScreenRects(); + return true; } return super.mouseReleased(mouseX, mouseY, button); } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + int[] first = resizeHover.first(); + // want the right click thing to have priority + if (!editBarWidget.isMouseOver(mouseX, mouseY) && button == 0 && first[0] != 0 && first[1] != 0) { + if (resizeHover.right()) { + resizedBars.left()[0] = first[0]; + resizedBars.left()[1] = first[1]; + if (FancyStatusBars.barGrid.coordinatesExist(first[0] + 1, first[1])) { + resizedBars.right()[0] = first[0] + 1; + resizedBars.right()[1] = first[1]; + } else { + resizedBars.right()[0] = 0; + resizedBars.right()[1] = 0; + } + } else { + resizedBars.right()[0] = first[0]; + resizedBars.right()[1] = first[1]; + if (FancyStatusBars.barGrid.coordinatesExist(first[0] - 1, first[1])) { + resizedBars.left()[0] = first[0] - 1; + resizedBars.left()[1] = first[1]; + } else { + resizedBars.left()[0] = 0; + resizedBars.left()[1] = 0; + } + } + resizing = true; + return true; + } + return super.mouseClicked(mouseX, mouseY, button); + } } diff --git a/src/main/java/de/hysky/skyblocker/utils/render/gui/AbstractPopupScreen.java b/src/main/java/de/hysky/skyblocker/utils/render/gui/AbstractPopupScreen.java index 2bd1595508..e7a3e8b2d6 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/gui/AbstractPopupScreen.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/gui/AbstractPopupScreen.java @@ -3,10 +3,16 @@ import com.mojang.blaze3d.platform.GlConst; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.TextFieldWidget; import net.minecraft.text.Text; import net.minecraft.util.Identifier; +import org.jetbrains.annotations.Nullable; +import org.lwjgl.glfw.GLFW; + +import java.util.function.Consumer; /** * A more bare-bones version of Vanilla's Popup Screen. Meant to be extended. @@ -57,4 +63,35 @@ public void onDisplayed() { super.onDisplayed(); this.backgroundScreen.blur(); } + + public static class EnterConfirmTextFieldWidget extends TextFieldWidget { + + private final Runnable onEnter; + + public EnterConfirmTextFieldWidget(TextRenderer textRenderer, int width, int height, Text text, Runnable onEnter) { + this(textRenderer, 0, 0, width, height, text, onEnter); + } + + public EnterConfirmTextFieldWidget(TextRenderer textRenderer, int x, int y, int width, int height, Text text,Runnable onEnter) { + this(textRenderer, x, y, width, height, null, text, onEnter); + } + + public EnterConfirmTextFieldWidget(TextRenderer textRenderer, int x, int y, int width, int height, @Nullable TextFieldWidget copyFrom, Text text, Runnable onEnter) { + super(textRenderer, x, y, width, height, copyFrom, text); + this.onEnter = onEnter; + } + + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if (!super.keyPressed(keyCode, scanCode, modifiers)) { + if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) { + onEnter.run(); + return true; + } + } else return true; + return false; + } + } + } \ No newline at end of file diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index d1a5966c49..5921cc957b 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -496,6 +496,16 @@ "text.autoconfig.skyblocker.option.general.dontStripSkinAlphaValues": "Correct Transparent Skin Pixels", "text.autoconfig.skyblocker.option.general.dontStripSkinAlphaValues.@Tooltip": "When enabled, the alpha values of pixels in skin textures are no longer stripped while in Skyblock.\n\nThis results in the \"filler\" pixels on items using Player Heads to now be completely transparent, although this may have some side effects in odd cases.", + "skyblocker.bars.config.health": "Health", + "skyblocker.bars.config.defense": "Defense", + "skyblocker.bars.config.intelligence": "Intelligence", + "skyblocker.bars.config.experience": "Experience", + "skyblocker.bars.config.mainColor": "Main Color", + "skyblocker.bars.config.overflowColor": "Overflow Color", + "skyblocker.bars.config.textColor": "Text Color", + "skyblocker.bars.config.showValue": "Show Value", + "skyblocker.bars.config.icon": "Icon", + "skyblocker.updaterepository.failed": "§cUpdating local repository failed. Remove files manually and restart game.", "skyblocker.dungeons.secrets.physicalEntranceNotFound": "§cDungeon Entrance Room coordinates not found. Please go back to the green Entrance Room.", diff --git a/src/main/resources/skyblocker.mixins.json b/src/main/resources/skyblocker.mixins.json index a483c0f049..261b707362 100644 --- a/src/main/resources/skyblocker.mixins.json +++ b/src/main/resources/skyblocker.mixins.json @@ -34,6 +34,7 @@ "RenderFishMixin", "ScoreboardMixin", "SocialInteractionsPlayerListWidgetMixin", + "WindowMixin", "WorldRendererMixin", "YggdrasilMinecraftSessionServiceMixin", "YggdrasilServicesKeyInfoMixin", From f0ff0b555621f2d7f240bc72ccc1c7667badab6f Mon Sep 17 00:00:00 2001 From: vicisacat Date: Wed, 17 Apr 2024 23:07:49 +0200 Subject: [PATCH 10/25] things happened yea rewrote the entire thing to use semi data-driven BarAnchors help button in the config screen --- .../config/categories/GeneralCategory.java | 6 + .../skyblocker/skyblock/FancyStatusBars.java | 233 ++++++------- .../auction/AuctionBrowserScreen.java | 2 +- .../skyblocker/skyblock/chat/ChatRule.java | 2 +- .../dungeon/secrets/DungeonMapUtils.java | 4 +- .../skyblock/fancybars/BarPositioner.java | 319 ++++++++++++++++++ .../skyblock/fancybars/StatusBar.java | 27 +- .../fancybars/StatusBarsConfigScreen.java | 299 ++++++++-------- .../searchoverlay/SearchOverManager.java | 2 +- .../assets/skyblocker/lang/en_us.json | 3 + 10 files changed, 611 insertions(+), 286 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarPositioner.java diff --git a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java index 0c6a3d7594..37faaf256f 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java @@ -2,6 +2,7 @@ import de.hysky.skyblocker.config.ConfigUtils; import de.hysky.skyblocker.config.SkyblockerConfig; +import de.hysky.skyblocker.skyblock.fancybars.StatusBarsConfigScreen; import de.hysky.skyblocker.skyblock.shortcut.ShortcutsConfigScreen; import de.hysky.skyblocker.utils.render.title.TitleContainerConfigScreen; import de.hysky.skyblocker.utils.waypoint.Waypoint; @@ -156,6 +157,11 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig //Fancy Bars .group(OptionGroup.createBuilder() + .option(ButtonOption.createBuilder() + .name(Text.translatable("skyblocker.bars.config.openScreen")) + .text(Text.translatable("text.skyblocker.open")) + .action((screen, opt) -> MinecraftClient.getInstance().setScreen(new StatusBarsConfigScreen())) + .build()) .name(Text.translatable("text.autoconfig.skyblocker.option.general.bars")) .collapsed(true) .option(Option.createBuilder() diff --git a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java index 6bf012ff20..306c24568a 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java @@ -4,6 +4,7 @@ import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.fancybars.BarGrid; +import de.hysky.skyblocker.skyblock.fancybars.BarPositioner; import de.hysky.skyblocker.skyblock.fancybars.StatusBar; import de.hysky.skyblocker.skyblock.fancybars.StatusBarsConfigScreen; import de.hysky.skyblocker.utils.Utils; @@ -15,6 +16,7 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.ScreenPos; import net.minecraft.client.texture.Sprite; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.Text; @@ -57,6 +59,8 @@ public class FancyStatusBars { private final int[] anchorsX = new int[3]; private final int[] anchorsY = new int[3]; + public static BarPositioner barPositioner = new BarPositioner(); + @Deprecated(forRemoval = true) public static BarGrid barGrid = new BarGrid(); public static Map statusBars = new HashMap<>(); @@ -76,17 +80,21 @@ public static void init() { // Default positions StatusBar health = statusBars.get("health"); - health.gridX = 1; - health.gridY = 1; + health.anchor = BarPositioner.BarAnchor.HOTBAR_TOP; + health.gridX = 0; + health.gridY = 0; StatusBar intelligence = statusBars.get("intelligence"); - intelligence.gridX = 2; - intelligence.gridY = 1; + intelligence.anchor = BarPositioner.BarAnchor.HOTBAR_TOP; + intelligence.gridX = 1; + intelligence.gridY = 0; StatusBar defense = statusBars.get("defense"); - defense.gridX = 1; - defense.gridY = -1; + defense.anchor = BarPositioner.BarAnchor.HOTBAR_RIGHT; + defense.gridX = 0; + defense.gridY = 0; StatusBar experience = statusBars.get("experience"); - experience.gridX = 1; - experience.gridY = 2; + experience.anchor = BarPositioner.BarAnchor.HOTBAR_TOP; + experience.gridX = 0; + experience.gridY = 1; CompletableFuture.supplyAsync(FancyStatusBars::loadBarConfig).thenAccept(object -> { if (object != null) { @@ -102,8 +110,11 @@ public static void init() { } } } - placeBarsInGrid(); + placeBarsInPositioner(); configLoaded = true; + }).exceptionally(throwable -> { + LOGGER.error("[Skyblocker] Failed reading status bars config", throwable); + return null; }); ClientLifecycleEvents.CLIENT_STOPPING.register((client) -> { saveBarConfig(); @@ -119,53 +130,30 @@ public static void init() { //placeBarsInGrid(); ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register( - ClientCommandManager.literal("skyblocker") - .then(ClientCommandManager.literal("bar_test").executes(Scheduler.queueOpenScreenCommand(StatusBarsConfigScreen::new))))); + ClientCommandManager.literal(SkyblockerMod.NAMESPACE) + .then(ClientCommandManager.literal("bars").executes(Scheduler.queueOpenScreenCommand(StatusBarsConfigScreen::new))))); } private static boolean configLoaded = false; - private static void placeBarsInGrid() { + private static void placeBarsInPositioner() { List original = statusBars.values().stream().toList(); - // TOP - List barList = new ArrayList<>(original.stream().filter(statusBar -> statusBar.gridY > 0).toList()); - barList.sort((a, b) -> a.gridY == b.gridY ? Integer.compare(a.gridX, b.gridX) : Integer.compare(a.gridY, b.gridY)); - - int y = 0; - int rowNum = 0; - for (StatusBar statusBar : barList) { - if (statusBar.gridY > y) { - barGrid.addRowToEnd(true, false); - rowNum++; - y = statusBar.gridY; - } - barGrid.addToEndOfRow(rowNum, false, statusBar); - } - - // BOTTOM LEFT - barList.clear(); - barList.addAll(original.stream().filter(statusBar -> statusBar.gridY < 0 && statusBar.gridX < 0).toList()); - barList.sort((a, b) -> a.gridY == b.gridY ? -Integer.compare(a.gridX, b.gridX) : -Integer.compare(a.gridY, b.gridY)); - doBottom(false, barList); - - // BOTTOM RIGHT - barList.clear(); - barList.addAll(original.stream().filter(statusBar -> statusBar.gridY < 0 && statusBar.gridX > 0).toList()); - barList.sort((a, b) -> a.gridY == b.gridY ? Integer.compare(a.gridX, b.gridX) : -Integer.compare(a.gridY, b.gridY)); - doBottom(true, barList); - } - - private static void doBottom(boolean right, List barList) { - int y = 0; - int rowNum = 0; - for (StatusBar statusBar : barList) { - if (statusBar.gridY < y) { - barGrid.addRowToEnd(false, right); - rowNum--; - y = statusBar.gridY; + for (BarPositioner.BarAnchor barAnchor : BarPositioner.BarAnchor.allAnchors()) { + List 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); } - barGrid.addToEndOfRow(rowNum, right, statusBar); } } @@ -193,97 +181,82 @@ public static void saveBarConfig() { public static void updatePositions() { if (!configLoaded) return; - final float hotbarSize = 182; final int width = MinecraftClient.getInstance().getWindow().getScaledWidth(); final int height = MinecraftClient.getInstance().getWindow().getScaledHeight(); - for (StatusBar value : statusBars.values()) { - if (value.gridX == 0 || value.gridY == 0) { - value.setX(-1); - value.setY(-1); - value.setWidth(0); - } - } - - // THE TOP - for (int i = 0; i < barGrid.getTopSize(); i++) { - List row = barGrid.getRow(i + 1, false); - System.out.println(row); - if (row.isEmpty()) continue; - int totalSize = 0; - for (StatusBar bar : row) { - totalSize += bar.size; - } - - // Fix sizing - whileLoop: - while (totalSize != 12) { - if (totalSize > 12) { - for (StatusBar bar : row) { - if (bar.size > bar.getMinimumSize()) { // TODO: this can cause infinite looping if we add more than 6 bars - bar.size--; - totalSize--; - } - if (totalSize == 12) break whileLoop; - } - } else { - for (StatusBar bar : row) { - if (bar.size < bar.getMaximumSize()) { - bar.size++; - totalSize++; + for (BarPositioner.BarAnchor barAnchor : BarPositioner.BarAnchor.allAnchors()) { + ScreenPos anchorPosition = barAnchor.getAnchorPosition(width, height); + BarPositioner.SizeRule sizeRule = barAnchor.getSizeRule(); + + if (sizeRule.isTargetSize()) { + for (int row = 0; row < barPositioner.getRowCount(barAnchor); row++) { + LinkedList barRow = barPositioner.getRow(barAnchor, row); + if (barRow.isEmpty()) continue; + + // FIX SIZES + int totalSize = 0; + for (StatusBar statusBar : barRow) + totalSize += (statusBar.size = MathHelper.clamp(statusBar.size, sizeRule.minSize(), sizeRule.maxSize())); + + whileLoop: + while (totalSize != sizeRule.targetSize()) { + if (totalSize > sizeRule.targetSize()) { + for (StatusBar statusBar : barRow) { + if (statusBar.size > sizeRule.minSize()) { + statusBar.size--; + totalSize--; + if (totalSize == sizeRule.targetSize()) break whileLoop; + } + } + } else { + for (StatusBar statusBar : barRow) { + if (statusBar.size < sizeRule.maxSize()) { + statusBar.size++; + totalSize++; + if (totalSize == sizeRule.targetSize()) break whileLoop; + } + } } - if (totalSize == 12) break whileLoop; } + } } - int x = width / 2 - 91; - int y = height - 33 - 10 * i; - int size = 0; - for (int j = 0; j < row.size(); j++) { - StatusBar bar = row.get(j); - bar.setX(x + (int) ((size / 12.d) * hotbarSize)); - bar.setY(y); - bar.setWidth((int) ((bar.size / 12.d) * hotbarSize)); - size += bar.size; - bar.gridY = i + 1; - bar.gridX = j + 1; - } - } + for (int row = 0; row < barPositioner.getRowCount(barAnchor); row++) { + List barRow = barPositioner.getRow(barAnchor, row); + if (barRow.isEmpty()) continue; - // BOTTOM LEFT - for (int i = 0; i < barGrid.getBottomLeftSize(); i++) { - List row = barGrid.getRow(-(i + 1), false); - if (row.isEmpty()) continue; - int x = width / 2 - 91 - 2; - int y = height - 15 - 10 * (barGrid.getBottomLeftSize() - i - 1); - for (int j = 0; j < row.size(); j++) { - StatusBar bar = row.get(j); - bar.size = MathHelper.clamp(bar.size, bar.getMinimumSize(), bar.getMaximumSize()); - bar.setY(y); - bar.setWidth(bar.size * 25); - x -= bar.getWidth(); - bar.setX(x); - bar.gridX = -j - 1; - bar.gridY = -i - 1; - } - } - // BOTTOM RIGHT - for (int i = 0; i < barGrid.getBottomRightSize(); i++) { - List row = barGrid.getRow(-(i + 1), true); - if (row.isEmpty()) continue; - int x = width / 2 + 91 + 2; - int y = height - 15 - 10 * (barGrid.getBottomRightSize() - i - 1); - for (int j = 0; j < row.size(); j++) { - StatusBar bar = row.get(j); - bar.size = MathHelper.clamp(bar.size, bar.getMinimumSize(), bar.getMaximumSize()); - bar.setX(x); - bar.setY(y); - bar.setWidth(bar.size * 25); - x += bar.getWidth(); - bar.gridX = j + 1; - bar.gridY = -i - 1; + + // Update the positions + float widthPerSize; + if (sizeRule.isTargetSize()) + widthPerSize = (float) sizeRule.totalWidth() / sizeRule.targetSize(); + else + widthPerSize = sizeRule.widthPerSize(); + + int currSize = 0; + for (int i = 0; i < barRow.size(); i++) { + StatusBar statusBar = barRow.get(i); + statusBar.size = MathHelper.clamp(statusBar.size, sizeRule.minSize(), sizeRule.maxSize()); + + float x = barAnchor.isRight() ? + anchorPosition.x() + currSize * widthPerSize : + anchorPosition.x() - currSize * widthPerSize - statusBar.size * widthPerSize; + statusBar.setX((int) x); + + int y = barAnchor.isUp() ? + anchorPosition.y() - (row + 1) * (statusBar.getHeight() + 1) : + anchorPosition.y() + row * (statusBar.getHeight() + 1); + statusBar.setY(y); + + statusBar.setWidth((int) (statusBar.size * widthPerSize)); + currSize += statusBar.size; + statusBar.gridX = i; + statusBar.gridY = row; + + } } + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java index c8bc1f13ac..d6111f1bba 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java @@ -352,7 +352,7 @@ private void parsePage(ItemStack stack) { List tooltip = ItemUtils.getNbtTooltips(stack); String str = tooltip.get(0).getString().trim(); str = str.substring(1, str.length() - 1); // remove parentheses - String[] parts = str.split("/"); // split the string + String[] parts = str.split("/"); // targetSize the string currentPage = Integer.parseInt(parts[0].replace(",", "")); // parse current page totalPages = Integer.parseInt(parts[1].replace(",", "")); // parse total } catch (Exception e) { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/chat/ChatRule.java b/src/main/java/de/hysky/skyblocker/skyblock/chat/ChatRule.java index 34cc635236..65cbde5baa 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/chat/ChatRule.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/chat/ChatRule.java @@ -235,7 +235,7 @@ protected Boolean isMatch(String inputString) { String rawLocation = Utils.getLocationRaw(); Boolean isLocationValid = null; - for (String validLocation : validLocations.replace(" ", "").toLowerCase().split(",")) {//the locations are raw locations split by "," and start with ! if not locations + for (String validLocation : validLocations.replace(" ", "").toLowerCase().split(",")) {//the locations are raw locations targetSize by "," and start with ! if not locations String rawValidLocation = ChatRulesHandler.locations.get(validLocation.replace("!","")); if (rawValidLocation == null) continue; if (validLocation.startsWith("!")) {//not location diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java index 8e0073f731..3d37302500 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java @@ -117,7 +117,7 @@ public static int getMapRoomSize(MapState map, Vector2ic mapEntrancePos) { * @param mapEntrancePos the map position of the top left corner of the entrance * @param mapRoomSize the size of a room on the map * @return the map position of the top left corner of the room the player is in - * @implNote {@code mapPos} is shifted by 2 so room borders are evenly split. + * @implNote {@code mapPos} is shifted by 2 so room borders are evenly targetSize. * {@code mapPos} is then shifted by {@code offset} to align the top left most room at (0, 0) * so subtracting the modulo will give the top left corner of the room shifted by {@code offset}. * Finally, {@code mapPos} is shifted back by {@code offset} to its intended position. @@ -168,7 +168,7 @@ public static Vector2ic getPhysicalRoomPos(@NotNull Vec3i pos) { * @param x the x position of the coordinate to calculate * @param z the z position of the coordinate to calculate * @return the physical position of the northwest corner of the room the player is in - * @implNote {@code physicalPos} is shifted by 0.5 so room borders are evenly split. + * @implNote {@code physicalPos} is shifted by 0.5 so room borders are evenly targetSize. * {@code physicalPos} is further shifted by 8 because Hypixel offset dungeons by 8 blocks in Skyblock 0.12.3. * Subtracting the modulo gives the northwest corner of the room shifted by 8. Finally, {@code physicalPos} is shifted back by 8 to its intended position. */ diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarPositioner.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarPositioner.java new file mode 100644 index 0000000000..7fde91177d --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarPositioner.java @@ -0,0 +1,319 @@ +package de.hysky.skyblocker.skyblock.fancybars; + +import net.minecraft.client.gui.ScreenPos; +import net.minecraft.client.gui.ScreenRect; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public class BarPositioner { + + private final Map>> map = new HashMap<>(BarAnchor.values().length); + + public BarPositioner() { + for (BarAnchor value : BarAnchor.values()) { + map.put(value, new LinkedList<>()); + } + } + + + public int getRowCount(@NotNull BarAnchor barAnchor) { + return map.get(barAnchor).size(); + } + + /** + * Adds a row to the end of an anchor + * + * @param barAnchor the anchor + */ + public void addRow(@NotNull BarAnchor barAnchor) { + map.get(barAnchor).add(new LinkedList<>()); + } + + /** + * Adds a row at the specified index + * + * @param barAnchor the anchor + * @param row row index + */ + public void addRow(@NotNull BarAnchor barAnchor, int row) { + map.get(barAnchor).add(row, new LinkedList<>()); + } + + /** + * adds a bar to the end of a row + * + * @param barAnchor the anchor + * @param row the row + * @param bar the bar to add + */ + public void addBar(@NotNull BarAnchor barAnchor, int row, StatusBar bar) { + LinkedList statusBars = map.get(barAnchor).get(row); + statusBars.add(bar); + bar.gridY = row; + bar.gridX = statusBars.lastIndexOf(bar); // optimization baby, start with the end! + bar.anchor = barAnchor; + } + + /** + * adds a bar to the specified x in a row + * + * @param barAnchor the anchor + * @param row the row + * @param x the index in the row + * @param bar the bar to add + */ + public void addBar(@NotNull BarAnchor barAnchor, int row, int x, StatusBar bar) { + LinkedList statusBars = map.get(barAnchor).get(row); + statusBars.add(x, bar); + bar.gridY = row; + bar.gridX = statusBars.indexOf(bar); + bar.anchor = barAnchor; + } + + /** + * removes the specified bar at x on the row. If it's row is empty after being removed, the row will be auto removed + * + * @param barAnchor the anchor + * @param row dah row + * @param x dah x + */ + public void removeBar(@NotNull BarAnchor barAnchor, int row, int x) { + LinkedList statusBars = map.get(barAnchor).get(row); + StatusBar remove = statusBars.remove(x); + remove.anchor = null; + for (int i = x; i < statusBars.size(); i++) { + statusBars.get(i).gridX--; + } + if (statusBars.isEmpty()) removeRow(barAnchor, row); + } + + /** + * removes the specified bar on the row. If it's row is empty after being removed, the row will be auto removed + * + * @param barAnchor the anchor + * @param row dah row + * @param bar dah bar + */ + public void removeBar(@NotNull BarAnchor barAnchor, int row, StatusBar bar) { + LinkedList barRow = map.get(barAnchor).get(row); + int x = barRow.indexOf(bar); + if (x < 0) return; // probably a bad idea + + barRow.remove(bar); + bar.anchor = null; + for (int i = x; i < barRow.size(); i++) { + barRow.get(i).gridX--; + } + if (barRow.isEmpty()) removeRow(barAnchor, row); + } + + /** + * row must be empty + * + * @param barAnchor the anchor + * @param row the row to remove + */ + public void removeRow(@NotNull BarAnchor barAnchor, int row) { + LinkedList barRow = map.get(barAnchor).get(row); + if (!barRow.isEmpty()) + throw new IllegalStateException("Can't remove a non-empty row (" + barAnchor + "," + row + ")"); + map.get(barAnchor).remove(row); + for (int i = row; i < map.get(barAnchor).size(); i++) { + for (StatusBar statusBar : map.get(barAnchor).get(i)) { + statusBar.gridY--; + } + } + } + + + public LinkedList getRow(@NotNull BarAnchor barAnchor, int row) { + return map.get(barAnchor).get(row); + } + + public StatusBar getBar(@NotNull BarAnchor barAnchor, int row, int x) { + return map.get(barAnchor).get(row).get(x); + } + + public boolean hasNeighbor(@NotNull BarAnchor barAnchor, int row, int x, boolean right) { + LinkedList statusBars = map.get(barAnchor).get(row); + if (barAnchor.isRight()) { + return (right && x < statusBars.size() - 1) || (!right && x > 0); + } else { + return (right && x > 0) || (!right && x < statusBars.size() - 1); + } + } + + + public enum BarAnchor { + HOTBAR_LEFT(true, false, + (scaledWidth, scaledHeight) -> new ScreenPos(scaledWidth / 2 - 91 - 2, scaledHeight - 5), + SizeRule.freeSize(25, 2, 6)), + + HOTBAR_RIGHT(true, true, + (scaledWidth, scaledHeight) -> new ScreenPos(scaledWidth / 2 + 91 + 2, scaledHeight - 5), + SizeRule.freeSize(25, 2, 6)), + + HOTBAR_TOP(true, true, + (scaledWidth, scaledHeight) -> new ScreenPos(scaledWidth / 2 - 91, scaledHeight - 23), + SizeRule.targetSize(12, 182, 2), + anchorPosition -> new ScreenRect(anchorPosition.x(), anchorPosition.y() - 20, 182, 20)), + + SCREEN_TOP_LEFT(false, true, + ((scaledWidth, scaledHeight) -> new ScreenPos(5, 5)), + SizeRule.freeSize(25, 2, 6) + ), + SCREEN_TOP_RIGHT(false, false, + ((scaledWidth, scaledHeight) -> new ScreenPos(scaledWidth - 5, 5)), + SizeRule.freeSize(25, 2, 6) + ), + SCREEN_BOTTOM_LEFT(true, true, + ((scaledWidth, scaledHeight) -> new ScreenPos(5, scaledHeight - 5)), + SizeRule.freeSize(25, 2, 6) + ), + SCREEN_BOTTOM_RIGHT(true, false, + ((scaledWidth, scaledHeight) -> new ScreenPos(scaledWidth - 5, scaledHeight - 5)), + SizeRule.freeSize(25, 2, 6) + ), + ; + + private final AnchorPositionProvider positionProvider; + private final AnchorHitboxProvider hitboxProvider; + private final boolean up; + private final boolean right; + private final SizeRule sizeRule; + + /** + * @param up whether the rows stack towards the top of the screen from the anchor (false is bottom) + * @param right whether the bars are line up towards the right of the screen from the anchor (false is left) + * @param positionProvider provides the position of the anchor for a give screen size + * @param sizeRule the rule the bars should follow. See {@link SizeRule} + * @param hitboxProvider provides the hitbox for when the anchor has no bars for the config screen + */ + BarAnchor(boolean up, boolean right, AnchorPositionProvider positionProvider, SizeRule sizeRule, AnchorHitboxProvider hitboxProvider) { + this.positionProvider = positionProvider; + this.up = up; + this.right = right; + this.hitboxProvider = hitboxProvider; + this.sizeRule = sizeRule; + } + + BarAnchor(boolean up, boolean right, AnchorPositionProvider positionProvider, SizeRule sizeRule) { + this(up, right, positionProvider, sizeRule, + anchorPosition -> new ScreenRect(anchorPosition.x() - (right ? 0 : 20), anchorPosition.y() - (up ? 20 : 0), 20, 20)); + } + + public ScreenPos getAnchorPosition(int scaledWidth, int scaledHeight) { + return positionProvider.getPosition(scaledWidth, scaledHeight); + } + + public ScreenRect getAnchorHitbox(ScreenPos anchorPosition) { + return hitboxProvider.getHitbox(anchorPosition); + } + + /** + * whether the rows stack towards the top of the screen from the anchor (false is bottom) + * + * @return true if towards the top, false otherwise + */ + public boolean isUp() { + return up; + } + + /** + * whether the bars are line up towards the right of the screen from the anchor (false is left) + * + * @return true if towards the right, false otherwise + */ + public boolean isRight() { + return right; + } + + public SizeRule getSizeRule() { + return sizeRule; + } + + private static final List cached = List.of(values()); + + /** + * cached version of {@link BarAnchor#values()} + * + * @return the list of anchors + */ + public static List allAnchors() { + return cached; + } + } + + /** + * The rules the bars on an anchor should follow + * + * @param isTargetSize whether the bars went to fit to a target width + * @param targetSize the size of all the bars on a row should add up to this (target size) + * @param totalWidth the total width taken by all the bars on the row (target size) + * @param widthPerSize the width of each size "unit" (free size) + * @param minSize the minimum (free and target size) + * @param maxSize the maximum (free and target size, THIS SHOULD BE THE SAME AS {@code targetSize} FOR {@code isTargetSize = true}) + */ + public record SizeRule(boolean isTargetSize, int targetSize, int totalWidth, int widthPerSize, int minSize, + int maxSize) { + public static SizeRule freeSize(int widthPerSize, int minSize, int maxSize) { + return new SizeRule(false, -1, -1, widthPerSize, minSize, maxSize); + } + + public static SizeRule targetSize(int targetSize, int totalWidth, int minSize) { + return new SizeRule(true, targetSize, totalWidth, -1, minSize, targetSize); + } + } + + /** + * A record representing a snapshot of a bar's position + * + * @param barAnchor + * @param x + * @param y the row + */ + public record BarLocation(@Nullable BarAnchor barAnchor, int x, int y) { + + public static final BarLocation NULL = new BarLocation(null, -1, -1); + + public static BarLocation of(StatusBar bar) { + return new BarLocation(bar.anchor, bar.gridX, bar.gridY); + } + + @Override + public boolean equals(Object object) { + if (this == object) return true; + if (object == null || getClass() != object.getClass()) return false; + + BarLocation that = (BarLocation) object; + return x == that.x && y == that.y && barAnchor == that.barAnchor; + } + + public boolean equals(BarAnchor barAnchor, int x, int y) { + return x == this.x && y == this.y && barAnchor == this.barAnchor; + } + } + + /** + * provides the position of the anchor for a give screen size + */ + @FunctionalInterface + interface AnchorPositionProvider { + + ScreenPos getPosition(int scaledWidth, int scaledHeight); + } + + @FunctionalInterface + interface AnchorHitboxProvider { + + /** + * The hitbox, as in how large the area of "snapping" is if there are no bars on this anchor + * + * @param anchorPosition the position of the anchor + * @return the rectangle that represents the hitbox + */ + ScreenRect getHitbox(ScreenPos anchorPosition); + } +} 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 ea4a03888f..5ece19340e 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java @@ -86,12 +86,14 @@ public Text getName() { private @Nullable OnClick onClick = null; public int gridX = 0; public int gridY = 0; + public @Nullable BarPositioner.BarAnchor anchor = null; public int size = 1; private int width = 0; public float fill = 0; public float overflowFill = 0; + public boolean ghost = false; private Object value = ""; @@ -116,6 +118,8 @@ public StatusBar(Identifier icon, Color[] colors, boolean hasOverflow, @Nullable @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { if (width <= 0) return; + // half works lol. only puts transparency on the filler of the bar + if (ghost) context.setShaderColor(1f,1f,1f,0.25f); switch (iconPosition) { case LEFT -> context.drawGuiTexture(icon, x, y, 9, 9); case RIGHT -> context.drawGuiTexture(icon, x + width - 9, y, 9, 9); @@ -130,6 +134,7 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { if (hasOverflow && overflowFill > 0) { RenderHelper.renderNineSliceColored(context, BAR_FILL, barX + 1, y + 2, (int) ((barWith - 2) * overflowFill), 5, colors[1]); } + if (ghost) context.setShaderColor(1f,1f,1f,1f); //context.drawText(MinecraftClient.getInstance().textRenderer, gridX + " " + gridY + " s:" + size , x, y-9, Colors.WHITE, true); } @@ -159,13 +164,19 @@ public void renderCursor(DrawContext context, int mouseX, int mouseY, float delt int temp_x = x; int temp_y = y; int temp_width = width; + boolean temp_ghost = ghost; + x = mouseX; y = mouseY; width = 100; + ghost = false; + render(context, mouseX, mouseY, delta); + x = temp_x; y = temp_y; width = temp_width; + ghost = temp_ghost; } // GUI shenanigans @@ -204,14 +215,6 @@ public int getHeight() { return 9; } - public int getMinimumSize() { - return 2; - } - - public int getMaximumSize() { - return gridY < 0 ? 6 : 12; - } - @Override public ScreenRect getNavigationFocus() { return Widget.super.getNavigationFocus(); @@ -267,6 +270,7 @@ public String toString() { .append("x", x) .append("y", y) .append("width", width) + .append("anchor", anchor) .toString(); } @@ -315,11 +319,13 @@ public void loadFromJson(JsonObject object) { 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); this.size = object.get("size").getAsInt(); this.gridX = object.get("x").getAsInt(); this.gridY = object.get("y").getAsInt(); // these are optional too, why not - if (object.has("icon_position")) this.iconPosition = IconPosition.valueOf(object.get("icon_position").getAsString()); + if (object.has("icon_position")) this.iconPosition = IconPosition.valueOf(object.get("icon_position").getAsString().trim()); if (object.has("show_text")) this.showText = object.get("show_text").getAsBoolean(); } @@ -335,6 +341,9 @@ public JsonObject toJson() { object.addProperty("text_color", Integer.toHexString(textColor.getRGB()).substring(2)); } object.addProperty("size", size); + if (anchor != null) { + object.addProperty("anchor", anchor.toString()); + } else object.addProperty("anchor", "null"); object.addProperty("x", gridX); object.addProperty("y", gridY); object.addProperty("icon_position", iconPosition.toString()); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java index 3bcc20113b..7c1aa71b18 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java @@ -10,12 +10,14 @@ import net.minecraft.client.gui.ScreenRect; import net.minecraft.client.gui.navigation.NavigationAxis; import net.minecraft.client.gui.navigation.NavigationDirection; +import net.minecraft.client.gui.screen.PopupScreen; import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.text.Text; -import net.minecraft.util.Colors; import net.minecraft.util.Identifier; import org.jetbrains.annotations.Nullable; import org.lwjgl.glfw.GLFW; +import de.hysky.skyblocker.skyblock.fancybars.BarPositioner.BarLocation; import java.util.Collection; import java.util.HashMap; @@ -27,7 +29,7 @@ public class StatusBarsConfigScreen extends Screen { public static final long RESIZE_CURSOR = GLFW.glfwCreateStandardCursor(GLFW.GLFW_HRESIZE_CURSOR); - private final Map meaningFullName = new HashMap<>(); + private final Map meaningFullName = new HashMap<>(); private static final int HOTBAR_WIDTH = 182; private @Nullable StatusBar cursorBar = null; @@ -37,21 +39,24 @@ public StatusBarsConfigScreen() { FancyStatusBars.updatePositions(); } - private final int[] currentCursorCoords = new int[]{0, 0}; + private BarLocation currentInsertLocation = new BarLocation(null, 0, 0); - private final Pair resizeHover = new ObjectBooleanMutablePair<>(new int[]{0, 0}, false); + private final Pair resizeHover = new ObjectBooleanMutablePair<>(BarLocation.NULL, false); - private final Pair resizedBars = ObjectObjectMutablePair.of(new int[]{0, 0}, new int[]{0, 0}); + private final Pair resizedBars = ObjectObjectMutablePair.of(BarLocation.NULL, BarLocation.NULL); private boolean resizing = false; private EditBarWidget editBarWidget; + // prioritize left and right cuz they are much smaller space than up and down + private static final NavigationDirection[] DIRECTION_CHECK_ORDER = new NavigationDirection[]{NavigationDirection.LEFT, NavigationDirection.RIGHT, NavigationDirection.UP, NavigationDirection.DOWN}; + @SuppressWarnings("UnreachableCode") // IntelliJ big stupid @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { - for (ScreenRect screenRect : meaningFullName.keySet()) { + /*for (ScreenRect screenRect : meaningFullName.keySet()) { context.fillGradient(screenRect.position().x(), screenRect.position().y(), screenRect.position().x() + screenRect.width(), screenRect.position().y() + screenRect.height(), 0xFFFF0000, 0xFF0000FF); - } + }*/ super.render(context, mouseX, mouseY, delta); context.drawGuiTexture(HOTBAR_TEXTURE, width / 2 - HOTBAR_WIDTH / 2, height - 22, HOTBAR_WIDTH, 22); editBarWidget.render(context, mouseX, mouseY, delta); @@ -60,109 +65,99 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { assert client != null; WindowAccessor window = (WindowAccessor) (Object) client.getWindow(); assert window != null; + if (cursorBar != null) { cursorBar.renderCursor(context, mouseX, mouseY, delta); - context.drawText(textRenderer, currentCursorCoords[0] + " " + currentCursorCoords[1], 100, 5, Colors.WHITE, true); - - - if (FancyStatusBars.barGrid.getTopSize() == 0 && topBarZone.overlaps(mouseRect) && currentCursorCoords[1] != 1) { - FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY); - FancyStatusBars.barGrid.addRow(1, true); - FancyStatusBars.barGrid.add(1, 1, cursorBar); - currentCursorCoords[1] = 1; - FancyStatusBars.updatePositions(); - } else if (FancyStatusBars.barGrid.getBottomLeftSize() == 0 && bottomLeftBarZone.overlaps(mouseRect) && (currentCursorCoords[0] != -1 || currentCursorCoords[1] != -1)) { - FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY); - FancyStatusBars.barGrid.addRow(-1, false); - FancyStatusBars.barGrid.add(-1, -1, cursorBar); - currentCursorCoords[0] = -1; - currentCursorCoords[1] = -1; - FancyStatusBars.updatePositions(); - } else if (FancyStatusBars.barGrid.getBottomRightSize() == 0 && bottomRightBarZone.overlaps(mouseRect) && (currentCursorCoords[0] != 1 || currentCursorCoords[1] != -1)) { - FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY); - FancyStatusBars.barGrid.addRow(-1, true); - FancyStatusBars.barGrid.add(1, -1, cursorBar); - currentCursorCoords[0] = 1; - currentCursorCoords[1] = -1; - FancyStatusBars.updatePositions(); - } else rectLoop:for (ScreenRect screenRect : meaningFullName.keySet()) { - for (NavigationDirection direction : NavigationDirection.values()) { + boolean inserted = false; + rectLoop: + for (ScreenRect screenRect : meaningFullName.keySet()) { + for (NavigationDirection direction : DIRECTION_CHECK_ORDER) { boolean overlaps = screenRect.getBorder(direction).add(direction).overlaps(mouseRect); if (overlaps) { - int[] ints = meaningFullName.get(screenRect); - final boolean vertical = direction.getAxis().equals(NavigationAxis.VERTICAL); - int offsetX = 0; - int offsetY = 0; - if (vertical) { - if (!direction.isPositive()) { - offsetY = ints[1] > 0 ? 1 : 0; - } else { - offsetY = ints[1] > 0 ? 0 : -1; + BarLocation barSnap = meaningFullName.get(screenRect); + if (direction.getAxis().equals(NavigationAxis.VERTICAL)) { + int neighborInsertY = getNeighborInsertY(barSnap, !direction.isPositive()); + if (!currentInsertLocation.equals(barSnap.barAnchor(), barSnap.x(), neighborInsertY)) { + if (cursorBar.anchor != null) + FancyStatusBars.barPositioner.removeBar(cursorBar.anchor, cursorBar.gridY, cursorBar); + FancyStatusBars.barPositioner.addRow(barSnap.barAnchor(), neighborInsertY); + FancyStatusBars.barPositioner.addBar(barSnap.barAnchor(), neighborInsertY, cursorBar); + currentInsertLocation = BarLocation.of(cursorBar); + inserted = true; } } else { - if (direction.isPositive()) { - offsetX = ints[0] > 0 ? 1 : 0; - } else { - offsetX = ints[0] > 0 ? 0 : -1; - } - } - context.drawText(textRenderer, ints[0] + offsetX + " " + ints[1] + offsetY, 100, 15, Colors.WHITE, true); - if (ints[0] + offsetX != currentCursorCoords[0] || ints[1] + offsetY != currentCursorCoords[1]) { - currentCursorCoords[0] = ints[0] + offsetX; - currentCursorCoords[1] = ints[1] + offsetY; - FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY); - - - if (vertical) { - - FancyStatusBars.barGrid.addRow(ints[1] + offsetY, ints[0] > 0); - FancyStatusBars.barGrid.add(ints[0] < 0 ? -1 : 1, ints[1] + offsetY, cursorBar); - } else { - - FancyStatusBars.barGrid.add(ints[0] + offsetX, ints[1], cursorBar); + int neighborInsertX = getNeighborInsertX(barSnap, direction.isPositive()); + if (!currentInsertLocation.equals(barSnap.barAnchor(), neighborInsertX, barSnap.y())) { + if (cursorBar.anchor != null) + FancyStatusBars.barPositioner.removeBar(cursorBar.anchor, cursorBar.gridY, cursorBar); + FancyStatusBars.barPositioner.addBar(barSnap.barAnchor(), barSnap.y(), neighborInsertX, cursorBar); + currentInsertLocation = BarLocation.of(cursorBar); + inserted = true; } - FancyStatusBars.updatePositions(); } break rectLoop; } } } + if (inserted) { + FancyStatusBars.updatePositions(); + return; + } + // check for hovering empty anchors + for (BarPositioner.BarAnchor barAnchor : BarPositioner.BarAnchor.allAnchors()) { + if (FancyStatusBars.barPositioner.getRowCount(barAnchor) != 0) continue; + ScreenRect anchorHitbox = barAnchor.getAnchorHitbox(barAnchor.getAnchorPosition(width, height)); + context.fill(anchorHitbox.getLeft(), anchorHitbox.getTop(), anchorHitbox.getRight(), anchorHitbox.getBottom(), 0x99FFFFFF); + if (anchorHitbox.overlaps(mouseRect) && currentInsertLocation.barAnchor() != barAnchor) { + if (cursorBar.anchor != null) + FancyStatusBars.barPositioner.removeBar(cursorBar.anchor, cursorBar.gridY, cursorBar); + FancyStatusBars.barPositioner.addRow(barAnchor); + FancyStatusBars.barPositioner.addBar(barAnchor, 0, cursorBar); + currentInsertLocation = BarLocation.of(cursorBar); + FancyStatusBars.updatePositions(); + } + } } else { - // RESIZING STATE - if (resizing) { + if (resizing) { // actively resizing one or 2 bars int middleX; - boolean bottom; - int[] left = resizedBars.left(); - int[] right = resizedBars.right(); - boolean hasRight = right[0] != 0; - boolean hasLeft = left[0] != 0; + BarLocation left = resizedBars.left(); + BarLocation right = resizedBars.right(); + boolean hasRight = !right.equals(BarLocation.NULL); + boolean hasLeft = !left.equals(BarLocation.NULL); + BarPositioner.BarAnchor barAnchor; if (!hasRight) { - StatusBar bar = FancyStatusBars.barGrid.getBar(left[0], left[1]); + barAnchor = left.barAnchor(); + StatusBar bar = FancyStatusBars.barPositioner.getBar(barAnchor, left.y(), left.x()); middleX = bar.getX() + bar.getWidth(); - bottom = bar.gridY < 0; } else { - middleX = FancyStatusBars.barGrid.getBar(right[0], right[1]).getX(); - bottom = right[1] < 0; + barAnchor = right.barAnchor(); + middleX = FancyStatusBars.barPositioner.getBar(barAnchor, right.y(), right.x()).getX(); } - int i = bottom ? 20 : 10; + boolean doResize = true; StatusBar rightBar = null; StatusBar leftBar = null; - context.drawText(textRenderer, Integer.toString(mouseX - middleX), 100, 25, -1, true); + BarPositioner.SizeRule sizeRule = barAnchor.getSizeRule(); - if (mouseX < middleX) { - if (middleX - mouseX > i) { + float widthPerSize; + if (sizeRule.isTargetSize()) + widthPerSize = (float) sizeRule.totalWidth() / sizeRule.targetSize(); + else + widthPerSize = sizeRule.widthPerSize(); + // resize towards the left + if (mouseX < middleX) { + if (middleX - mouseX > widthPerSize / .75f) { if (hasRight) { - rightBar = FancyStatusBars.barGrid.getBar(right[0], right[1]); - if (rightBar.size + 1 > rightBar.getMaximumSize()) doResize = false; + rightBar = FancyStatusBars.barPositioner.getBar(barAnchor, right.y(), right.x()); + if (rightBar.size + 1 > sizeRule.maxSize()) doResize = false; } if (hasLeft) { - leftBar = FancyStatusBars.barGrid.getBar(left[0], left[1]); - if (leftBar.size - 1 < leftBar.getMinimumSize()) doResize = false; + leftBar = FancyStatusBars.barPositioner.getBar(barAnchor, left.y(), left.x()); + if (leftBar.size - 1 < sizeRule.minSize()) doResize = false; } if (doResize) { @@ -171,18 +166,16 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { FancyStatusBars.updatePositions(); } } - } else { - if (mouseX - middleX > i) { - + } else { // towards the right + if (mouseX - middleX > widthPerSize / .75f) { if (hasRight) { - rightBar = FancyStatusBars.barGrid.getBar(right[0], right[1]); - if (rightBar.size - 1 < rightBar.getMinimumSize()) doResize = false; + rightBar = FancyStatusBars.barPositioner.getBar(barAnchor, right.y(), right.x()); + if (rightBar.size - 1 < sizeRule.minSize()) doResize = false; } if (hasLeft) { - leftBar = FancyStatusBars.barGrid.getBar(left[0], left[1]); - if (leftBar.size + 1 > leftBar.getMaximumSize()) doResize = false; + leftBar = FancyStatusBars.barPositioner.getBar(barAnchor, left.y(), left.x()); + if (leftBar.size + 1 > sizeRule.maxSize()) doResize = false; } - context.drawText(textRenderer, leftBar.size + " " + leftBar.getMaximumSize(), 100, 35, -1, true); if (doResize) { if (hasRight) rightBar.size--; @@ -191,29 +184,26 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { } } } - GLFW.glfwSetCursor(window.getHandle(), RESIZE_CURSOR); - } - // NOT RESIZING STATE - else { + + } else { // hovering bars rectLoop: for (ScreenRect screenRect : meaningFullName.keySet()) { for (NavigationDirection direction : new NavigationDirection[]{NavigationDirection.LEFT, NavigationDirection.RIGHT}) { boolean overlaps = screenRect.getBorder(direction).add(direction).overlaps(mouseRect); if (overlaps && !editBarWidget.isMouseOver(mouseX, mouseY)) { - int[] ints = meaningFullName.get(screenRect); - boolean left = direction.equals(NavigationDirection.LEFT); - if ((ints[0] == 1 && left) || (ints[0] == -1 && !left) || (!left && ints[1] > 0 && ints[0] == FancyStatusBars.barGrid.getRow(ints[1], true).size())) { + BarLocation barLocation = meaningFullName.get(screenRect); + boolean right = direction.equals(NavigationDirection.RIGHT); + // can't resize on the edge of a target size row! + if (barLocation.barAnchor().getSizeRule().isTargetSize() && !FancyStatusBars.barPositioner.hasNeighbor(barLocation.barAnchor(), barLocation.y(), barLocation.x(), right)) { break; } - resizeHover.first()[0] = ints[0]; - resizeHover.first()[1] = ints[1]; - resizeHover.right(!left); + resizeHover.first(barLocation); + resizeHover.right(right); GLFW.glfwSetCursor(window.getHandle(), RESIZE_CURSOR); break rectLoop; } else { - resizeHover.first()[0] = 0; - resizeHover.first()[1] = 0; + resizeHover.first(BarLocation.NULL); GLFW.glfwSetCursor(window.getHandle(), 0); } } @@ -222,9 +212,27 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { } } - private ScreenRect topBarZone = new ScreenRect(0, 0, 0, 0); - private ScreenRect bottomLeftBarZone = new ScreenRect(0, 0, 0, 0); - private ScreenRect bottomRightBarZone = new ScreenRect(0, 0, 0, 0); + private static int getNeighborInsertX(BarLocation barLocation, boolean right) { + BarPositioner.BarAnchor barAnchor = barLocation.barAnchor(); + int gridX = barLocation.x(); + if (barAnchor == null) return 0; + if (right) { + return barAnchor.isRight() ? gridX + 1 : gridX; + } else { + return barAnchor.isRight() ? gridX : gridX + 1; + } + } + + private static int getNeighborInsertY(BarLocation barLocation, boolean up) { + BarPositioner.BarAnchor barAnchor = barLocation.barAnchor(); + int gridY = barLocation.y(); + if (barAnchor == null) return 0; + if (up) { + return barAnchor.isUp() ? gridY + 1 : gridY; + } else { + return barAnchor.isUp() ? gridY : gridY + 1; + } + } @Override protected void init() { @@ -234,24 +242,31 @@ protected void init() { addSelectableChild(editBarWidget); // rendering separately to have it above hotbar Collection values = FancyStatusBars.statusBars.values(); values.forEach(this::setup); - checkZeroCoordinates(values); + checkNullAnchor(values); updateScreenRects(); - topBarZone = new ScreenRect(width / 2 - HOTBAR_WIDTH / 2, height - 22 - 15, HOTBAR_WIDTH, 15); - bottomLeftBarZone = new ScreenRect(width / 2 - HOTBAR_WIDTH / 2 - 20, height - 22, 20, 22); - bottomRightBarZone = new ScreenRect(width / 2 + HOTBAR_WIDTH / 2, height - 22, 20, 22); + this.addDrawableChild(ButtonWidget.builder(Text.literal("?"), + button -> { + assert client != null; + client.setScreen(new PopupScreen.Builder(this, Text.translatable("skyblocker.bars.config.explanationTitle")) + .button(Text.translatable("gui.ok"), PopupScreen::close) + .message(Text.translatable("skyblocker.bars.config.explanation")) + .build()); + }) + .dimensions(width - 20, (height - 15) / 2, 15, 15) + .build()); } private void setup(StatusBar statusBar) { this.addDrawableChild(statusBar); - statusBar.setOnClick(this::onClick); + statusBar.setOnClick(this::onBarClick); } - private static void checkZeroCoordinates(Iterable bars) { + private static void checkNullAnchor(Iterable bars) { int offset = 0; for (StatusBar statusBar : bars) { - if (statusBar.gridX == 0 || statusBar.gridY == 0) { + if (statusBar.anchor == null) { statusBar.setX(5); - statusBar.setY(5 + offset); + statusBar.setY(50 + offset); statusBar.setWidth(30); offset += statusBar.getHeight(); } @@ -263,6 +278,7 @@ private static void checkZeroCoordinates(Iterable bars) { public void removed() { super.removed(); FancyStatusBars.statusBars.values().forEach(statusBar -> statusBar.setOnClick(null)); + if (cursorBar != null) cursorBar.ghost = false; FancyStatusBars.updatePositions(); assert client != null; GLFW.glfwSetCursor(((WindowAccessor) (Object) client.getWindow()).getHandle(), 0); @@ -274,11 +290,14 @@ public boolean shouldPause() { return false; } - private void onClick(StatusBar statusBar, int button, int mouseX, int mouseY) { + private void onBarClick(StatusBar statusBar, int button, int mouseX, int mouseY) { if (button == 0) { cursorBar = statusBar; - FancyStatusBars.barGrid.remove(statusBar.gridX, statusBar.gridY); + cursorBar.ghost = true; + if (statusBar.anchor != null) + FancyStatusBars.barPositioner.removeBar(statusBar.anchor, statusBar.gridY, statusBar); FancyStatusBars.updatePositions(); + cursorBar.setX(width + 5); // send it to limbo lol updateScreenRects(); } else if (button == 1) { int x = Math.min(mouseX - 1, width - editBarWidget.getWidth()); @@ -292,25 +311,27 @@ private void onClick(StatusBar statusBar, int button, int mouseX, int mouseY) { private void updateScreenRects() { meaningFullName.clear(); - FancyStatusBars.statusBars.values().forEach(statusBar1 -> meaningFullName.put( - new ScreenRect(new ScreenPos(statusBar1.getX(), statusBar1.getY()), statusBar1.getWidth(), statusBar1.getHeight()), - new int[]{statusBar1.gridX, statusBar1.gridY})); + FancyStatusBars.statusBars.values().forEach(statusBar1 -> { + if (statusBar1.anchor == null) return; + meaningFullName.put( + new ScreenRect(new ScreenPos(statusBar1.getX(), statusBar1.getY()), statusBar1.getWidth(), statusBar1.getHeight()), + BarLocation.of(statusBar1)); + }); } @Override public boolean mouseReleased(double mouseX, double mouseY, int button) { if (cursorBar != null) { + cursorBar.ghost = false; cursorBar = null; FancyStatusBars.updatePositions(); - checkZeroCoordinates(FancyStatusBars.statusBars.values()); + checkNullAnchor(FancyStatusBars.statusBars.values()); updateScreenRects(); return true; } else if (resizing) { resizing = false; - resizedBars.left()[0] = 0; - resizedBars.left()[1] = 0; - resizedBars.right()[0] = 0; - resizedBars.right()[1] = 0; + resizedBars.left(BarLocation.NULL); + resizedBars.right(BarLocation.NULL); updateScreenRects(); return true; } @@ -319,29 +340,23 @@ public boolean mouseReleased(double mouseX, double mouseY, int button) { @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { - int[] first = resizeHover.first(); + BarLocation first = resizeHover.first(); // want the right click thing to have priority - if (!editBarWidget.isMouseOver(mouseX, mouseY) && button == 0 && first[0] != 0 && first[1] != 0) { + if (!editBarWidget.isMouseOver(mouseX, mouseY) && button == 0 && !first.equals(BarLocation.NULL)) { + BarPositioner.BarAnchor barAnchor = first.barAnchor(); + assert barAnchor != null; if (resizeHover.right()) { - resizedBars.left()[0] = first[0]; - resizedBars.left()[1] = first[1]; - if (FancyStatusBars.barGrid.coordinatesExist(first[0] + 1, first[1])) { - resizedBars.right()[0] = first[0] + 1; - resizedBars.right()[1] = first[1]; - } else { - resizedBars.right()[0] = 0; - resizedBars.right()[1] = 0; - } + resizedBars.left(first); + + if (FancyStatusBars.barPositioner.hasNeighbor(barAnchor, first.y(), first.x(), true)) { + resizedBars.right(new BarLocation(barAnchor, first.x() + (barAnchor.isRight() ? 1 : -1), first.y())); + } else resizedBars.right(BarLocation.NULL); } else { - resizedBars.right()[0] = first[0]; - resizedBars.right()[1] = first[1]; - if (FancyStatusBars.barGrid.coordinatesExist(first[0] - 1, first[1])) { - resizedBars.left()[0] = first[0] - 1; - resizedBars.left()[1] = first[1]; - } else { - resizedBars.left()[0] = 0; - resizedBars.left()[1] = 0; - } + resizedBars.right(first); + + if (FancyStatusBars.barPositioner.hasNeighbor(barAnchor, first.y(), first.x(), false)) { + resizedBars.left(new BarLocation(barAnchor, first.x() + (barAnchor.isRight() ? -1 : 1), first.y())); + } else resizedBars.left(BarLocation.NULL); } resizing = true; return true; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/searchoverlay/SearchOverManager.java b/src/main/java/de/hysky/skyblocker/skyblock/searchoverlay/SearchOverManager.java index 1d740601d0..c5811dd27e 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/searchoverlay/SearchOverManager.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/searchoverlay/SearchOverManager.java @@ -318,7 +318,7 @@ private static void pushCommand() { } /** - * pushes the ({@link SearchOverManager#search}) to the sign. It needs to split it over two lines without splitting a word + * pushes the ({@link SearchOverManager#search}) to the sign. It needs to targetSize it over two lines without splitting a word */ private static void pushSign() { //splits text into 2 lines max = 30 chars diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 5921cc957b..e28b23166d 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -505,6 +505,9 @@ "skyblocker.bars.config.textColor": "Text Color", "skyblocker.bars.config.showValue": "Show Value", "skyblocker.bars.config.icon": "Icon", + "skyblocker.bars.config.openScreen": "Status Bars Config screen", + "skyblocker.bars.config.explanationTitle": "What is this?", + "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) or existing bars.\nYou can right click them to edit a bunch of properties.\n\nEverything is saved when you leave", "skyblocker.updaterepository.failed": "§cUpdating local repository failed. Remove files manually and restart game.", From 28521b8c1457146da6852316c5115afb2e64481c Mon Sep 17 00:00:00 2001 From: vicisacat Date: Wed, 17 Apr 2024 23:28:22 +0200 Subject: [PATCH 11/25] remove any mention of old status bars also moved FancyStatusBars.java --- .../de/hysky/skyblocker/SkyblockerMod.java | 1 + .../skyblocker/config/SkyblockerConfig.java | 39 ---- .../config/categories/GeneralCategory.java | 43 +--- .../skyblocker/mixin/InGameHudMixin.java | 2 +- .../hysky/skyblocker/mixin/WindowMixin.java | 2 +- .../{ => fancybars}/FancyStatusBars.java | 208 ++---------------- .../fancybars/StatusBarsConfigScreen.java | 1 - .../assets/skyblocker/lang/en_us.json | 8 - 8 files changed, 23 insertions(+), 281 deletions(-) rename src/main/java/de/hysky/skyblocker/skyblock/{ => fancybars}/FancyStatusBars.java (57%) diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index 6d86c88da9..e0815eee66 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -25,6 +25,7 @@ import de.hysky.skyblocker.skyblock.end.EnderNodes; import de.hysky.skyblocker.skyblock.end.TheEnd; import de.hysky.skyblocker.skyblock.entity.MobBoundingBoxes; +import de.hysky.skyblocker.skyblock.fancybars.FancyStatusBars; import de.hysky.skyblocker.skyblock.garden.FarmingHud; import de.hysky.skyblocker.skyblock.garden.LowerSensitivity; import de.hysky.skyblocker.skyblock.garden.VisitorHelper; diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index 20124e4bef..28e96a5012 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java @@ -163,9 +163,6 @@ public static class General { @SerialEntry public boolean fancyCraftingTable = true; - @SerialEntry - public boolean oldBars = false; - @SerialEntry public boolean backpackPreviewWithoutShift = false; @@ -307,42 +304,6 @@ public String toString() { public static class Bars { @SerialEntry public boolean enableBars = true; - - @SerialEntry - public BarPositions barPositions = new BarPositions(); - } - - public static class BarPositions { - @SerialEntry - public BarPosition healthBarPosition = BarPosition.LAYER1; - - @SerialEntry - public BarPosition manaBarPosition = BarPosition.LAYER1; - - @SerialEntry - public BarPosition defenceBarPosition = BarPosition.LAYER1; - - @SerialEntry - public BarPosition experienceBarPosition = BarPosition.LAYER1; - - } - - public enum BarPosition { - LAYER1, LAYER2, RIGHT, NONE; - - @Override - public String toString() { - return I18n.translate("text.autoconfig.skyblocker.option.general.bars.barpositions." + name()); - } - - public int toInt() { - return switch (this) { - case LAYER1 -> 0; - case LAYER2 -> 1; - case RIGHT -> 2; - case NONE -> -1; - }; - } } public static class Experiments { diff --git a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java index 37faaf256f..77627242a8 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java @@ -28,13 +28,6 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig newValue -> config.general.enableTips = newValue) .controller(ConfigUtils::createBooleanController) .build()) - .option(Option.createBuilder() - .name(Text.literal("old bars")) - .binding(defaults.general.oldBars, - () -> config.general.oldBars, - newValue -> config.general.oldBars = newValue) - .controller(ConfigUtils::createBooleanController) - .build()) .option(Option.createBuilder() .name(Text.translatable("text.autoconfig.skyblocker.option.general.acceptReparty")) .binding(defaults.general.acceptReparty, @@ -157,11 +150,6 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig //Fancy Bars .group(OptionGroup.createBuilder() - .option(ButtonOption.createBuilder() - .name(Text.translatable("skyblocker.bars.config.openScreen")) - .text(Text.translatable("text.skyblocker.open")) - .action((screen, opt) -> MinecraftClient.getInstance().setScreen(new StatusBarsConfigScreen())) - .build()) .name(Text.translatable("text.autoconfig.skyblocker.option.general.bars")) .collapsed(true) .option(Option.createBuilder() @@ -171,33 +159,10 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig newValue -> config.general.bars.enableBars = newValue) .controller(ConfigUtils::createBooleanController) .build()) - .option(Option.createBuilder() - .name(Text.translatable("text.autoconfig.skyblocker.option.general.bars.barpositions.healthBarPosition")) - .binding(defaults.general.bars.barPositions.healthBarPosition, - () -> config.general.bars.barPositions.healthBarPosition, - newValue -> config.general.bars.barPositions.healthBarPosition = newValue) - .controller(ConfigUtils::createEnumCyclingListController) - .build()) - .option(Option.createBuilder() - .name(Text.translatable("text.autoconfig.skyblocker.option.general.bars.barpositions.manaBarPosition")) - .binding(defaults.general.bars.barPositions.manaBarPosition, - () -> config.general.bars.barPositions.manaBarPosition, - newValue -> config.general.bars.barPositions.manaBarPosition = newValue) - .controller(ConfigUtils::createEnumCyclingListController) - .build()) - .option(Option.createBuilder() - .name(Text.translatable("text.autoconfig.skyblocker.option.general.bars.barpositions.defenceBarPosition")) - .binding(defaults.general.bars.barPositions.defenceBarPosition, - () -> config.general.bars.barPositions.defenceBarPosition, - newValue -> config.general.bars.barPositions.defenceBarPosition = newValue) - .controller(ConfigUtils::createEnumCyclingListController) - .build()) - .option(Option.createBuilder() - .name(Text.translatable("text.autoconfig.skyblocker.option.general.bars.barpositions.experienceBarPosition")) - .binding(defaults.general.bars.barPositions.experienceBarPosition, - () -> config.general.bars.barPositions.experienceBarPosition, - newValue -> config.general.bars.barPositions.experienceBarPosition = newValue) - .controller(ConfigUtils::createEnumCyclingListController) + .option(ButtonOption.createBuilder() + .name(Text.translatable("skyblocker.bars.config.openScreen")) + .text(Text.translatable("text.skyblocker.open")) + .action((screen, opt) -> MinecraftClient.getInstance().setScreen(new StatusBarsConfigScreen())) .build()) .build()) diff --git a/src/main/java/de/hysky/skyblocker/mixin/InGameHudMixin.java b/src/main/java/de/hysky/skyblocker/mixin/InGameHudMixin.java index 75c516df71..b0970b4bc2 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/InGameHudMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixin/InGameHudMixin.java @@ -5,7 +5,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfigManager; -import de.hysky.skyblocker.skyblock.FancyStatusBars; +import de.hysky.skyblocker.skyblock.fancybars.FancyStatusBars; import de.hysky.skyblocker.skyblock.dungeon.DungeonMap; import de.hysky.skyblocker.skyblock.dungeon.DungeonScore; import de.hysky.skyblocker.skyblock.dungeon.DungeonScoreHUD; diff --git a/src/main/java/de/hysky/skyblocker/mixin/WindowMixin.java b/src/main/java/de/hysky/skyblocker/mixin/WindowMixin.java index 92ca967d12..474b2577ef 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/WindowMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixin/WindowMixin.java @@ -1,6 +1,6 @@ package de.hysky.skyblocker.mixin; -import de.hysky.skyblocker.skyblock.FancyStatusBars; +import de.hysky.skyblocker.skyblock.fancybars.FancyStatusBars; import net.minecraft.client.util.Window; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java similarity index 57% rename from src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java rename to src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java index 306c24568a..9a9dc391ed 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java @@ -1,24 +1,18 @@ -package de.hysky.skyblocker.skyblock; +package de.hysky.skyblocker.skyblock.fancybars; import com.google.gson.JsonObject; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfigManager; -import de.hysky.skyblocker.skyblock.fancybars.BarGrid; -import de.hysky.skyblocker.skyblock.fancybars.BarPositioner; -import de.hysky.skyblocker.skyblock.fancybars.StatusBar; -import de.hysky.skyblocker.skyblock.fancybars.StatusBarsConfigScreen; +import de.hysky.skyblocker.skyblock.StatusBarTracker; import de.hysky.skyblocker.utils.Utils; -import de.hysky.skyblocker.utils.render.RenderHelper; import de.hysky.skyblocker.utils.scheduler.Scheduler; import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.ScreenPos; import net.minecraft.client.texture.Sprite; -import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.util.math.MathHelper; @@ -39,29 +33,13 @@ import java.util.function.Supplier; public class FancyStatusBars { - private static final Identifier BARS = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/bars.png"); 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 OldStatusBar[] bars = new OldStatusBar[]{ - new OldStatusBar(0, 16733525, 2, new Color[]{new Color(255, 0, 0), new Color(255, 220, 0)}), // Health Bar - new OldStatusBar(1, 5636095, 2, new Color[]{new Color(0, 255, 255), new Color(180, 0, 255)}), // Intelligence Bar - new OldStatusBar(2, 12106180, 1, new Color[]{new Color(255, 255, 255)}), // Defence Bar - new OldStatusBar(3, 8453920, 1, new Color[]{new Color(100, 220, 70)}), // Experience Bar - }; - - // Positions to show the bars - // 0: Hotbar Layer 1, 1: Hotbar Layer 2, 2: Right of hotbar - // Anything outside the set values hides the bar - private final int[] anchorsX = new int[3]; - private final int[] anchorsY = new int[3]; - public static BarPositioner barPositioner = new BarPositioner(); - @Deprecated(forRemoval = true) - public static BarGrid barGrid = new BarGrid(); public static Map statusBars = new HashMap<>(); public static void init() { @@ -260,16 +238,7 @@ public static void updatePositions() { } } - public FancyStatusBars() { - moveBar(0, 0); - moveBar(1, 0); - moveBar(2, 0); - moveBar(3, 0); - } - - private int fill(int value, int max) { - return (100 * value) / max; - } + public FancyStatusBars() {} private static final Identifier BAR_FILL = new Identifier(SkyblockerMod.NAMESPACE, "bars/bar_fill"); private static final Identifier BAR_BACK = new Identifier(SkyblockerMod.NAMESPACE, "bars/bar_back"); @@ -280,166 +249,21 @@ public boolean render(DrawContext context, int scaledWidth, int scaledHeight) { if (!SkyblockerConfigManager.get().general.bars.enableBars || player == null || Utils.isInTheRift()) return false; - if (!SkyblockerConfigManager.get().general.oldBars) { - Collection barCollection = statusBars.values(); - for (StatusBar value : barCollection) { - value.render(context, -1, -1, client.getLastFrameDuration()); - } - for (StatusBar statusBar : barCollection) { - if (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").updateValues(intelligence.value() / (float) intelligence.max(), intelligence.overflow() / (float) intelligence.max(), intelligence.value()); - int defense = statusBarTracker.getDefense(); - statusBars.get("defense").updateValues(defense / (defense + 100.f), 0, defense); - statusBars.get("experience").updateValues(player.experienceProgress, 0, player.experienceLevel); - return true; - } - anchorsX[0] = scaledWidth / 2 - 91; - anchorsY[0] = scaledHeight - 33; - anchorsX[1] = anchorsX[0]; - anchorsY[1] = anchorsY[0] - 10; - anchorsX[2] = (scaledWidth / 2 + 91) + 2; - anchorsY[2] = scaledHeight - 16; - - bars[0].update(statusBarTracker.getHealth()); - bars[1].update(statusBarTracker.getMana()); - int def = statusBarTracker.getDefense(); - bars[2].fill[0] = fill(def, def + 100); - bars[2].text = def; - bars[3].fill[0] = (int) (100 * player.experienceProgress); - bars[3].text = player.experienceLevel; - - // Update positions of bars from config - for (int i = 0; i < 4; i++) { - int configAnchorNum = switch (i) { - case 0 -> SkyblockerConfigManager.get().general.bars.barPositions.healthBarPosition.toInt(); - case 1 -> SkyblockerConfigManager.get().general.bars.barPositions.manaBarPosition.toInt(); - case 2 -> SkyblockerConfigManager.get().general.bars.barPositions.defenceBarPosition.toInt(); - case 3 -> SkyblockerConfigManager.get().general.bars.barPositions.experienceBarPosition.toInt(); - default -> 0; - }; - - if (bars[i].anchorNum != configAnchorNum) - moveBar(i, configAnchorNum); - } - - for (var bar : bars) { - bar.draw(context); + Collection barCollection = statusBars.values(); + for (StatusBar value : barCollection) { + value.render(context, -1, -1, client.getLastFrameDuration()); } - for (var bar : bars) { - bar.drawText(context); + for (StatusBar statusBar : barCollection) { + if (statusBar.showText()) statusBar.renderText(context); } - MatrixStack matrices = context.getMatrices(); - matrices.push(); - matrices.translate(50, 50, 0); - matrices.scale(2, 2, 1); - context.drawSprite(0, 0, 0, 60, 5, SUPPLIER.get(), 1, 0.25f, 0.25f, 1); - matrices.pop(); + 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").updateValues(intelligence.value() / (float) intelligence.max(), intelligence.overflow() / (float) intelligence.max(), intelligence.value()); + int defense = statusBarTracker.getDefense(); + statusBars.get("defense").updateValues(defense / (defense + 100.f), 0, defense); + statusBars.get("experience").updateValues(player.experienceProgress, 0, player.experienceLevel); return true; - } - - public void moveBar(int bar, int location) { - // Set the bar to the new anchor - bars[bar].anchorNum = location; - - // Count how many bars are in each location - int layer1Count = 0, layer2Count = 0; - for (int i = 0; i < 4; i++) { - switch (bars[i].anchorNum) { - case 0 -> layer1Count++; - case 1 -> layer2Count++; - } - } - - // Set the bars width and offsetX according to their anchor and how many bars are on that layer - int adjustedLayer1Count = 0, adjustedLayer2Count = 0, adjustedRightCount = 0; - for (int i = 0; i < 4; i++) { - switch (bars[i].anchorNum) { - case 0 -> { - bars[i].bar_width = (172 - ((layer1Count - 1) * 11)) / layer1Count; - bars[i].offsetX = adjustedLayer1Count * (bars[i].bar_width + 11 + (layer1Count == 3 ? 0 : 1)); - adjustedLayer1Count++; - } - case 1 -> { - bars[i].bar_width = (172 - ((layer2Count - 1) * 11)) / layer2Count; - bars[i].offsetX = adjustedLayer2Count * (bars[i].bar_width + 11 + (layer2Count == 3 ? 0 : 1)); - adjustedLayer2Count++; - } - case 2 -> { - bars[i].bar_width = 50; - bars[i].offsetX = adjustedRightCount * (50 + 11); - adjustedRightCount++; - } - } - } - } - - private class OldStatusBar { - public final int[] fill; - private final Color[] colors; - public int offsetX; - private final int v; - private final int text_color; - public int anchorNum; - public int bar_width; - public Object text; - - private OldStatusBar(int i, int textColor, int fillNum, Color[] colors) { - this.v = i * 9; - this.text_color = textColor; - this.fill = new int[fillNum]; - this.fill[0] = 100; - this.anchorNum = 0; - this.text = ""; - this.colors = colors; - } - - public void update(StatusBarTracker.Resource resource) { - int max = resource.max(); - int val = resource.value(); - this.fill[0] = fill(val, max); - this.fill[1] = fill(resource.overflow(), max); - this.text = val; } - - public void draw(DrawContext context) { - // Dont draw if anchorNum is outside of range - if (anchorNum < 0 || anchorNum > 2) return; - - // Draw the icon for the bar - context.drawTexture(BARS, anchorsX[anchorNum] + offsetX, anchorsY[anchorNum], 0, v, 9, 9); - - // Draw the background for the bar - context.drawGuiTexture(BAR_BACK, anchorsX[anchorNum] + offsetX + 10, anchorsY[anchorNum] + 1, bar_width, 7); - - // Draw the filled part of the bar - for (int i = 0; i < fill.length; i++) { - int fill_width = this.fill[i] * (bar_width - 2) / 100; - if (fill_width >= 1) { - RenderHelper.renderNineSliceColored(context, BAR_FILL, anchorsX[anchorNum] + offsetX + 11, anchorsY[anchorNum] + 2, fill_width, 5, colors[i]); - } - } - } - - public void drawText(DrawContext context) { - // Dont draw if anchorNum is outside of range - if (anchorNum < 0 || anchorNum > 2) return; - - TextRenderer textRenderer = client.textRenderer; - String text = this.text.toString(); - int x = anchorsX[anchorNum] + this.offsetX + 11 + (bar_width - textRenderer.getWidth(text)) / 2; - int y = anchorsY[anchorNum] - 3; - - final int[] offsets = new int[]{-1, 1}; - for (int i : offsets) { - context.drawText(textRenderer, text, x + i, y, 0, false); - context.drawText(textRenderer, text, x, y + i, 0, false); - } - context.drawText(textRenderer, text, x, y, text_color, false); - } - } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java index 7c1aa71b18..4d23dc079e 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java @@ -1,7 +1,6 @@ package de.hysky.skyblocker.skyblock.fancybars; import de.hysky.skyblocker.mixin.accessor.WindowAccessor; -import de.hysky.skyblocker.skyblock.FancyStatusBars; import it.unimi.dsi.fastutil.Pair; import it.unimi.dsi.fastutil.objects.ObjectBooleanMutablePair; import it.unimi.dsi.fastutil.objects.ObjectObjectMutablePair; diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index e28b23166d..63b959e5d7 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -26,14 +26,6 @@ "text.autoconfig.skyblocker.option.general.bars": "Health, Mana, Defence & XP Bars", "text.autoconfig.skyblocker.option.general.bars.enableBars": "Enable Bars", "text.autoconfig.skyblocker.option.general.bars.barpositions": "Configure Bar Positions", - "text.autoconfig.skyblocker.option.general.bars.barpositions.LAYER1": "Layer 1", - "text.autoconfig.skyblocker.option.general.bars.barpositions.LAYER2": "Layer 2", - "text.autoconfig.skyblocker.option.general.bars.barpositions.RIGHT": "Right", - "text.autoconfig.skyblocker.option.general.bars.barpositions.NONE": "Disabled", - "text.autoconfig.skyblocker.option.general.bars.barpositions.healthBarPosition": "Health Bar Position", - "text.autoconfig.skyblocker.option.general.bars.barpositions.manaBarPosition": "Mana Bar Position", - "text.autoconfig.skyblocker.option.general.bars.barpositions.defenceBarPosition": "Defence Bar Position", - "text.autoconfig.skyblocker.option.general.bars.barpositions.experienceBarPosition": "Experience Bar Position", "text.autoconfig.skyblocker.option.general.experiments": "Experiments Solver", "text.autoconfig.skyblocker.option.general.experiments.enableChronomatronSolver": "Enable Chronomatron Solver", "text.autoconfig.skyblocker.option.general.experiments.enableSuperpairsSolver": "Enable Superpairs Solver", From 313657ac022186c323b2c3045bb4741e742c8427 Mon Sep 17 00:00:00 2001 From: vicisacat Date: Wed, 17 Apr 2024 23:29:03 +0200 Subject: [PATCH 12/25] remove unused fields --- .../hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java | 4 ---- 1 file changed, 4 deletions(-) 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 9a9dc391ed..1b96f6528b 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java @@ -240,10 +240,6 @@ public static void updatePositions() { public FancyStatusBars() {} - private static final Identifier BAR_FILL = new Identifier(SkyblockerMod.NAMESPACE, "bars/bar_fill"); - private static final Identifier BAR_BACK = new Identifier(SkyblockerMod.NAMESPACE, "bars/bar_back"); - private static final Supplier SUPPLIER = () -> MinecraftClient.getInstance().getGuiAtlasManager().getSprite(BAR_FILL); - public boolean render(DrawContext context, int scaledWidth, int scaledHeight) { var player = client.player; if (!SkyblockerConfigManager.get().general.bars.enableBars || player == null || Utils.isInTheRift()) From 61364b02bd2d7dfbbf351c8e3b296d0080e83e41 Mon Sep 17 00:00:00 2001 From: vicisacat Date: Wed, 17 Apr 2024 23:29:30 +0200 Subject: [PATCH 13/25] remove unused imports --- .../de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java | 2 -- 1 file changed, 2 deletions(-) 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 1b96f6528b..ab72cc6deb 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java @@ -12,7 +12,6 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.ScreenPos; -import net.minecraft.client.texture.Sprite; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.util.math.MathHelper; @@ -30,7 +29,6 @@ import java.util.*; import java.util.List; import java.util.concurrent.CompletableFuture; -import java.util.function.Supplier; public class FancyStatusBars { private static final Path FILE = SkyblockerMod.CONFIG_DIR.resolve("status_bars.json"); From 67ca667c3d796d6796a374050dd0ddcdcdade4df Mon Sep 17 00:00:00 2001 From: vicisacat Date: Thu, 18 Apr 2024 14:16:09 +0200 Subject: [PATCH 14/25] remove WindowAccessor.java added some null checks --- .../mixin/accessor/WindowAccessor.java | 11 ------- .../fancybars/StatusBarsConfigScreen.java | 29 +++++++++---------- src/main/resources/skyblocker.mixins.json | 1 - 3 files changed, 14 insertions(+), 27 deletions(-) delete mode 100644 src/main/java/de/hysky/skyblocker/mixin/accessor/WindowAccessor.java diff --git a/src/main/java/de/hysky/skyblocker/mixin/accessor/WindowAccessor.java b/src/main/java/de/hysky/skyblocker/mixin/accessor/WindowAccessor.java deleted file mode 100644 index ffbf34879a..0000000000 --- a/src/main/java/de/hysky/skyblocker/mixin/accessor/WindowAccessor.java +++ /dev/null @@ -1,11 +0,0 @@ -package de.hysky.skyblocker.mixin.accessor; - -import net.minecraft.client.util.Window; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(Window.class) -public interface WindowAccessor { - @Accessor("handle") - long getHandle(); -} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java index 4d23dc079e..00231ec8d6 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java @@ -1,6 +1,5 @@ package de.hysky.skyblocker.skyblock.fancybars; -import de.hysky.skyblocker.mixin.accessor.WindowAccessor; import it.unimi.dsi.fastutil.Pair; import it.unimi.dsi.fastutil.objects.ObjectBooleanMutablePair; import it.unimi.dsi.fastutil.objects.ObjectObjectMutablePair; @@ -12,6 +11,7 @@ import net.minecraft.client.gui.screen.PopupScreen; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.util.Window; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import org.jetbrains.annotations.Nullable; @@ -28,7 +28,7 @@ public class StatusBarsConfigScreen extends Screen { public static final long RESIZE_CURSOR = GLFW.glfwCreateStandardCursor(GLFW.GLFW_HRESIZE_CURSOR); - private final Map meaningFullName = new HashMap<>(); + private final Map rectToBarLocation = new HashMap<>(); private static final int HOTBAR_WIDTH = 182; private @Nullable StatusBar cursorBar = null; @@ -50,7 +50,6 @@ public StatusBarsConfigScreen() { // prioritize left and right cuz they are much smaller space than up and down private static final NavigationDirection[] DIRECTION_CHECK_ORDER = new NavigationDirection[]{NavigationDirection.LEFT, NavigationDirection.RIGHT, NavigationDirection.UP, NavigationDirection.DOWN}; - @SuppressWarnings("UnreachableCode") // IntelliJ big stupid @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { /*for (ScreenRect screenRect : meaningFullName.keySet()) { @@ -62,19 +61,19 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { ScreenRect mouseRect = new ScreenRect(new ScreenPos(mouseX - 1, mouseY - 1), 3, 3); assert client != null; - WindowAccessor window = (WindowAccessor) (Object) client.getWindow(); - assert window != null; + Window window = client.getWindow(); if (cursorBar != null) { cursorBar.renderCursor(context, mouseX, mouseY, delta); boolean inserted = false; rectLoop: - for (ScreenRect screenRect : meaningFullName.keySet()) { + for (ScreenRect screenRect : rectToBarLocation.keySet()) { for (NavigationDirection direction : DIRECTION_CHECK_ORDER) { boolean overlaps = screenRect.getBorder(direction).add(direction).overlaps(mouseRect); if (overlaps) { - BarLocation barSnap = meaningFullName.get(screenRect); + BarLocation barSnap = rectToBarLocation.get(screenRect); + if (barSnap.barAnchor() == null) break; if (direction.getAxis().equals(NavigationAxis.VERTICAL)) { int neighborInsertY = getNeighborInsertY(barSnap, !direction.isPositive()); if (!currentInsertLocation.equals(barSnap.barAnchor(), barSnap.x(), neighborInsertY)) { @@ -123,8 +122,8 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { BarLocation left = resizedBars.left(); BarLocation right = resizedBars.right(); - boolean hasRight = !right.equals(BarLocation.NULL); - boolean hasLeft = !left.equals(BarLocation.NULL); + boolean hasRight = right.barAnchor() != null; + boolean hasLeft = left.barAnchor() != null; BarPositioner.BarAnchor barAnchor; if (!hasRight) { barAnchor = left.barAnchor(); @@ -186,12 +185,13 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { } else { // hovering bars rectLoop: - for (ScreenRect screenRect : meaningFullName.keySet()) { + for (ScreenRect screenRect : rectToBarLocation.keySet()) { for (NavigationDirection direction : new NavigationDirection[]{NavigationDirection.LEFT, NavigationDirection.RIGHT}) { boolean overlaps = screenRect.getBorder(direction).add(direction).overlaps(mouseRect); if (overlaps && !editBarWidget.isMouseOver(mouseX, mouseY)) { - BarLocation barLocation = meaningFullName.get(screenRect); + BarLocation barLocation = rectToBarLocation.get(screenRect); + if (barLocation.barAnchor() == null) break; boolean right = direction.equals(NavigationDirection.RIGHT); // can't resize on the edge of a target size row! if (barLocation.barAnchor().getSizeRule().isTargetSize() && !FancyStatusBars.barPositioner.hasNeighbor(barLocation.barAnchor(), barLocation.y(), barLocation.x(), right)) { @@ -272,7 +272,6 @@ private static void checkNullAnchor(Iterable bars) { } } - @SuppressWarnings("UnreachableCode") @Override public void removed() { super.removed(); @@ -280,7 +279,7 @@ public void removed() { if (cursorBar != null) cursorBar.ghost = false; FancyStatusBars.updatePositions(); assert client != null; - GLFW.glfwSetCursor(((WindowAccessor) (Object) client.getWindow()).getHandle(), 0); + GLFW.glfwSetCursor(client.getWindow().getHandle(), 0); FancyStatusBars.saveBarConfig(); } @@ -309,10 +308,10 @@ private void onBarClick(StatusBar statusBar, int button, int mouseX, int mouseY) } private void updateScreenRects() { - meaningFullName.clear(); + rectToBarLocation.clear(); FancyStatusBars.statusBars.values().forEach(statusBar1 -> { if (statusBar1.anchor == null) return; - meaningFullName.put( + rectToBarLocation.put( new ScreenRect(new ScreenPos(statusBar1.getX(), statusBar1.getY()), statusBar1.getWidth(), statusBar1.getHeight()), BarLocation.of(statusBar1)); }); diff --git a/src/main/resources/skyblocker.mixins.json b/src/main/resources/skyblocker.mixins.json index 261b707362..8169c0c4d6 100644 --- a/src/main/resources/skyblocker.mixins.json +++ b/src/main/resources/skyblocker.mixins.json @@ -50,7 +50,6 @@ "accessor.ScreenAccessor", "accessor.SkullBlockEntityAccessor", "accessor.SlotAccessor", - "accessor.WindowAccessor", "accessor.WorldRendererAccessor", "discordipc.ConnectionMixin" ], From 25032b8804e00343a0f0b7fec774ce0954d2c88d Mon Sep 17 00:00:00 2001 From: vicisacat Date: Thu, 18 Apr 2024 22:14:15 +0200 Subject: [PATCH 15/25] add padding between bars to make it look less stupid --- .../skyblock/fancybars/FancyStatusBars.java | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) 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 ab72cc6deb..0595dda940 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java @@ -211,21 +211,35 @@ public static void updatePositions() { widthPerSize = sizeRule.widthPerSize(); int currSize = 0; - for (int i = 0; i < barRow.size(); i++) { + 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 = MathHelper.clamp(statusBar.size, sizeRule.minSize(), sizeRule.maxSize()); float x = barAnchor.isRight() ? anchorPosition.x() + currSize * widthPerSize : anchorPosition.x() - currSize * widthPerSize - statusBar.size * widthPerSize; - statusBar.setX((int) x); + 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((int) (statusBar.size * widthPerSize)); + statusBar.setWidth(MathHelper.floor(statusBar.size * widthPerSize) - lessWidth); currSize += statusBar.size; statusBar.gridX = i; statusBar.gridY = row; From 007c58424de0bc44cca9faf77185e0ce9e7b2234 Mon Sep 17 00:00:00 2001 From: vicisacat Date: Thu, 18 Apr 2024 22:24:28 +0200 Subject: [PATCH 16/25] formatting and things fix silly intelliJ refactoring random strings delete unused BarGrid.java why is this even here still --- .../hysky/skyblocker/mixin/WindowMixin.java | 2 +- .../mixin/accessor/DrawContextInvoker.java | 1 + .../skyblocker/skyblock/chat/ChatRule.java | 2 +- .../dungeon/secrets/DungeonMapUtils.java | 2 +- .../skyblock/fancybars/BarGrid.java | 136 ------------------ .../skyblock/fancybars/BarPositioner.java | 6 +- .../skyblock/fancybars/EditBarColorPopup.java | 2 +- .../skyblock/fancybars/FancyStatusBars.java | 4 +- .../skyblock/fancybars/StatusBar.java | 4 +- .../fancybars/StatusBarsConfigScreen.java | 1 - .../searchoverlay/SearchOverManager.java | 2 +- 11 files changed, 11 insertions(+), 151 deletions(-) delete mode 100644 src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java diff --git a/src/main/java/de/hysky/skyblocker/mixin/WindowMixin.java b/src/main/java/de/hysky/skyblocker/mixin/WindowMixin.java index 474b2577ef..481a70a635 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/WindowMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixin/WindowMixin.java @@ -10,7 +10,7 @@ @Mixin(Window.class) public class WindowMixin { @Inject(method = "setScaleFactor", at = @At("TAIL")) - public void onScaleFactorChange(double scaleFactor, CallbackInfo ci) { + public void skyblocker$onScaleFactorChange(double scaleFactor, CallbackInfo ci) { FancyStatusBars.updatePositions(); } } diff --git a/src/main/java/de/hysky/skyblocker/mixin/accessor/DrawContextInvoker.java b/src/main/java/de/hysky/skyblocker/mixin/accessor/DrawContextInvoker.java index bb201dce85..9c14fdc667 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/accessor/DrawContextInvoker.java +++ b/src/main/java/de/hysky/skyblocker/mixin/accessor/DrawContextInvoker.java @@ -15,6 +15,7 @@ public interface DrawContextInvoker { @Invoker void invokeDrawTooltip(TextRenderer textRenderer, List components, int x, int y, TooltipPositioner positioner); + @Invoker void invokeDrawTexturedQuad(Identifier texture, int x1, int x2, int y1, int y2, int z, float u1, float u2, float v1, float v2, float red, float green, float blue, float alpha); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/chat/ChatRule.java b/src/main/java/de/hysky/skyblocker/skyblock/chat/ChatRule.java index 65cbde5baa..34cc635236 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/chat/ChatRule.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/chat/ChatRule.java @@ -235,7 +235,7 @@ protected Boolean isMatch(String inputString) { String rawLocation = Utils.getLocationRaw(); Boolean isLocationValid = null; - for (String validLocation : validLocations.replace(" ", "").toLowerCase().split(",")) {//the locations are raw locations targetSize by "," and start with ! if not locations + for (String validLocation : validLocations.replace(" ", "").toLowerCase().split(",")) {//the locations are raw locations split by "," and start with ! if not locations String rawValidLocation = ChatRulesHandler.locations.get(validLocation.replace("!","")); if (rawValidLocation == null) continue; if (validLocation.startsWith("!")) {//not location diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java index 3d37302500..617e709474 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java @@ -117,7 +117,7 @@ public static int getMapRoomSize(MapState map, Vector2ic mapEntrancePos) { * @param mapEntrancePos the map position of the top left corner of the entrance * @param mapRoomSize the size of a room on the map * @return the map position of the top left corner of the room the player is in - * @implNote {@code mapPos} is shifted by 2 so room borders are evenly targetSize. + * @implNote {@code mapPos} is shifted by 2 so room borders are evenly split. * {@code mapPos} is then shifted by {@code offset} to align the top left most room at (0, 0) * so subtracting the modulo will give the top left corner of the room shifted by {@code offset}. * Finally, {@code mapPos} is shifted back by {@code offset} to its intended position. diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java deleted file mode 100644 index 384250f9c5..0000000000 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarGrid.java +++ /dev/null @@ -1,136 +0,0 @@ -package de.hysky.skyblocker.skyblock.fancybars; - -import java.util.LinkedList; -import java.util.List; - -public class BarGrid { - private final LinkedList> top = new LinkedList<>(); - private final LinkedList> bottomLeft = new LinkedList<>(); - private final LinkedList> bottomRight = new LinkedList<>(); - - public BarGrid() {} - - public void add(int row, StatusBar bar, boolean right) { - if (row > 0) - top.get(row).add(bar); - else if (row < 0) { - if (right) { - bottomRight.get(Math.abs(row)).add(bar); - } else { - bottomLeft.get(Math.abs(row)).add(bar); - } - } - } - - public void add(int x, int y, StatusBar bar) { - if (y > 0) { - if (x < 1) throw new IllegalArgumentException("x can't be negative, x: " + x); - LinkedList statusBars = top.get(y-1); - statusBars.add(Math.min(x-1, statusBars.size()), bar); - bar.gridY = y; - bar.gridX = statusBars.indexOf(bar)+1; - } else if (y < 0) { - LinkedList statusBars = (x < 0? bottomLeft: bottomRight).get(Math.abs(y)-1); - statusBars.add(Math.min(Math.abs(x)-1, statusBars.size()), bar); - bar.gridY = y; - bar.gridX = (int) ((statusBars.indexOf(bar)+1) * Math.signum(x)); - } - } - - public List getRow(int row, boolean right) { - if (row > 0) { - return top.get(row-1); - } else { - return (right ? bottomRight: bottomLeft).get(Math.abs(row)-1); - } - } - - public void addRow(int row, boolean right) { - if (row>0) { - top.add(row-1, new LinkedList<>()); - } else if (row<0) { - (right ? bottomRight: bottomLeft).add(Math.abs(row)-1, new LinkedList<>()); - } - } - - public void addRowToEnd(boolean top, boolean right) { - if (top) { - this.top.add(new LinkedList<>()); - } else { - (right ? bottomRight: bottomLeft).add(new LinkedList<>()); - } - } - - public void addToEndOfRow(int row, boolean right, StatusBar bar) { - if (row>0) { - LinkedList statusBars = top.get(row - 1); - statusBars.add(bar); - bar.gridY = row; - bar.gridX = statusBars.indexOf(bar)+1; - } else if (row<0) { - LinkedList statusBars = (right? bottomRight: bottomLeft).get(Math.abs(row)-1); - statusBars.add(bar); - bar.gridY = row; - bar.gridX = (statusBars.indexOf(bar)+1) * (right ? 1: -1); - } - } - - public void remove(int x, int y) { - System.out.println("Removing x: " + x + " y: " + y); - if (y > 0) { - if (x < 1) throw new IllegalArgumentException("x can't be negative, x: " + x); - LinkedList statusBars = top.get(y-1); - StatusBar remove = statusBars.remove(x-1); - for (int i = x-1; i < statusBars.size(); i++) { - statusBars.get(i).gridX--; - } - remove.gridX = 0; - remove.gridY = 0; - if (statusBars.isEmpty()) { - top.remove(y - 1); - for (int i = y-1; i < top.size(); i++) { - for (StatusBar bar : top.get(i)) { - bar.gridY--; - } - } - } - } else if (y < 0) { - LinkedList> bottom = x < 0 ? bottomLeft : bottomRight; - LinkedList statusBars = bottom.get(Math.abs(y)-1); - StatusBar remove = statusBars.remove(Math.abs(x) - 1); - for (int i = Math.abs(x)-1; i < statusBars.size(); i++) { - statusBars.get(i).gridX--; - } - remove.gridX = 0; - remove.gridY = 0; - if (statusBars.isEmpty()) { - bottom.remove(Math.abs(y) - 1); - for (int i = Math.abs(y)-1; i < bottom.size(); i++) { - for (StatusBar bar : bottom.get(i)) { - bar.gridY--; - } - } - } - } - } - - public boolean coordinatesExist(int x, int y) { - if (x == 0 || y == 0) return false; - if (y > 0) { - if (y > getTopSize()) return false; - return x <= getRow(y, false).size(); - } else { - if (Math.abs(y) > (x < 0 ? getBottomLeftSize(): getBottomRightSize())) return false; - return Math.abs(x) <= getRow(y, x > 0).size(); - } - } - - public StatusBar getBar(int x, int y) { - return getRow(y, x>0).get(Math.abs(x)-1); - } - - public int getTopSize() {return top.size();} - - public int getBottomLeftSize() {return bottomLeft.size();} - public int getBottomRightSize() {return bottomRight.size();} -} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarPositioner.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarPositioner.java index 7fde91177d..3b5b865ba3 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarPositioner.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarPositioner.java @@ -175,8 +175,7 @@ public enum BarAnchor { SCREEN_BOTTOM_RIGHT(true, false, ((scaledWidth, scaledHeight) -> new ScreenPos(scaledWidth - 5, scaledHeight - 5)), SizeRule.freeSize(25, 2, 6) - ), - ; + ); private final AnchorPositionProvider positionProvider; private final AnchorHitboxProvider hitboxProvider; @@ -256,8 +255,7 @@ public static List allAnchors() { * @param minSize the minimum (free and target size) * @param maxSize the maximum (free and target size, THIS SHOULD BE THE SAME AS {@code targetSize} FOR {@code isTargetSize = true}) */ - public record SizeRule(boolean isTargetSize, int targetSize, int totalWidth, int widthPerSize, int minSize, - int maxSize) { + public record SizeRule(boolean isTargetSize, int targetSize, int totalWidth, int widthPerSize, int minSize, int maxSize) { public static SizeRule freeSize(int widthPerSize, int minSize, int maxSize) { return new SizeRule(false, -1, -1, widthPerSize, minSize, maxSize); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarColorPopup.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarColorPopup.java index a3ce4e43fc..64e79bab89 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarColorPopup.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarColorPopup.java @@ -105,7 +105,7 @@ protected void appendClickableNarrations(NarrationMessageBuilder builder) { @Override public void setX(int x) { super.setX(x); - textFieldWidget.setX(getX()+16); + textFieldWidget.setX(getX() + 16); } @Override 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 0595dda940..a87871be98 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java @@ -250,8 +250,6 @@ else if (i == rowSize-1) { } } - public FancyStatusBars() {} - public boolean render(DrawContext context, int scaledWidth, int scaledHeight) { var player = client.player; if (!SkyblockerConfigManager.get().general.bars.enableBars || player == null || Utils.isInTheRift()) @@ -273,5 +271,5 @@ public boolean render(DrawContext context, int scaledWidth, int scaledHeight) { statusBars.get("defense").updateValues(defense / (defense + 100.f), 0, defense); statusBars.get("experience").updateValues(player.experienceProgress, 0, player.experienceLevel); return true; - } + } } 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 5ece19340e..8a38be092c 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java @@ -119,7 +119,7 @@ public StatusBar(Identifier icon, Color[] colors, boolean hasOverflow, @Nullable public void render(DrawContext context, int mouseX, int mouseY, float delta) { if (width <= 0) return; // half works lol. only puts transparency on the filler of the bar - if (ghost) context.setShaderColor(1f,1f,1f,0.25f); + if (ghost) context.setShaderColor(1f, 1f, 1f, 0.25f); switch (iconPosition) { case LEFT -> context.drawGuiTexture(icon, x, y, 9, 9); case RIGHT -> context.drawGuiTexture(icon, x + width - 9, y, 9, 9); @@ -134,7 +134,7 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { if (hasOverflow && overflowFill > 0) { RenderHelper.renderNineSliceColored(context, BAR_FILL, barX + 1, y + 2, (int) ((barWith - 2) * overflowFill), 5, colors[1]); } - if (ghost) context.setShaderColor(1f,1f,1f,1f); + if (ghost) context.setShaderColor(1f, 1f, 1f, 1f); //context.drawText(MinecraftClient.getInstance().textRenderer, gridX + " " + gridY + " s:" + size , x, y-9, Colors.WHITE, true); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java index 00231ec8d6..e49cc7feac 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java @@ -23,7 +23,6 @@ import java.util.Map; public class StatusBarsConfigScreen extends Screen { - private static final Identifier HOTBAR_TEXTURE = new Identifier("hud/hotbar"); public static final long RESIZE_CURSOR = GLFW.glfwCreateStandardCursor(GLFW.GLFW_HRESIZE_CURSOR); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/searchoverlay/SearchOverManager.java b/src/main/java/de/hysky/skyblocker/skyblock/searchoverlay/SearchOverManager.java index c5811dd27e..1d740601d0 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/searchoverlay/SearchOverManager.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/searchoverlay/SearchOverManager.java @@ -318,7 +318,7 @@ private static void pushCommand() { } /** - * pushes the ({@link SearchOverManager#search}) to the sign. It needs to targetSize it over two lines without splitting a word + * pushes the ({@link SearchOverManager#search}) to the sign. It needs to split it over two lines without splitting a word */ private static void pushSign() { //splits text into 2 lines max = 30 chars From c6262dcd261ae8088cb2073bcb1413ebbcbb3fb2 Mon Sep 17 00:00:00 2001 From: vicisacat Date: Thu, 18 Apr 2024 22:39:27 +0200 Subject: [PATCH 17/25] remove equals override from BarPositioner.BarLocation --- .../skyblocker/skyblock/fancybars/BarPositioner.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarPositioner.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarPositioner.java index 3b5b865ba3..a72b955ba4 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarPositioner.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarPositioner.java @@ -280,15 +280,6 @@ public static BarLocation of(StatusBar bar) { return new BarLocation(bar.anchor, bar.gridX, bar.gridY); } - @Override - public boolean equals(Object object) { - if (this == object) return true; - if (object == null || getClass() != object.getClass()) return false; - - BarLocation that = (BarLocation) object; - return x == that.x && y == that.y && barAnchor == that.barAnchor; - } - public boolean equals(BarAnchor barAnchor, int x, int y) { return x == this.x && y == this.y && barAnchor == this.barAnchor; } From a8ef82dc26fb6bed83047e4f136f533b6b733385 Mon Sep 17 00:00:00 2001 From: vicisacat Date: Thu, 18 Apr 2024 22:56:10 +0200 Subject: [PATCH 18/25] 1px offset bahahaahahahah --- .../java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8a38be092c..f81098521f 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java @@ -147,7 +147,7 @@ public void updateValues(float fill, float overflowFill, Object text) { public void renderText(DrawContext context) { TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; int barWith = iconPosition.equals(IconPosition.OFF) ? width : width - 10; - int barX = iconPosition.equals(IconPosition.LEFT) ? x + 10 : x; + int barX = iconPosition.equals(IconPosition.LEFT) ? x + 11 : x; String text = this.value.toString(); int x = barX + (barWith - textRenderer.getWidth(text)) / 2; int y = this.y - 3; From de10287482995655bea8850aa364a257e9ce9b29 Mon Sep 17 00:00:00 2001 From: vicisacat Date: Thu, 18 Apr 2024 22:59:15 +0200 Subject: [PATCH 19/25] mention resizing in explanation and add spacing --- .../hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java | 4 ++-- src/main/resources/assets/skyblocker/lang/en_us.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) 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 a87871be98..2f2ec000ea 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java @@ -217,8 +217,8 @@ public static void updatePositions() { 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) { + if (i == 0) lessWidth = 1; + else if (i == rowSize - 1) { lessWidth = 1; offsetX = 1; } else { diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 63b959e5d7..1b81a3f5b6 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -499,7 +499,7 @@ "skyblocker.bars.config.icon": "Icon", "skyblocker.bars.config.openScreen": "Status Bars Config screen", "skyblocker.bars.config.explanationTitle": "What is this?", - "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) or existing bars.\nYou can right click them to edit a bunch of properties.\n\nEverything is saved when you leave", + "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) or existing bars.\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.updaterepository.failed": "§cUpdating local repository failed. Remove files manually and restart game.", From 04396b153a9226be5add8fd7fcb7f6629ec0e520 Mon Sep 17 00:00:00 2001 From: vicisacat Date: Sat, 20 Apr 2024 16:12:28 +0200 Subject: [PATCH 20/25] fix intellij refactor oopsies --- .../hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java | 2 +- .../skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java index d6111f1bba..c8bc1f13ac 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java @@ -352,7 +352,7 @@ private void parsePage(ItemStack stack) { List tooltip = ItemUtils.getNbtTooltips(stack); String str = tooltip.get(0).getString().trim(); str = str.substring(1, str.length() - 1); // remove parentheses - String[] parts = str.split("/"); // targetSize the string + String[] parts = str.split("/"); // split the string currentPage = Integer.parseInt(parts[0].replace(",", "")); // parse current page totalPages = Integer.parseInt(parts[1].replace(",", "")); // parse total } catch (Exception e) { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java index 617e709474..8e0073f731 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java @@ -168,7 +168,7 @@ public static Vector2ic getPhysicalRoomPos(@NotNull Vec3i pos) { * @param x the x position of the coordinate to calculate * @param z the z position of the coordinate to calculate * @return the physical position of the northwest corner of the room the player is in - * @implNote {@code physicalPos} is shifted by 0.5 so room borders are evenly targetSize. + * @implNote {@code physicalPos} is shifted by 0.5 so room borders are evenly split. * {@code physicalPos} is further shifted by 8 because Hypixel offset dungeons by 8 blocks in Skyblock 0.12.3. * Subtracting the modulo gives the northwest corner of the room shifted by 8. Finally, {@code physicalPos} is shifted back by 8 to its intended position. */ From d91367ae8faee90736cc0390bb025f2d71e9560f Mon Sep 17 00:00:00 2001 From: vicisacat Date: Sat, 20 Apr 2024 21:50:39 +0200 Subject: [PATCH 21/25] fetch positions from old config --- .../skyblocker/config/SkyblockerConfig.java | 37 +++++++++++++++++ .../skyblock/fancybars/FancyStatusBars.java | 41 +++++++++++++------ 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index 28e96a5012..e7f1476398 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java @@ -304,6 +304,43 @@ public String toString() { public static class Bars { @SerialEntry public boolean enableBars = true; + + // Kept in for backwards compatibility, remove if needed + @SerialEntry + public OldBarPositions barPositions = new OldBarPositions(); + } + + public static class OldBarPositions { + @SerialEntry + public OldBarPosition healthBarPosition = OldBarPosition.LAYER1; + + @SerialEntry + public OldBarPosition manaBarPosition = OldBarPosition.LAYER1; + + @SerialEntry + public OldBarPosition defenceBarPosition = OldBarPosition.LAYER1; + + @SerialEntry + public OldBarPosition experienceBarPosition = OldBarPosition.LAYER1; + + } + + public enum OldBarPosition { + LAYER1, LAYER2, RIGHT, NONE; + + @Override + public String toString() { + return I18n.translate("text.autoconfig.skyblocker.option.general.bars.barpositions." + name()); + } + + public int toInt() { + return switch (this) { + case LAYER1 -> 0; + case LAYER2 -> 1; + case RIGHT -> 2; + case NONE -> -1; + }; + } } public static class Experiments { 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 2f2ec000ea..009f2e5900 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java @@ -2,6 +2,7 @@ import com.google.gson.JsonObject; import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.config.SkyblockerConfig; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.StatusBarTracker; import de.hysky.skyblocker.utils.Utils; @@ -54,23 +55,17 @@ public static void init() { new Color[]{new Color(100, 230, 70)}, false, new Color(128, 255, 32), Text.translatable("skyblocker.bars.config.experience"))); - // Default positions + // Fetch from old status bar config + int[] counts = new int[3]; // counts for RIGHT, LAYER1, LAYER2 StatusBar health = statusBars.get("health"); - health.anchor = BarPositioner.BarAnchor.HOTBAR_TOP; - health.gridX = 0; - health.gridY = 0; + SkyblockerConfig.OldBarPositions barPositions = SkyblockerConfigManager.get().general.bars.barPositions; + updateBarPosition(health, counts, barPositions.healthBarPosition); StatusBar intelligence = statusBars.get("intelligence"); - intelligence.anchor = BarPositioner.BarAnchor.HOTBAR_TOP; - intelligence.gridX = 1; - intelligence.gridY = 0; + updateBarPosition(intelligence, counts, barPositions.manaBarPosition); StatusBar defense = statusBars.get("defense"); - defense.anchor = BarPositioner.BarAnchor.HOTBAR_RIGHT; - defense.gridX = 0; - defense.gridY = 0; + updateBarPosition(defense, counts, barPositions.defenceBarPosition); StatusBar experience = statusBars.get("experience"); - experience.anchor = BarPositioner.BarAnchor.HOTBAR_TOP; - experience.gridX = 0; - experience.gridY = 1; + updateBarPosition(experience, counts, barPositions.experienceBarPosition); CompletableFuture.supplyAsync(FancyStatusBars::loadBarConfig).thenAccept(object -> { if (object != null) { @@ -110,6 +105,26 @@ public static void init() { .then(ClientCommandManager.literal("bars").executes(Scheduler.queueOpenScreenCommand(StatusBarsConfigScreen::new))))); } + private static void updateBarPosition(StatusBar bar, int[] counts, SkyblockerConfig.OldBarPosition 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() { From 5ebff97c8a403178b4c3ddf6da231e666ddeac7d Mon Sep 17 00:00:00 2001 From: vicisacat Date: Sat, 20 Apr 2024 21:52:01 +0200 Subject: [PATCH 22/25] remove unused things from old bars config --- .../skyblocker/config/SkyblockerConfig.java | 22 ++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index e7f1476398..912636d694 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java @@ -310,6 +310,9 @@ public static class Bars { public OldBarPositions barPositions = new OldBarPositions(); } + /** + * Backwards compat + */ public static class OldBarPositions { @SerialEntry public OldBarPosition healthBarPosition = OldBarPosition.LAYER1; @@ -325,22 +328,11 @@ public static class OldBarPositions { } + /** + * Backwards compat + */ public enum OldBarPosition { - LAYER1, LAYER2, RIGHT, NONE; - - @Override - public String toString() { - return I18n.translate("text.autoconfig.skyblocker.option.general.bars.barpositions." + name()); - } - - public int toInt() { - return switch (this) { - case LAYER1 -> 0; - case LAYER2 -> 1; - case RIGHT -> 2; - case NONE -> -1; - }; - } + LAYER1, LAYER2, RIGHT, NONE } public static class Experiments { From 6807d6eb71030429e8fa9a3abda3d6c7afda05aa Mon Sep 17 00:00:00 2001 From: vicisacat Date: Sat, 20 Apr 2024 22:01:49 +0200 Subject: [PATCH 23/25] fix being able to resize when you shouldn't be able to --- .../skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java index e49cc7feac..d1009a254e 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java @@ -196,6 +196,8 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { if (barLocation.barAnchor().getSizeRule().isTargetSize() && !FancyStatusBars.barPositioner.hasNeighbor(barLocation.barAnchor(), barLocation.y(), barLocation.x(), right)) { break; } + if (!barLocation.barAnchor().getSizeRule().isTargetSize() && barLocation.x() == 0 && barLocation.barAnchor().isRight() != right) + break; resizeHover.first(barLocation); resizeHover.right(right); GLFW.glfwSetCursor(window.getHandle(), RESIZE_CURSOR); From 88ab0fba0fe2ee8f598b977de14a05e44d7ae049 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Sun, 21 Apr 2024 14:15:50 -0400 Subject: [PATCH 24/25] Refactor old bar loading --- .../skyblock/fancybars/FancyStatusBars.java | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) 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 009f2e5900..a960c9afb2 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java @@ -59,13 +59,13 @@ public static void init() { int[] counts = new int[3]; // counts for RIGHT, LAYER1, LAYER2 StatusBar health = statusBars.get("health"); SkyblockerConfig.OldBarPositions barPositions = SkyblockerConfigManager.get().general.bars.barPositions; - updateBarPosition(health, counts, barPositions.healthBarPosition); + loadOldBarPosition(health, counts, barPositions.healthBarPosition); StatusBar intelligence = statusBars.get("intelligence"); - updateBarPosition(intelligence, counts, barPositions.manaBarPosition); + loadOldBarPosition(intelligence, counts, barPositions.manaBarPosition); StatusBar defense = statusBars.get("defense"); - updateBarPosition(defense, counts, barPositions.defenceBarPosition); + loadOldBarPosition(defense, counts, barPositions.defenceBarPosition); StatusBar experience = statusBars.get("experience"); - updateBarPosition(experience, counts, barPositions.experienceBarPosition); + loadOldBarPosition(experience, counts, barPositions.experienceBarPosition); CompletableFuture.supplyAsync(FancyStatusBars::loadBarConfig).thenAccept(object -> { if (object != null) { @@ -91,21 +91,19 @@ public static void init() { saveBarConfig(); GLFW.glfwDestroyCursor(StatusBarsConfigScreen.RESIZE_CURSOR); }); - /*barGrid.addRow(1, false); - barGrid.add(1, 1, statusBars.get("health")); - barGrid.add(2, 1, statusBars.get("intelligence")); - barGrid.addRow(2, false); - barGrid.add(1, 2, statusBars.get("experience")); - barGrid.addRow(-1, true); - barGrid.add(1, -1, statusBars.get("defense"));*/ - //placeBarsInGrid(); ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register( ClientCommandManager.literal(SkyblockerMod.NAMESPACE) .then(ClientCommandManager.literal("bars").executes(Scheduler.queueOpenScreenCommand(StatusBarsConfigScreen::new))))); } - private static void updateBarPosition(StatusBar bar, int[] counts, SkyblockerConfig.OldBarPosition position) { + /** + * Loads the bar position from the old config + * @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 loadOldBarPosition(StatusBar bar, int[] counts, SkyblockerConfig.OldBarPosition position) { switch (position) { case RIGHT: bar.anchor = BarPositioner.BarAnchor.HOTBAR_RIGHT; From c43370daf17ea547f80908cf9391fac1d7756b45 Mon Sep 17 00:00:00 2001 From: Kevin <92656833+kevinthegreat1@users.noreply.github.com> Date: Sun, 21 Apr 2024 15:33:06 -0400 Subject: [PATCH 25/25] Delete src/main/resources/assets/skyblocker/textures/gui/bars.png --- .../assets/skyblocker/textures/gui/bars.png | Bin 9288 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/main/resources/assets/skyblocker/textures/gui/bars.png diff --git a/src/main/resources/assets/skyblocker/textures/gui/bars.png b/src/main/resources/assets/skyblocker/textures/gui/bars.png deleted file mode 100644 index 5ea1f8309deb02eb1aadaddaafa4f3c633032325..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9288 zcmeHNdpuO>A0E?SI=WDbm4vojie}E4IcKKYbx%?#{FIdpW+D|Op_>`qX}hSl-E^^) zMCtO;O{l5Vwp~`pCY!WfL>JU5UBvHu&Wt#yR=3?h_V~=1_dW0XeZJ50yx;fj(_y)r zi(^+r4`DDEU7beSk7F=YpsB)OtHGDg%v}=b%nY`(a|;d#U@%PAM6CJ7`Lvt%lCr~b z;|BHB9=vV!&vAAd4mSG9u@lqmzB`%bJTvj2ZNid7ZL__x@pdO|W<3t6=~rQX)SMk_ zyiD+-Q@!_&-0(!(_=6_bH!ZE(QWsX8DYZ(+PFFcGmQ>b^HaANzzq;diBuh)y{kHC! zpQc%eb;2w3tX6qAJ=WC8Id(N-g)DXoCco-B{KDWW&Agr|NA#U*3?6d^{i=Ga=Plio zPCd$yiI1O;3Cq7dU~bZ(YReQ|-8k{MbMVqr0-%c4l>g~T6r z>NC8utnXY)$h^Lqd9Z$?+B_e|!f3w=1NPpz8B?lm*LOZQt*~dQ%2G%9*F{T-2FBgg z$qnwCEMs92I){y%5YAv|^dvtjjE$RgVMz*SIgFn*P84YvHZxQbJXLHsD>_VUD2@u2 zFc9*N7?KytMG+pK5a2=_=fK4i@`R`e8UnHh7un`;xEvmJr#f$1T>5k5%>W7m81%>w zTmlLjP@0}|70+Q7b#X<|;zLu}M+5=N0e|{{kYoWDDuCxCcoUE^5k@jX;khy%5h@!P znHdJS%84SSJX|OsT1xX*&L@*l7da0;2zkQ@3Y)`KvS{7s5#U}RA0}ZaD#joe+)+#b zA9wYIESu!m2 zA&Mh>4lckY1P?wK)glREKn)Nv0S_ffg9l1ciZsYC`N7v2jNT3HW{H{>#z5dkw*X5)_5!LYzlF;S(627l?6qfv^M^ z%!MLEcmhI1Kp-C@L_9H{hr>4jVi*LWC?>(g91#{k2rv=UECk|#WHKBoi|pe8xR}7m zF@($jY(O>10~09*-b|;MG{XRdKgCI)SU}(-A!(o-1ml5KDs~Ei!}_8m6EHFW zrtxqb6Y)_VkB7J7p%^2n2oM75gMhV0C8&g;E>uhaTU1QtB2WobgpmA!7Fj|Ps1+0q zR3w0Ji~uhQ9)fcT0UAgOBF7axS~39|;4L_Z;zEK0(u81w7?>%Uf-NYdFo zD@8oAtb|bPu#k|gWjL1}pqSq_8G?)X5DrUAtsd0R8-po0a>Yb^LEAvZK5S+Q(%RBg zvJ}Eb;lk$S^8!e&I04WCN+czdp0Y{Wn;<^9>!I4)4{2IMOhoQ7*s@>=YeshvH?>1_`QEW)NdE`#x!Fk33aUce~BhM!Au4#8tb<})VKmgd=G^nVt=1~X~ zVq*A*BLFs3)25}KaYV|3Bt!mQfC9YjeB^BzngUv8Z_Sq)Q_6?E_I~{|uy)TUOpGWF z)Mm|!Bb9WC3U71h)BS7W4QF<9^W$1y7O450d^_te%joSqnn&Kk=*n$h@PV(J=%XEIuh7+?msWB^}_t~j9RC2g?3(9lkd9VwHkt=1OYF5;B_++e=VpR{EEfG$==2z%J)&JYmmODE~93Hca0&N zU+b2p?!ZycF=J2DI^bY5(tMZ2wq5FHo_UPzZZI?dyWJJ32KHCt58gUysFJL;=CEm0 zZ9;5Reu>=#md)kDp`i)a9!@7D7jU~L$IBL8F1^(7YC-k~=+^=rRt zd~`hJsFT#%iRnJ(RAfrZgGBeuF85Dt?x%+wHR~}zxFSw0s4BSKYm&8W__?fzQ$s9w z@`larYGcWs?~pVM!+ORBM@MJs)MZvyYC2TArMTrs3sZQ>96*D+|%)gJcAA|GSaZl z7^ZF5=w+L&JFsBr<;AK)n9 zo$YkynD4%4)t#P7nA;O#o_0N!6+gIeG&_9CZ-fek*av^%cxOC8e_Ohbz=F34QxqVHV!+X6&IE_D$ zza%aq$5(&2n%kJjLfMp;UR@VWi3z(Rldsm0>31^CVB2qPSarXs>b_s&iRjQu4Jq!; z_LShu;^b-8dp7%)x=7{c1~IPn(9>lhI_K0?vSNH*44VJ?(qjE7)d_z64MI#GGPS=o zU8LifblgBb<;m5tR?jLLcIwtvc@c9`H2V8$RTMw&X*4_jTfyrE74H5s3Km!tY<^LG z>Xc6K^r~N9<~R7S?pGc1b8qHdTQ3XN{r~;CwftUL9Eu-{vtGB?cX`GUakXpx62m+- ze?cAr-Z z)w;-HRn>abS69s~EwgO&SUN2H)#QW|H&^QD$y8*U>Rlh6NNvch{;hB6-LkC{LQh<^ zH4Ip4ZNz-am2RrfGl=>oXI}Zpl0$W}+R1#4sJ|+%t&5jm9&LEhTbiwwv@LbAOA0PkSX4-(GS6Gih8Hne&6o7AtR)MiY%m$vWi*`{Hc$ESaK&6E{@7C$c>T z#JsG%bKW?$;E%tGu61)rs`WKk5jr^|Z|mB|(~GMM7sog5j43!$xjxgeV918u=9<~x zWLK9TGaV5m{M|Xl*xvl?h$LV3thyVib4nTuuG>`}&dDlR^C~pG`rd3uPu-2ZXBb_M z^t4$~V0=a|*_DXPxN+~otCy~Q1@6^q4=2n&6JGSXU(9@>6n%PMo_cCojNV1A^!p`i z%0lPLd{|HN8_P}l^%-wsI$7oL{7?<4JWehjTULH$(w1l4r@e^QGPIU5RG2Kb=EpP^ zcea1A_SWKv#4sk?=W0Lo&AE13KicPobe_7>Iz-hk{P^+60oHy!WWOWUI|d=H1xCKk zNdlRvR}ag*w^{aW3HbS_gfPyoe=?l;2st=g&rK`nNWgqO*$kHVAja)^U*#EDCrtz} z>0;|gv-i06-!EnjW|g25|BP=(MX^3$;lC7R_4v^v=}@6GPQGK}-KVVS*}&}P*_epx zky7~%W_mA%hHT&?^L-}!$EX6>&c63TdbYJh*GsM^osm3zm30;~eY2VetK`x6tt0&O zfs9-*>1;S#Gsr9H5Yx}dEvxT?LiW_JR5WCVM|(Xt{z!xW3;*~c{m;XH+`~k(ntlfg X3sw&{FRp?=RA4wcxY+Nt^^5&KE)y4g