From 841cd822cd210396e9e951171471a0d47ad7bab3 Mon Sep 17 00:00:00 2001
From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>
Date: Wed, 16 Aug 2023 15:09:02 +0800
Subject: Remove development logging and add Javadocs
---
.../skyblock/dungeon/secrets/DungeonSecrets.java | 27 ++++++-
.../skyblocker/skyblock/dungeon/secrets/Room.java | 91 ++++++++++++++++++++--
2 files changed, 110 insertions(+), 8 deletions(-)
(limited to 'src/main/java/me/xmrvizzy')
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 bb01a39e..7bd1ab28 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
@@ -201,8 +201,31 @@ public class DungeonSecrets {
return null;
}
+ /**
+ * Updates the dungeon. The general idea is similar to the Dungeon Rooms Mod.
+ *
+ * When entering a new dungeon, this method:
+ *
+ * - Gets the upper left corner of entrance room on the map and saves it in {@link #mapEntrancePos}.
+ * - Gets the size of a room on the map in pixels and saves it in {@link #mapRoomSize}.
+ * - Gets the physical northwest corner position of the entrance room and saves it in {@link #physicalEntrancePos}.
+ * - Creates a new {@link Room} with {@link Room.Type} {@link Room.Type.ENTRANCE ENTRANCE} and sets {@link #currentRoom}.
+ *
+ * When processing an existing dungeon, this method:
+ *
+ * - Calculates the physical northwest corner and upper left corner on the map of the room the player is currently in.
+ * - Gets the room type based on the map color.
+ * - If the room has not been created (when the physical northwest corner is not in {@link #rooms}):
+ *
+ * - If the room type is {@link Room.Type.ROOM}, gets the northwest corner of all connected room segments with {@link DungeonMapUtils#getRoomSegments(MapState, Vector2ic, int, byte)}. (For example, a 1x2 room has two room segments.)
+ * - Create a new room.
+ *
+ * - Sets {@link #currentRoom} to the current room, either created from the previous step or from {@link #rooms}.
+ * - Calls {@link Room#update()} on {@link #currentRoom}.
+ *
+ */
+ @SuppressWarnings("JavadocReference")
private static void update() {
- long startTime = System.currentTimeMillis();
if (!SkyblockerConfig.get().locations.dungeons.secretWaypoints) {
return;
}
@@ -259,8 +282,6 @@ public class DungeonSecrets {
currentRoom = room;
}
currentRoom.update();
- long endTime = System.currentTimeMillis();
- LOGGER.info("[Skyblocker] Updated dungeon secrets in {} ms", endTime - startTime); // TODO change to debug
}
/**
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 7467ccba..53d12d74 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
@@ -41,11 +41,26 @@ public class Room {
private final Type type;
@NotNull
private final Set segments;
+ /**
+ * The shape of the room. See {@link #getShape(IntSortedSet, IntSortedSet)}.
+ */
@NotNull
private final Shape shape;
+ /**
+ * The room data containing all rooms for a specific dungeon and {@link #shape}.
+ */
private HashMap roomsData;
+ /**
+ * Contains all possible dungeon rooms for this room. The list is gradually shrunk by checking blocks until only one room is left.
+ */
private List>> possibleRooms;
+ /**
+ * Contains all blocks that have been checked to prevent checking the same block multiple times.
+ */
private Set checkedBlocks = new HashSet<>();
+ /**
+ * The task that is used to check blocks. This is used to ensure only one such task can run at a time.
+ */
private CompletableFuture findRoom;
/**
* Represents the matching state of the room with the following possible values:
@@ -127,6 +142,24 @@ public class Room {
};
}
+ /**
+ * Updates the room.
+ *
+ * This method returns immediately if any of the following conditions are met:
+ *
+ * - The room does not need to be scanned and matched. (When the room is not of type {@link Type.ROOM}, {@link Type.PUZZLE}, or {@link Type.TRAP}. See {@link Type#needsScanning()})
+ * - The room has been matched or failed to match and is on cooldown. See {@link #matched}.
+ * - {@link #findRoom The previous update} has not completed.
+ *
+ * Then this method tries to match this room through:
+ *
+ * - Iterate over a 11 by 11 by 11 box around the player.
+ * - Check it the block is part of this room and not part of a doorway. See {@link #segments} and {@link #notInDoorway(BlockPos)}.
+ * - Checks if the position has been checked and adds it to {@link #checkedBlocks}.
+ * - Calls {@link #checkBlock(ClientWorld, BlockPos)}
+ *
+ */
+ @SuppressWarnings("JavadocReference")
protected void update() {
// Logical AND has higher precedence than logical OR
if (!type.needsScanning() || matched != TriState.DEFAULT || !DungeonSecrets.isRoomsLoaded() || findRoom != null && !findRoom.isDone()) {
@@ -139,14 +172,11 @@ public class Room {
return;
}
findRoom = CompletableFuture.runAsync(() -> {
- long startTime = System.currentTimeMillis();
for (BlockPos pos : BlockPos.iterate(player.getBlockPos().add(-5, -5, -5), player.getBlockPos().add(5, 5, 5))) {
if (segments.contains(DungeonMapUtils.getPhysicalRoomPos(pos)) && notInDoorway(pos) && checkedBlocks.add(pos) && checkBlock(world, pos)) {
break;
}
}
- long endTime = System.currentTimeMillis();
- DungeonSecrets.LOGGER.info("[Skyblocker] Processed room in {} ms", endTime - startTime); // TODO change to debug
});
}
@@ -159,6 +189,43 @@ public class Room {
return (x < 13 || x > 17 || z > 2 && z < 28) && (z < 13 || z > 17 || x > 2 && x < 28);
}
+ /**
+ * Filters out dungeon rooms which does not contain the block at the given position.
+ *
+ * This method:
+ *
+ * - Checks if the block type is included in the dungeon rooms data. See {@link DungeonSecrets#NUMERIC_ID}.
+ * - For each possible direction:
+ *
+ * - Rotate and convert the position to a relative position. See {@link DungeonMapUtils#actualToRelative(Vector2ic, Direction, BlockPos)}.
+ * - Encode the block based on the relative position and the custom numeric block id. See {@link #posIdToInt(BlockPos, byte)}.
+ * - For each possible room in the current direction:
+ *
+ * - Check if {@link #roomsData} contains the encoded block.
+ * - If so, add the room to the new list of possible rooms for this direction.
+ *
+ * - Replace the old possible room list for the current direction with the new one.
+ *
+ * - If there are no matching rooms left:
+ *
+ * - Terminate matching by setting {@link #matched} to {@link TriState#FALSE}.
+ * - Schedule another matching attempt in 50 ticks (2.5 seconds).
+ * - Reset {@link #possibleRooms} and {@link #checkedBlocks} with {@link #reset()}.
+ * - Return {@code true}
+ *
+ * - If there are exactly one room matching:
+ *
+ * - Call {@link #roomMatched(Triple)}.
+ * - Discard the no longer needed fields to save memory.
+ * - Return {@code true}
+ *
+ * - Return {@code false}
+ *
+ *
+ * @param world the world to get the block from
+ * @param pos the position of the block to check
+ * @return whether room matching should end. Either a match is found or there are no valid rooms left
+ */
private boolean checkBlock(ClientWorld world, BlockPos pos) {
byte id = DungeonSecrets.NUMERIC_ID.getByte(Registries.BLOCK.getId(world.getBlockState(pos).getBlock()).toString());
if (id == 0) {
@@ -194,15 +261,29 @@ public class Room {
}
return false; // This should never happen, we just checked that there is one possible room, and the return true in the loop should activate
} else {
- DungeonSecrets.LOGGER.info("[Skyblocker] {} rooms remaining after checking {} block(s)", matchingRoomsSize, checkedBlocks.size()); // TODO change to debug
+ DungeonSecrets.LOGGER.debug("[Skyblocker] {} rooms remaining after checking {} block(s)", matchingRoomsSize, checkedBlocks.size());
return false;
}
}
+ /**
+ * Encodes a {@link BlockPos} and the custom numeric block id into an integer.
+ *
+ * @param pos the position of the block
+ * @param id the custom numeric block id
+ * @return the encoded integer
+ */
private int posIdToInt(BlockPos pos, byte id) {
return pos.getX() << 24 | pos.getY() << 16 | pos.getZ() << 8 | id;
}
+ /**
+ * Loads the secret waypoints for the room from {@link DungeonSecrets#waypointsJson} once it has been matched
+ * and sets {@link #matched} to {@link TriState#TRUE}.
+ *
+ * @param directionRooms the direction, position, and name of the room
+ */
+ @SuppressWarnings("JavadocReference")
private void roomMatched(Triple> directionRooms) {
Table secretWaypointsMutable = HashBasedTable.create();
String name = directionRooms.getRight().get(0);
@@ -215,7 +296,7 @@ public class Room {
}
secretWaypoints = ImmutableTable.copyOf(secretWaypointsMutable);
matched = TriState.TRUE;
- DungeonSecrets.LOGGER.info("[Skyblocker] Room {} matched after checking {} block(s)", name, checkedBlocks.size()); // TODO change to debug
+ DungeonSecrets.LOGGER.info("[Skyblocker] Room {} matched after checking {} block(s)", name, checkedBlocks.size());
}
/**
--
cgit