From 886153a396b899ba68654d15b81f4a4aaa42ee69 Mon Sep 17 00:00:00 2001 From: Julienraptor01 Date: Thu, 24 Aug 2023 12:09:24 +0200 Subject: small quicknav storage cause work in rift now (#252) they made so /storage in rift now open your 1st rift storage tab so i modified the regex to match it too --- src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/me/xmrvizzy/skyblocker/config') diff --git a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java index 104c9c7a..491ef8ea 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java @@ -79,7 +79,7 @@ public class SkyblockerConfig implements ConfigData { @ConfigEntry.Category("button6") @ConfigEntry.Gui.CollapsibleObject() - public QuickNavItem button6 = new QuickNavItem(true, new ItemData("ender_chest"), "Storage", "/storage"); + public QuickNavItem button6 = new QuickNavItem(true, new ItemData("ender_chest"), "(?:Rift )?Storage(?: \\(1/2\\))?", "/storage"); @ConfigEntry.Category("button7") @ConfigEntry.Gui.CollapsibleObject() -- cgit From 7bb19de683c70aeccea710d53ca3b13974a1c95d Mon Sep 17 00:00:00 2001 From: Aaron <51387595+AzureAaron@users.noreply.github.com> Date: Wed, 30 Aug 2023 00:32:20 -0400 Subject: Tic Tac Toe Solver! (#253) * Tic Tac Toe Solver! * alpha-beta-pruning * Small changes --------- Co-authored-by: Yasin --- .../java/me/xmrvizzy/skyblocker/SkyblockerMod.java | 3 + .../skyblocker/config/SkyblockerConfig.java | 2 + .../skyblocker/skyblock/dungeon/TicTacToe.java | 138 +++++++++++++++++++++ .../skyblocker/utils/tictactoe/TicTacToeUtils.java | 104 ++++++++++++++++ .../resources/assets/skyblocker/lang/en_us.json | 2 + 5 files changed, 249 insertions(+) create mode 100644 src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/TicTacToe.java create mode 100644 src/main/java/me/xmrvizzy/skyblocker/utils/tictactoe/TicTacToeUtils.java (limited to 'src/main/java/me/xmrvizzy/skyblocker/config') diff --git a/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java b/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java index 4ec579ae..3d1427a2 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java +++ b/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java @@ -10,6 +10,7 @@ import me.xmrvizzy.skyblocker.skyblock.*; import me.xmrvizzy.skyblocker.skyblock.dungeon.DungeonBlaze; import me.xmrvizzy.skyblocker.skyblock.dungeon.DungeonMap; import me.xmrvizzy.skyblocker.skyblock.dungeon.LividColor; +import me.xmrvizzy.skyblocker.skyblock.dungeon.TicTacToe; import me.xmrvizzy.skyblocker.skyblock.dwarven.DwarvenHud; import me.xmrvizzy.skyblocker.skyblock.item.CustomArmorDyeColors; import me.xmrvizzy.skyblocker.skyblock.item.CustomArmorTrims; @@ -94,10 +95,12 @@ public class SkyblockerMod implements ClientModInitializer { CustomItemNames.init(); CustomArmorDyeColors.init(); CustomArmorTrims.init(); + TicTacToe.init(); containerSolverManager.init(); scheduler.scheduleCyclic(Utils::update, 20); scheduler.scheduleCyclic(DiscordRPCManager::updateDataAndPresence, 100); scheduler.scheduleCyclic(DungeonBlaze::update, 4); + scheduler.scheduleCyclic(TicTacToe::tick, 4); scheduler.scheduleCyclic(LividColor::update, 10); scheduler.scheduleCyclic(BackpackPreview::tick, 50); scheduler.scheduleCyclic(DwarvenHud::update, 40); diff --git a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java index 491ef8ea..68ea596e 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java @@ -417,6 +417,8 @@ public class SkyblockerConfig implements ConfigData { @ConfigEntry.Gui.Tooltip public boolean blazesolver = true; public boolean solveTrivia = true; + @ConfigEntry.Gui.Tooltip + public boolean solveTicTacToe = true; @ConfigEntry.Gui.CollapsibleObject public LividColor lividColor = new LividColor(); @ConfigEntry.Gui.CollapsibleObject() diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/TicTacToe.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/TicTacToe.java new file mode 100644 index 00000000..f5d55d2c --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/TicTacToe.java @@ -0,0 +1,138 @@ +package me.xmrvizzy.skyblocker.skyblock.dungeon; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import me.xmrvizzy.skyblocker.config.SkyblockerConfig; +import me.xmrvizzy.skyblocker.utils.RenderUtils; +import me.xmrvizzy.skyblocker.utils.Utils; +import me.xmrvizzy.skyblocker.utils.color.QuadColor; +import me.xmrvizzy.skyblocker.utils.tictactoe.TicTacToeUtils; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.decoration.ItemFrameEntity; +import net.minecraft.item.FilledMapItem; +import net.minecraft.item.map.MapState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.Direction; + +/** + * Thanks to Danker for a reference implementation! + */ +public class TicTacToe { + private static final Logger LOGGER = LoggerFactory.getLogger(TicTacToe.class); + private static final QuadColor RED = QuadColor.single(1.0f, 0.0f, 0.0f, 1f); + private static Box nextBestMoveToMake = null; + + public static void init() { + WorldRenderEvents.BEFORE_DEBUG_RENDER.register(TicTacToe::solutionRenderer); + } + + public static void tick() { + MinecraftClient client = MinecraftClient.getInstance(); + ClientWorld world = client.world; + ClientPlayerEntity player = client.player; + + nextBestMoveToMake = null; + + if (world == null || player == null || !Utils.isInDungeons()) return; + + //Search within 21 blocks for item frames that contain maps + Box searchBox = new Box(player.getX() - 21, player.getY() - 21, player.getZ() - 21, player.getX() + 21, player.getY() + 21, player.getZ() + 21); + List itemFramesThatHoldMaps = world.getEntitiesByClass(ItemFrameEntity.class, searchBox, ItemFrameEntity::containsMap); + + try { + //Only attempt to solve if its the player's turn + if (itemFramesThatHoldMaps.size() != 9 && itemFramesThatHoldMaps.size() % 2 == 1) { + char[][] board = new char[3][3]; + BlockPos leftmostRow = null; + int sign = 1; + char facing = 'X'; + + for (ItemFrameEntity itemFrame : itemFramesThatHoldMaps) { + MapState mapState = world.getMapState(FilledMapItem.getMapName(itemFrame.getMapId().getAsInt())); + + if (mapState == null) continue; + + int column = 0, row; + sign = 1; + + //Find position of the item frame relative to where it is on the tic tac toe board + if (itemFrame.getHorizontalFacing() == Direction.SOUTH || itemFrame.getHorizontalFacing() == Direction.WEST) sign = -1; + BlockPos itemFramePos = BlockPos.ofFloored(itemFrame.getX(), itemFrame.getY(), itemFrame.getZ()); + + for (int i = 2; i >= 0; i--) { + int realI = i * sign; + BlockPos blockPos = itemFramePos; + + if (itemFrame.getX() % 0.5 == 0) { + blockPos = itemFramePos.add(realI, 0, 0); + } else if (itemFrame.getZ() % 0.5 == 0) { + blockPos = itemFramePos.add(0, 0, realI); + facing = 'Z'; + } + + Block block = world.getBlockState(blockPos).getBlock(); + if (block == Blocks.AIR || block == Blocks.STONE_BUTTON) { + leftmostRow = blockPos; + column = i; + + break; + } + } + + //Determine the row of the item frame + if (itemFrame.getY() == 72.5) { + row = 0; + } else if (itemFrame.getY() == 71.5) { + row = 1; + } else if (itemFrame.getY() == 70.5) { + row = 2; + } else { + continue; + } + + + //Get the color of the middle pixel of the map which determines whether its X or O + int middleColor = mapState.colors[8256] & 255; + + if (middleColor == 114) { + board[row][column] = 'X'; + } else if (middleColor == 33) { + board[row][column] = 'O'; + } + + int bestMove = TicTacToeUtils.getBestMove(board) - 1; + + if (leftmostRow != null) { + double drawX = facing == 'X' ? leftmostRow.getX() - sign * (bestMove % 3) : leftmostRow.getX(); + double drawY = 72 - (double) (bestMove / 3); + double drawZ = facing == 'Z' ? leftmostRow.getZ() - sign * (bestMove % 3) : leftmostRow.getZ(); + + nextBestMoveToMake = new Box(drawX, drawY, drawZ, drawX + 1, drawY + 1, drawZ + 1); + } + } + } + } catch (Exception e) { + LOGGER.error("[Skyblocker Tic Tac Toe] Encountered an exception while determining a tic tac toe solution!", e); + } + } + + private static void solutionRenderer(WorldRenderContext context) { + try { + if (SkyblockerConfig.get().locations.dungeons.solveTicTacToe && nextBestMoveToMake != null) { + RenderUtils.drawBoxOutline(nextBestMoveToMake, RED, 5); + } + } catch (Exception e) { + LOGGER.error("[Skyblocker Tic Tac Toe] Encountered an exception while rendering the tic tac toe solution!", e); + } + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/tictactoe/TicTacToeUtils.java b/src/main/java/me/xmrvizzy/skyblocker/utils/tictactoe/TicTacToeUtils.java new file mode 100644 index 00000000..5e5c8f89 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/utils/tictactoe/TicTacToeUtils.java @@ -0,0 +1,104 @@ +package me.xmrvizzy.skyblocker.utils.tictactoe; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public class TicTacToeUtils { + + public static int getBestMove(char[][] board) { + HashMap moves = new HashMap<>(); + for (int row = 0; row < board.length; row++) { + for (int col = 0; col < board[row].length; col++) { + if (board[row][col] != '\0') continue; + board[row][col] = 'O'; + int score = alphabeta(board, Integer.MIN_VALUE, Integer.MAX_VALUE, false, 0); + board[row][col] = '\0'; + moves.put(row * 3 + col + 1, score); + } + } + return Collections.max(moves.entrySet(), Map.Entry.comparingByValue()).getKey(); + } + + public static boolean hasMovesLeft(char[][] board) { + for (char[] rows : board) { + for (char col : rows) { + if (col == '\0') return true; + } + } + return false; + } + + public static int getBoardRanking(char[][] board) { + for (int row = 0; row < 3; row++) { + if (board[row][0] == board[row][1] && board[row][0] == board[row][2]) { + if (board[row][0] == 'X') { + return -10; + } else if (board[row][0] == 'O') { + return 10; + } + } + } + + for (int col = 0; col < 3; col++) { + if (board[0][col] == board[1][col] && board[0][col] == board[2][col]) { + if (board[0][col] == 'X') { + return -10; + } else if (board[0][col] == 'O') { + return 10; + } + } + } + + if (board[0][0] == board[1][1] && board[0][0] == board[2][2]) { + if (board[0][0] == 'X') { + return -10; + } else if (board[0][0] == 'O') { + return 10; + } + } else if (board[0][2] == board[1][1] && board[0][2] == board[2][0]) { + if (board[0][2] == 'X') { + return -10; + } else if (board[0][2] == 'O') { + return 10; + } + } + + return 0; + } + public static int alphabeta(char[][] board, int alpha, int beta, boolean max, int depth) { + int score = getBoardRanking(board); + if (score == 10 || score == -10) return score; + if (!hasMovesLeft(board)) return 0; + + if (max) { + int bestScore = Integer.MIN_VALUE; + for (int row = 0; row < 3; row++) { + for (int col = 0; col < 3; col++) { + if (board[row][col] == '\0') { + board[row][col] = 'O'; + bestScore = Math.max(bestScore, alphabeta(board, alpha, beta, false, depth + 1)); + board[row][col] = '\0'; + alpha = Math.max(alpha, bestScore); + if (beta <= alpha) break; // Pruning + } + } + } + return bestScore - depth; + } else { + int bestScore = Integer.MAX_VALUE; + for (int row = 0; row < 3; row++) { + for (int col = 0; col < 3; col++) { + if (board[row][col] == '\0') { + board[row][col] = 'X'; + bestScore = Math.min(bestScore, alphabeta(board, alpha, beta, true, depth + 1)); + board[row][col] = '\0'; + beta = Math.min(beta, bestScore); + if (beta <= alpha) break; // Pruning + } + } + } + return bestScore + depth; + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 39a215d2..ae24d9ed 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -208,6 +208,8 @@ "text.autoconfig.skyblocker.option.locations.dungeons.blazesolver": "Solve Blaze Puzzle", "text.autoconfig.skyblocker.option.locations.dungeons.blazesolver.@Tooltip": "Boxes the correct blaze in green, also draws a line to and boxes the next blaze to kill in white.", "text.autoconfig.skyblocker.option.locations.dungeons.solveTrivia": "Solve Trivia Puzzle", + "text.autoconfig.skyblocker.option.locations.dungeons.solveTicTacToe": "Solve Tic Tac Toe Puzzle", + "text.autoconfig.skyblocker.option.locations.dungeons.solveTicTacToe.@Tooltip": "Puts a red box around the next best move for you to make!", "text.autoconfig.skyblocker.option.locations.dungeons.lividColor": "Livid Color", "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor": "Enable Livid Color", "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor.@Tooltip": "Send the livid color in the chat during the Livid boss fight.", -- cgit From 44819b6eda32ec3dee637396c94f62bf0bcb0adc Mon Sep 17 00:00:00 2001 From: Aaron <51387595+AzureAaron@users.noreply.github.com> Date: Wed, 30 Aug 2023 21:26:21 -0400 Subject: Starred Mob Glow (#260) --- .../skyblocker/config/SkyblockerConfig.java | 2 + .../skyblocker/mixin/WorldRendererMixin.java | 33 ++++++++++++++ .../skyblock/dungeon/StarredMobGlow.java | 51 ++++++++++++++++++++++ .../resources/assets/skyblocker/lang/en_us.json | 2 + src/main/resources/skyblocker.mixins.json | 1 + 5 files changed, 89 insertions(+) create mode 100644 src/main/java/me/xmrvizzy/skyblocker/mixin/WorldRendererMixin.java create mode 100644 src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/StarredMobGlow.java (limited to 'src/main/java/me/xmrvizzy/skyblocker/config') diff --git a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java index 68ea596e..e6961819 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java @@ -413,6 +413,8 @@ public class SkyblockerConfig implements ConfigData { public float mapScaling = 1f; public int mapX = 2; public int mapY = 2; + @ConfigEntry.Gui.Tooltip + public boolean starredMobGlow = false; public boolean solveThreeWeirdos = true; @ConfigEntry.Gui.Tooltip public boolean blazesolver = true; diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/WorldRendererMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/WorldRendererMixin.java new file mode 100644 index 00000000..3b796c38 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/WorldRendererMixin.java @@ -0,0 +1,33 @@ +package me.xmrvizzy.skyblocker.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.sugar.Local; +import com.llamalad7.mixinextras.sugar.Share; +import com.llamalad7.mixinextras.sugar.ref.LocalBooleanRef; + +import me.xmrvizzy.skyblocker.config.SkyblockerConfig; +import me.xmrvizzy.skyblocker.skyblock.dungeon.StarredMobGlow; +import net.minecraft.client.render.WorldRenderer; +import net.minecraft.entity.Entity; + +@Mixin(WorldRenderer.class) +public class WorldRendererMixin { + + @ModifyExpressionValue(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;hasOutline(Lnet/minecraft/entity/Entity;)Z")) + private boolean skyblocker$shouldStarredMobGlow(boolean original, @Local Entity entity, @Share("isGlowingStarredMob") LocalBooleanRef isGlowingStarredMob) { + boolean isAStarredMobThatShouldGlow = SkyblockerConfig.get().locations.dungeons.starredMobGlow && StarredMobGlow.shouldMobGlow(entity); + + isGlowingStarredMob.set(isAStarredMobThatShouldGlow); + + return original || isAStarredMobThatShouldGlow; + } + + @ModifyVariable(method = "render", at = @At("STORE"), ordinal = 0) + private int skyblocker$modifyGlowColor(int color, @Local Entity entity, @Share("isGlowingStarredMob") LocalBooleanRef isGlowingStarredMob) { + return isGlowingStarredMob.get() ? StarredMobGlow.getGlowColor(entity) : color; + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/StarredMobGlow.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/StarredMobGlow.java new file mode 100644 index 00000000..b45242f9 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/StarredMobGlow.java @@ -0,0 +1,51 @@ +package me.xmrvizzy.skyblocker.skyblock.dungeon; + +import java.util.List; + +import me.xmrvizzy.skyblocker.utils.Utils; +import me.xmrvizzy.skyblocker.utils.culling.OcclusionCulling; +import net.minecraft.entity.Entity; +import net.minecraft.entity.decoration.ArmorStandEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.predicate.entity.EntityPredicates; +import net.minecraft.util.math.Box; + +public class StarredMobGlow { + + public static boolean shouldMobGlow(Entity entity) { + Box box = entity.getBoundingBox(); + + if (Utils.isInDungeons() && !entity.isInvisible() && OcclusionCulling.isVisible(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ)) { + //Minibosses + if (entity instanceof PlayerEntity) { + switch (entity.getName().getString()) { + case "Lost Adventurer": return true; + case "Shadow Assassin": return true; + case "Diamond Guy": return true; + } + } + + //Regular Mobs + if (!(entity instanceof ArmorStandEntity)) { + Box searchBox = box.expand(0, 2, 0); + List armorStands = entity.getWorld().getEntitiesByClass(ArmorStandEntity.class, searchBox, EntityPredicates.NOT_MOUNTED); + + if (!armorStands.isEmpty() && armorStands.get(0).getName().getString().contains("✯")) return true; + } + } + + return false; + } + + public static int getGlowColor(Entity entity) { + if (entity instanceof PlayerEntity) { + switch (entity.getName().getString()) { + case "Lost Adventurer": return 0xfee15c; + case "Shadow Assassin": return 0x5b2cb2; + case "Diamond Guy": return 0x57c2f7; + } + } + + return 0xf57738; + } +} diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index ae24d9ed..016d6d28 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -204,6 +204,8 @@ "text.autoconfig.skyblocker.option.locations.dungeons.mapScaling": "Map Scaling", "text.autoconfig.skyblocker.option.locations.dungeons.mapX": "Map X", "text.autoconfig.skyblocker.option.locations.dungeons.mapY": "Map Y", + "text.autoconfig.skyblocker.option.locations.dungeons.starredMobGlow": "Starred Mob Glow", + "text.autoconfig.skyblocker.option.locations.dungeons.starredMobGlow.@Tooltip": "Applies the glowing effect to starred mobs that are visible.", "text.autoconfig.skyblocker.option.locations.dungeons.solveThreeWeirdos": "Solve Three Weirdos Puzzle", "text.autoconfig.skyblocker.option.locations.dungeons.blazesolver": "Solve Blaze Puzzle", "text.autoconfig.skyblocker.option.locations.dungeons.blazesolver.@Tooltip": "Boxes the correct blaze in green, also draws a line to and boxes the next blaze to kill in white.", diff --git a/src/main/resources/skyblocker.mixins.json b/src/main/resources/skyblocker.mixins.json index 266a653b..6ba7dc22 100644 --- a/src/main/resources/skyblocker.mixins.json +++ b/src/main/resources/skyblocker.mixins.json @@ -19,6 +19,7 @@ "PlayerListHudMixin", "PlayerSkinProviderMixin", "ScoreboardMixin", + "WorldRendererMixin", "accessor.BeaconBlockEntityRendererInvoker", "accessor.FrustumInvoker", "accessor.HandledScreenAccessor", -- cgit From 2a13974954867ab519e5e2af8cffc629bbb5de24 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Tue, 11 Jul 2023 10:39:38 +0800 Subject: Add Dungeon Secret Waypoint options --- .../skyblocker/config/SkyblockerConfig.java | 2 ++ .../skyblock/dungeon/secrets/DungeonSecrets.java | 36 +++++++++++++++------- .../resources/assets/skyblocker/lang/en_us.json | 3 ++ 3 files changed, 30 insertions(+), 11 deletions(-) (limited to 'src/main/java/me/xmrvizzy/skyblocker/config') diff --git a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java index e6961819..c7b84b25 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java @@ -407,6 +407,8 @@ public class SkyblockerConfig implements ConfigData { } public static class Dungeons { + public boolean secretWaypoints = true; + public boolean noLoadSecretWaypoints = false; @ConfigEntry.Gui.Tooltip() public boolean croesusHelper = true; public boolean enableMap = true; diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java index 6e72c1c4..8be626d2 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java @@ -2,6 +2,7 @@ package me.xmrvizzy.skyblocker.skyblock.dungeon.secrets; import com.google.gson.JsonObject; import me.xmrvizzy.skyblocker.SkyblockerMod; +import me.xmrvizzy.skyblocker.config.SkyblockerConfig; import net.minecraft.client.MinecraftClient; import net.minecraft.util.Identifier; import org.jetbrains.annotations.Nullable; @@ -12,7 +13,10 @@ import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.ObjectInputStream; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.zip.InflaterInputStream; @@ -29,10 +33,17 @@ public class DungeonSecrets { return roomsLoaded != null && roomsLoaded.isDone(); } + /** + * Loads the dungeon secrets asynchronously from {@code /assets/skyblocker/dungeons}. + * Use {@link #isRoomsLoaded()} to check for completion of loading. + */ public static void init() { + if (SkyblockerConfig.get().locations.dungeons.noLoadSecretWaypoints) { + return; + } CompletableFuture.runAsync(() -> { - List> dungeonFutures = Collections.synchronizedList(new ArrayList<>()); try { + List> dungeonFutures = new ArrayList<>(); //noinspection DataFlowIssue File dungeons = new File(SkyblockerMod.class.getResource(DUNGEONS_DATA_DIR).getFile()); int resourcePathIndex = dungeons.getPath().indexOf(DUNGEONS_DATA_DIR); @@ -53,17 +64,20 @@ public class DungeonSecrets { } dungeonFutures.add(CompletableFuture.allOf(roomShapeFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.debug("Loaded dungeon secrets for dungeon {} with {} room shapes and {} rooms total", dungeon.getName(), ROOMS.get(dungeon.getName()).size(), ROOMS.get(dungeon.getName()).values().stream().mapToInt(HashMap::size).sum()))); } - } catch (NullPointerException e) { + // Execute with MinecraftClient as executor since we need to wait for MinecraftClient#resourceManager to be set + dungeonFutures.add(CompletableFuture.runAsync(() -> { + try (BufferedReader roomsReader = MinecraftClient.getInstance().getResourceManager().openAsReader(new Identifier(SkyblockerMod.NAMESPACE, "dungeons/dungeonrooms.json")); BufferedReader waypointsReader = MinecraftClient.getInstance().getResourceManager().openAsReader(new Identifier(SkyblockerMod.NAMESPACE, "dungeons/secretlocations.json"))) { + roomsJson = SkyblockerMod.GSON.fromJson(roomsReader, JsonObject.class); + waypointsJson = SkyblockerMod.GSON.fromJson(waypointsReader, JsonObject.class); + LOGGER.debug("Loaded dungeon secrets json"); + } catch (Exception e) { + LOGGER.error("Failed to load dungeon secrets json", e); + } + }, MinecraftClient.getInstance())); + roomsLoaded = CompletableFuture.allOf(dungeonFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Loaded dungeon secrets for {} dungeon(s), {} room shapes, and {} rooms total", ROOMS.size(), ROOMS.values().stream().mapToInt(HashMap::size).sum(), ROOMS.values().stream().map(HashMap::values).flatMap(Collection::stream).mapToInt(HashMap::size).sum())); + } catch (Exception e) { LOGGER.error("Failed to load dungeon secrets", e); } - try (BufferedReader roomsReader = MinecraftClient.getInstance().getResourceManager().openAsReader(new Identifier(SkyblockerMod.NAMESPACE, "dungeons/dungeonrooms.json")); BufferedReader waypointsReader = MinecraftClient.getInstance().getResourceManager().openAsReader(new Identifier(SkyblockerMod.NAMESPACE, "dungeons/secretlocations.json"))) { - roomsJson = SkyblockerMod.GSON.fromJson(roomsReader, JsonObject.class); - waypointsJson = SkyblockerMod.GSON.fromJson(waypointsReader, JsonObject.class); - LOGGER.debug("Loaded dungeon secrets json"); - } catch (IOException e) { - LOGGER.error("Failed to load dungeon secrets json", e); - } - roomsLoaded = CompletableFuture.allOf(dungeonFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Loaded dungeon secrets for {} dungeon(s), {} room shapes, and {} rooms total", ROOMS.size(), ROOMS.values().stream().mapToInt(HashMap::size).sum(), ROOMS.values().stream().map(HashMap::values).flatMap(Collection::stream).mapToInt(HashMap::size).sum())); }); } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 016d6d28..16684a41 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -198,6 +198,9 @@ "text.autoconfig.skyblocker.option.locations.barn.solveHungryHiker": "Solve Hungry Hiker", "text.autoconfig.skyblocker.option.locations.barn.solveTreasureHunter": "Solve Treasure Hunter", "text.autoconfig.skyblocker.option.locations.dungeons": "Dungeons", + "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints": "Dungeon Secret Waypoints", + "text.autoconfig.skyblocker.option.locations.dungeons.noLoadSecretWaypoints": "Not Load Secret Waypoints", + "text.autoconfig.skyblocker.option.locations.dungeons.noLoadSecretWaypoints.@Tooltip": "This option can save around 40 MB of ram if enabled, but Secret Waypoint will require a restart after turning off this option to work.", "text.autoconfig.skyblocker.option.locations.dungeons.croesusHelper": "Croesus Helper", "text.autoconfig.skyblocker.option.locations.dungeons.croesusHelper.@Tooltip": "Gray out chests that have already been opened.", "text.autoconfig.skyblocker.option.locations.dungeons.enableMap": "Enable Map", -- cgit From 7257ed162b44bcbe49241d4177e25981bdb32092 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Mon, 31 Jul 2023 12:17:20 +0800 Subject: Add secrets resetting --- .../skyblocker/config/SkyblockerConfig.java | 2 +- .../skyblock/dungeon/secrets/DungeonSecrets.java | 39 +++++++++++++++++----- .../skyblocker/skyblock/dungeon/secrets/Room.java | 2 +- .../resources/assets/skyblocker/lang/en_us.json | 4 +-- 4 files changed, 35 insertions(+), 12 deletions(-) (limited to 'src/main/java/me/xmrvizzy/skyblocker/config') diff --git a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java index c7b84b25..8da4bb41 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java @@ -408,7 +408,7 @@ public class SkyblockerConfig implements ConfigData { public static class Dungeons { public boolean secretWaypoints = true; - public boolean noLoadSecretWaypoints = false; + public boolean noInitSecretWaypoints = false; @ConfigEntry.Gui.Tooltip() public boolean croesusHelper = true; public boolean enableMap = true; diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java index 94529726..7c0a0afb 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java @@ -16,6 +16,7 @@ import net.minecraft.item.Items; import net.minecraft.item.map.MapState; import net.minecraft.text.Text; import net.minecraft.util.Identifier; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.joml.Vector2ic; import org.slf4j.Logger; @@ -79,6 +80,7 @@ public class DungeonSecrets { /** * The map position of the top left corner of the entrance room. */ + @Nullable private static Vector2ic mapEntrancePos; /** * The size of a room on the map. @@ -87,7 +89,9 @@ public class DungeonSecrets { /** * The physical position of the northwest corner of the entrance room. */ + @Nullable private static Vector2ic physicalEntrancePos; + @NotNull private static final Map rooms = new HashMap<>(); private static Room currentRoom; @@ -108,7 +112,7 @@ public class DungeonSecrets { * Use {@link #isRoomsLoaded()} to check for completion of loading. */ public static void init() { - if (SkyblockerConfig.get().locations.dungeons.noLoadSecretWaypoints) { + if (SkyblockerConfig.get().locations.dungeons.noInitSecretWaypoints) { return; } CompletableFuture.runAsync(DungeonSecrets::load); @@ -186,7 +190,13 @@ public class DungeonSecrets { private static void update() { long startTime = System.currentTimeMillis(); - if (!SkyblockerConfig.get().locations.dungeons.secretWaypoints || !Utils.isInDungeons()) { + if (!SkyblockerConfig.get().locations.dungeons.secretWaypoints) { + return; + } + if (!Utils.isInDungeons()) { + if (mapEntrancePos != null) { + reset(); + } return; } MinecraftClient client = MinecraftClient.getInstance(); @@ -229,8 +239,7 @@ public class DungeonSecrets { if (room == null) { switch (type) { case ENTRANCE, PUZZLE, TRAP, MINIBOSS, FAIRY, BLOOD -> room = newRoom(type, physicalPos); - case ROOM -> - room = newRoom(type, DungeonMapUtils.getPhysicalPosFromMap(mapEntrancePos, mapRoomSize, physicalEntrancePos, DungeonMapUtils.getRoomSegments(map, mapPos, mapRoomSize, type.color))); + case ROOM -> room = newRoom(type, DungeonMapUtils.getPhysicalPosFromMap(mapEntrancePos, mapRoomSize, physicalEntrancePos, DungeonMapUtils.getRoomSegments(map, mapPos, mapRoomSize, type.color))); } } if (room != null && currentRoom != room) { @@ -248,12 +257,18 @@ public class DungeonSecrets { * @param type the type of room to create * @param physicalPositions the physical positions of the room */ + @Nullable private static Room newRoom(Room.Type type, Vector2ic... physicalPositions) { - Room newRoom = new Room(type, physicalPositions); - for (Vector2ic physicalPos : physicalPositions) { - rooms.put(physicalPos, newRoom); + try { + Room newRoom = new Room(type, physicalPositions); + for (Vector2ic physicalPos : physicalPositions) { + rooms.put(physicalPos, newRoom); + } + return newRoom; + } catch (IllegalArgumentException e) { + LOGGER.error("[Skyblocker] Failed to create room", e); } - return newRoom; + return null; } private static void render(WorldRenderContext context) { @@ -261,4 +276,12 @@ public class DungeonSecrets { currentRoom.render(context); } } + + private static void reset() { + mapEntrancePos = null; + mapRoomSize = 0; + physicalEntrancePos = null; + rooms.clear(); + currentRoom = null; + } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/Room.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/Room.java index 84510997..0eae2793 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/Room.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/Room.java @@ -97,7 +97,7 @@ public class Room { } else if (segmentsX.size() == 1 && segmentsY.size() > 1) { yield new Direction[]{Direction.NE, Direction.SW}; } - throw new IllegalStateException("Shape " + shape.shape + " does not match segments: " + Arrays.toString(segments.toArray())); + throw new IllegalArgumentException("Shape " + shape.shape + " does not match segments: " + Arrays.toString(segments.toArray())); } case L_SHAPE -> { if (!segments.contains(new Vector2i(segmentsX.firstInt(), segmentsY.firstInt()))) { diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 90dfa3b9..842c4591 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -199,8 +199,8 @@ "text.autoconfig.skyblocker.option.locations.barn.solveTreasureHunter": "Solve Treasure Hunter", "text.autoconfig.skyblocker.option.locations.dungeons": "Dungeons", "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints": "Dungeon Secret Waypoints", - "text.autoconfig.skyblocker.option.locations.dungeons.noLoadSecretWaypoints": "Not Load Secret Waypoints", - "text.autoconfig.skyblocker.option.locations.dungeons.noLoadSecretWaypoints.@Tooltip": "This option can save around 20 MB of ram if enabled, but Secret Waypoint will require a restart after turning off this option to work.", + "text.autoconfig.skyblocker.option.locations.dungeons.noInitSecretWaypoints": "Do Not Initialize Secret Waypoints", + "text.autoconfig.skyblocker.option.locations.dungeons.noInitSecretWaypoints.@Tooltip": "This option can save around 20 MB of ram if enabled, but Secret Waypoint will require a restart after turning off this option to work.", "text.autoconfig.skyblocker.option.locations.dungeons.croesusHelper": "Croesus Helper", "text.autoconfig.skyblocker.option.locations.dungeons.croesusHelper.@Tooltip": "Gray out chests that have already been opened.", "text.autoconfig.skyblocker.option.locations.dungeons.enableMap": "Enable Map", -- cgit From f51e8de1532b7fe052fe518638f46e9e5c5fd602 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Sun, 20 Aug 2023 14:08:57 +0800 Subject: Make waypoint categories toggleable --- .../skyblocker/config/SkyblockerConfig.java | 22 ++++++++++++-- .../skyblock/dungeon/secrets/DungeonSecrets.java | 6 ++-- .../skyblocker/skyblock/dungeon/secrets/Room.java | 2 +- .../skyblock/dungeon/secrets/SecretWaypoint.java | 34 +++++++++++++--------- .../resources/assets/skyblocker/lang/en_us.json | 16 ++++++++-- 5 files changed, 59 insertions(+), 21 deletions(-) (limited to 'src/main/java/me/xmrvizzy/skyblocker/config') diff --git a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java index 8da4bb41..6ddbdf65 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java @@ -407,8 +407,8 @@ public class SkyblockerConfig implements ConfigData { } public static class Dungeons { - public boolean secretWaypoints = true; - public boolean noInitSecretWaypoints = false; + @ConfigEntry.Gui.CollapsibleObject + public SecretWaypoints secretWaypoints = new SecretWaypoints(); @ConfigEntry.Gui.Tooltip() public boolean croesusHelper = true; public boolean enableMap = true; @@ -429,6 +429,24 @@ public class SkyblockerConfig implements ConfigData { public Terminals terminals = new Terminals(); } + public static class SecretWaypoints { + + public boolean enableSecretWaypoints = true; + @ConfigEntry.Gui.Tooltip() + public boolean noInitSecretWaypoints = false; + public boolean enableEntranceWaypoints = true; + public boolean enableSuperboomWaypoints = true; + public boolean enableChestWaypoints = true; + public boolean enableItemWaypoints = true; + public boolean enableBatWaypoints = true; + public boolean enableWitherWaypoints = true; + public boolean enableLeverWaypoints = true; + public boolean enableFairySoulWaypoints = true; + public boolean enableStonkWaypoints = true; + @ConfigEntry.Gui.Tooltip() + public boolean enableDefaultWaypoints = true; + } + public static class LividColor { @ConfigEntry.Gui.Tooltip() public boolean enableLividColor = true; diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java index 889c2829..11139971 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java @@ -120,7 +120,7 @@ public class DungeonSecrets { * Use {@link #isRoomsLoaded()} to check for completion of loading. */ public static void init() { - if (SkyblockerConfig.get().locations.dungeons.noInitSecretWaypoints) { + if (SkyblockerConfig.get().locations.dungeons.secretWaypoints.noInitSecretWaypoints) { return; } // Execute with MinecraftClient as executor since we need to wait for MinecraftClient#resourceManager to be set @@ -210,7 +210,7 @@ public class DungeonSecrets { */ @SuppressWarnings("JavadocReference") private static void update() { - if (!SkyblockerConfig.get().locations.dungeons.secretWaypoints) { + if (!SkyblockerConfig.get().locations.dungeons.secretWaypoints.enableSecretWaypoints) { return; } if (!Utils.isInDungeons()) { @@ -378,7 +378,7 @@ public class DungeonSecrets { * @return whether dungeon secrets should be processed */ private static boolean shouldProcess() { - return SkyblockerConfig.get().locations.dungeons.secretWaypoints && Utils.isInDungeons(); + return SkyblockerConfig.get().locations.dungeons.secretWaypoints.enableSecretWaypoints && Utils.isInDungeons(); } /** diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/Room.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/Room.java index 0904a7f1..383e246d 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/Room.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/Room.java @@ -324,7 +324,7 @@ public class Room { */ protected void render(WorldRenderContext context) { for (SecretWaypoint secretWaypoint : secretWaypoints.values()) { - if (secretWaypoint.isMissing()) { + if (secretWaypoint.shouldRender()) { secretWaypoint.render(context); } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java index 96fd7374..73a03fbc 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java @@ -1,6 +1,7 @@ package me.xmrvizzy.skyblocker.skyblock.dungeon.secrets; import com.google.gson.JsonObject; +import me.xmrvizzy.skyblocker.config.SkyblockerConfig; import me.xmrvizzy.skyblocker.utils.RenderHelper; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; import net.minecraft.client.MinecraftClient; @@ -10,6 +11,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import java.util.List; +import java.util.function.Predicate; public class SecretWaypoint { static final List SECRET_ITEMS = List.of("Decoy", "Defuse Kit", "Dungeon Chest Key", "Healing VIII", "Inflatable Jerry", "Spirit Leap", "Training Weights", "Trap", "Treasure Talisman"); @@ -29,8 +31,8 @@ public class SecretWaypoint { this.missing = true; } - public boolean isMissing() { - return missing; + public boolean shouldRender() { + return category.isEnabled() && missing; } public void setFound() { @@ -49,19 +51,21 @@ public class SecretWaypoint { } enum Category { - ENTRANCE(0, 255, 0), - SUPERBOOM(255, 0, 0), - CHEST(2, 213, 250), - ITEM(2, 64, 250), - BAT(142, 66, 0), - WITHER(30, 30, 30), - LEVER(250, 217, 2), - FAIRYSOUL(255, 85, 255), - STONK(146, 52, 235), - DEFAULT(190, 255, 252); + ENTRANCE(secretWaypoints -> secretWaypoints.enableEntranceWaypoints, 0, 255, 0), + SUPERBOOM(secretWaypoints -> secretWaypoints.enableSuperboomWaypoints, 255, 0, 0), + CHEST(secretWaypoints -> secretWaypoints.enableChestWaypoints, 2, 213, 250), + ITEM(secretWaypoints -> secretWaypoints.enableItemWaypoints, 2, 64, 250), + BAT(secretWaypoints -> secretWaypoints.enableBatWaypoints, 142, 66, 0), + WITHER(secretWaypoints -> secretWaypoints.enableWitherWaypoints, 30, 30, 30), + LEVER(secretWaypoints -> secretWaypoints.enableLeverWaypoints, 250, 217, 2), + FAIRYSOUL(secretWaypoints -> secretWaypoints.enableFairySoulWaypoints, 255, 85, 255), + STONK(secretWaypoints -> secretWaypoints.enableStonkWaypoints, 146, 52, 235), + DEFAULT(secretWaypoints -> secretWaypoints.enableDefaultWaypoints, 190, 255, 252); + private final Predicate enabledPredicate; private final float[] colorComponents; - Category(int... intColorComponents) { + Category(Predicate enabledPredicate, int... intColorComponents) { + this.enabledPredicate = enabledPredicate; colorComponents = new float[intColorComponents.length]; for (int i = 0; i < intColorComponents.length; i++) { colorComponents[i] = intColorComponents[i] / 255F; @@ -90,5 +94,9 @@ public class SecretWaypoint { boolean needsItemPickup() { return this == ITEM || this == BAT; } + + boolean isEnabled() { + return enabledPredicate.test(SkyblockerConfig.get().locations.dungeons.secretWaypoints); + } } } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 842c4591..59cfdcf5 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -199,8 +199,20 @@ "text.autoconfig.skyblocker.option.locations.barn.solveTreasureHunter": "Solve Treasure Hunter", "text.autoconfig.skyblocker.option.locations.dungeons": "Dungeons", "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints": "Dungeon Secret Waypoints", - "text.autoconfig.skyblocker.option.locations.dungeons.noInitSecretWaypoints": "Do Not Initialize Secret Waypoints", - "text.autoconfig.skyblocker.option.locations.dungeons.noInitSecretWaypoints.@Tooltip": "This option can save around 20 MB of ram if enabled, but Secret Waypoint will require a restart after turning off this option to work.", + "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableSecretWaypoints": "Enable Dungeon Secret Waypoints", + "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.noInitSecretWaypoints": "Do Not Initialize Secret Waypoints", + "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.noInitSecretWaypoints.@Tooltip": "This option can save around 20 MB of ram if enabled, but Secret Waypoint will require a restart after turning off this option to work.", + "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableEntranceWaypoints" : "Enable Entrance Waypoints", + "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableSuperboomWaypoints" : "Enable Superboom Waypoints", + "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableChestWaypoints" : "Enable Chest Waypoints", + "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableItemWaypoints" : "Enable Item Waypoints", + "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableBatWaypoints" : "Enable Bat Waypoints", + "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableWitherWaypoints" : "Enable Wither Essence Waypoints", + "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableLeverWaypoints" : "Enable Lever Waypoints", + "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableFairySoulWaypoints" : "Enable Fairy Soul Waypoints", + "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableStonkWaypoints" : "Enable Stonk Waypoints", + "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableDefaultWaypoints" : "Enable Default Waypoints", + "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableDefaultWaypoints.@Tooltip" : "This includes all waypoints that do not belong to a category.", "text.autoconfig.skyblocker.option.locations.dungeons.croesusHelper": "Croesus Helper", "text.autoconfig.skyblocker.option.locations.dungeons.croesusHelper.@Tooltip": "Gray out chests that have already been opened.", "text.autoconfig.skyblocker.option.locations.dungeons.enableMap": "Enable Map", -- cgit