aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorKevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>2023-08-16 13:09:45 +0800
committerKevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>2023-08-30 22:49:54 -0400
commit69a6d8dde08a0d1710d4f6adabff2f2dd3fe65c9 (patch)
tree7740679d61cd60fb3a0bdcc6c3a601d46dfbd444 /src/main/java
parent3cfcfa8f0767563ca6d0e14df90b509bbc6ad812 (diff)
downloadSkyblocker-69a6d8dde08a0d1710d4f6adabff2f2dd3fe65c9.tar.gz
Skyblocker-69a6d8dde08a0d1710d4f6adabff2f2dd3fe65c9.tar.bz2
Skyblocker-69a6d8dde08a0d1710d4f6adabff2f2dd3fe65c9.zip
Reset and reattempt matching when matching fails
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/Room.java60
1 files changed, 39 insertions, 21 deletions
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 3af1f2c3..7467ccba 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
@@ -8,6 +8,7 @@ import com.google.gson.JsonObject;
import it.unimi.dsi.fastutil.ints.IntRBTreeSet;
import it.unimi.dsi.fastutil.ints.IntSortedSet;
import it.unimi.dsi.fastutil.ints.IntSortedSets;
+import me.xmrvizzy.skyblocker.SkyblockerMod;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.fabricmc.fabric.api.util.TriState;
import net.minecraft.block.BlockState;
@@ -43,7 +44,7 @@ public class Room {
@NotNull
private final Shape shape;
private HashMap<String, int[]> roomsData;
- private List<MutableTriple<Direction, Vector2ic, List<String>>> possibleRooms = new ArrayList<>();
+ private List<MutableTriple<Direction, Vector2ic, List<String>>> possibleRooms;
private Set<BlockPos> checkedBlocks = new HashSet<>();
private CompletableFuture<Void> findRoom;
/**
@@ -56,19 +57,13 @@ public class Room {
private Table<Integer, BlockPos, SecretWaypoint> secretWaypoints;
public Room(@NotNull Type type, @NotNull Vector2ic... physicalPositions) {
- long startTime = System.currentTimeMillis();
this.type = type;
segments = Set.of(physicalPositions);
IntSortedSet segmentsX = IntSortedSets.unmodifiable(new IntRBTreeSet(segments.stream().mapToInt(Vector2ic::x).toArray()));
IntSortedSet segmentsY = IntSortedSets.unmodifiable(new IntRBTreeSet(segments.stream().mapToInt(Vector2ic::y).toArray()));
shape = getShape(segmentsX, segmentsY);
roomsData = DungeonSecrets.ROOMS_DATA.get("catacombs").get(shape.shape);
- List<String> possibleDirectionRooms = new ArrayList<>(roomsData.keySet());
- for (Direction direction : getPossibleDirections(segmentsX, segmentsY)) {
- possibleRooms.add(MutableTriple.of(direction, DungeonMapUtils.getPhysicalCornerPos(direction, segmentsX, segmentsY), possibleDirectionRooms));
- }
- long endTime = System.currentTimeMillis();
- DungeonSecrets.LOGGER.info("Created {} in {} ms", this, endTime - startTime); // TODO change to debug
+ possibleRooms = getPossibleRooms(segmentsX, segmentsY);
}
@NotNull
@@ -96,6 +91,15 @@ public class Room {
};
}
+ private List<MutableTriple<Direction, Vector2ic, List<String>>> getPossibleRooms(IntSortedSet segmentsX, IntSortedSet segmentsY) {
+ List<String> possibleDirectionRooms = new ArrayList<>(roomsData.keySet());
+ List<MutableTriple<Direction, Vector2ic, List<String>>> possibleRooms = new ArrayList<>();
+ for (Direction direction : getPossibleDirections(segmentsX, segmentsY)) {
+ possibleRooms.add(MutableTriple.of(direction, DungeonMapUtils.getPhysicalCornerPos(direction, segmentsX, segmentsY), possibleDirectionRooms));
+ }
+ return possibleRooms;
+ }
+
@NotNull
private Direction[] getPossibleDirections(IntSortedSet segmentsX, IntSortedSet segmentsY) {
return switch (shape) {
@@ -138,7 +142,6 @@ 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)) {
- discard();
break;
}
}
@@ -174,17 +177,22 @@ public class Room {
int matchingRoomsSize = possibleRooms.stream().map(Triple::getRight).mapToInt(Collection::size).sum();
if (matchingRoomsSize == 0) {
+ // If no rooms match, reset the fields and scan again after 50 ticks.
matched = TriState.FALSE;
DungeonSecrets.LOGGER.warn("[Skyblocker] No dungeon room matches after checking {} block(s)", checkedBlocks.size());
+ SkyblockerMod.getInstance().scheduler.schedule(() -> matched = TriState.DEFAULT, 50);
+ reset();
return true;
} else if (matchingRoomsSize == 1) {
+ // If one room matches, load the secrets for that room and discard the no longer needed fields.
for (Triple<Direction, Vector2ic, List<String>> directionRooms : possibleRooms) {
if (directionRooms.getRight().size() == 1) {
roomMatched(directionRooms);
- break;
+ discard();
+ return true;
}
}
- return true;
+ 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
return false;
@@ -210,6 +218,26 @@ public class Room {
DungeonSecrets.LOGGER.info("[Skyblocker] Room {} matched after checking {} block(s)", name, checkedBlocks.size()); // TODO change to debug
}
+ /**
+ * Resets fields for another round of matching after room matching fails.
+ */
+ private void reset() {
+ IntSortedSet segmentsX = IntSortedSets.unmodifiable(new IntRBTreeSet(segments.stream().mapToInt(Vector2ic::x).toArray()));
+ IntSortedSet segmentsY = IntSortedSets.unmodifiable(new IntRBTreeSet(segments.stream().mapToInt(Vector2ic::y).toArray()));
+ possibleRooms = getPossibleRooms(segmentsX, segmentsY);
+ checkedBlocks = new HashSet<>();
+ }
+
+ /**
+ * Discards fields after room matching completes when a room is found.
+ * These fields are no longer needed and are discarded to save memory.
+ */
+ private void discard() {
+ roomsData = null;
+ possibleRooms = null;
+ checkedBlocks = null;
+ }
+
protected void render(WorldRenderContext context) {
for (SecretWaypoint secretWaypoint : secretWaypoints.values()) {
if (secretWaypoint.isMissing()) {
@@ -254,16 +282,6 @@ public class Room {
DungeonSecrets.LOGGER.info(msg, args);
}
- /**
- * 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 discard() {
- roomsData = null;
- possibleRooms = null;
- checkedBlocks = null;
- }
-
public enum Type {
ENTRANCE(MapColor.DARK_GREEN.getRenderColorByte(MapColor.Brightness.HIGH)),
ROOM(MapColor.ORANGE.getRenderColorByte(MapColor.Brightness.LOWEST)),