aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/me/xmrvizzy/skyblocker
diff options
context:
space:
mode:
authorKevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>2023-07-11 21:29:42 +0800
committerKevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>2023-08-30 22:49:49 -0400
commitd54ee77fb2c007b16bcc3d6b77acf008f948596d (patch)
tree928f8c5a30911cc623b0999486c3345f2dadb316 /src/main/java/me/xmrvizzy/skyblocker
parent2a13974954867ab519e5e2af8cffc629bbb5de24 (diff)
downloadSkyblocker-d54ee77fb2c007b16bcc3d6b77acf008f948596d.tar.gz
Skyblocker-d54ee77fb2c007b16bcc3d6b77acf008f948596d.tar.bz2
Skyblocker-d54ee77fb2c007b16bcc3d6b77acf008f948596d.zip
Add entrance pos and room width parsing
Diffstat (limited to 'src/main/java/me/xmrvizzy/skyblocker')
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java52
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java109
2 files changed, 124 insertions, 37 deletions
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java
new file mode 100644
index 00000000..9d1c7ccb
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java
@@ -0,0 +1,52 @@
+package me.xmrvizzy.skyblocker.skyblock.dungeon.secrets;
+
+import net.minecraft.block.MapColor;
+import net.minecraft.item.map.MapIcon;
+import net.minecraft.item.map.MapState;
+import org.joml.Vector2i;
+
+public class DungeonMapUtils {
+ public static final byte ENTRANCE_COLOR = MapColor.DARK_GREEN.getRenderColorByte(MapColor.Brightness.HIGH);
+ public static final byte ROOM_COLOR = MapColor.ORANGE.getRenderColorByte(MapColor.Brightness.LOWEST);
+ public static final byte PUZZLE_COLOR = MapColor.MAGENTA.getRenderColorByte(MapColor.Brightness.HIGH);
+ public static final byte MINIBOSS_COLOR = MapColor.YELLOW.getRenderColorByte(MapColor.Brightness.HIGH);
+ public static final byte FAIRY_COLOR = MapColor.PINK.getRenderColorByte(MapColor.Brightness.HIGH);
+ public static final byte BLOOD_COLOR = MapColor.BRIGHT_RED.getRenderColorByte(MapColor.Brightness.HIGH);
+ public static final byte UNKNOWN_COLOR = MapColor.GRAY.getRenderColorByte(MapColor.Brightness.NORMAL);
+ public static final byte BLACK_COLOR = MapColor.BLACK.getRenderColorByte(MapColor.Brightness.LOWEST);
+ public static final byte WHITE_COLOR = MapColor.WHITE.getRenderColorByte(MapColor.Brightness.HIGH);
+
+ public static Vector2i getEntrancePos(MapState map) {
+ for (MapIcon icon : map.getIcons()) {
+ if (icon.getType() == MapIcon.Type.FRAME) {
+ int x = (icon.getX() >> 1) + 64;
+ int z = (icon.getZ() >> 1) + 64;
+ if (getColor(map, x, z) == ENTRANCE_COLOR) {
+ while (getColor(map, x - 1, z) == ENTRANCE_COLOR) {
+ x--;
+ }
+ while (getColor(map, x, z - 1) == ENTRANCE_COLOR) {
+ z--;
+ }
+ return new Vector2i(x, z);
+ }
+ }
+ }
+ return null;
+ }
+
+ public static int getRoomWidth(MapState map, Vector2i entrancePos) {
+ int i = 0;
+ while (getColor(map, entrancePos.x + i, entrancePos.y) == ENTRANCE_COLOR) {
+ i++;
+ }
+ return i;
+ }
+
+ private static byte getColor(MapState map, int x, int z) {
+ if (x < 0 || z < 0 || x >= 128 || z >= 128) {
+ return -1;
+ }
+ return map.colors[x + (z << 7)];
+ }
+}
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 8be626d2..d293bb88 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
@@ -3,9 +3,15 @@ package me.xmrvizzy.skyblocker.skyblock.dungeon.secrets;
import com.google.gson.JsonObject;
import me.xmrvizzy.skyblocker.SkyblockerMod;
import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
+import me.xmrvizzy.skyblocker.utils.Utils;
import net.minecraft.client.MinecraftClient;
+import net.minecraft.item.FilledMapItem;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
+import net.minecraft.item.map.MapState;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.Nullable;
+import org.joml.Vector2i;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -21,13 +27,15 @@ import java.util.concurrent.CompletableFuture;
import java.util.zip.InflaterInputStream;
public class DungeonSecrets {
- private static final Logger LOGGER = LoggerFactory.getLogger(DungeonSecrets.class);
+ protected static final Logger LOGGER = LoggerFactory.getLogger(DungeonSecrets.class);
private static final String DUNGEONS_DATA_DIR = "/assets/skyblocker/dungeons";
private static final HashMap<String, HashMap<String, HashMap<String, long[]>>> ROOMS = new HashMap<>();
private static JsonObject roomsJson;
private static JsonObject waypointsJson;
@Nullable
private static CompletableFuture<Void> roomsLoaded;
+ private static Vector2i mapEntrancePos;
+ private static int mapRoomWidth;
public static boolean isRoomsLoaded() {
return roomsLoaded != null && roomsLoaded.isDone();
@@ -41,44 +49,47 @@ public class DungeonSecrets {
if (SkyblockerConfig.get().locations.dungeons.noLoadSecretWaypoints) {
return;
}
- CompletableFuture.runAsync(() -> {
- try {
- List<CompletableFuture<Void>> dungeonFutures = new ArrayList<>();
- //noinspection DataFlowIssue
- File dungeons = new File(SkyblockerMod.class.getResource(DUNGEONS_DATA_DIR).getFile());
- int resourcePathIndex = dungeons.getPath().indexOf(DUNGEONS_DATA_DIR);
- //noinspection DataFlowIssue
- for (File dungeon : dungeons.listFiles()) {
- if (!dungeon.isDirectory()) {
- continue;
- }
- File[] roomShapes = dungeon.listFiles();
- if (roomShapes == null) {
- LOGGER.error("Failed to load dungeon secrets for dungeon {}", dungeon.getName());
- continue;
- }
- ROOMS.put(dungeon.getName(), new HashMap<>());
- List<CompletableFuture<Void>> roomShapeFutures = new ArrayList<>();
- for (File roomShape : roomShapes) {
- roomShapeFutures.add(CompletableFuture.supplyAsync(() -> readRooms(roomShape, resourcePathIndex)).thenAccept(rooms -> ROOMS.get(dungeon.getName()).put(roomShape.getName(), rooms)));
- }
- 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())));
+ CompletableFuture.runAsync(DungeonSecrets::load);
+ SkyblockerMod.getInstance().scheduler.scheduleCyclic(DungeonSecrets::update, 10);
+ }
+
+ private static void load() {
+ try {
+ List<CompletableFuture<Void>> dungeonFutures = new ArrayList<>();
+ //noinspection DataFlowIssue
+ File dungeons = new File(SkyblockerMod.class.getResource(DUNGEONS_DATA_DIR).getFile());
+ int resourcePathIndex = dungeons.getPath().indexOf(DUNGEONS_DATA_DIR);
+ //noinspection DataFlowIssue
+ for (File dungeon : dungeons.listFiles()) {
+ if (!dungeon.isDirectory()) {
+ continue;
+ }
+ File[] roomShapes = dungeon.listFiles();
+ if (roomShapes == null) {
+ LOGGER.error("Failed to load dungeon secrets for dungeon {}", dungeon.getName());
+ continue;
+ }
+ ROOMS.put(dungeon.getName(), new HashMap<>());
+ List<CompletableFuture<Void>> roomShapeFutures = new ArrayList<>();
+ for (File roomShape : roomShapes) {
+ roomShapeFutures.add(CompletableFuture.supplyAsync(() -> readRooms(roomShape, resourcePathIndex)).thenAccept(rooms -> ROOMS.get(dungeon.getName()).put(roomShape.getName(), rooms)));
}
- // 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);
+ 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())));
}
- });
+ // 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);
+ }
}
private static HashMap<String, long[]> readRooms(File roomShape, int resourcePathIndex) {
@@ -101,4 +112,28 @@ public class DungeonSecrets {
LOGGER.debug("Loaded dungeon secrets room shape {} with {} rooms", roomShape.getName(), data.size());
return data;
}
+
+ private static void update() {
+ if (!SkyblockerConfig.get().locations.dungeons.secretWaypoints || !Utils.isInDungeons()) {
+ return;
+ }
+ MinecraftClient client = MinecraftClient.getInstance();
+ if (client.player == null || client.world == null) {
+ return;
+ }
+ ItemStack stack = client.player.getInventory().main.get(8);
+ if (!stack.isOf(Items.FILLED_MAP)) {
+ return;
+ }
+ MapState map = FilledMapItem.getMapState(FilledMapItem.getMapId(stack), client.world);
+ if (map == null) {
+ return;
+ }
+ if (mapEntrancePos == null && (mapEntrancePos = DungeonMapUtils.getEntrancePos(map)) == null) {
+ return;
+ }
+ if (mapRoomWidth == 0 && (mapRoomWidth = DungeonMapUtils.getRoomWidth(map, mapEntrancePos)) == 0) {
+ return;
+ }
+ }
}