From 96aa59888b553ed70bea666b0bd4ac6cba705b94 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Sat, 5 Aug 2023 16:52:53 +0800 Subject: Refactor Room --- .../skyblock/dungeon/secrets/DungeonSecrets.java | 2 +- .../skyblocker/skyblock/dungeon/secrets/Room.java | 76 ++++++++++------------ 2 files changed, 35 insertions(+), 43 deletions(-) (limited to 'src/main/java') 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 7c0a0afb..9e31fe5f 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 @@ -272,7 +272,7 @@ public class DungeonSecrets { } private static void render(WorldRenderContext context) { - if (SkyblockerConfig.get().locations.dungeons.secretWaypoints && Utils.isInDungeons() && currentRoom != null && currentRoom.getName() != null) { + if (SkyblockerConfig.get().locations.dungeons.secretWaypoints && Utils.isInDungeons() && currentRoom != null && currentRoom.isMatched()) { currentRoom.render(context); } } 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 85a20f0a..da3ea5eb 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 @@ -7,6 +7,7 @@ import it.unimi.dsi.fastutil.ints.IntSortedSet; import it.unimi.dsi.fastutil.ints.IntSortedSets; import me.xmrvizzy.skyblocker.utils.RenderHelper; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import net.fabricmc.fabric.api.util.TriState; import net.minecraft.block.MapColor; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayerEntity; @@ -23,7 +24,6 @@ import java.util.*; import java.util.concurrent.CompletableFuture; public class Room { - public static final String UNKNOWN_NAME = "Unknown"; private final Type type; private final Set segments; private final Shape shape; @@ -31,10 +31,14 @@ public class Room { private List>> possibleRooms = new ArrayList<>(); private Set checkedBlocks = new HashSet<>(); private CompletableFuture findRoom; - private String name; - private Direction direction; - private Vector2ic corner; - private final List secretWaypoints = new ArrayList<>(); + /** + * Represents the matching state of the room with the following possible values: + *
  • {@link TriState#DEFAULT} means that the room has not been checked, is being processed, or does not {@link Type#needsScanning() need to be processed}. + *
  • {@link TriState#FALSE} means that the room has been checked and there is no match. + *
  • {@link TriState#TRUE} means that the room has been checked and there is a match. + */ + private TriState matched = TriState.DEFAULT; + private List secretWaypoints; public Room(Type type, Vector2ic... physicalPositions) { long startTime = System.currentTimeMillis(); @@ -56,36 +60,23 @@ public class Room { return type; } - public String getName() { - return name; + public boolean isMatched() { + return matched == TriState.TRUE; } @Override public String toString() { - return "Room{type=" + type + ", shape=" + shape + ", name='" + name + "', direction=" + direction + ", corner=" + corner + ", segments=" + Arrays.toString(segments.toArray()) + "}"; + return "Room{type=" + type + ", shape=" + shape + ", matched=" + matched + ", segments=" + Arrays.toString(segments.toArray()) + "}"; } private Shape getShape(IntSortedSet segmentsX, IntSortedSet segmentsY) { - int segmentsSize = segments.size(); - if (segmentsSize == 1) { - return Shape.ONE_BY_ONE; - } - if (segmentsSize == 2) { - return Shape.ONE_BY_TWO; - } - if (segmentsSize == 3) { - if (segmentsX.size() == 2 && segmentsY.size() == 2) { - return Shape.L_SHAPE; - } - return Shape.ONE_BY_THREE; - } - if (segmentsSize == 4) { - if (segmentsX.size() == 2 && segmentsY.size() == 2) { - return Shape.TWO_BY_TWO; - } - return Shape.ONE_BY_FOUR; - } - throw new IllegalArgumentException("There are no matching room shapes with this set of physical positions: " + Arrays.toString(segments.toArray())); + return switch (segments.size()) { + case 1 -> Shape.ONE_BY_ONE; + case 2 -> Shape.ONE_BY_TWO; + case 3 -> segmentsX.size() == 2 && segmentsY.size() == 2 ? Shape.L_SHAPE : Shape.ONE_BY_THREE; + case 4 -> segmentsX.size() == 2 && segmentsY.size() == 2 ? Shape.TWO_BY_TWO : Shape.ONE_BY_FOUR; + default -> throw new IllegalArgumentException("There are no matching room shapes with this set of physical positions: " + Arrays.toString(segments.toArray())); + }; } private Direction[] getPossibleDirections(IntSortedSet segmentsX, IntSortedSet segmentsY) { @@ -116,7 +107,7 @@ public class Room { protected void update() { // Logical AND has higher precedence than logical OR - if (!type.needsScanning() || name != null || !DungeonSecrets.isRoomsLoaded() || findRoom != null && !findRoom.isDone()) { + if (!type.needsScanning() || matched != TriState.DEFAULT || !DungeonSecrets.isRoomsLoaded() || findRoom != null && !findRoom.isDone()) { return; } MinecraftClient client = MinecraftClient.getInstance(); @@ -129,7 +120,7 @@ public class Room { 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)) { - reset(); + discard(); break; } } @@ -153,9 +144,7 @@ public class Room { return false; } for (MutableTriple> directionRooms : possibleRooms) { - Direction direction = directionRooms.getLeft(); - BlockPos relative = DungeonMapUtils.actualToRelative(directionRooms.getMiddle(), direction, pos); - int block = posIdToInt(relative, id); + int block = posIdToInt(DungeonMapUtils.actualToRelative(directionRooms.getMiddle(), directionRooms.getLeft(), pos), id); List possibleDirectionRooms = new ArrayList<>(); for (String room : directionRooms.getRight()) { if (Arrays.binarySearch(roomsData.get(room), block) >= 0) { @@ -167,8 +156,8 @@ public class Room { int matchingRoomsSize = possibleRooms.stream().map(Triple::getRight).mapToInt(Collection::size).sum(); if (matchingRoomsSize == 0) { + matched = TriState.FALSE; DungeonSecrets.LOGGER.warn("[Skyblocker] No dungeon room matches after checking {} block(s)", checkedBlocks.size()); - name = UNKNOWN_NAME; return true; } else if (matchingRoomsSize == 1) { for (Triple> directionRooms : possibleRooms) { @@ -177,7 +166,6 @@ public class Room { break; } } - DungeonSecrets.LOGGER.info("[Skyblocker] Room {} matched after checking {} block(s)", name, checkedBlocks.size()); // TODO change to debug return true; } else { DungeonSecrets.LOGGER.info("[Skyblocker] {} rooms remaining after checking {} block(s)", matchingRoomsSize, checkedBlocks.size()); // TODO change to debug @@ -190,15 +178,16 @@ public class Room { } private void roomMatched(Triple> directionRooms) { - name = directionRooms.getRight().get(0); - direction = directionRooms.getLeft(); - corner = directionRooms.getMiddle(); + matched = TriState.TRUE; + secretWaypoints = new ArrayList<>(); + String name = directionRooms.getRight().get(0); for (JsonElement waypointElement : DungeonSecrets.getWaypointsJson().get(name).getAsJsonArray()) { JsonObject waypoint = waypointElement.getAsJsonObject(); - String name = waypoint.get("secretName").getAsString(); - int secretIndex = Integer.parseInt(Character.isDigit(name.charAt(1)) ? name.substring(0, 2) : name.substring(0, 1)); - secretWaypoints.add(new SecretWaypoint(secretIndex, getCategory(waypoint), DungeonMapUtils.relativeToActual(corner, direction, waypoint), true)); + String secretName = waypoint.get("secretName").getAsString(); + int secretIndex = Integer.parseInt(secretName.substring(0, Character.isDigit(secretName.charAt(1)) ? 2 : 1)); + secretWaypoints.add(new SecretWaypoint(secretIndex, getCategory(waypoint), DungeonMapUtils.relativeToActual(directionRooms.getMiddle(), directionRooms.getLeft(), waypoint), true)); } + DungeonSecrets.LOGGER.info("[Skyblocker] Room {} matched after checking {} block(s)", name, checkedBlocks.size()); // TODO change to debug } private SecretWaypoint.Category getCategory(JsonObject categoryJson) { @@ -228,7 +217,7 @@ public class Room { * Resets fields after room matching completes, where either a room is found or none matched. * These fields are no longer needed and are discarded to save memory. */ - private void reset() { + private void discard() { roomsData = null; possibleRooms = null; checkedBlocks = null; @@ -249,6 +238,9 @@ public class Room { this.color = color; } + /** + * @return whether this room type has secrets and needs to be scanned and matched. + */ private boolean needsScanning() { return switch (this) { case ROOM, PUZZLE, TRAP -> true; -- cgit