From 3581365e654306cf08d0c4284ddfa454befd519d Mon Sep 17 00:00:00 2001 From: vicisacat Date: Sat, 13 Apr 2024 00:00:50 +0200 Subject: ssergorp --- src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java | 3 +++ .../de/hysky/skyblocker/config/categories/GeneralCategory.java | 7 +++++++ 2 files changed, 10 insertions(+) (limited to 'src/main/java/de/hysky/skyblocker/config') diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index 86405f58..20124e4b 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 class SkyblockerConfig { @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 dbfbbb10..0c6a3d75 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 class GeneralCategory { 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, -- cgit From f0ff0b555621f2d7f240bc72ccc1c7667badab6f Mon Sep 17 00:00:00 2001 From: vicisacat Date: Wed, 17 Apr 2024 23:07:49 +0200 Subject: things happened yea rewrote the entire thing to use semi data-driven BarAnchors help button in the config screen --- .../config/categories/GeneralCategory.java | 6 + .../hysky/skyblocker/skyblock/FancyStatusBars.java | 233 +++++++-------- .../skyblock/auction/AuctionBrowserScreen.java | 2 +- .../hysky/skyblocker/skyblock/chat/ChatRule.java | 2 +- .../skyblock/dungeon/secrets/DungeonMapUtils.java | 4 +- .../skyblock/fancybars/BarPositioner.java | 319 +++++++++++++++++++++ .../skyblocker/skyblock/fancybars/StatusBar.java | 27 +- .../skyblock/fancybars/StatusBarsConfigScreen.java | 299 ++++++++++--------- .../skyblock/searchoverlay/SearchOverManager.java | 2 +- .../resources/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 (limited to 'src/main/java/de/hysky/skyblocker/config') 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 0c6a3d75..37faaf25 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 @@ package de.hysky.skyblocker.config.categories; 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 class GeneralCategory { //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 6bf012ff..306c2456 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 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.utils.Utils; @@ -15,6 +16,7 @@ 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; @@ -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 class FancyStatusBars { // 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 class FancyStatusBars { } } } - 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 class FancyStatusBars { //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 class FancyStatusBars { 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 c8bc1f13..d6111f1b 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 @@ public class AuctionBrowserScreen extends AbstractCustomHypixelGUI 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 34cc6352..65cbde5b 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 @@ public class ChatRule { 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 8e0073f7..3d373025 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 class DungeonMapUtils { * @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 class DungeonMapUtils { * @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 00000000..7fde9117 --- /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 ea4a0388..5ece1934 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 class StatusBar implements Widget, Drawable, Element, Selectable { 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 class StatusBar implements Widget, Drawable, Element, Selectable { @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 class StatusBar implements Widget, Drawable, Element, Selectable { 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 class StatusBar implements Widget, Drawable, Element, Selectable { 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 class StatusBar implements Widget, Drawable, Element, Selectable { 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 class StatusBar implements Widget, Drawable, Element, Selectable { .append("x", x) .append("y", y) .append("width", width) + .append("anchor", anchor) .toString(); } @@ -315,11 +319,13 @@ public class StatusBar implements Widget, Drawable, Element, Selectable { 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 class StatusBar implements Widget, Drawable, Element, Selectable { 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 3bcc2011..7c1aa71b 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.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.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 class StatusBarsConfigScreen extends Screen { 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 class StatusBarsConfigScreen extends Screen { 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 class StatusBarsConfigScreen extends Screen { 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 class StatusBarsConfigScreen extends Screen { } } } - 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 class StatusBarsConfigScreen extends Screen { } } - 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 @@ public class StatusBarsConfigScreen extends Screen { 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 @@ public class StatusBarsConfigScreen extends Screen { 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 class StatusBarsConfigScreen extends Screen { 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 @@ public class StatusBarsConfigScreen extends Screen { 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 class StatusBarsConfigScreen extends Screen { @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 1d740601..c5811dd2 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 @@ public class SearchOverManager { } /** - * 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 5921cc95..e28b2316 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.", -- cgit From 28521b8c1457146da6852316c5115afb2e64481c Mon Sep 17 00:00:00 2001 From: vicisacat Date: Wed, 17 Apr 2024 23:28:22 +0200 Subject: remove any mention of old status bars also moved FancyStatusBars.java --- .../java/de/hysky/skyblocker/SkyblockerMod.java | 1 + .../hysky/skyblocker/config/SkyblockerConfig.java | 39 -- .../config/categories/GeneralCategory.java | 43 +- .../de/hysky/skyblocker/mixin/InGameHudMixin.java | 2 +- .../de/hysky/skyblocker/mixin/WindowMixin.java | 2 +- .../hysky/skyblocker/skyblock/FancyStatusBars.java | 445 --------------------- .../skyblock/fancybars/FancyStatusBars.java | 269 +++++++++++++ .../skyblock/fancybars/StatusBarsConfigScreen.java | 1 - .../resources/assets/skyblocker/lang/en_us.json | 8 - 9 files changed, 276 insertions(+), 534 deletions(-) delete mode 100644 src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java (limited to 'src/main/java/de/hysky/skyblocker/config') diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index 6d86c88d..e0815eee 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.BeaconHighlighter; 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 20124e4b..28e96a50 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 class SkyblockerConfig { @SerialEntry public boolean fancyCraftingTable = true; - @SerialEntry - public boolean oldBars = false; - @SerialEntry public boolean backpackPreviewWithoutShift = false; @@ -307,42 +304,6 @@ public class SkyblockerConfig { 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 37faaf25..77627242 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 class GeneralCategory { 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 class GeneralCategory { //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 class GeneralCategory { 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 75c516df..b0970b4b 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.llamalad7.mixinextras.sugar.Local; 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 92ca967d..474b2577 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/FancyStatusBars.java deleted file mode 100644 index 306c2456..00000000 --- a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java +++ /dev/null @@ -1,445 +0,0 @@ -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; -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; -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; -import org.lwjgl.glfw.GLFW; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.awt.*; -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.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; - - 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() { - 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.anchor = BarPositioner.BarAnchor.HOTBAR_TOP; - health.gridX = 0; - health.gridY = 0; - StatusBar intelligence = statusBars.get("intelligence"); - intelligence.anchor = BarPositioner.BarAnchor.HOTBAR_TOP; - intelligence.gridX = 1; - intelligence.gridY = 0; - StatusBar defense = statusBars.get("defense"); - defense.anchor = BarPositioner.BarAnchor.HOTBAR_RIGHT; - defense.gridX = 0; - defense.gridY = 0; - StatusBar experience = statusBars.get("experience"); - experience.anchor = BarPositioner.BarAnchor.HOTBAR_TOP; - experience.gridX = 0; - experience.gridY = 1; - - CompletableFuture.supplyAsync(FancyStatusBars::loadBarConfig).thenAccept(object -> { - if (object != null) { - for (String s : object.keySet()) { - if (statusBars.containsKey(s)) { - try { - statusBars.get(s).loadFromJson(object.get(s).getAsJsonObject()); - } catch (Exception e) { - LOGGER.error("[Skyblocker] Failed to load {} status bar", s, e); - } - } else { - LOGGER.warn("[Skyblocker] Unknown status bar: {}", s); - } - } - } - placeBarsInPositioner(); - configLoaded = true; - }).exceptionally(throwable -> { - LOGGER.error("[Skyblocker] Failed reading status bars config", throwable); - return null; - }); - ClientLifecycleEvents.CLIENT_STOPPING.register((client) -> { - saveBarConfig(); - GLFW.glfwDestroyCursor(StatusBarsConfigScreen.RESIZE_CURSOR); - }); - /*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 boolean configLoaded = false; - - private static void placeBarsInPositioner() { - List original = statusBars.values().stream().toList(); - - 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); - } - } - } - - public static JsonObject loadBarConfig() { - try (BufferedReader reader = Files.newBufferedReader(FILE)) { - return SkyblockerMod.GSON.fromJson(reader, JsonObject.class); - } catch (NoSuchFileException e) { - LOGGER.warn("[Skyblocker] No status bar config file found, using defaults"); - } catch (Exception e) { - LOGGER.error("[Skyblocker] Failed to load status bars config", e); - } - return null; - } - - public static void saveBarConfig() { - JsonObject output = new JsonObject(); - statusBars.forEach((s, statusBar) -> output.add(s, statusBar.toJson())); - try (BufferedWriter writer = Files.newBufferedWriter(FILE)) { - SkyblockerMod.GSON.toJson(output, writer); - LOGGER.info("[Skyblocker] Saved status bars config"); - } catch (IOException e) { - LOGGER.error("[Skyblocker] Failed to save status bars config", e); - } - } - - public static void updatePositions() { - if (!configLoaded) return; - final int width = MinecraftClient.getInstance().getWindow().getScaledWidth(); - final int height = MinecraftClient.getInstance().getWindow().getScaledHeight(); - - for (BarPositioner.BarAnchor barAnchor : BarPositioner.BarAnchor.allAnchors()) { - ScreenPos anchorPosition = barAnchor.getAnchorPosition(width, height); - BarPositioner.SizeRule sizeRule = barAnchor.getSizeRule(); - - 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; - } - } - } - } - - } - } - - for (int row = 0; row < barPositioner.getRowCount(barAnchor); row++) { - List barRow = barPositioner.getRow(barAnchor, row); - if (barRow.isEmpty()) continue; - - - // 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; - - } - } - - } - } - - 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; - } - - 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()) - 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); - } - 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; - } - - 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/FancyStatusBars.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java new file mode 100644 index 00000000..9a9dc391 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/FancyStatusBars.java @@ -0,0 +1,269 @@ +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.StatusBarTracker; +import de.hysky.skyblocker.utils.Utils; +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.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; +import org.lwjgl.glfw.GLFW; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.awt.*; +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.concurrent.CompletableFuture; +import java.util.function.Supplier; + +public class FancyStatusBars { + private static final Path FILE = SkyblockerMod.CONFIG_DIR.resolve("status_bars.json"); + private static final Logger LOGGER = LoggerFactory.getLogger(FancyStatusBars.class); + + private final MinecraftClient client = MinecraftClient.getInstance(); + private final StatusBarTracker statusBarTracker = SkyblockerMod.getInstance().statusBarTracker; + + public static BarPositioner barPositioner = new BarPositioner(); + 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, 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.anchor = BarPositioner.BarAnchor.HOTBAR_TOP; + health.gridX = 0; + health.gridY = 0; + StatusBar intelligence = statusBars.get("intelligence"); + intelligence.anchor = BarPositioner.BarAnchor.HOTBAR_TOP; + intelligence.gridX = 1; + intelligence.gridY = 0; + StatusBar defense = statusBars.get("defense"); + defense.anchor = BarPositioner.BarAnchor.HOTBAR_RIGHT; + defense.gridX = 0; + defense.gridY = 0; + StatusBar experience = statusBars.get("experience"); + experience.anchor = BarPositioner.BarAnchor.HOTBAR_TOP; + experience.gridX = 0; + experience.gridY = 1; + + CompletableFuture.supplyAsync(FancyStatusBars::loadBarConfig).thenAccept(object -> { + if (object != null) { + for (String s : object.keySet()) { + if (statusBars.containsKey(s)) { + try { + statusBars.get(s).loadFromJson(object.get(s).getAsJsonObject()); + } catch (Exception e) { + LOGGER.error("[Skyblocker] Failed to load {} status bar", s, e); + } + } else { + LOGGER.warn("[Skyblocker] Unknown status bar: {}", s); + } + } + } + placeBarsInPositioner(); + configLoaded = true; + }).exceptionally(throwable -> { + LOGGER.error("[Skyblocker] Failed reading status bars config", throwable); + return null; + }); + ClientLifecycleEvents.CLIENT_STOPPING.register((client) -> { + saveBarConfig(); + GLFW.glfwDestroyCursor(StatusBarsConfigScreen.RESIZE_CURSOR); + }); + /*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 boolean configLoaded = false; + + private static void placeBarsInPositioner() { + List original = statusBars.values().stream().toList(); + + 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); + } + } + } + + public static JsonObject loadBarConfig() { + try (BufferedReader reader = Files.newBufferedReader(FILE)) { + return SkyblockerMod.GSON.fromJson(reader, JsonObject.class); + } catch (NoSuchFileException e) { + LOGGER.warn("[Skyblocker] No status bar config file found, using defaults"); + } catch (Exception e) { + LOGGER.error("[Skyblocker] Failed to load status bars config", e); + } + return null; + } + + public static void saveBarConfig() { + JsonObject output = new JsonObject(); + statusBars.forEach((s, statusBar) -> output.add(s, statusBar.toJson())); + try (BufferedWriter writer = Files.newBufferedWriter(FILE)) { + SkyblockerMod.GSON.toJson(output, writer); + LOGGER.info("[Skyblocker] Saved status bars config"); + } catch (IOException e) { + LOGGER.error("[Skyblocker] Failed to save status bars config", e); + } + } + + public static void updatePositions() { + if (!configLoaded) return; + final int width = MinecraftClient.getInstance().getWindow().getScaledWidth(); + final int height = MinecraftClient.getInstance().getWindow().getScaledHeight(); + + for (BarPositioner.BarAnchor barAnchor : BarPositioner.BarAnchor.allAnchors()) { + ScreenPos anchorPosition = barAnchor.getAnchorPosition(width, height); + BarPositioner.SizeRule sizeRule = barAnchor.getSizeRule(); + + 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; + } + } + } + } + + } + } + + for (int row = 0; row < barPositioner.getRowCount(barAnchor); row++) { + List barRow = barPositioner.getRow(barAnchor, row); + if (barRow.isEmpty()) continue; + + + // 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; + + } + } + + } + } + + 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()) + return false; + + 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; + } +} 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 7c1aa71b..4d23dc07 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 e28b2316..63b959e5 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", -- cgit From d91367ae8faee90736cc0390bb025f2d71e9560f Mon Sep 17 00:00:00 2001 From: vicisacat Date: Sat, 20 Apr 2024 21:50:39 +0200 Subject: fetch positions from old config --- .../hysky/skyblocker/config/SkyblockerConfig.java | 37 +++++++++++++++++++ .../skyblock/fancybars/FancyStatusBars.java | 41 +++++++++++++++------- 2 files changed, 65 insertions(+), 13 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker/config') diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index 28e96a50..e7f14763 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 class SkyblockerConfig { 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 2f2ec000..009f2e59 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 @@ package de.hysky.skyblocker.skyblock.fancybars; 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 class FancyStatusBars { 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 class FancyStatusBars { .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() { -- cgit From 5ebff97c8a403178b4c3ddf6da231e666ddeac7d Mon Sep 17 00:00:00 2001 From: vicisacat Date: Sat, 20 Apr 2024 21:52:01 +0200 Subject: remove unused things from old bars config --- .../hysky/skyblocker/config/SkyblockerConfig.java | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) (limited to 'src/main/java/de/hysky/skyblocker/config') diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index e7f14763..912636d6 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 class SkyblockerConfig { public OldBarPositions barPositions = new OldBarPositions(); } + /** + * Backwards compat + */ public static class OldBarPositions { @SerialEntry public OldBarPosition healthBarPosition = OldBarPosition.LAYER1; @@ -325,22 +328,11 @@ public class SkyblockerConfig { } + /** + * 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 { -- cgit