From 2e9a54f81e9839fd48eb0b77b700313f915bb711 Mon Sep 17 00:00:00 2001 From: viciscat <51047087+viciscat@users.noreply.github.com> Date: Sun, 30 Jun 2024 12:59:49 +0200 Subject: really having trouble naming these commits anyway started making the config accessible from yacl config default config based on old config for HUDs --- .../config/categories/OtherLocationsCategory.java | 4 +- .../skyblocker/skyblock/end/EndHudWidget.java | 10 +- .../de/hysky/skyblocker/skyblock/end/TheEnd.java | 4 +- .../skyblocker/skyblock/garden/FarmingHud.java | 2 +- .../skyblock/garden/FarmingHudWidget.java | 9 +- .../skyblock/tabhud/config/PreviewTab.java | 78 +++++++----- .../tabhud/config/WidgetsConfigurationScreen.java | 51 ++++++-- .../tabhud/screenbuilder/ScreenBuilder.java | 7 +- .../tabhud/screenbuilder/ScreenMaster.java | 132 +++++++++++++++++---- .../screenbuilder/pipeline/PositionRule.java | 6 +- .../screenbuilder/pipeline/WidgetPositioner.java | 27 +++++ .../skyblock/tabhud/util/PlayerListMgr.java | 15 ++- .../tabhud/widget/DungeonPlayerWidget.java | 2 +- .../skyblock/tabhud/widget/EmptyWidget.java | 2 + .../skyblock/tabhud/widget/HudWidget.java | 4 + .../skyblock/tabhud/widget/TabHudWidget.java | 1 + .../skyblock/tabhud/widget/hud/HudCommsWidget.java | 1 + 17 files changed, 276 insertions(+), 79 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/config/categories/OtherLocationsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/OtherLocationsCategory.java index 67397b9d..c670c898 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/OtherLocationsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/OtherLocationsCategory.java @@ -5,6 +5,8 @@ import de.hysky.skyblocker.config.SkyblockerConfig; import de.hysky.skyblocker.skyblock.end.EndHudConfigScreen; import de.hysky.skyblocker.skyblock.end.EndHudWidget; import de.hysky.skyblocker.skyblock.end.TheEnd; +import de.hysky.skyblocker.skyblock.tabhud.config.WidgetsConfigurationScreen; +import de.hysky.skyblocker.utils.Location; import dev.isxander.yacl3.api.*; import dev.isxander.yacl3.api.controller.IntegerSliderControllerBuilder; import net.minecraft.client.MinecraftClient; @@ -128,7 +130,7 @@ public class OtherLocationsCategory { .option(ButtonOption.createBuilder() .name(Text.translatable("skyblocker.config.otherLocations.end.screen")) .text(Text.translatable("text.skyblocker.open")) // Reusing again lol - .action((screen, opt) -> MinecraftClient.getInstance().setScreen(new EndHudConfigScreen(screen))) + .action((screen, opt) -> MinecraftClient.getInstance().setScreen(new WidgetsConfigurationScreen(Location.THE_END, EndHudWidget.INSTANCE.getInternalID()))) .build()) .option(ButtonOption.createBuilder() .name(Text.translatable("skyblocker.config.otherLocations.end.resetName")) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/end/EndHudWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/end/EndHudWidget.java index d91b8efe..74ee3ecb 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/end/EndHudWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/end/EndHudWidget.java @@ -33,8 +33,8 @@ public class EndHudWidget extends HudWidget { ENDERMAN_HEAD.set(DataComponentTypes.PROFILE, new ProfileComponent(Optional.of("MHF_Enderman"), Optional.empty(), new PropertyMap())); POPPY.set(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, true); - INSTANCE.setX(SkyblockerConfigManager.get().otherLocations.end.x); - INSTANCE.setY(SkyblockerConfigManager.get().otherLocations.end.y); + //INSTANCE.setX(SkyblockerConfigManager.get().otherLocations.end.x); + //INSTANCE.setY(SkyblockerConfigManager.get().otherLocations.end.y); } public EndHudWidget(MutableText title, Integer colorValue) { @@ -74,4 +74,10 @@ public class EndHudWidget extends HudWidget { } } } + + @Override + public String getNiceName() { + return "End Hud"; + } + } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/end/TheEnd.java b/src/main/java/de/hysky/skyblocker/skyblock/end/TheEnd.java index 0468f392..5aa9eae7 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/end/TheEnd.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/end/TheEnd.java @@ -76,12 +76,12 @@ public class TheEnd { }); - HudRenderEvents.AFTER_MAIN_HUD.register((drawContext, tickCounter) -> { + /*HudRenderEvents.AFTER_MAIN_HUD.register((drawContext, tickCounter) -> { if (!Utils.isInTheEnd()) return; if (!SkyblockerConfigManager.get().otherLocations.end.hudEnabled) return; EndHudWidget.INSTANCE.render(drawContext, SkyblockerConfigManager.get().uiAndVisuals.tabHud.enableHudBackground); - }); + });*/ ClientChunkEvents.CHUNK_LOAD.register((world, chunk) -> { String lowerCase = Utils.getIslandArea().toLowerCase(); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/garden/FarmingHud.java b/src/main/java/de/hysky/skyblocker/skyblock/garden/FarmingHud.java index 54a823bf..648c4f2a 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/garden/FarmingHud.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/garden/FarmingHud.java @@ -64,7 +64,7 @@ public class FarmingHud { } FarmingHudWidget.INSTANCE.update(); - FarmingHudWidget.INSTANCE.render(context, SkyblockerConfigManager.get().uiAndVisuals.tabHud.enableHudBackground); + //FarmingHudWidget.INSTANCE.render(context, SkyblockerConfigManager.get().uiAndVisuals.tabHud.enableHudBackground); } }); ClientPlayerBlockBreakEvents.AFTER.register((world, player, pos, state) -> { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/garden/FarmingHudWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/garden/FarmingHudWidget.java index 15be316a..0becb387 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/garden/FarmingHudWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/garden/FarmingHudWidget.java @@ -53,8 +53,8 @@ public class FarmingHudWidget extends HudWidget { public FarmingHudWidget() { super(TITLE, Formatting.YELLOW.getColorValue(), "hud_farming"); - setX(SkyblockerConfigManager.get().farming.garden.farmingHud.x); - setY(SkyblockerConfigManager.get().farming.garden.farmingHud.y); + //setX(SkyblockerConfigManager.get().farming.garden.farmingHud.x); + //setY(SkyblockerConfigManager.get().farming.garden.farmingHud.y); update(); } @@ -107,4 +107,9 @@ public class FarmingHudWidget extends HudWidget { public boolean shouldRender(Location location) { return location.equals(Location.GARDEN) && SkyblockerConfigManager.get().farming.garden.farmingHud.enableHud; } + + @Override + public String getNiceName() { + return "Farming Hud"; + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/config/PreviewTab.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/config/PreviewTab.java index 45548812..8eed31b8 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/config/PreviewTab.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/config/PreviewTab.java @@ -3,8 +3,10 @@ package de.hysky.skyblocker.skyblock.tabhud.config; import de.hysky.skyblocker.skyblock.tabhud.screenbuilder.ScreenBuilder; import de.hysky.skyblocker.skyblock.tabhud.screenbuilder.ScreenMaster; import de.hysky.skyblocker.skyblock.tabhud.screenbuilder.pipeline.PositionRule; +import de.hysky.skyblocker.skyblock.tabhud.screenbuilder.pipeline.WidgetPositioner; import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr; import de.hysky.skyblocker.skyblock.tabhud.widget.HudWidget; +import de.hysky.skyblocker.skyblock.tabhud.widget.TabHudWidget; import de.hysky.skyblocker.utils.ItemUtils; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; @@ -52,8 +54,8 @@ public class PreviewTab implements Tab { widgetOptions.setWidth(RIGHT_SIDE_WIDTH - 10); ScreenMaster.ScreenLayer[] values = ScreenMaster.ScreenLayer.values(); - layerButtons = new ButtonWidget[values.length]; - for (int i = 0; i < values.length; i++) { + layerButtons = new ButtonWidget[3]; + for (int i = 0; i < 3; i++) { ScreenMaster.ScreenLayer screenLayer = values[i]; layerButtons[i] = ButtonWidget.builder(Text.literal(screenLayer.toString()), button -> { this.currentScreenLayer = screenLayer; @@ -67,6 +69,11 @@ public class PreviewTab implements Tab { } } + public void goToLayer(ScreenMaster.ScreenLayer layer) { + if (layer == ScreenMaster.ScreenLayer.DEFAULT) layer = ScreenMaster.ScreenLayer.HUD; + layerButtons[layer.ordinal()].onPress(); + } + @Override public Text getTitle() { return Text.literal("Preview"); @@ -100,7 +107,7 @@ public class PreviewTab implements Tab { widgetOptions.setPosition(tabArea.width() - widgetOptions.getWidth() - 5, optionsY); widgetOptions.setHeight(tabArea.height() - optionsY - 5); - forEachChild(clickableWidget -> clickableWidget.visible = parent.isPreviewVisible()); + forEachChild(clickableWidget -> clickableWidget.visible = parent.isPreviewVisible() || parent.noHandler); } private void updatePlayerListFromPreview() { @@ -136,6 +143,13 @@ public class PreviewTab implements Tab { ScreenBuilder screenBuilder = ScreenMaster.getScreenBuilder(parent.getCurrentLocation()); PositionRule positionRule = screenBuilder.getPositionRule(hudWidget.getInternalID()); int width = widgetOptions.getWidth() - widgetOptions.getScrollerWidth(); + + // Normal hud widgets don't have auto. + if (positionRule == null && !(hudWidget instanceof TabHudWidget)) { + screenBuilder.setPositionRule(hudWidget.getInternalID(), PositionRule.DEFAULT); + positionRule = PositionRule.DEFAULT; + } + // TODO localization widgetOptions.addWidget(new TextWidget(width, 9, Text.literal(hudWidget.getNiceName()).formatted(Formatting.BOLD, Formatting.UNDERLINE), client.textRenderer)); @@ -148,28 +162,24 @@ public class PreviewTab implements Tab { .width(width) .build()); } else { - widgetOptions.addWidget(ButtonWidget.builder(Text.literal("Positioning: Custom"), button -> { - screenBuilder.setPositionRule(hudWidget.getInternalID(), null); - updateWidgets(); - onHudWidgetSelected(hudWidget); - }) - .width(width) - .build()); + // Normal hud widgets don't have auto. + if (hudWidget instanceof TabHudWidget) { + widgetOptions.addWidget(ButtonWidget.builder(Text.literal("Positioning: Custom"), button -> { + screenBuilder.setPositionRule(hudWidget.getInternalID(), null); + updateWidgets(); + onHudWidgetSelected(hudWidget); + }) + .width(width) + .build()); + } - String ye = "Layer: " + (positionRule.screenLayer() == null ? "Default" : positionRule.screenLayer().toString()); + String ye = "Layer: " + positionRule.screenLayer().toString(); widgetOptions.addWidget(ButtonWidget.builder(Text.literal(ye), button -> { ScreenBuilder builder = ScreenMaster.getScreenBuilder(parent.getCurrentLocation()); PositionRule rule = builder.getPositionRuleOrDefault(hudWidget.getInternalID()); ScreenMaster.ScreenLayer[] values = ScreenMaster.ScreenLayer.values(); - ScreenMaster.ScreenLayer newLayer; - if (rule.screenLayer() == null) { - newLayer = values[0]; - } else if (rule.screenLayer().ordinal() == values.length - 1) { - newLayer = null; - } else { - newLayer = values[rule.screenLayer().ordinal() + 1]; - } + ScreenMaster.ScreenLayer newLayer = values[(rule.screenLayer().ordinal() + 1) % values.length]; PositionRule newRule = new PositionRule( rule.parent(), @@ -180,9 +190,9 @@ public class PreviewTab implements Tab { newLayer ); builder.setPositionRule(hudWidget.getInternalID(), newRule); - button.setMessage(Text.literal("Layer: " + (newRule.screenLayer() == null ? "Default" : newRule.screenLayer().toString()))); + button.setMessage(Text.literal("Layer: " + newRule.screenLayer().toString())); updateWidgets(); - if (newLayer != null) { + if (newLayer != ScreenMaster.ScreenLayer.DEFAULT) { layerButtons[newLayer.ordinal()].onPress(); } @@ -534,26 +544,36 @@ public class PreviewTab implements Tab { @Override public void onClick(double mouseX, double mouseY) { - if (hoveredPoint != null && previewWidget.selectedWidget != null) { + HudWidget affectedWidget = previewWidget.selectedWidget; + if (hoveredPoint != null && affectedWidget != null) { ScreenBuilder screenBuilder = ScreenMaster.getScreenBuilder(parent.getCurrentLocation()); - String internalID = previewWidget.selectedWidget.getInternalID(); - PositionRule oldRule = screenBuilder.getPositionRule(internalID); - if (oldRule == null) oldRule = PositionRule.DEFAULT; + String internalID = affectedWidget.getInternalID(); + PositionRule oldRule = screenBuilder.getPositionRuleOrDefault(internalID); + // Get the x, y of the parent's point + ScreenPos startPos = WidgetPositioner.getStartPosition(oldRule.parent(), parent.width, parent.height, other ? hoveredPoint: oldRule.parentPoint()); + if (startPos == null) startPos = new ScreenPos(0, 0); + // Same but for the affected widget + PositionRule.Point thisPoint = other ? oldRule.thisPoint() : hoveredPoint; + ScreenPos endPos = new ScreenPos( + (int) (affectedWidget.getX() + thisPoint.horizontalPoint().getPercentage() * affectedWidget.getWidth()), + (int) (affectedWidget.getY() + thisPoint.verticalPoint().getPercentage() * affectedWidget.getHeight()) + ); + if (other) { screenBuilder.setPositionRule(internalID, new PositionRule( oldRule.parent(), hoveredPoint, oldRule.thisPoint(), - oldRule.relativeX(), - oldRule.relativeY(), + endPos.x() - startPos.x(), + endPos.y() - startPos.y(), oldRule.screenLayer())); } else { screenBuilder.setPositionRule(internalID, new PositionRule( oldRule.parent(), oldRule.parentPoint(), hoveredPoint, - oldRule.relativeX(), - oldRule.relativeY(), + endPos.x() - startPos.x(), + endPos.y() - startPos.y(), oldRule.screenLayer())); } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/config/WidgetsConfigurationScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/config/WidgetsConfigurationScreen.java index 157be8fe..dbbc5bdc 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/config/WidgetsConfigurationScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/config/WidgetsConfigurationScreen.java @@ -1,6 +1,7 @@ package de.hysky.skyblocker.skyblock.tabhud.config; import com.mojang.logging.LogUtils; +import de.hysky.skyblocker.skyblock.tabhud.screenbuilder.ScreenMaster; import de.hysky.skyblocker.utils.ItemUtils; import de.hysky.skyblocker.utils.Location; import de.hysky.skyblocker.utils.Utils; @@ -14,6 +15,7 @@ import net.minecraft.screen.GenericContainerScreenHandler; import net.minecraft.screen.ScreenHandler; import net.minecraft.screen.ScreenHandlerListener; import net.minecraft.text.Text; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @@ -25,6 +27,8 @@ public class WidgetsConfigurationScreen extends Screen implements ScreenHandlerL private GenericContainerScreenHandler handler; private String titleLowercase; + public final boolean noHandler; + private String widgetsLayer = null; private boolean tabPreview = false; private PreviewTab previewTab; @@ -66,24 +70,49 @@ public class WidgetsConfigurationScreen extends Screen implements ScreenHandlerL private boolean switchingToPopup = false; - public WidgetsConfigurationScreen(GenericContainerScreenHandler handler, String titleLowercase) { + /** + * Creates the screen to configure, putting the handler at null will hide the first tab. Putting it to null is used in the config + * @param handler the container handler + * @param titleLowercase the title in lowercase + */ + private WidgetsConfigurationScreen(@Nullable GenericContainerScreenHandler handler, String titleLowercase, Location targetLocation, @Nullable String widgetLayerToGoTo) { super(Text.literal("Widgets Configuration")); this.handler = handler; this.titleLowercase = titleLowercase; - this.handler.addListener(this); - parseLocation(); + this.noHandler = handler == null; + if (!noHandler) { + this.handler.addListener(this); + parseLocation(); + } else { + currentLocation = targetLocation; + widgetsLayer = widgetLayerToGoTo; + } + } + // TODO java doc this + public WidgetsConfigurationScreen(@NotNull GenericContainerScreenHandler handler, String titleLowercase) { + this(handler, titleLowercase, Location.UNKNOWN, null); + } + public WidgetsConfigurationScreen(Location targetLocation, String widgetLayerToGoTo) { + this(null, "", targetLocation, widgetLayerToGoTo); } @Override protected void init() { - widgetsOrderingTab = new WidgetsOrderingTab(this.client, this.handler); previewTab = new PreviewTab(this.client, this); - this.tabNavigation = TabNavigationWidget.builder(this.tabManager, this.width) - .tabs(this.widgetsOrderingTab, this.previewTab) - .build(); + if (noHandler) { + this.tabNavigation = TabNavigationWidget.builder(this.tabManager, this.width) + .tabs(this.previewTab) + .build(); + previewTab.goToLayer(ScreenMaster.getScreenBuilder(currentLocation).getPositionRuleOrDefault(widgetsLayer).screenLayer()); + } else { + widgetsOrderingTab = new WidgetsOrderingTab(this.client, this.handler); + this.tabNavigation = TabNavigationWidget.builder(this.tabManager, this.width) + .tabs(this.widgetsOrderingTab, this.previewTab) + .build(); + } this.tabNavigation.selectTab(0, false); - this.addDrawableChild(tabNavigation); switchingToPopup = false; + this.addDrawableChild(tabNavigation); this.initTabNavigation(); } @@ -99,6 +128,7 @@ public class WidgetsConfigurationScreen extends Screen implements ScreenHandlerL } public void updateHandler(GenericContainerScreenHandler newHandler, String titleLowercase) { + if (noHandler) return; handler.removeListener(this); handler = newHandler; handler.addListener(this); @@ -130,6 +160,7 @@ public class WidgetsConfigurationScreen extends Screen implements ScreenHandlerL @Override public void onSlotUpdate(ScreenHandler handler, int slotId, ItemStack stack) { + if (noHandler) return; if (slotId == 4) { tabPreview = stack.isOf(Items.PLAYER_HEAD); } @@ -152,6 +183,7 @@ public class WidgetsConfigurationScreen extends Screen implements ScreenHandlerL @Override public void tick() { super.tick(); + if (noHandler) return; if (slotThirteenBacklog != null && widgetsOrderingTab != null) { widgetsOrderingTab.hopper(ItemUtils.getLore(slotThirteenBacklog)); slotThirteenBacklog = null; @@ -163,7 +195,7 @@ public class WidgetsConfigurationScreen extends Screen implements ScreenHandlerL @Override public void close() { - this.client.player.closeHandledScreen(); + if (!noHandler) this.client.player.closeHandledScreen(); super.close(); } @@ -172,6 +204,7 @@ public class WidgetsConfigurationScreen extends Screen implements ScreenHandlerL @Override public void removed() { + if (noHandler) return; if (!switchingToPopup && this.client != null && this.client.player != null) { this.handler.onClosed(this.client.player); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/screenbuilder/ScreenBuilder.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/screenbuilder/ScreenBuilder.java index d4f3e3d9..b05a6a03 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/screenbuilder/ScreenBuilder.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/screenbuilder/ScreenBuilder.java @@ -1,6 +1,7 @@ package de.hysky.skyblocker.skyblock.tabhud.screenbuilder; import java.util.*; +import java.util.function.BiConsumer; import java.util.function.BiFunction; import com.google.gson.JsonObject; @@ -147,6 +148,10 @@ public class ScreenBuilder { return positioning.get(widgetInternalId); } + public void forEachPositionRuleEntry(BiConsumer action) { + positioning.forEach(action); + } + public PositionRule getPositionRuleOrDefault(String widgetInternalId) { PositionRule positionRule = getPositionRule(widgetInternalId); return positionRule == null ? PositionRule.DEFAULT : positionRule; @@ -253,7 +258,7 @@ public class ScreenBuilder { case MAIN_TAB -> mainTabScreen; case SECONDARY_TAB -> secondaryTabScreen; case HUD -> hudScreen; - case null -> List.of(); + case null, default -> List.of(); }; } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/screenbuilder/ScreenMaster.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/screenbuilder/ScreenMaster.java index 6b7068d6..b1893417 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/screenbuilder/ScreenMaster.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/screenbuilder/ScreenMaster.java @@ -1,28 +1,35 @@ package de.hysky.skyblocker.skyblock.tabhud.screenbuilder; import com.google.common.reflect.ClassPath; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; import com.mojang.logging.LogUtils; import com.mojang.serialization.Codec; +import com.mojang.serialization.JsonOps; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.events.HudRenderEvents; import de.hysky.skyblocker.events.SkyblockEvents; import de.hysky.skyblocker.annotations.Init; import de.hysky.skyblocker.skyblock.tabhud.TabHud; +import de.hysky.skyblocker.skyblock.tabhud.screenbuilder.pipeline.PositionRule; import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr; +import de.hysky.skyblocker.skyblock.tabhud.widget.DungeonPlayerWidget; import de.hysky.skyblocker.skyblock.tabhud.widget.HudWidget; import de.hysky.skyblocker.skyblock.tabhud.widget.TabHudWidget; import de.hysky.skyblocker.utils.Location; import de.hysky.skyblocker.utils.Utils; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; 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.util.Window; import net.minecraft.util.Identifier; -import net.minecraft.util.StringIdentifiable; import org.slf4j.Logger; import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; import java.nio.file.NoSuchFileException; @@ -35,24 +42,20 @@ public class ScreenMaster { private static final Logger LOGGER = LogUtils.getLogger(); - private static final int VERSION = 1; + private static final int VERSION = 2; private static final Path FILE = SkyblockerMod.CONFIG_DIR.resolve("hud_widgets.json"); - private static final Map builderMap = new EnumMap<>(Location.class); + private static Map createBuilderMap() { + EnumMap map = new EnumMap<>(Location.class); + for (Location value : Location.values()) { + map.put(value, new ScreenBuilder(value)); + } + return map; + } - public static final Map widgetInstances = new HashMap<>(); + private static final Map builderMap = createBuilderMap(); - /** - * Load a screen mapping from an identifier - */ - public static void load(Identifier ident) { - - String path = ident.getPath(); - String[] parts = path.split("/"); - String screenType = parts[parts.length - 2]; - String location = parts[parts.length - 1]; - location = location.replace(".json", ""); - } + public static final Map widgetInstances = new HashMap<>(); public static ScreenBuilder getScreenBuilder(Location location) { return builderMap.get(location); @@ -81,14 +84,76 @@ public class ScreenMaster { public static void loadConfig() { try (BufferedReader reader = Files.newBufferedReader(FILE)) { - + JsonObject object = SkyblockerMod.GSON.fromJson(reader, JsonObject.class); + JsonObject positions = object.getAsJsonObject("positions"); + for (Map.Entry builderEntry : builderMap.entrySet()) { + Location location = builderEntry.getKey(); + ScreenBuilder screenBuilder = builderEntry.getValue(); + if (positions.has(location.id())) { + JsonObject locationObject = positions.getAsJsonObject(location.id()); + for (Map.Entry entry : locationObject.entrySet()) { + PositionRule.CODEC.decode(JsonOps.INSTANCE, entry.getValue()) + .ifSuccess(pair -> screenBuilder.setPositionRule(entry.getKey(), pair.getFirst())) + .ifError(pairError -> LOGGER.error("[Skyblocker] Failed to parse position rule: {}", pairError.messageSupplier().get())); + } + } + } } catch (NoSuchFileException e) { - LOGGER.warn("[Skyblocker] No status bar config file found, using defaults"); + LOGGER.warn("[Skyblocker] No hud widget config file found, using defaults"); } catch (Exception e) { LOGGER.error("[Skyblocker] Failed to load hud widgets config", e); } } + public static void saveConfig() { + JsonObject output = new JsonObject(); + JsonObject positions = new JsonObject(); + for (Map.Entry builderEntry : builderMap.entrySet()) { + Location location = builderEntry.getKey(); + ScreenBuilder screenBuilder = builderEntry.getValue(); + JsonObject locationObject = new JsonObject(); + screenBuilder.forEachPositionRuleEntry((s, positionRule) -> locationObject.add(s, PositionRule.CODEC.encodeStart(JsonOps.INSTANCE, positionRule).getOrThrow())); + if (locationObject.isEmpty()) continue; + positions.add(location.id(), locationObject); + } + output.add("positions", positions); + try (BufferedWriter writer = Files.newBufferedWriter(FILE)) { + SkyblockerMod.GSON.toJson(output, writer); + LOGGER.info("[Skyblocker] Saved hud widget config"); + } catch (IOException e) { + LOGGER.error("[Skyblocker] Failed to save hud widget config", e); + } + } + + // All non-tab HUDs should have a position rule initialised here, because they don't have an auto positioning + private static void fillDefaultConfig() { + ScreenBuilder screenBuilder = getScreenBuilder(Location.THE_END); + screenBuilder.setPositionRule( + "hud_end", + new PositionRule("screen", PositionRule.Point.DEFAULT, PositionRule.Point.DEFAULT, SkyblockerConfigManager.get().otherLocations.end.x, SkyblockerConfigManager.get().otherLocations.end.y, ScreenMaster.ScreenLayer.HUD) + ); + + screenBuilder = getScreenBuilder(Location.GARDEN); + screenBuilder.setPositionRule( + "hud_farming", + new PositionRule("screen", PositionRule.Point.DEFAULT, PositionRule.Point.DEFAULT, SkyblockerConfigManager.get().farming.garden.farmingHud.x, SkyblockerConfigManager.get().farming.garden.farmingHud.y, ScreenMaster.ScreenLayer.HUD) + ); + + for (Location loc : new Location[]{Location.CRYSTAL_HOLLOWS, Location.DWARVEN_MINES}) { + screenBuilder = getScreenBuilder(loc); + screenBuilder.setPositionRule( + "commissions", + new PositionRule("screen", PositionRule.Point.DEFAULT, PositionRule.Point.DEFAULT, 5, 5, ScreenMaster.ScreenLayer.HUD) + ); + screenBuilder.setPositionRule( + "powders", + new PositionRule("commissions", new PositionRule.Point(PositionRule.VerticalPoint.BOTTOM, PositionRule.HorizontalPoint.LEFT), PositionRule.Point.DEFAULT, 0, 2, ScreenMaster.ScreenLayer.HUD) + ); + + } + + } + @Init public static void init() { @@ -107,8 +172,15 @@ public class ScreenMaster { try { Class load = Class.forName(classInfo.getName()); if (!load.getSuperclass().equals(TabHudWidget.class)) return; - TabHudWidget tabHudWidget = (TabHudWidget) load.getDeclaredConstructor().newInstance(); - PlayerListMgr.tabWidgetInstances.put(tabHudWidget.getHypixelWidgetName(), tabHudWidget); + if (load.equals(DungeonPlayerWidget.class)) { + for (int i = 1; i < 6; i++) { + DungeonPlayerWidget widget = new DungeonPlayerWidget(i); + PlayerListMgr.tabWidgetInstances.put(widget.getHypixelWidgetName(), widget); + } + } else { + TabHudWidget tabHudWidget = (TabHudWidget) load.getDeclaredConstructor().newInstance(); + PlayerListMgr.tabWidgetInstances.put(tabHudWidget.getHypixelWidgetName(), tabHudWidget); + } } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException | ClassNotFoundException e) { LOGGER.error("[Skyblocker] Failed to load {} hud widget", classInfo.getName(), e); @@ -118,12 +190,14 @@ public class ScreenMaster { } catch (Exception e) { LOGGER.error("[Skyblocker] Failed to get instances of hud widgets", e); } + fillDefaultConfig(); + loadConfig(); }); - for (Location value : Location.values()) { - builderMap.put(value, new ScreenBuilder(value)); - } + ClientLifecycleEvents.CLIENT_STOPPING.register(client -> saveConfig()); + + /* @@ -188,14 +262,19 @@ public class ScreenMaster { */ } + /** + * @implNote !! The 3 first ones shouldn't be moved, ordinal is used in some places + */ public enum ScreenLayer { MAIN_TAB, SECONDARY_TAB, - HUD; + HUD, + /** + * Default is only present for config and isn't used anywhere else + */ + DEFAULT; - public static final Codec CODEC_NULLABLE = Codec.STRING.xmap( - s -> s.equals("null") ? null : ScreenLayer.valueOf(s), - screenLayer -> screenLayer == null ? "null": screenLayer.name()); + public static final Codec CODEC = Codec.STRING.xmap(ScreenLayer::valueOf, ScreenLayer::name); @Override public String toString() { @@ -203,6 +282,7 @@ public class ScreenMaster { case MAIN_TAB -> "Main Tab"; case SECONDARY_TAB -> "Secondary Tab"; case HUD -> "HUD"; + case DEFAULT -> "You shouldn't be seeing this..."; }; } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/screenbuilder/pipeline/PositionRule.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/screenbuilder/pipeline/PositionRule.java index c71b13a9..0504c99b 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/screenbuilder/pipeline/PositionRule.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/screenbuilder/pipeline/PositionRule.java @@ -5,10 +5,10 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import de.hysky.skyblocker.skyblock.tabhud.screenbuilder.ScreenMaster; import org.jetbrains.annotations.Nullable; -public record PositionRule(String parent, Point parentPoint, Point thisPoint, int relativeX, int relativeY, @Nullable +public record PositionRule(String parent, Point parentPoint, Point thisPoint, int relativeX, int relativeY, ScreenMaster.ScreenLayer screenLayer) { - public static final PositionRule DEFAULT = new PositionRule("screen", Point.DEFAULT, Point.DEFAULT, 0, 0, null); + public static final PositionRule DEFAULT = new PositionRule("screen", Point.DEFAULT, Point.DEFAULT, 5, 5, ScreenMaster.ScreenLayer.DEFAULT); public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( Codec.STRING.fieldOf("parent").forGetter(PositionRule::parent), @@ -16,7 +16,7 @@ ScreenMaster.ScreenLayer screenLayer) { Point.CODEC.fieldOf("this_anchor").forGetter(PositionRule::thisPoint), Codec.INT.fieldOf("relative_x").forGetter(PositionRule::relativeX), Codec.INT.fieldOf("relative_y").forGetter(PositionRule::relativeY), - ScreenMaster.ScreenLayer.CODEC_NULLABLE.fieldOf("layer").forGetter(PositionRule::screenLayer) + ScreenMaster.ScreenLayer.CODEC.fieldOf("layer").forGetter(PositionRule::screenLayer) ).apply(instance, PositionRule::new)); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/screenbuilder/pipeline/WidgetPositioner.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/screenbuilder/pipeline/WidgetPositioner.java index dd3e4806..a8614d3d 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/screenbuilder/pipeline/WidgetPositioner.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/screenbuilder/pipeline/WidgetPositioner.java @@ -2,6 +2,8 @@ package de.hysky.skyblocker.skyblock.tabhud.screenbuilder.pipeline; import de.hysky.skyblocker.skyblock.tabhud.screenbuilder.ScreenMaster; import de.hysky.skyblocker.skyblock.tabhud.widget.HudWidget; +import net.minecraft.client.gui.ScreenPos; +import org.jetbrains.annotations.Nullable; import java.util.function.Function; @@ -58,9 +60,34 @@ public abstract class WidgetPositioner { case CENTER -> startY + relativeY - widget.getHeight() / 2; case BOTTOM -> startY + relativeY - widget.getHeight(); }); + } + + /** + * Returns the start position (aka the starting point of {@code relativeX} ane {@code relativeY}) of a widget based on + * the parent widget's position and size + * + * @param parent The parent widget's internal ID + * @param screenWidth The width of the screen + * @param screenHeight The height of the screen + * @param parentPoint The point on the parent widget that the child widget should be positioned relative to + * @return The start position of the child widget + */ + public static @Nullable ScreenPos getStartPosition(String parent, int screenWidth, int screenHeight, PositionRule.Point parentPoint) { + if (parent.equals("screen")) { + return new ScreenPos( + (int) (parentPoint.horizontalPoint().getPercentage() * screenWidth), + (int) (parentPoint.verticalPoint().getPercentage() * screenHeight) + ); + } else { + HudWidget parentWidget = ScreenMaster.widgetInstances.get(parent); + if (parentWidget == null) return null; + return new ScreenPos( + parentWidget.getX() + (int) (parentPoint.horizontalPoint().getPercentage() * parentWidget.getWidth()), + parentWidget.getY() + (int) (parentPoint.verticalPoint().getPercentage() * parentWidget.getHeight())); + } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/PlayerListMgr.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/PlayerListMgr.java index 2f0f3bba..c0847007 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/PlayerListMgr.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/PlayerListMgr.java @@ -70,8 +70,19 @@ public class PlayerListMgr { playerStringList = playerList.stream().map(PlayerListEntry::getDisplayName).filter(Objects::nonNull).map(Text::getString).map(String::strip).toList(); } - // TODO DUNGEONS CHECK - if (!(MinecraftClient.getInstance().currentScreen instanceof WidgetsConfigurationScreen widgetsConfigurationScreen && widgetsConfigurationScreen.isPreviewVisible())) { + if (Utils.isInDungeons()) { + tabWidgetsToShow.clear(); + tabWidgetsToShow.add(tabWidgetInstances.get("Dungeon Buffs")); + tabWidgetsToShow.add(tabWidgetInstances.get("Dungeon Deaths")); + tabWidgetsToShow.add(tabWidgetInstances.get("Dungeon Downed")); + tabWidgetsToShow.add(tabWidgetInstances.get("Dungeon Puzzles")); + tabWidgetsToShow.add(tabWidgetInstances.get("Dungeon Discoveries")); + tabWidgetsToShow.add(tabWidgetInstances.get("Dungeon Info")); + for (int i = 1; i < 6; i++) { + tabWidgetsToShow.add(tabWidgetInstances.get("Dungeon Player " + i)); + } + } + else if (!(MinecraftClient.getInstance().currentScreen instanceof WidgetsConfigurationScreen widgetsConfigurationScreen && widgetsConfigurationScreen.isPreviewVisible())) { updateWidgetsFrom(playerList.stream().map(PlayerListEntry::getDisplayName).filter(Objects::nonNull).toList()); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPlayerWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPlayerWidget.java index cbf881ea..d5274399 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPlayerWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPlayerWidget.java @@ -50,7 +50,7 @@ public class DungeonPlayerWidget extends TabHudWidget { // title needs to be changeable here public DungeonPlayerWidget(int player) { - super("Dungeon Players", TITLE, Formatting.DARK_PURPLE.getColorValue()); + super("Dungeon Player " + player, TITLE, Formatting.DARK_PURPLE.getColorValue()); this.player = player; } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/EmptyWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/EmptyWidget.java index 640bd38d..3c1ede95 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/EmptyWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/EmptyWidget.java @@ -3,6 +3,7 @@ package de.hysky.skyblocker.skyblock.tabhud.widget; import de.hysky.skyblocker.utils.Location; import net.minecraft.text.Text; +// TODO remove this class public class EmptyWidget extends HudWidget { public EmptyWidget() { super(Text.empty(), 0, "empty"); @@ -15,4 +16,5 @@ public class EmptyWidget extends HudWidget { public boolean shouldRender(Location location) { return false; } + } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/HudWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/HudWidget.java index 1dde94c2..82e4f116 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/HudWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/HudWidget.java @@ -1,17 +1,21 @@ package de.hysky.skyblocker.skyblock.tabhud.widget; import java.util.ArrayList; +import java.util.List; import java.util.Objects; import java.util.function.Consumer; import com.mojang.blaze3d.systems.RenderSystem; import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.skyblock.tabhud.screenbuilder.ScreenBuilder; import de.hysky.skyblocker.skyblock.tabhud.screenbuilder.ScreenMaster; +import de.hysky.skyblocker.skyblock.tabhud.screenbuilder.pipeline.PositionRule; import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr; import de.hysky.skyblocker.skyblock.tabhud.widget.component.Component; import de.hysky.skyblocker.skyblock.tabhud.widget.component.IcoTextComponent; import de.hysky.skyblocker.utils.Location; +import it.unimi.dsi.fastutil.Pair; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/TabHudWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/TabHudWidget.java index ec05c843..8301636d 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/TabHudWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/TabHudWidget.java @@ -54,4 +54,5 @@ public abstract class TabHudWidget extends HudWidget { public final void addComponent(Component c) { cachedComponents.add(c); } + } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/hud/HudCommsWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/hud/HudCommsWidget.java index bdea47a3..2531dfd6 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/hud/HudCommsWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/hud/HudCommsWidget.java @@ -73,4 +73,5 @@ public class HudCommsWidget extends HudWidget { public boolean shouldRender(Location location) { return location.equals(Location.DWARVEN_MINES) || location.equals(Location.CRYSTAL_HOLLOWS) && SkyblockerConfigManager.get().mining.dwarvenHud.enabledCommissions; } + } -- cgit