aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de/hysky/skyblocker/skyblock
diff options
context:
space:
mode:
authorKevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>2023-12-20 23:00:48 +0800
committerKevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>2023-12-21 09:57:36 +0800
commit66b6be50ed9480d2d6e442c21ad16ed4bd48b2d6 (patch)
tree61d5609bd7ee393a06327d95010dcb44d0becbb4 /src/main/java/de/hysky/skyblocker/skyblock
parent88eb4ce59bead62d86b8cece7a8be8e30a740e01 (diff)
downloadSkyblocker-66b6be50ed9480d2d6e442c21ad16ed4bd48b2d6.tar.gz
Skyblocker-66b6be50ed9480d2d6e442c21ad16ed4bd48b2d6.tar.bz2
Skyblocker-66b6be50ed9480d2d6e442c21ad16ed4bd48b2d6.zip
Render match against command
Diffstat (limited to 'src/main/java/de/hysky/skyblocker/skyblock')
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DebugRoom.java38
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java43
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java56
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java4
5 files changed, 111 insertions, 32 deletions
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DebugRoom.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DebugRoom.java
index 93e4be6e..b686607b 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DebugRoom.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DebugRoom.java
@@ -1,10 +1,48 @@
package de.hysky.skyblocker.skyblock.dungeon.secrets;
+import de.hysky.skyblocker.utils.waypoint.Waypoint;
+import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
+import net.minecraft.client.world.ClientWorld;
+import net.minecraft.registry.Registries;
+import net.minecraft.util.math.BlockPos;
+import org.apache.commons.lang3.tuple.MutableTriple;
import org.jetbrains.annotations.NotNull;
import org.joml.Vector2ic;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
public class DebugRoom extends Room {
+ private final List<Waypoint> checkedBlocks = Collections.synchronizedList(new ArrayList<>());
+
public DebugRoom(@NotNull Type type, @NotNull Vector2ic... physicalPositions) {
super(type, physicalPositions);
}
+
+ @Override
+ protected boolean checkBlock(ClientWorld world, BlockPos pos) {
+ byte id = DungeonManager.NUMERIC_ID.getByte(Registries.BLOCK.getId(world.getBlockState(pos).getBlock()).toString());
+ if (id == 0) {
+ return false;
+ }
+ for (MutableTriple<Direction, Vector2ic, List<String>> directionRooms : possibleRooms) {
+ int block = posIdToInt(DungeonMapUtils.actualToRelative(directionRooms.getLeft(), directionRooms.getMiddle(), pos), id);
+ for (String room : directionRooms.getRight()) {
+ checkedBlocks.add(new Waypoint(pos, SecretWaypoint.TYPE_SUPPLIER, Arrays.binarySearch(roomsData.get(room), block) >= 0 ? Room.GREEN_COLOR_COMPONENTS : Room.RED_COLOR_COMPONENTS));
+ }
+ }
+ return false;
+ }
+
+ @Override
+ protected void render(WorldRenderContext context) {
+ super.render(context);
+ synchronized (checkedBlocks) {
+ for (Waypoint checkedBlock : checkedBlocks) {
+ checkedBlock.render(context);
+ }
+ }
+ }
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java
index 4364abff..52915b98 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java
@@ -14,6 +14,7 @@ import com.mojang.serialization.JsonOps;
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.config.SkyblockerConfig;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import de.hysky.skyblocker.debug.Debug;
import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.scheduler.Scheduler;
@@ -158,11 +159,13 @@ public class DungeonManager {
@SuppressWarnings("unused")
public static JsonObject getRoomMetadata(String room) {
- return roomsJson.get(room).getAsJsonObject();
+ JsonElement value = roomsJson.get(room);
+ return value != null ? value.getAsJsonObject() : null;
}
public static JsonArray getRoomWaypoints(String room) {
- return waypointsJson.get(room).getAsJsonArray();
+ JsonElement value = waypointsJson.get(room);
+ return value != null ? value.getAsJsonArray() : null;
}
/**
@@ -225,8 +228,21 @@ public class DungeonManager {
.then(literal("addWaypointRelatively").then(addCustomWaypointCommand(true)))
.then(literal("removeWaypoint").then(removeCustomWaypointCommand(false)))
.then(literal("removeWaypointRelatively").then(removeCustomWaypointCommand(true)))
- .then(literal("matchAgainst").then(matchAgainstCommand()))
))));
+ if (Debug.debugEnabled()) {
+ ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(literal(SkyblockerMod.NAMESPACE).then(literal("dungeons").then(literal("secrets")
+ .then(literal("matchAgainst").then(matchAgainstCommand()))
+ .then(literal("clearSubRooms").executes(context -> {
+ if (currentRoom != null) {
+ currentRoom.subRooms.clear();
+ context.getSource().sendFeedback(Constants.PREFIX.get().append("§rCleared sub rooms in the current room"));
+ } else {
+ context.getSource().sendError(Constants.PREFIX.get().append("§cCurrent room is null"));
+ }
+ return Command.SINGLE_SUCCESS;
+ }))
+ ))));
+ }
ClientPlayConnectionEvents.JOIN.register(((handler, sender, client) -> reset()));
}
@@ -341,7 +357,7 @@ public class DungeonManager {
Room room = getRoomAtPhysical(pos);
if (isRoomMatched(room)) {
BlockPos relativePos = currentRoom.actualToRelative(pos);
- source.sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.dungeons.secrets.posMessage", currentRoom.getName(), relativePos.getX(), relativePos.getY(), relativePos.getZ())));
+ source.sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.dungeons.secrets.posMessage", currentRoom.getName(), currentRoom.getDirection().asString(), relativePos.getX(), relativePos.getY(), relativePos.getZ())));
} else {
source.sendError(Constants.PREFIX.get().append(Text.translatable("skyblocker.dungeons.secrets.notMatched")));
}
@@ -411,22 +427,22 @@ public class DungeonManager {
private static RequiredArgumentBuilder<FabricClientCommandSource, String> matchAgainstCommand() {
return argument("room", StringArgumentType.string()).suggests((context, builder) -> CommandSource.suggestMatching(ROOMS_DATA.values().stream().map(Map::values).flatMap(Collection::stream).map(Map::keySet).flatMap(Collection::stream), builder)).then(argument("direction", Room.Direction.DirectionArgumentType.direction()).executes(context -> {
if (physicalEntrancePos == null || mapEntrancePos == null || mapRoomSize == 0) {
- context.getSource().sendError(Constants.PREFIX.get().append(Text.literal("§cYou are not in a dungeon")));
+ context.getSource().sendError(Constants.PREFIX.get().append("§cYou are not in a dungeon"));
return Command.SINGLE_SUCCESS;
}
MinecraftClient client = MinecraftClient.getInstance();
if (client.player == null || client.world == null) {
- context.getSource().sendError(Constants.PREFIX.get().append(Text.literal("§cFailed to get player or world")));
+ context.getSource().sendError(Constants.PREFIX.get().append("§cFailed to get player or world"));
return Command.SINGLE_SUCCESS;
}
ItemStack stack = client.player.getInventory().main.get(8);
if (!stack.isOf(Items.FILLED_MAP)) {
- context.getSource().sendError(Constants.PREFIX.get().append(Text.literal("§cFailed to get dungeon map")));
+ context.getSource().sendError(Constants.PREFIX.get().append("§cFailed to get dungeon map"));
return Command.SINGLE_SUCCESS;
}
MapState map = FilledMapItem.getMapState(FilledMapItem.getMapId(stack), client.world);
if (map == null) {
- context.getSource().sendError(Constants.PREFIX.get().append(Text.literal("§cFailed to get dungeon map state")));
+ context.getSource().sendError(Constants.PREFIX.get().append("§cFailed to get dungeon map state"));
return Command.SINGLE_SUCCESS;
}
@@ -440,18 +456,23 @@ public class DungeonManager {
} else if ((roomData = ROOMS_DATA.get("catacombs").get(Room.Shape.TRAP.shape).get(roomName)) != null) {
room = new DebugRoom(Room.Type.TRAP, DungeonMapUtils.getPhysicalRoomPos(client.player.getPos()));
} else if ((roomData = ROOMS_DATA.get("catacombs").values().stream().map(Map::entrySet).flatMap(Collection::stream).filter(entry -> entry.getKey().equals(roomName)).findAny().map(Map.Entry::getValue).orElse(null)) != null) {
- room = new DebugRoom(Room.Type.ROOM, DungeonMapUtils.getPhysicalPosFromMap(mapEntrancePos, mapRoomSize, physicalEntrancePos, DungeonMapUtils.getRoomSegments(map, DungeonMapUtils.getMapPosFromPhysical(physicalEntrancePos, mapEntrancePos, mapRoomSize, DungeonMapUtils.getPhysicalRoomPos(client.player.getPos())), mapRoomSize, Room.Type.ROOM.color)));
+ room = new DebugRoom(Room.Type.ROOM, DungeonMapUtils.getPhysicalPosFromMap(mapEntrancePos, mapRoomSize, physicalEntrancePos, DungeonMapUtils.getRoomSegments(map, DungeonMapUtils.getMapRoomPos(map, mapEntrancePos, mapRoomSize), mapRoomSize, Room.Type.ROOM.color)));
}
if (room == null) {
- context.getSource().sendError(Constants.PREFIX.get().append(Text.literal("§cFailed to find room with name " + roomName)));
+ context.getSource().sendError(Constants.PREFIX.get().append("§cFailed to find room with name " + roomName));
return Command.SINGLE_SUCCESS;
}
IntSortedSet segmentsX = IntSortedSets.unmodifiable(new IntRBTreeSet(room.segments.stream().mapToInt(Vector2ic::x).toArray()));
IntSortedSet segmentsY = IntSortedSets.unmodifiable(new IntRBTreeSet(room.segments.stream().mapToInt(Vector2ic::y).toArray()));
room.roomsData = Map.of(roomName, roomData);
room.possibleRooms = List.of(MutableTriple.of(direction, DungeonMapUtils.getPhysicalCornerPos(direction, segmentsX, segmentsY), List.of(roomName)));
- Scheduler.INSTANCE.scheduleCyclic(room::update, 10);
+ if (currentRoom != null) {
+ currentRoom.subRooms.add(room);
+ context.getSource().sendFeedback(Constants.PREFIX.get().append("§rMatching room " + roomName + " with direction " + direction + " against current room"));
+ } else {
+ context.getSource().sendError(Constants.PREFIX.get().append("§cCurrent room is null"));
+ }
return Command.SINGLE_SUCCESS;
}));
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java
index 516c3bad..b12bba62 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java
@@ -130,7 +130,7 @@ public class DungeonMapUtils {
return null;
}
Vector2ic offset = new Vector2i(mapEntrancePos.x() % mapRoomSizeWithGap, mapEntrancePos.y() % mapRoomSizeWithGap);
- return mapPos.add(2, 2).sub(offset).sub(mapPos.x() % mapRoomSizeWithGap, mapPos.y() % mapRoomSizeWithGap).add(offset);
+ return mapPos.add(2, 2).sub(offset).sub(Math.floorMod(mapPos.x(), mapRoomSizeWithGap), Math.floorMod(mapPos.y(), mapRoomSizeWithGap)).add(offset);
}
/**
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java
index 23302182..40488717 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java
@@ -2,6 +2,7 @@ package de.hysky.skyblocker.skyblock.dungeon.secrets;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
+import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.mojang.brigadier.arguments.IntegerArgumentType;
@@ -52,8 +53,8 @@ public class Room {
private static final Pattern SECRET_INDEX = Pattern.compile("^(\\d+)");
private static final Pattern SECRETS = Pattern.compile("§7(\\d{1,2})/(\\d{1,2}) Secrets");
private static final Vec3d DOOR_SIZE = new Vec3d(3, 4, 3);
- private static final float[] RED_COLOR_COMPONENTS = {1, 0, 0};
- private static final float[] GREEN_COLOR_COMPONENTS = {0, 1, 0};
+ protected static final float[] RED_COLOR_COMPONENTS = {1, 0, 0};
+ protected static final float[] GREEN_COLOR_COMPONENTS = {0, 1, 0};
@NotNull
private final Type type;
@NotNull
@@ -67,11 +68,11 @@ public class Room {
/**
* The room data containing all rooms for a specific dungeon and {@link #shape}.
*/
- Map<String, int[]> roomsData;
+ protected Map<String, int[]> roomsData;
/**
* Contains all possible dungeon rooms for this room. The list is gradually shrunk by checking blocks until only one room is left.
*/
- List<MutableTriple<Direction, Vector2ic, List<String>>> possibleRooms;
+ protected List<MutableTriple<Direction, Vector2ic, List<String>>> possibleRooms;
/**
* Contains all blocks that have been checked to prevent checking the same block multiple times.
*/
@@ -88,12 +89,13 @@ public class Room {
* <li>{@link MatchState#MATCHED} means that the room has a unique match ans has been double checked.</li>
* <li>{@link MatchState#FAILED} means that the room has been checked and there is no match.</li>
*/
- private MatchState matchState = MatchState.MATCHING;
+ protected MatchState matchState = MatchState.MATCHING;
private Table<Integer, BlockPos, SecretWaypoint> secretWaypoints;
private String name;
private Direction direction;
private Vector2ic physicalCornerPos;
+ protected List<Room> subRooms = new ArrayList<>();
@Nullable
private BlockPos doorPos;
@Nullable
@@ -126,6 +128,13 @@ public class Room {
return name;
}
+ /**
+ * Not null if {@link #isMatched()}.
+ */
+ public Direction getDirection() {
+ return direction;
+ }
+
@Override
public String toString() {
return "Room{type=%s, segments=%s, shape=%s, matchState=%s, name=%s, direction=%s, physicalCornerPos=%s}".formatted(type, Arrays.toString(segments.toArray()), shape, matchState, name, direction, physicalCornerPos);
@@ -283,6 +292,10 @@ public class Room {
return;
}
+ for (Room subRoom : subRooms) {
+ subRoom.update();
+ }
+
// Wither and blood door
if (SkyblockerConfigManager.get().locations.dungeons.doorHighlight.enableDoorHighlight && doorPos == null) {
doorPos = DungeonMapUtils.getWitherBloodDoorPos(world, segments);
@@ -366,7 +379,7 @@ public class Room {
* @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) {
+ protected boolean checkBlock(ClientWorld world, BlockPos pos) {
byte id = DungeonManager.NUMERIC_ID.getByte(Registries.BLOCK.getId(world.getBlockState(pos).getBlock()).toString());
if (id == 0) {
return false;
@@ -422,7 +435,7 @@ public class Room {
* @param id the custom numeric block id
* @return the encoded integer
*/
- private int posIdToInt(BlockPos pos, byte id) {
+ protected int posIdToInt(BlockPos pos, byte id) {
return pos.getX() << 24 | pos.getY() << 16 | pos.getZ() << 8 | id;
}
@@ -435,13 +448,16 @@ public class Room {
@SuppressWarnings("JavadocReference")
private void roomMatched() {
secretWaypoints = HashBasedTable.create();
- for (JsonElement waypointElement : DungeonManager.getRoomWaypoints(name)) {
- JsonObject waypoint = waypointElement.getAsJsonObject();
- String secretName = waypoint.get("secretName").getAsString();
- Matcher secretIndexMatcher = SECRET_INDEX.matcher(secretName);
- int secretIndex = secretIndexMatcher.find() ? Integer.parseInt(secretIndexMatcher.group(1)) : 0;
- BlockPos pos = DungeonMapUtils.relativeToActual(direction, physicalCornerPos, waypoint);
- secretWaypoints.put(secretIndex, pos, new SecretWaypoint(secretIndex, waypoint, secretName, pos));
+ JsonArray secretWaypointsJson = DungeonManager.getRoomWaypoints(name);
+ if (secretWaypointsJson != null) {
+ for (JsonElement waypointElement : secretWaypointsJson) {
+ JsonObject waypoint = waypointElement.getAsJsonObject();
+ String secretName = waypoint.get("secretName").getAsString();
+ Matcher secretIndexMatcher = SECRET_INDEX.matcher(secretName);
+ int secretIndex = secretIndexMatcher.find() ? Integer.parseInt(secretIndexMatcher.group(1)) : 0;
+ BlockPos pos = DungeonMapUtils.relativeToActual(direction, physicalCornerPos, waypoint);
+ secretWaypoints.put(secretIndex, pos, new SecretWaypoint(secretIndex, waypoint, secretName, pos));
+ }
}
DungeonManager.getCustomWaypoints(name).values().forEach(this::addCustomWaypoint);
matchState = MatchState.DOUBLE_CHECKING;
@@ -450,7 +466,7 @@ public class Room {
/**
* Resets fields for another round of matching after room matching fails.
*/
- private void reset() {
+ protected 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);
@@ -491,6 +507,10 @@ public class Room {
* Calls {@link SecretWaypoint#render(WorldRenderContext)} on {@link #secretWaypoints all secret waypoints} and renders a highlight around the wither or blood door, if it exists.
*/
protected void render(WorldRenderContext context) {
+ for (Room subRoom : subRooms) {
+ subRoom.render(context);
+ }
+
if (SkyblockerConfigManager.get().locations.dungeons.secretWaypoints.enableSecretWaypoints && isMatched()) {
for (SecretWaypoint secretWaypoint : secretWaypoints.values()) {
if (secretWaypoint.shouldRender()) {
@@ -632,7 +652,7 @@ public class Room {
}
}
- enum Shape {
+ protected enum Shape {
ONE_BY_ONE("1x1"),
ONE_BY_TWO("1x2"),
ONE_BY_THREE("1x3"),
@@ -653,7 +673,7 @@ public class Room {
}
}
- enum Direction implements StringIdentifiable {
+ public enum Direction implements StringIdentifiable {
NW("northwest"), NE("northeast"), SW("southwest"), SE("southeast");
private static final Codec<Direction> CODEC = StringIdentifiable.createCodec(Direction::values);
private final String name;
@@ -682,7 +702,7 @@ public class Room {
}
}
- private enum MatchState {
+ protected enum MatchState {
MATCHING, DOUBLE_CHECKING, MATCHED, FAILED
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java
index b7c19210..98ffa157 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java
@@ -29,7 +29,7 @@ import java.util.function.Supplier;
import java.util.function.ToDoubleFunction;
public class SecretWaypoint extends Waypoint {
- protected static final Logger LOGGER = LoggerFactory.getLogger(SecretWaypoint.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(SecretWaypoint.class);
public static final Codec<SecretWaypoint> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.INT.fieldOf("secretIndex").forGetter(secretWaypoint -> secretWaypoint.secretIndex),
Category.CODEC.fieldOf("category").forGetter(secretWaypoint -> secretWaypoint.category),
@@ -39,7 +39,7 @@ public class SecretWaypoint extends Waypoint {
public static final Codec<List<SecretWaypoint>> LIST_CODEC = CODEC.listOf();
static final List<String> SECRET_ITEMS = List.of("Decoy", "Defuse Kit", "Dungeon Chest Key", "Healing VIII", "Inflatable Jerry", "Spirit Leap", "Training Weights", "Trap", "Treasure Talisman");
private static final Supplier<SkyblockerConfig.SecretWaypoints> CONFIG = () -> SkyblockerConfigManager.get().locations.dungeons.secretWaypoints;
- private static final Supplier<Type> TYPE_SUPPLIER = () -> CONFIG.get().waypointType;
+ static final Supplier<Type> TYPE_SUPPLIER = () -> CONFIG.get().waypointType;
final int secretIndex;
final Category category;
final Text name;