diff --git a/src/main/java/ee/futur/easygotr/EasyGOTRConfig.java b/src/main/java/ee/futur/easygotr/EasyGOTRConfig.java index d7e0701..1fb2315 100644 --- a/src/main/java/ee/futur/easygotr/EasyGOTRConfig.java +++ b/src/main/java/ee/futur/easygotr/EasyGOTRConfig.java @@ -285,4 +285,133 @@ public interface EasyGOTRConfig extends Config { default boolean tickDelay() { return false; } + + @ConfigSection( + name = "Debug Highlights", + description = "Enable debug highlighting for specific game elements. Useful for debugging plugin behavior.", + position = 200, + closedByDefault = true + ) + String debugSection = "debugSection"; + + @ConfigItem( + keyName = "debugHighlightBarriers", + name = "Highlight Barriers", + description = "Highlight barrier objects", + position = 201, + section = debugSection + ) + default boolean debugHighlightBarriers() { + return false; + } + + @ConfigItem( + keyName = "debugHighlightPortals", + name = "Highlight Portals", + description = "Highlight portal objects (huge guardian portal, altar portals)", + position = 202, + section = debugSection + ) + default boolean debugHighlightPortals() { + return false; + } + + @ConfigItem( + keyName = "debugHighlightAltars", + name = "Highlight Altars/Guardians", + description = "Highlight guardian portals (altar entrances)", + position = 203, + section = debugSection + ) + default boolean debugHighlightAltars() { + return false; + } + + @ConfigItem( + keyName = "debugHighlightWorkbench", + name = "Highlight Workbench", + description = "Highlight the workbench for crafting essence", + position = 204, + section = debugSection + ) + default boolean debugHighlightWorkbench() { + return false; + } + + @ConfigItem( + keyName = "debugHighlightGreatGuardian", + name = "Highlight Great Guardian", + description = "Highlight the Great Guardian NPC", + position = 205, + section = debugSection + ) + default boolean debugHighlightGreatGuardian() { + return false; + } + + @ConfigItem( + keyName = "debugHighlightRemains", + name = "Highlight Guardian Remains", + description = "Highlight guardian remains (regular, large, huge) for mining", + position = 206, + section = debugSection + ) + default boolean debugHighlightRemains() { + return false; + } + + @ConfigItem( + keyName = "debugHighlightRubble", + name = "Highlight Rubble/Climb Points", + description = "Highlight climbable rubble to access east mine", + position = 207, + section = debugSection + ) + default boolean debugHighlightRubble() { + return false; + } + + @ConfigItem( + keyName = "debugHighlightDepositPool", + name = "Highlight Deposit Pool", + description = "Highlight the deposit pool for runes", + position = 208, + section = debugSection + ) + default boolean debugHighlightDepositPool() { + return false; + } + + @ConfigItem( + keyName = "debugHighlightUnchargedCells", + name = "Highlight Uncharged Cells", + description = "Highlight uncharged cell containers", + position = 209, + section = debugSection + ) + default boolean debugHighlightUnchargedCells() { + return false; + } + + @ConfigItem( + keyName = "debugHighlightCellTiles", + name = "Highlight Cell Tiles", + description = "Highlight cell tiles for barrier placement", + position = 210, + section = debugSection + ) + default boolean debugHighlightCellTiles() { + return false; + } + + @ConfigItem( + keyName = "debugHighlightBindingNecklace", + name = "Highlight Binding Necklace", + description = "Highlight binding necklace in inventory when broken", + position = 211, + section = debugSection + ) + default boolean debugHighlightBindingNecklace() { + return false; + } } diff --git a/src/main/java/ee/futur/easygotr/EasyGOTROverlay.java b/src/main/java/ee/futur/easygotr/EasyGOTROverlay.java index dbd66e1..875632f 100644 --- a/src/main/java/ee/futur/easygotr/EasyGOTROverlay.java +++ b/src/main/java/ee/futur/easygotr/EasyGOTROverlay.java @@ -125,17 +125,70 @@ public class EasyGOTROverlay extends OverlayPanel { } for (String note : localHint.getNotesSafe()) { - panelComponent.getChildren().add(LineComponent.builder() - .left("Tip:") - .leftColor(Color.LIGHT_GRAY) - .right(note) - .rightColor(Color.LIGHT_GRAY) - .build()); + // Split long notes into multiple lines for better readability + String[] lines = splitNoteIntoLines(note, 50); // ~50 chars per line + for (String line : lines) { + panelComponent.getChildren().add(LineComponent.builder() + .left("") + .right(line) + .rightColor(Color.LIGHT_GRAY) + .build()); + } } } - panelComponent.setPreferredSize(new Dimension(250, 250)); + // Dynamically size panel based on content + int estimatedHeight = 50 + (panelComponent.getChildren().size() * 16); + panelComponent.setPreferredSize(new Dimension(280, Math.min(estimatedHeight, 400))); } return super.render(graphics); } + + /** + * Splits a note into multiple lines, breaking at word boundaries when possible. + * @param note The note text to split + * @param maxLength Maximum characters per line + * @return Array of lines + */ + private String[] splitNoteIntoLines(String note, int maxLength) { + if (note == null || note.length() <= maxLength) { + return new String[]{note}; + } + + java.util.List lines = new java.util.ArrayList<>(); + String[] words = note.split(" "); + StringBuilder currentLine = new StringBuilder(); + + for (String word : words) { + if (currentLine.length() + word.length() + 1 <= maxLength) { + if (currentLine.length() > 0) { + currentLine.append(" "); + } + currentLine.append(word); + } else { + if (currentLine.length() > 0) { + lines.add(currentLine.toString()); + currentLine = new StringBuilder(); + } + // If a single word is longer than maxLength, split it anyway + if (word.length() > maxLength) { + // Split the long word + int start = 0; + while (start < word.length()) { + int end = Math.min(start + maxLength, word.length()); + lines.add(word.substring(start, end)); + start = end; + } + } else { + currentLine.append(word); + } + } + } + + if (currentLine.length() > 0) { + lines.add(currentLine.toString()); + } + + return lines.toArray(new String[0]); + } } diff --git a/src/main/java/ee/futur/easygotr/EasyGOTRPlugin.java b/src/main/java/ee/futur/easygotr/EasyGOTRPlugin.java index 0c322d4..f8966df 100644 --- a/src/main/java/ee/futur/easygotr/EasyGOTRPlugin.java +++ b/src/main/java/ee/futur/easygotr/EasyGOTRPlugin.java @@ -870,6 +870,8 @@ public class EasyGOTRPlugin extends Plugin { maybeHighlightBindingNecklace(builder); + addDebugHighlights(builder); + EasyGOTRActionHint hint = builder.build(); if (hint.getCurrentAction() == null || hint.getCurrentAction().isEmpty()) { return hint.toBuilder().currentAction("Track the highlighted targets.").build(); @@ -914,7 +916,12 @@ public class EasyGOTRPlugin extends Plugin { builder.note("Dump stones on the Great Guardian right away for energy + run energy refills before heading back to portals."); break; case ENTER_ALTAR: - builder.note("Prioritise elemental guardians first so you can keep crafting combination runes every trip."); + int elemental = riftState.getElementalPoints(); + if (elemental >= 0 && elemental < 500) { + builder.note("Prioritise elemental guardians early (<500 points) for combination runes (polyelemental stones give +3 energy)."); + } else { + builder.note("Balance elemental/catalytic points. Elemental altars still preferred for combination runes when available."); + } break; case LEAVE_ALTAR: builder.note("Exit quickly and deposit runes within ~5 seconds of the guardian reaching 100% to secure the third catalytic point."); @@ -1442,6 +1449,81 @@ public class EasyGOTRPlugin extends Plugin { } } + private void addDebugHighlights(EasyGOTRActionHint.EasyGOTRActionHintBuilder builder) { + if (config.debugHighlightBarriers()) { + findBarrier().ifPresent(barrier -> + builder.highlight(EasyGOTRHighlightTarget.forTileObject(barrier, Color.YELLOW, "Barrier (Debug)"))); + } + + if (config.debugHighlightPortals()) { + findPortal().ifPresent(portal -> + builder.highlight(EasyGOTRHighlightTarget.forTileObject(portal, Color.MAGENTA, "Portal (Debug)"))); + } + + if (config.debugHighlightAltars()) { + Optional nextAltar = Optional.ofNullable(riftState.getNextAltar()); + nextAltar.ifPresent(altar -> + builder.highlight(EasyGOTRHighlightTarget.forTileObject(altar, Color.GREEN, "Altar (Debug)"))); + + // Also highlight all active guardians + TileObjects.search().nameContains("Guardian of").result().forEach(guardian -> { + if (guardian instanceof GameObject) { + GameObject gameObject = (GameObject) guardian; + if (gameObject.getRenderable() instanceof DynamicObject) { + Animation animation = ((DynamicObject) gameObject.getRenderable()).getAnimation(); + if (animation != null && animation.getId() == 9363) { // Active guardian + builder.highlight(EasyGOTRHighlightTarget.forTileObject(guardian, Color.GREEN, "Active Guardian (Debug)")); + } + } + } + }); + } + + if (config.debugHighlightWorkbench()) { + findWorkbench().ifPresent(workbench -> + builder.highlight(EasyGOTRHighlightTarget.forTileObject(workbench, Color.CYAN, "Workbench (Debug)"))); + } + + if (config.debugHighlightGreatGuardian()) { + findGreatGuardian().ifPresent(guardian -> + builder.highlight(EasyGOTRHighlightTarget.forNpc(guardian, Color.GREEN, "Great Guardian (Debug)"))); + } + + if (config.debugHighlightRemains()) { + findHugeRemains().ifPresent(remains -> + builder.highlight(EasyGOTRHighlightTarget.forTileObject(remains, Color.ORANGE, "Huge Remains (Debug)"))); + findLargeRemains().ifPresent(remains -> + builder.highlight(EasyGOTRHighlightTarget.forTileObject(remains, Color.ORANGE, "Large Remains (Debug)"))); + findRegularRemains().ifPresent(remains -> + builder.highlight(EasyGOTRHighlightTarget.forTileObject(remains, Color.ORANGE, "Regular Remains (Debug)"))); + } + + if (config.debugHighlightRubble()) { + findClimbableRubble().ifPresent(rubble -> + builder.highlight(EasyGOTRHighlightTarget.forTileObject(rubble, Color.ORANGE, "Rubble (Debug)"))); + } + + if (config.debugHighlightDepositPool()) { + findDepositPool().ifPresent(pool -> + builder.highlight(EasyGOTRHighlightTarget.forTileObject(pool, Color.CYAN, "Deposit Pool (Debug)"))); + } + + if (config.debugHighlightUnchargedCells()) { + findUnchargedCells().ifPresent(cells -> + builder.highlight(EasyGOTRHighlightTarget.forTileObject(cells, Color.CYAN, "Uncharged Cells (Debug)"))); + } + + if (config.debugHighlightCellTiles()) { + TileObjects.search().nameContains("cell tile").result().forEach(tile -> + builder.highlight(EasyGOTRHighlightTarget.forTileObject(tile, Color.CYAN, "Cell Tile (Debug)"))); + } + + if (config.debugHighlightBindingNecklace()) { + Inventory.search().withId(ItemID.BINDING_NECKLACE).first().ifPresent(widget -> + builder.highlight(EasyGOTRHighlightTarget.forWidget(widget, Color.MAGENTA, "Binding Necklace (Debug)"))); + } + } + private void maybeHighlightBindingNecklace(EasyGOTRActionHint.EasyGOTRActionHintBuilder builder) { if (hasBindingNecklaceEquipped()) { return; diff --git a/src/main/java/ee/futur/easygotr/EasyGOTRWidgetOverlay.java b/src/main/java/ee/futur/easygotr/EasyGOTRWidgetOverlay.java index 546b9ed..bb72ffd 100644 --- a/src/main/java/ee/futur/easygotr/EasyGOTRWidgetOverlay.java +++ b/src/main/java/ee/futur/easygotr/EasyGOTRWidgetOverlay.java @@ -53,3 +53,5 @@ public class EasyGOTRWidgetOverlay extends Overlay { } } + + diff --git a/src/main/java/ee/futur/easygotr/GOTRState.java b/src/main/java/ee/futur/easygotr/GOTRState.java index d33bc29..51b289a 100644 --- a/src/main/java/ee/futur/easygotr/GOTRState.java +++ b/src/main/java/ee/futur/easygotr/GOTRState.java @@ -329,6 +329,17 @@ public class GOTRState { return catalyticAltar; } + // Early game: prioritize elemental altars for combination runes (polyelemental stones give +3 energy) + // Guide suggests focusing elemental until ~500-1000 points, then balance with catalytic + if (elemental < 500) { + // Prefer elemental early, but still use catalytic if it's very low (< 100) to avoid being too unbalanced + if (catalytic < 100) { + return catalyticAltar; + } + return elementalAltar; + } + + // Mid/late game: balance points (current logic) if (catalytic > elemental) { return elementalAltar; }