diff options
author | Kevin <92656833+kevinthegreat1@users.noreply.github.com> | 2023-10-22 23:34:26 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-22 23:34:26 -0400 |
commit | b465840f67aa4c48652c60be912cf28390436ed2 (patch) | |
tree | 0590d66d90e5f7d7caa72d6e16ac462556a96394 /src/main/java/de/hysky/skyblocker/skyblock | |
parent | a2ebc54efb704abc56994e20bbcc6859d5c03eff (diff) | |
parent | 54bf37cc7860ce0d8467a058d81cbcf07af2bd7d (diff) | |
download | Skyblocker-b465840f67aa4c48652c60be912cf28390436ed2.tar.gz Skyblocker-b465840f67aa4c48652c60be912cf28390436ed2.tar.bz2 Skyblocker-b465840f67aa4c48652c60be912cf28390436ed2.zip |
Merge pull request #381 from AzureAaron/aotv-pearl-secret-waypoints
AOTV & Pearl Secret Waypoints
Diffstat (limited to 'src/main/java/de/hysky/skyblocker/skyblock')
4 files changed, 96 insertions, 16 deletions
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 259cc3f3..73d4a452 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 @@ -7,7 +7,6 @@ import net.minecraft.block.MapColor; import net.minecraft.item.map.MapIcon; import net.minecraft.item.map.MapState; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3i; import org.jetbrains.annotations.NotNull; @@ -173,7 +172,7 @@ public class DungeonMapUtils { @NotNull 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); + return physicalPos.sub(Math.floorMod(physicalPos.x(), 32), Math.floorMod(physicalPos.y(), 32)).sub(8, 8); } public static Vector2ic[] getPhysicalPosFromMap(Vector2ic mapEntrancePos, int mapRoomSize, Vector2ic physicalEntrancePos, Vector2ic... mapPositions) { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java index cb9615fb..08b84852 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java @@ -7,14 +7,14 @@ import com.mojang.brigadier.Command; import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.builder.ArgumentBuilder; import com.mojang.brigadier.builder.RequiredArgumentBuilder; -import it.unimi.dsi.fastutil.objects.Object2ByteMap; -import it.unimi.dsi.fastutil.objects.Object2ByteOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectIntPair; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.utils.Constants; import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.scheduler.Scheduler; +import it.unimi.dsi.fastutil.objects.Object2ByteMap; +import it.unimi.dsi.fastutil.objects.Object2ByteOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectIntPair; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; @@ -37,7 +37,10 @@ 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.hit.HitResult; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.Vec3i; import net.minecraft.world.World; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -149,7 +152,9 @@ public class DungeonSecrets { UseBlockCallback.EVENT.register((player, world, hand, hitResult) -> onUseBlock(world, hitResult)); ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(literal(SkyblockerMod.NAMESPACE).then(literal("dungeons").then(literal("secrets") .then(literal("markAsFound").then(markSecretsCommand(true))) - .then(literal("markAsMissing").then(markSecretsCommand(false))))))); + .then(literal("markAsMissing").then(markSecretsCommand(false))) + .then(literal("getRelativePos").executes(context -> getRelativePos(context.getSource()))) + .then(literal("getRelativeTargetPos").executes(context -> getRelativeTargetPos(context.getSource()))))))); ClientPlayConnectionEvents.JOIN.register(((handler, sender, client) -> reset())); } @@ -204,8 +209,9 @@ public class DungeonSecrets { /** * Loads the json from the given {@link BufferedReader} into the given {@link Map}. + * * @param reader the reader to read the json from - * @param map the map to load into + * @param map the map to load into */ private static void loadJson(BufferedReader reader, Map<String, JsonElement> map) { SkyblockerMod.GSON.fromJson(reader, JsonObject.class).asMap().forEach((room, jsonElement) -> map.put(room.toLowerCase().replaceAll(" ", "-"), jsonElement)); @@ -223,6 +229,30 @@ public class DungeonSecrets { }); } + private static int getRelativePos(FabricClientCommandSource source) { + return getRelativePos(source, source.getPlayer().getBlockPos()); + } + + private static int getRelativeTargetPos(FabricClientCommandSource source) { + if (MinecraftClient.getInstance().crosshairTarget instanceof BlockHitResult blockHitResult && blockHitResult.getType() == HitResult.Type.BLOCK) { + return getRelativePos(source, blockHitResult.getBlockPos()); + } else { + source.sendError(Constants.PREFIX.get().append(Text.translatable("skyblocker.dungeons.secrets.noTarget"))); + } + return Command.SINGLE_SUCCESS; + } + + private static int getRelativePos(FabricClientCommandSource source, BlockPos pos) { + 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()))); + } else { + source.sendError(Constants.PREFIX.get().append(Text.translatable("skyblocker.dungeons.secrets.notMatched"))); + } + return Command.SINGLE_SUCCESS; + } + /** * Updates the dungeon. The general idea is similar to the Dungeon Rooms Mod. * <p></p> @@ -340,9 +370,16 @@ public class DungeonSecrets { * Used to detect when all secrets in a room are found. */ private static void onChatMessage(Text text, boolean overlay) { + String message = text.getString(); + if (overlay && isCurrentRoomMatched()) { - currentRoom.onChatMessage(text.getString()); + currentRoom.onChatMessage(message); } + + if (message.equals("[BOSS] Bonzo: Gratz for making it this far, but I'm basically unbeatable.") || message.equals("[BOSS] Scarf: This is where the journey ends for you, Adventurers.") + || message.equals("[BOSS] The Professor: I was burdened with terrible news recently...") || message.equals("[BOSS] Thorn: Welcome Adventurers! I am Thorn, the Spirit! And host of the Vegan Trials!") + || message.equals("[BOSS] Livid: Welcome, you've arrived right on time. I am Livid, the Master of Shadows.") || message.equals("[BOSS] Sadan: So you made it all the way here... Now you wish to defy me? Sadan?!") + || message.equals("[BOSS] Maxor: WELL! WELL! WELL! LOOK WHO'S HERE!")) reset(); } /** @@ -411,6 +448,19 @@ public class DungeonSecrets { } /** + * Gets the room at the given physical position. + * + * @param pos the physical position + * @return the room at the given physical position, or null if there is no room at the given physical position + * @see #rooms + * @see DungeonMapUtils#getPhysicalRoomPos(Vec3i) + */ + @Nullable + private static Room getRoomAtPhysical(Vec3i pos) { + return rooms.get(DungeonMapUtils.getPhysicalRoomPos(pos)); + } + + /** * Calls {@link #isRoomMatched(Room)} on {@link #currentRoom}. * * @return {@code true} if {@link #currentRoom} is not null and {@link #isRoomMatched(Room)} @@ -440,7 +490,7 @@ public class DungeonSecrets { } /** - * Resets fields when leaving a dungeon. + * Resets fields when leaving a dungeon or entering boss. */ private static void reset() { mapEntrancePos = null; 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 dd7dc91e..0d7a444f 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 @@ -5,10 +5,10 @@ import com.google.common.collect.ImmutableTable; import com.google.common.collect.Table; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import de.hysky.skyblocker.utils.scheduler.Scheduler; import it.unimi.dsi.fastutil.ints.IntRBTreeSet; import it.unimi.dsi.fastutil.ints.IntSortedSet; import it.unimi.dsi.fastutil.ints.IntSortedSets; -import de.hysky.skyblocker.utils.scheduler.Scheduler; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; import net.fabricmc.fabric.api.util.TriState; import net.minecraft.block.BlockState; @@ -23,7 +23,6 @@ import net.minecraft.entity.mob.AmbientEntity; import net.minecraft.registry.Registries; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; -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; @@ -72,6 +71,9 @@ public class Room { */ private TriState matched = TriState.DEFAULT; private Table<Integer, BlockPos, SecretWaypoint> secretWaypoints; + private String name; + private Direction direction; + private Vector2ic physicalCornerPos; public Room(@NotNull Type type, @NotNull Vector2ic... physicalPositions) { this.type = type; @@ -92,6 +94,13 @@ public class Room { return matched == TriState.TRUE; } + /** + * Not null if {@link #isMatched()}. + */ + public String getName() { + return name; + } + @Override public String toString() { return "Room{type=" + type + ", shape=" + shape + ", matched=" + matched + ", segments=" + Arrays.toString(segments.toArray()) + "}"; @@ -186,8 +195,8 @@ public class Room { if (pos.getY() < 66 || pos.getY() > 73) { return true; } - int x = MathHelper.floorMod(pos.getX() - 8, 32); - int z = MathHelper.floorMod(pos.getZ() - 8, 32); + int x = Math.floorMod(pos.getX() - 8, 32); + int z = Math.floorMod(pos.getZ() - 8, 32); return (x < 13 || x > 17 || z > 2 && z < 28) && (z < 13 || z > 17 || x > 2 && x < 28); } @@ -217,7 +226,7 @@ public class Room { * </ul> * <li> If there are exactly one room matching: </li> * <ul> - * <li> Call {@link #roomMatched(String, Direction, Vector2ic)}. </li> + * <li> Call {@link #roomMatched()}. </li> * <li> Discard the no longer needed fields to save memory. </li> * <li> Return {@code true} </li> * </ul> @@ -256,7 +265,10 @@ public class Room { // 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.getRight().get(0), directionRooms.getLeft(), directionRooms.getMiddle()); + name = directionRooms.getRight().get(0); + direction = directionRooms.getLeft(); + physicalCornerPos = directionRooms.getMiddle(); + roomMatched(); discard(); return true; } @@ -286,7 +298,7 @@ public class Room { * @param directionRooms the direction, position, and name of the room */ @SuppressWarnings("JavadocReference") - private void roomMatched(String name, Direction direction, Vector2ic physicalCornerPos) { + private void roomMatched() { Table<Integer, BlockPos, SecretWaypoint> secretWaypointsMutable = HashBasedTable.create(); for (JsonElement waypointElement : DungeonSecrets.getRoomWaypoints(name)) { JsonObject waypoint = waypointElement.getAsJsonObject(); @@ -297,6 +309,7 @@ public class Room { } secretWaypoints = ImmutableTable.copyOf(secretWaypointsMutable); matched = TriState.TRUE; + DungeonSecrets.LOGGER.info("[Skyblocker] Room {} matched after checking {} block(s)", name, checkedBlocks.size()); } @@ -323,6 +336,20 @@ public class Room { } /** + * Fails if !{@link #isMatched()} + */ + protected BlockPos actualToRelative(BlockPos pos) { + return DungeonMapUtils.actualToRelative(direction, physicalCornerPos, pos); + } + + /** + * Fails if !{@link #isMatched()} + */ + protected BlockPos relativeToActual(BlockPos pos) { + return DungeonMapUtils.relativeToActual(direction, physicalCornerPos, pos); + } + + /** * Calls {@link SecretWaypoint#render(WorldRenderContext)} on {@link #secretWaypoints all secret waypoints}. */ protected void render(WorldRenderContext context) { 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 0d9bdff1..a520c73f 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 @@ -112,6 +112,8 @@ public class SecretWaypoint { LEVER(secretWaypoints -> secretWaypoints.enableLeverWaypoints, 250, 217, 2), FAIRYSOUL(secretWaypoints -> secretWaypoints.enableFairySoulWaypoints, 255, 85, 255), STONK(secretWaypoints -> secretWaypoints.enableStonkWaypoints, 146, 52, 235), + AOTV(secretWaypoints -> secretWaypoints.enableAotvWaypoints, 252, 98, 3), + PEARL(secretWaypoints -> secretWaypoints.enablePearlWaypoints, 57, 117, 125), DEFAULT(secretWaypoints -> secretWaypoints.enableDefaultWaypoints, 190, 255, 252); private final Predicate<SkyblockerConfig.SecretWaypoints> enabledPredicate; private final float[] colorComponents; @@ -135,6 +137,8 @@ public class SecretWaypoint { case "lever" -> Category.LEVER; case "fairysoul" -> Category.FAIRYSOUL; case "stonk" -> Category.STONK; + case "aotv" -> Category.AOTV; + case "pearl" -> Category.PEARL; default -> Category.DEFAULT; }; } |