From 739eeb014e31aec54ad12b4ef14f95eca4bc2dea Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Mon, 23 Oct 2023 22:47:15 -0400 Subject: Support for adding custom waypoints --- .../skyblock/dungeon/secrets/DungeonSecrets.java | 51 +++++++++++++- .../skyblock/dungeon/secrets/SecretWaypoint.java | 80 +++++++++++++--------- 2 files changed, 98 insertions(+), 33 deletions(-) (limited to 'src/main/java/de') 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 08b84852..38dc1060 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 @@ -5,13 +5,16 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.mojang.brigadier.Command; import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.ArgumentBuilder; import com.mojang.brigadier.builder.RequiredArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; 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 de.hysky.skyblocker.utils.waypoint.Waypoint; import it.unimi.dsi.fastutil.objects.Object2ByteMap; import it.unimi.dsi.fastutil.objects.Object2ByteOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectIntPair; @@ -24,6 +27,8 @@ import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; import net.fabricmc.fabric.api.event.player.UseBlockCallback; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.command.argument.BlockPosArgumentType; +import net.minecraft.command.argument.PosArgument; import net.minecraft.entity.ItemEntity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.mob.AmbientEntity; @@ -33,6 +38,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.item.map.MapState; import net.minecraft.resource.Resource; +import net.minecraft.server.command.ServerCommandSource; import net.minecraft.text.Text; import net.minecraft.util.ActionResult; import net.minecraft.util.Identifier; @@ -101,6 +107,7 @@ public class DungeonSecrets { private static final Map rooms = new HashMap<>(); private static final Map roomsJson = new HashMap<>(); private static final Map waypointsJson = new HashMap<>(); + private static final Map customWaypoints = new HashMap<>(); @Nullable private static CompletableFuture roomsLoaded; /** @@ -154,7 +161,10 @@ public class DungeonSecrets { .then(literal("markAsFound").then(markSecretsCommand(true))) .then(literal("markAsMissing").then(markSecretsCommand(false))) .then(literal("getRelativePos").executes(context -> getRelativePos(context.getSource()))) - .then(literal("getRelativeTargetPos").executes(context -> getRelativeTargetPos(context.getSource()))))))); + .then(literal("getRelativeTargetPos").executes(context -> getRelativeTargetPos(context.getSource()))) + .then(literal("addWaypoint").then(addWaypointCommand(false))) + .then(literal("addWaypointRelatively").then(addWaypointCommand(true))) + )))); ClientPlayConnectionEvents.JOIN.register(((handler, sender, client) -> reset())); } @@ -253,6 +263,42 @@ public class DungeonSecrets { return Command.SINGLE_SUCCESS; } + private static ArgumentBuilder> addWaypointCommand(boolean relative) { + return argument("pos", BlockPosArgumentType.blockPos()) + .then(argument("secretIndex", IntegerArgumentType.integer()) + .then(argument("category", SecretWaypoint.Category.CategoryArgumentType.category()) + .then(argument("name", StringArgumentType.greedyString()).executes(context -> { + // TODO Less hacky way with custom ClientBlockPosArgumentType + BlockPos pos = context.getArgument("pos", PosArgument.class).toAbsoluteBlockPos(new ServerCommandSource(null, context.getSource().getPosition(), context.getSource().getRotation(), null, 0, null, null, null, null)); + return relative ? addWaypointRelative(context, pos) : addWaypoint(context, pos); + })) + ) + ); + } + + private static int addWaypoint(CommandContext context, BlockPos pos) { + Room room = getRoomAtPhysical(pos); + if (isRoomMatched(room)) { + addWaypointRelative(context, room, room.actualToRelative(pos)); + } else { + context.getSource().sendError(Constants.PREFIX.get().append(Text.translatable("skyblocker.dungeons.secrets.notMatched"))); + } + return Command.SINGLE_SUCCESS; + } + + private static int addWaypointRelative(CommandContext context, BlockPos pos) { + if (isCurrentRoomMatched()) { + addWaypointRelative(context, currentRoom, pos); + } else { + context.getSource().sendError(Constants.PREFIX.get().append(Text.translatable("skyblocker.dungeons.secrets.notMatched"))); + } + return Command.SINGLE_SUCCESS; + } + + private static void addWaypointRelative(CommandContext context, Room room, BlockPos pos) { + customWaypoints.put(room.getName(), new SecretWaypoint(IntegerArgumentType.getInteger(context, "secretIndex"), SecretWaypoint.Category.CategoryArgumentType.getCategory(context, "category"), StringArgumentType.getString(context, "name"), pos)); + } + /** * Updates the dungeon. The general idea is similar to the Dungeon Rooms Mod. *

@@ -326,7 +372,8 @@ public class DungeonSecrets { } switch (type) { case ENTRANCE, PUZZLE, TRAP, MINIBOSS, FAIRY, BLOOD -> room = newRoom(type, physicalPos); - case ROOM -> room = newRoom(type, DungeonMapUtils.getPhysicalPosFromMap(mapEntrancePos, mapRoomSize, physicalEntrancePos, DungeonMapUtils.getRoomSegments(map, mapPos, mapRoomSize, type.color))); + case ROOM -> + room = newRoom(type, DungeonMapUtils.getPhysicalPosFromMap(mapEntrancePos, mapRoomSize, physicalEntrancePos, DungeonMapUtils.getRoomSegments(map, mapPos, mapRoomSize, type.color))); } } if (room != null && currentRoom != room) { 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 ab6d6f7d..5fbce68a 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 @@ -1,15 +1,20 @@ package de.hysky.skyblocker.skyblock.dungeon.secrets; import com.google.gson.JsonObject; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.serialization.Codec; +import com.mojang.serialization.JsonOps; import de.hysky.skyblocker.config.SkyblockerConfig; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.utils.render.RenderHelper; import de.hysky.skyblocker.utils.waypoint.Waypoint; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; import net.minecraft.client.MinecraftClient; +import net.minecraft.command.argument.EnumArgumentType; import net.minecraft.entity.Entity; import net.minecraft.text.Text; import net.minecraft.util.Formatting; +import net.minecraft.util.StringIdentifiable; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; @@ -28,9 +33,13 @@ public class SecretWaypoint extends Waypoint { private final Vec3d centerPos; SecretWaypoint(int secretIndex, JsonObject waypoint, String name, BlockPos pos) { - super(pos, typeSupplier, Category.get(waypoint).colorComponents); + this(secretIndex, Category.get(waypoint), name, pos); + } + + SecretWaypoint(int secretIndex, Category category, String name, BlockPos pos) { + super(pos, typeSupplier, category.colorComponents); this.secretIndex = secretIndex; - this.category = Category.get(waypoint); + this.category = category; this.name = Text.of(name); this.centerPos = pos.toCenterPos(); } @@ -80,23 +89,26 @@ public class SecretWaypoint extends Waypoint { } } - enum Category { - ENTRANCE(secretWaypoints -> secretWaypoints.enableEntranceWaypoints, 0, 255, 0), - SUPERBOOM(secretWaypoints -> secretWaypoints.enableSuperboomWaypoints, 255, 0, 0), - CHEST(secretWaypoints -> secretWaypoints.enableChestWaypoints, 2, 213, 250), - ITEM(secretWaypoints -> secretWaypoints.enableItemWaypoints, 2, 64, 250), - BAT(secretWaypoints -> secretWaypoints.enableBatWaypoints, 142, 66, 0), - WITHER(secretWaypoints -> secretWaypoints.enableWitherWaypoints, 30, 30, 30), - 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); + enum Category implements StringIdentifiable { + ENTRANCE("entrance", secretWaypoints -> secretWaypoints.enableEntranceWaypoints, 0, 255, 0), + SUPERBOOM("superboom", secretWaypoints -> secretWaypoints.enableSuperboomWaypoints, 255, 0, 0), + CHEST("chest", secretWaypoints -> secretWaypoints.enableChestWaypoints, 2, 213, 250), + ITEM("item", secretWaypoints -> secretWaypoints.enableItemWaypoints, 2, 64, 250), + BAT("bat", secretWaypoints -> secretWaypoints.enableBatWaypoints, 142, 66, 0), + WITHER("wither", secretWaypoints -> secretWaypoints.enableWitherWaypoints, 30, 30, 30), + LEVER("lever", secretWaypoints -> secretWaypoints.enableLeverWaypoints, 250, 217, 2), + FAIRYSOUL("fairysoul", secretWaypoints -> secretWaypoints.enableFairySoulWaypoints, 255, 85, 255), + STONK("stonk", secretWaypoints -> secretWaypoints.enableStonkWaypoints, 146, 52, 235), + AOTV("aotv", secretWaypoints -> secretWaypoints.enableAotvWaypoints, 252, 98, 3), + PEARL("pearl", secretWaypoints -> secretWaypoints.enablePearlWaypoints, 57, 117, 125), + DEFAULT("default", secretWaypoints -> secretWaypoints.enableDefaultWaypoints, 190, 255, 252); + private static final Codec CODEC = StringIdentifiable.createCodec(Category::values); + private final String name; private final Predicate enabledPredicate; private final float[] colorComponents; - Category(Predicate enabledPredicate, int... intColorComponents) { + Category(String name, Predicate enabledPredicate, int... intColorComponents) { + this.name = name; this.enabledPredicate = enabledPredicate; colorComponents = new float[intColorComponents.length]; for (int i = 0; i < intColorComponents.length; i++) { @@ -104,21 +116,8 @@ public class SecretWaypoint extends Waypoint { } } - private static Category get(JsonObject categoryJson) { - return switch (categoryJson.get("category").getAsString()) { - case "entrance" -> Category.ENTRANCE; - case "superboom" -> Category.SUPERBOOM; - case "chest" -> Category.CHEST; - case "item" -> Category.ITEM; - case "bat" -> Category.BAT; - case "wither" -> Category.WITHER; - case "lever" -> Category.LEVER; - case "fairysoul" -> Category.FAIRYSOUL; - case "stonk" -> Category.STONK; - case "aotv" -> Category.AOTV; - case "pearl" -> Category.PEARL; - default -> Category.DEFAULT; - }; + private static Category get(JsonObject waypointJson) { + return CODEC.parse(JsonOps.INSTANCE, waypointJson.get("category")).resultOrPartial(DungeonSecrets.LOGGER::error).orElseThrow(); } boolean needsInteraction() { @@ -140,5 +139,24 @@ public class SecretWaypoint extends Waypoint { boolean isEnabled() { return enabledPredicate.test(SkyblockerConfigManager.get().locations.dungeons.secretWaypoints); } + + @Override + public String asString() { + return name; + } + + static class CategoryArgumentType extends EnumArgumentType { + public CategoryArgumentType() { + super(Category.CODEC, Category::values); + } + + public static CategoryArgumentType category() { + return new CategoryArgumentType(); + } + + public static Category getCategory(CommandContext context, String name) { + return context.getArgument(name, Category.class); + } + } } } -- cgit