diff options
author | Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> | 2023-08-16 12:44:30 +0800 |
---|---|---|
committer | Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> | 2023-08-30 22:49:54 -0400 |
commit | 3cfcfa8f0767563ca6d0e14df90b509bbc6ad812 (patch) | |
tree | aeedebe1530f8a7fb6e4335ba460eb319accf8d9 /src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets | |
parent | 3eb57e60d5375b4074ee236c1ab50c4bb319d9a2 (diff) | |
download | Skyblocker-3cfcfa8f0767563ca6d0e14df90b509bbc6ad812.tar.gz Skyblocker-3cfcfa8f0767563ca6d0e14df90b509bbc6ad812.tar.bz2 Skyblocker-3cfcfa8f0767563ca6d0e14df90b509bbc6ad812.zip |
Finish secret found detection
Diffstat (limited to 'src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets')
4 files changed, 86 insertions, 32 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 index 519b365d..310e0501 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonMapUtils.java @@ -120,26 +120,34 @@ public class DungeonMapUtils { } /** - * Gets the physical position of the northwest corner of the room the player is in. Hypixel Skyblock Dungeons are aligned to a 32 by 32 blocks grid, allowing corners to be calculated through math. - * - * @param playerPos the position of the player - * @return the physical position of the northwest corner of the room the player is in - * @implNote {@code physicalPos} is shifted by 0.5 so room borders are evenly split. - * {@code physicalPos} is further shifted by 8 because Hypixel offset dungeons by 8 blocks in Skyblock 0.12.3. - * Subtracting the modulo gives the northwest corner of the room shifted by 8. Finally, {@code physicalPos} is shifted back by 8 to its intended position. + * @see #getPhysicalRoomPos(double, double) */ @NotNull - public static Vector2ic getPhysicalRoomPos(@NotNull Vec3d playerPos) { - Vector2i physicalPos = new Vector2i(playerPos.getX() + 8.5, playerPos.getZ() + 8.5, RoundingMode.TRUNCATE); - return physicalPos.sub(MathHelper.floorMod(physicalPos.x(), 32), MathHelper.floorMod(physicalPos.y(), 32)).sub(8, 8); + public static Vector2ic getPhysicalRoomPos(@NotNull Vec3d pos) { + return getPhysicalRoomPos(pos.getX(), pos.getZ()); + } + + /** + * @see #getPhysicalRoomPos(double, double) + */ + @NotNull + public static Vector2ic getPhysicalRoomPos(@NotNull Vec3i pos) { + return getPhysicalRoomPos(pos.getX(), pos.getZ()); } /** - * @see #getPhysicalRoomPos(Vec3d) + * Gets the physical position of the northwest corner of the room the given coordinate is in. Hypixel Skyblock Dungeons are aligned to a 32 by 32 blocks grid, allowing corners to be calculated through math. + * + * @param x the x position of the coordinate to calculate + * @param z the z position of the coordinate to calculate + * @return the physical position of the northwest corner of the room the player is in + * @implNote {@code physicalPos} is shifted by 0.5 so room borders are evenly split. + * {@code physicalPos} is further shifted by 8 because Hypixel offset dungeons by 8 blocks in Skyblock 0.12.3. + * Subtracting the modulo gives the northwest corner of the room shifted by 8. Finally, {@code physicalPos} is shifted back by 8 to its intended position. */ @NotNull - public static Vector2ic getPhysicalRoomPos(@NotNull Vec3i playerPos) { - Vector2i physicalPos = new Vector2i(playerPos.getX() + 8.5, playerPos.getZ() + 8.5, RoundingMode.TRUNCATE); + public static Vector2ic getPhysicalRoomPos(double x, double z) { + Vector2i physicalPos = new Vector2i(x + 8.5, z + 8.5, RoundingMode.TRUNCATE); return physicalPos.sub(MathHelper.floorMod(physicalPos.x(), 32), MathHelper.floorMod(physicalPos.y(), 32)).sub(8, 8); } @@ -175,9 +183,12 @@ public class DungeonMapUtils { public static BlockPos actualToRelative(Vector2ic physicalCornerPos, Room.Direction direction, BlockPos pos) { return switch (direction) { case NW -> new BlockPos(pos.getX() - physicalCornerPos.x(), pos.getY(), pos.getZ() - physicalCornerPos.y()); - case NE -> new BlockPos(pos.getZ() - physicalCornerPos.y(), pos.getY(), -pos.getX() + physicalCornerPos.x()); - case SW -> new BlockPos(-pos.getZ() + physicalCornerPos.y(), pos.getY(), pos.getX() - physicalCornerPos.x()); - case SE -> new BlockPos(-pos.getX() + physicalCornerPos.x(), pos.getY(), -pos.getZ() + physicalCornerPos.y()); + case NE -> + new BlockPos(pos.getZ() - physicalCornerPos.y(), pos.getY(), -pos.getX() + physicalCornerPos.x()); + case SW -> + new BlockPos(-pos.getZ() + physicalCornerPos.y(), pos.getY(), pos.getX() - physicalCornerPos.x()); + case SE -> + new BlockPos(-pos.getX() + physicalCornerPos.x(), pos.getY(), -pos.getZ() + physicalCornerPos.y()); }; } @@ -188,9 +199,12 @@ public class DungeonMapUtils { public static BlockPos relativeToActual(Vector2ic physicalCornerPos, Room.Direction direction, BlockPos pos) { return switch (direction) { case NW -> new BlockPos(pos.getX() + physicalCornerPos.x(), pos.getY(), pos.getZ() + physicalCornerPos.y()); - case NE -> new BlockPos(-pos.getZ() + physicalCornerPos.x(), pos.getY(), pos.getX() + physicalCornerPos.y()); - case SW -> new BlockPos(pos.getZ() + physicalCornerPos.x(), pos.getY(), -pos.getX() + physicalCornerPos.y()); - case SE -> new BlockPos(-pos.getX() + physicalCornerPos.x(), pos.getY(), -pos.getZ() + physicalCornerPos.y()); + case NE -> + new BlockPos(-pos.getZ() + physicalCornerPos.x(), pos.getY(), pos.getX() + physicalCornerPos.y()); + case SW -> + new BlockPos(pos.getZ() + physicalCornerPos.x(), pos.getY(), -pos.getX() + physicalCornerPos.y()); + case SE -> + new BlockPos(-pos.getX() + physicalCornerPos.x(), pos.getY(), -pos.getZ() + physicalCornerPos.y()); }; } 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 3eb4e036..bb01a39e 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 @@ -22,7 +22,9 @@ import net.minecraft.text.Text; import net.minecraft.util.ActionResult; import net.minecraft.util.Identifier; import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.joml.Vector2ic; @@ -301,14 +303,35 @@ public class DungeonSecrets { return ActionResult.PASS; } - public static void onItemPickup(ItemEntity itemEntity, LivingEntity collector) { - if (isCurrentRoomMatched()) { - currentRoom.onItemPickup(itemEntity, collector); + public static void onItemPickup(ItemEntity itemEntity, LivingEntity collector, boolean isPlayer) { + if (isPlayer) { + if (isCurrentRoomMatched()) { + currentRoom.onItemPickup(itemEntity, collector); + } + } else { + Room room = getRoomAtPhysical(collector.getPos()); + if (isRoomMatched(room)) { + room.onItemPickup(itemEntity, collector); + } } } + @Nullable + private static Room getRoomAtPhysical(Vec3d pos) { + return rooms.get(DungeonMapUtils.getPhysicalRoomPos(pos)); + } + private static boolean isCurrentRoomMatched() { - return SkyblockerConfig.get().locations.dungeons.secretWaypoints && Utils.isInDungeons() && currentRoom != null && currentRoom.isMatched(); + return isRoomMatched(currentRoom); + } + + @Contract("null -> false") + private static boolean isRoomMatched(@Nullable Room room) { + return shouldProcess() && room != null && room.isMatched(); + } + + private static boolean shouldProcess() { + return SkyblockerConfig.get().locations.dungeons.secretWaypoints && Utils.isInDungeons(); } private static void reset() { 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 7833233f..3af1f2c3 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 @@ -25,15 +25,22 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import org.apache.commons.lang3.tuple.MutableTriple; import org.apache.commons.lang3.tuple.Triple; +import org.jetbrains.annotations.NotNull; import org.joml.Vector2i; import org.joml.Vector2ic; import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class Room { + private static final Pattern SECRETS = Pattern.compile("ยง7(\\d{1,2})/(\\d{1,2}) Secrets"); + @NotNull private final Type type; + @NotNull private final Set<Vector2ic> segments; + @NotNull private final Shape shape; private HashMap<String, int[]> roomsData; private List<MutableTriple<Direction, Vector2ic, List<String>>> possibleRooms = new ArrayList<>(); @@ -48,7 +55,7 @@ public class Room { private TriState matched = TriState.DEFAULT; private Table<Integer, BlockPos, SecretWaypoint> secretWaypoints; - public Room(Type type, Vector2ic... physicalPositions) { + public Room(@NotNull Type type, @NotNull Vector2ic... physicalPositions) { long startTime = System.currentTimeMillis(); this.type = type; segments = Set.of(physicalPositions); @@ -64,6 +71,7 @@ public class Room { DungeonSecrets.LOGGER.info("Created {} in {} ms", this, endTime - startTime); // TODO change to debug } + @NotNull public Type getType() { return type; } @@ -77,6 +85,7 @@ public class Room { return "Room{type=" + type + ", shape=" + shape + ", matched=" + matched + ", segments=" + Arrays.toString(segments.toArray()) + "}"; } + @NotNull private Shape getShape(IntSortedSet segmentsX, IntSortedSet segmentsY) { return switch (segments.size()) { case 1 -> Shape.ONE_BY_ONE; @@ -87,6 +96,7 @@ public class Room { }; } + @NotNull private Direction[] getPossibleDirections(IntSortedSet segmentsX, IntSortedSet segmentsY) { return switch (shape) { case ONE_BY_ONE, TWO_BY_TWO -> Direction.values(); @@ -186,7 +196,6 @@ public class Room { } private void roomMatched(Triple<Direction, Vector2ic, List<String>> directionRooms) { - matched = TriState.TRUE; Table<Integer, BlockPos, SecretWaypoint> secretWaypointsMutable = HashBasedTable.create(); String name = directionRooms.getRight().get(0); for (JsonElement waypointElement : DungeonSecrets.getWaypointsJson().get(name).getAsJsonArray()) { @@ -197,6 +206,7 @@ public class Room { secretWaypointsMutable.put(secretIndex, pos, new SecretWaypoint(secretIndex, waypoint, secretName, pos)); } secretWaypoints = ImmutableTable.copyOf(secretWaypointsMutable); + matched = TriState.TRUE; DungeonSecrets.LOGGER.info("[Skyblocker] Room {} matched after checking {} block(s)", name, checkedBlocks.size()); // TODO change to debug } @@ -209,14 +219,21 @@ public class Room { } protected void onChatMessage(String message) { - if (message.toLowerCase().contains("secret")) { // TODO for dev purposes only - DungeonSecrets.LOGGER.info(message); + if (isAllSecretsFound(message)) { + secretWaypoints.values().forEach(SecretWaypoint::setFound); + } + } + + protected static boolean isAllSecretsFound(String message) { + Matcher matcher = SECRETS.matcher(message); + if (matcher.find()) { + return Integer.parseInt(matcher.group(1)) >= Integer.parseInt(matcher.group(2)); } + return false; } protected void onUseBlock(World world, BlockHitResult hitResult) { BlockState state = world.getBlockState(hitResult.getBlockPos()); - DungeonSecrets.LOGGER.info(state.getBlock().toString()); // TODO for dev purposes only if (!state.isOf(Blocks.CHEST) && !state.isOf(Blocks.PLAYER_HEAD) && !state.isOf(Blocks.PLAYER_WALL_HEAD)) { return; } @@ -225,9 +242,7 @@ public class Room { } protected void onItemPickup(ItemEntity itemEntity, LivingEntity collector) { - String name = itemEntity.getName().getString(); - DungeonSecrets.LOGGER.info(name); // TODO for dev purposes only - if (Arrays.stream(SecretWaypoint.SECRET_ITEMS).noneMatch(name::contains)) { + if (SecretWaypoint.SECRET_ITEMS.stream().noneMatch(itemEntity.getStack().getName().getString()::contains)) { return; } secretWaypoints.values().stream().filter(secretWaypoint -> secretWaypoint.category.needsItemPickup()).min(Comparator.comparingDouble(secretWaypoint -> collector.squaredDistanceTo(secretWaypoint.centerPos))).filter(secretWaypoint -> collector.squaredDistanceTo(secretWaypoint.centerPos) <= 36D) diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java index 71459e50..ceb38af5 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java @@ -9,8 +9,10 @@ import net.minecraft.util.Formatting; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import java.util.List; + public class SecretWaypoint { - static final String[] SECRET_ITEMS = {"Decoy", "Defuse Kit", "Dungeon Chest Key", "Healing VIII", "Inflatable Jerry", "Spirit Leap", "Training Weights", "Trap", "treasure Talisman"}; + 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"); final int secretIndex; final Category category; private final Text name; |