diff options
author | Rime <81419447+Emirlol@users.noreply.github.com> | 2024-07-10 23:38:08 +0300 |
---|---|---|
committer | Rime <81419447+Emirlol@users.noreply.github.com> | 2024-07-10 23:38:08 +0300 |
commit | 47b3679a1c490c585c4470341c736cc1eb4f6ae0 (patch) | |
tree | 131ab68ed18a0fdb97a738bb5a68f736c4054268 /src/main/java/de/hysky | |
parent | d3ca54c64fffc34fa0f100a2f51dbe5314b7b3e1 (diff) | |
download | Skyblocker-47b3679a1c490c585c4470341c736cc1eb4f6ae0.tar.gz Skyblocker-47b3679a1c490c585c4470341c736cc1eb4f6ae0.tar.bz2 Skyblocker-47b3679a1c490c585c4470341c736cc1eb4f6ae0.zip |
Add client block pos and egg type argument types and update usages
Diffstat (limited to 'src/main/java/de/hysky')
9 files changed, 418 insertions, 56 deletions
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java index 620da37c..38694ec4 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java @@ -1,16 +1,16 @@ package de.hysky.skyblocker.skyblock.chocolatefactory; import com.mojang.brigadier.Command; -import com.mojang.brigadier.arguments.IntegerArgumentType; -import com.mojang.brigadier.arguments.StringArgumentType; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.events.SkyblockEvents; import de.hysky.skyblocker.utils.*; +import de.hysky.skyblocker.utils.command.argumenttypes.ClientBlockPosArgumentType; +import de.hysky.skyblocker.utils.command.argumenttypes.ClientPosArgument; +import de.hysky.skyblocker.utils.command.argumenttypes.EggTypeArgumentType; import de.hysky.skyblocker.utils.scheduler.MessageScheduler; import de.hysky.skyblocker.utils.waypoint.Waypoint; import it.unimi.dsi.fastutil.objects.ObjectImmutableList; -import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; @@ -24,6 +24,7 @@ import net.minecraft.text.ClickEvent; import net.minecraft.text.HoverEvent; import net.minecraft.text.Text; import net.minecraft.util.Formatting; +import org.apache.commons.lang3.text.WordUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,6 +32,9 @@ import java.util.LinkedList; import java.util.regex.Matcher; import java.util.regex.Pattern; +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; + public class EggFinder { private static final Pattern eggFoundPattern = Pattern.compile("^(?:HOPPITY'S HUNT You found a Chocolate|You have already collected this Chocolate) (Breakfast|Lunch|Dinner)"); private static final Pattern newEggPattern = Pattern.compile("^HOPPITY'S HUNT A Chocolate (Breakfast|Lunch|Dinner) Egg has appeared!$"); @@ -47,17 +51,15 @@ public class EggFinder { SkyblockEvents.LOCATION_CHANGE.register(EggFinder::handleLocationChange); ClientReceiveMessageEvents.GAME.register(EggFinder::onChatMessage); WorldRenderEvents.AFTER_TRANSLUCENT.register(EggFinder::renderWaypoints); - ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(ClientCommandManager.literal(SkyblockerMod.NAMESPACE) - .then(ClientCommandManager.literal("eggFinder") - .then(ClientCommandManager.literal("shareLocation") - .then(ClientCommandManager.argument("x", IntegerArgumentType.integer()) - .then(ClientCommandManager.argument("y", IntegerArgumentType.integer()) - .then(ClientCommandManager.argument("z", IntegerArgumentType.integer()) - .then(ClientCommandManager.argument("eggType", StringArgumentType.word()) - .executes(context -> { - MessageScheduler.INSTANCE.sendMessageAfterCooldown("[Skyblocker] Chocolate " + context.getArgument("eggType", String.class) + " Egg found at " + context.getArgument("x", Integer.class) + " " + context.getArgument("y", Integer.class) + " " + context.getArgument("z", Integer.class) + "!"); - return Command.SINGLE_SUCCESS; - }))))))))); + ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(literal(SkyblockerMod.NAMESPACE) + .then(literal("eggFinder") + .then(literal("shareLocation") + .then(argument("blockPos", ClientBlockPosArgumentType.blockPos()) + .then(argument("eggType", new EggTypeArgumentType()) + .executes(context -> { + MessageScheduler.INSTANCE.sendMessageAfterCooldown("[Skyblocker] Chocolate " + context.getArgument("eggType", EggType.class) + " Egg found at " + context.getArgument("blockPos", ClientPosArgument.class).toAbsoluteBlockPos(context.getSource()) .toShortString() + "!"); + return Command.SINGLE_SUCCESS; + }))))))); } private static void handleLocationChange(Location location) { @@ -161,7 +163,7 @@ public class EggFinder { record Egg(ArmorStandEntity entity, Waypoint waypoint) {} @SuppressWarnings("DataFlowIssue") //Removes that pesky "unboxing of Integer might cause NPE" warning when we already know it's not null - enum EggType { + public enum EggType { LUNCH(Formatting.BLUE.getColorValue(), "ewogICJ0aW1lc3RhbXAiIDogMTcxMTQ2MjU2ODExMiwKICAicHJvZmlsZUlkIiA6ICI3NzUwYzFhNTM5M2Q0ZWQ0Yjc2NmQ4ZGUwOWY4MjU0NiIsCiAgInByb2ZpbGVOYW1lIiA6ICJSZWVkcmVsIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzdhZTZkMmQzMWQ4MTY3YmNhZjk1MjkzYjY4YTRhY2Q4NzJkNjZlNzUxZGI1YTM0ZjJjYmM2NzY2YTAzNTZkMGEiCiAgICB9CiAgfQp9"), DINNER(Formatting.GREEN.getColorValue(), "ewogICJ0aW1lc3RhbXAiIDogMTcxMTQ2MjY0OTcwMSwKICAicHJvZmlsZUlkIiA6ICI3NGEwMzQxNWY1OTI0ZTA4YjMyMGM2MmU1NGE3ZjJhYiIsCiAgInByb2ZpbGVOYW1lIiA6ICJNZXp6aXIiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZTVlMzYxNjU4MTlmZDI4NTBmOTg1NTJlZGNkNzYzZmY5ODYzMTMxMTkyODNjMTI2YWNlMGM0Y2M0OTVlNzZhOCIKICAgIH0KICB9Cn0"), BREAKFAST(Formatting.GOLD.getColorValue(), "ewogICJ0aW1lc3RhbXAiIDogMTcxMTQ2MjY3MzE0OSwKICAicHJvZmlsZUlkIiA6ICJiN2I4ZTlhZjEwZGE0NjFmOTY2YTQxM2RmOWJiM2U4OCIsCiAgInByb2ZpbGVOYW1lIiA6ICJBbmFiYW5hbmFZZzciLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTQ5MzMzZDg1YjhhMzE1ZDAzMzZlYjJkZjM3ZDhhNzE0Y2EyNGM1MWI4YzYwNzRmMWI1YjkyN2RlYjUxNmMyNCIKICAgIH0KICB9Cn0"); @@ -179,7 +181,7 @@ public class EggFinder { private long messageLastSent = 0; //This is to not create an array each time we iterate over the values - public static final ObjectImmutableList<EggType> entries = ObjectImmutableList.of(BREAKFAST, LUNCH, DINNER); + public static final ObjectImmutableList<EggType> entries = ObjectImmutableList.of(EggType.values()); EggType(int color, String texture) { this.color = color; @@ -187,12 +189,9 @@ public class EggFinder { } @Override + @SuppressWarnings("deprecation") // It's either a new dependency or a deprecated method, and I'd rather use the deprecated method public String toString() { - return switch (this) { - case LUNCH -> "Lunch"; - case DINNER -> "Dinner"; - case BREAKFAST -> "Breakfast"; - }; + return WordUtils.capitalizeFully(this.name()); } } } 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 b9986731..e6faff70 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 @@ -12,14 +12,16 @@ import com.mojang.brigadier.builder.RequiredArgumentBuilder; import com.mojang.brigadier.context.CommandContext; import com.mojang.serialization.JsonOps; import de.hysky.skyblocker.SkyblockerMod; -import de.hysky.skyblocker.config.configs.DungeonsConfig; import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.config.configs.DungeonsConfig; import de.hysky.skyblocker.debug.Debug; import de.hysky.skyblocker.skyblock.dungeon.DungeonBoss; import de.hysky.skyblocker.skyblock.dungeon.DungeonMap; import de.hysky.skyblocker.utils.Constants; import de.hysky.skyblocker.utils.Tickable; import de.hysky.skyblocker.utils.Utils; +import de.hysky.skyblocker.utils.command.argumenttypes.ClientBlockPosArgumentType; +import de.hysky.skyblocker.utils.command.argumenttypes.ClientPosArgument; import de.hysky.skyblocker.utils.scheduler.Scheduler; import it.unimi.dsi.fastutil.objects.Object2ByteMap; import it.unimi.dsi.fastutil.objects.Object2ByteMaps; @@ -37,8 +39,6 @@ import net.minecraft.block.Blocks; import net.minecraft.client.MinecraftClient; import net.minecraft.command.CommandRegistryAccess; import net.minecraft.command.CommandSource; -import net.minecraft.command.argument.BlockPosArgumentType; -import net.minecraft.command.argument.PosArgument; import net.minecraft.command.argument.TextArgumentType; import net.minecraft.component.DataComponentTypes; import net.minecraft.entity.Entity; @@ -53,7 +53,6 @@ import net.minecraft.item.Items; import net.minecraft.item.map.MapState; import net.minecraft.registry.Registry; 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; @@ -387,13 +386,12 @@ public class DungeonManager { return Command.SINGLE_SUCCESS; } - private static RequiredArgumentBuilder<FabricClientCommandSource, PosArgument> addCustomWaypointCommand(boolean relative, CommandRegistryAccess registryAccess) { - return argument("pos", BlockPosArgumentType.blockPos()) + private static RequiredArgumentBuilder<FabricClientCommandSource, ClientPosArgument> addCustomWaypointCommand(boolean relative, CommandRegistryAccess registryAccess) { + return argument("pos", ClientBlockPosArgumentType.blockPos()) .then(argument("secretIndex", IntegerArgumentType.integer()) .then(argument("category", SecretWaypoint.Category.CategoryArgumentType.category()) .then(argument("name", TextArgumentType.text(registryAccess)).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)); + BlockPos pos = context.getArgument("pos", ClientPosArgument.class).toAbsoluteBlockPos(context.getSource()); return relative ? addCustomWaypointRelative(context, pos) : addCustomWaypoint(context, pos); })) ) @@ -419,11 +417,10 @@ public class DungeonManager { return Command.SINGLE_SUCCESS; } - private static RequiredArgumentBuilder<FabricClientCommandSource, PosArgument> removeCustomWaypointCommand(boolean relative) { - return argument("pos", BlockPosArgumentType.blockPos()) + private static RequiredArgumentBuilder<FabricClientCommandSource, ClientPosArgument> removeCustomWaypointCommand(boolean relative) { + return argument("pos", ClientBlockPosArgumentType.blockPos()) .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)); + BlockPos pos = context.getArgument("pos", ClientPosArgument.class).toAbsoluteBlockPos(context.getSource()); return relative ? removeCustomWaypointRelative(context, pos) : removeCustomWaypoint(context, pos); }); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java index d709181f..9f5afcc3 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CrystalsLocationsManager.java @@ -8,6 +8,8 @@ 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.command.argumenttypes.ClientBlockPosArgumentType; +import de.hysky.skyblocker.utils.command.argumenttypes.ClientPosArgument; import de.hysky.skyblocker.utils.scheduler.MessageScheduler; import de.hysky.skyblocker.utils.scheduler.Scheduler; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; @@ -18,9 +20,6 @@ import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; import net.minecraft.client.MinecraftClient; import net.minecraft.command.CommandRegistryAccess; -import net.minecraft.command.argument.BlockPosArgumentType; -import net.minecraft.command.argument.PosArgument; -import net.minecraft.server.command.ServerCommandSource; import net.minecraft.text.ClickEvent; import net.minecraft.text.MutableText; import net.minecraft.text.Text; @@ -123,10 +122,10 @@ public class CrystalsLocationsManager { private static void registerWaypointLocationCommands(CommandDispatcher<FabricClientCommandSource> dispatcher, CommandRegistryAccess registryAccess) { dispatcher.register(literal(SkyblockerMod.NAMESPACE) .then(literal("crystalWaypoints") - .then(argument("pos", BlockPosArgumentType.blockPos()) + .then(argument("pos", ClientBlockPosArgumentType.blockPos()) .then(argument("place", StringArgumentType.greedyString()) .suggests((context, builder) -> suggestMatching(WAYPOINT_LOCATIONS.keySet(), builder)) - .executes(context -> addWaypointFromCommand(context.getSource(), getString(context, "place"), context.getArgument("pos", PosArgument.class))) + .executes(context -> addWaypointFromCommand(context.getSource(), getString(context, "place"), context.getArgument("pos", ClientPosArgument.class))) ) ) .then(literal("share") @@ -160,9 +159,8 @@ public class CrystalsLocationsManager { return text; } - public static int addWaypointFromCommand(FabricClientCommandSource source, String place, PosArgument location) { - // TODO Less hacky way with custom ClientBlockPosArgumentType - BlockPos blockPos = location.toAbsoluteBlockPos(new ServerCommandSource(null, source.getPosition(), source.getRotation(), null, 0, null, null, null, null)); + public static int addWaypointFromCommand(FabricClientCommandSource source, String place, ClientPosArgument location) { + BlockPos blockPos = location.toAbsoluteBlockPos(source); if (WAYPOINT_LOCATIONS.containsKey(place)) { addCustomWaypoint(place, blockPos); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/waypoint/OrderedWaypoints.java b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/OrderedWaypoints.java index 11ec1b8d..10fe0b6b 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/waypoint/OrderedWaypoints.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/OrderedWaypoints.java @@ -15,6 +15,8 @@ import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.item.CustomArmorDyeColors; import de.hysky.skyblocker.utils.Constants; import de.hysky.skyblocker.utils.Utils; +import de.hysky.skyblocker.utils.command.argumenttypes.ClientBlockPosArgumentType; +import de.hysky.skyblocker.utils.command.argumenttypes.ClientPosArgument; import de.hysky.skyblocker.utils.render.RenderHelper; import de.hysky.skyblocker.utils.waypoint.Waypoint; import it.unimi.dsi.fastutil.floats.FloatArrayList; @@ -30,9 +32,6 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.command.CommandRegistryAccess; import net.minecraft.command.CommandSource; -import net.minecraft.command.argument.BlockPosArgumentType; -import net.minecraft.command.argument.PosArgument; -import net.minecraft.server.command.ServerCommandSource; import net.minecraft.text.Text; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; @@ -87,24 +86,24 @@ public class OrderedWaypoints { .then(literal("add") .then(argument("groupName", word()) .suggests((source, builder) -> CommandSource.suggestMatching(WAYPOINTS.keySet(), builder)) - .then(argument("pos", BlockPosArgumentType.blockPos()) - .executes(context -> addWaypoint(context.getSource(), getString(context, "groupName"), context.getArgument("pos", PosArgument.class), Integer.MIN_VALUE, null)) + .then(argument("pos", ClientBlockPosArgumentType.blockPos()) + .executes(context -> addWaypoint(context.getSource(), getString(context, "groupName"), context.getArgument("pos", ClientPosArgument.class), Integer.MIN_VALUE, null)) .then(argument("hex", word()) - .executes(context -> addWaypoint(context.getSource(), getString(context, "groupName"), context.getArgument("pos", PosArgument.class), Integer.MIN_VALUE, getString(context, "hex"))))))) + .executes(context -> addWaypoint(context.getSource(), getString(context, "groupName"), context.getArgument("pos", ClientPosArgument.class), Integer.MIN_VALUE, getString(context, "hex"))))))) .then(literal("addAt") .then(argument("groupName", word()) .suggests((source, builder) -> CommandSource.suggestMatching(WAYPOINTS.keySet(), builder)) .then(argument("index", IntegerArgumentType.integer(0)) - .then(argument("pos", BlockPosArgumentType.blockPos()) - .executes(context -> addWaypoint(context.getSource(), getString(context, "groupName"), context.getArgument("pos", PosArgument.class), IntegerArgumentType.getInteger(context, "index"), null)) + .then(argument("pos", ClientBlockPosArgumentType.blockPos()) + .executes(context -> addWaypoint(context.getSource(), getString(context, "groupName"), context.getArgument("pos", ClientPosArgument.class), IntegerArgumentType.getInteger(context, "index"), null)) .then(argument("hex", word()) - .executes(context -> addWaypoint(context.getSource(), getString(context, "groupName"), context.getArgument("pos", PosArgument.class), IntegerArgumentType.getInteger(context, "index"), getString(context, "hex")))))))) + .executes(context -> addWaypoint(context.getSource(), getString(context, "groupName"), context.getArgument("pos", ClientPosArgument.class), IntegerArgumentType.getInteger(context, "index"), getString(context, "hex")))))))) .then(literal("remove") .then(argument("groupName", word()) .suggests((source, builder) -> CommandSource.suggestMatching(WAYPOINTS.keySet(), builder)) .executes(context -> removeWaypointGroup(context.getSource(), getString(context, "groupName"))) - .then(argument("pos", BlockPosArgumentType.blockPos()) - .executes(context -> removeWaypoint(context.getSource(), getString(context, "groupName"), context.getArgument("pos", PosArgument.class), Integer.MIN_VALUE))))) + .then(argument("pos", ClientBlockPosArgumentType.blockPos()) + .executes(context -> removeWaypoint(context.getSource(), getString(context, "groupName"), context.getArgument("pos", ClientPosArgument.class), Integer.MIN_VALUE))))) .then(literal("removeAt") .then(argument("groupName", word()) .suggests((source, builder) -> CommandSource.suggestMatching(WAYPOINTS.keySet(), builder)) @@ -126,8 +125,8 @@ public class OrderedWaypoints { .executes(context -> export(context.getSource())))))); } - private static int addWaypoint(FabricClientCommandSource source, String groupName, PosArgument posArgument, int index, String hex) { - BlockPos pos = posArgument.toAbsoluteBlockPos(new ServerCommandSource(null, source.getPosition(), source.getRotation(), null, 0, null, null, null, null)); + private static int addWaypoint(FabricClientCommandSource source, String groupName, ClientPosArgument posArgument, int index, String hex) { + BlockPos pos = posArgument.toAbsoluteBlockPos(source); SEMAPHORE.acquireUninterruptibly(); @@ -175,13 +174,13 @@ public class OrderedWaypoints { return Command.SINGLE_SUCCESS; } - private static int removeWaypoint(FabricClientCommandSource source, String groupName, PosArgument posArgument, int index) { + private static int removeWaypoint(FabricClientCommandSource source, String groupName, ClientPosArgument posArgument, int index) { if (WAYPOINTS.containsKey(groupName)) { SEMAPHORE.acquireUninterruptibly(); OrderedWaypointGroup group = WAYPOINTS.get(groupName); if (posArgument != null) { - BlockPos pos = posArgument.toAbsoluteBlockPos(new ServerCommandSource(null, source.getPosition(), source.getRotation(), null, 0, null, null, null, null)); + BlockPos pos = posArgument.toAbsoluteBlockPos(source); group.waypoints().removeIf(waypoint -> waypoint.getPos().equals(pos)); INDEX_STORE.removeInt(group.name()); diff --git a/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/ClientBlockPosArgumentType.java b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/ClientBlockPosArgumentType.java new file mode 100644 index 00000000..484606ec --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/ClientBlockPosArgumentType.java @@ -0,0 +1,87 @@ +package de.hysky.skyblocker.utils.command.argumenttypes; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.command.CommandSource; +import net.minecraft.server.command.CommandManager; +import net.minecraft.text.Text; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.concurrent.CompletableFuture; + +public class ClientBlockPosArgumentType implements ArgumentType<ClientPosArgument> { + private static final Collection<String> EXAMPLES = Arrays.asList("0 0 0", "~ ~ ~", "^ ^ ^", "^1 ^ ^-5", "~0.5 ~1 ~-5"); + public static final SimpleCommandExceptionType UNLOADED_EXCEPTION = new SimpleCommandExceptionType(Text.translatable("argument.pos.unloaded")); + public static final SimpleCommandExceptionType OUT_OF_WORLD_EXCEPTION = new SimpleCommandExceptionType(Text.translatable("argument.pos.outofworld")); + public static final SimpleCommandExceptionType OUT_OF_BOUNDS_EXCEPTION = new SimpleCommandExceptionType(Text.translatable("argument.pos.outofbounds")); + + public static ClientBlockPosArgumentType blockPos() { + return new ClientBlockPosArgumentType(); + } + + public static BlockPos getLoadedBlockPos(CommandContext<FabricClientCommandSource> context, String name) throws CommandSyntaxException { + ClientWorld clientWorld = context.getSource().getWorld(); + return getLoadedBlockPos(context, clientWorld, name); + } + + public static BlockPos getLoadedBlockPos(CommandContext<FabricClientCommandSource> context, ClientWorld world, String name) throws CommandSyntaxException { + BlockPos blockPos = getBlockPos(context, name); + if (!world.isChunkLoaded(blockPos)) { + throw UNLOADED_EXCEPTION.create(); + } else if (!world.isInBuildLimit(blockPos)) { + throw OUT_OF_WORLD_EXCEPTION.create(); + } else { + return blockPos; + } + } + + public static BlockPos getBlockPos(CommandContext<FabricClientCommandSource> context, String name) { + return context.getArgument(name, ClientPosArgument.class).toAbsoluteBlockPos(context.getSource()); + } + + public static BlockPos getValidBlockPos(CommandContext<FabricClientCommandSource> context, String name) throws CommandSyntaxException { + BlockPos blockPos = getBlockPos(context, name); + if (!World.isValid(blockPos)) { + throw OUT_OF_BOUNDS_EXCEPTION.create(); + } else { + return blockPos; + } + } + + public ClientPosArgument parse(StringReader stringReader) throws CommandSyntaxException { + return stringReader.canRead() && stringReader.peek() == '^' ? LookingClientPosArgument.parse(stringReader) : DefaultClientPosArgument.parse(stringReader); + } + + @Override + public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) { + if (!(context.getSource() instanceof CommandSource)) { + return Suggestions.empty(); + } else { + String string = builder.getRemaining(); + Collection<CommandSource.RelativePosition> collection; + if (!string.isEmpty() && string.charAt(0) == '^') { + collection = Collections.singleton(CommandSource.RelativePosition.ZERO_LOCAL); + } else { + collection = ((CommandSource)context.getSource()).getBlockPositionSuggestions(); + } + + return CommandSource.suggestPositions(string, collection, builder, CommandManager.getCommandValidator(this::parse)); + } + } + + @Override + public Collection<String> getExamples() { + return EXAMPLES; + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/ClientPosArgument.java b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/ClientPosArgument.java new file mode 100644 index 00000000..ad0da38b --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/ClientPosArgument.java @@ -0,0 +1,27 @@ +package de.hysky.skyblocker.utils.command.argumenttypes; + +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec2f; +import net.minecraft.util.math.Vec3d; + +/** + * This interface, its 2 implementations and ClientBlockPosArgumentType are all copied from minecraft + * and converted to use FabricClientCommandSource instead of ServerCommandSource. + * This removes the need for hacky workarounds such as creating new ServerCommandSources with null or 0 on every argument. + */ +public interface ClientPosArgument { + Vec3d toAbsolutePos(FabricClientCommandSource source); + + Vec2f toAbsoluteRotation(FabricClientCommandSource source); + + default BlockPos toAbsoluteBlockPos(FabricClientCommandSource source) { + return BlockPos.ofFloored(this.toAbsolutePos(source)); + } + + boolean isXRelative(); + + boolean isYRelative(); + + boolean isZRelative(); +} diff --git a/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/DefaultClientPosArgument.java b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/DefaultClientPosArgument.java new file mode 100644 index 00000000..99507f64 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/DefaultClientPosArgument.java @@ -0,0 +1,113 @@ +package de.hysky.skyblocker.utils.command.argumenttypes; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.command.argument.CoordinateArgument; +import net.minecraft.command.argument.Vec3ArgumentType; +import net.minecraft.util.math.Vec2f; +import net.minecraft.util.math.Vec3d; + +public class DefaultClientPosArgument implements ClientPosArgument { + private final CoordinateArgument x; + private final CoordinateArgument y; + private final CoordinateArgument z; + + public DefaultClientPosArgument(CoordinateArgument x, CoordinateArgument y, CoordinateArgument z) { + this.x = x; + this.y = y; + this.z = z; + } + + @Override + public Vec3d toAbsolutePos(FabricClientCommandSource source) { + Vec3d vec3d = source.getPosition(); + return new Vec3d(this.x.toAbsoluteCoordinate(vec3d.x), this.y.toAbsoluteCoordinate(vec3d.y), this.z.toAbsoluteCoordinate(vec3d.z)); + } + + @Override + public Vec2f toAbsoluteRotation(FabricClientCommandSource source) { + Vec2f vec2f = source.getRotation(); + return new Vec2f((float)this.x.toAbsoluteCoordinate(vec2f.x), (float)this.y.toAbsoluteCoordinate(vec2f.y)); + } + + @Override + public boolean isXRelative() { + return this.x.isRelative(); + } + + @Override + public boolean isYRelative() { + return this.y.isRelative(); + } + + @Override + public boolean isZRelative() { + return this.z.isRelative(); + } + + public boolean equals(Object o) { + if (this == o) return true; + + return o instanceof DefaultClientPosArgument defaultPosArgument && + this.x.equals(defaultPosArgument.x) && this.y.equals(defaultPosArgument.y) && this.z.equals(defaultPosArgument.z); + } + + public static DefaultClientPosArgument parse(StringReader reader) throws CommandSyntaxException { + int i = reader.getCursor(); + CoordinateArgument coordinateArgument = CoordinateArgument.parse(reader); + if (reader.canRead() && reader.peek() == ' ') { + reader.skip(); + CoordinateArgument coordinateArgument2 = CoordinateArgument.parse(reader); + if (reader.canRead() && reader.peek() == ' ') { + reader.skip(); + CoordinateArgument coordinateArgument3 = CoordinateArgument.parse(reader); + return new DefaultClientPosArgument(coordinateArgument, coordinateArgument2, coordinateArgument3); + } else { + reader.setCursor(i); + throw Vec3ArgumentType.INCOMPLETE_EXCEPTION.createWithContext(reader); + } + } else { + reader.setCursor(i); + throw Vec3ArgumentType.INCOMPLETE_EXCEPTION.createWithContext(reader); + } + } + + public static DefaultClientPosArgument parse(StringReader reader, boolean centerIntegers) throws CommandSyntaxException { + int i = reader.getCursor(); + CoordinateArgument coordinateArgument = CoordinateArgument.parse(reader, centerIntegers); + if (reader.canRead() && reader.peek() == ' ') { + reader.skip(); + CoordinateArgument coordinateArgument2 = CoordinateArgument.parse(reader, false); + if (reader.canRead() && reader.peek() == ' ') { + reader.skip(); + CoordinateArgument coordinateArgument3 = CoordinateArgument.parse(reader, centerIntegers); + return new DefaultClientPosArgument(coordinateArgument, coordinateArgument2, coordinateArgument3); + } else { + reader.setCursor(i); + throw Vec3ArgumentType.INCOMPLETE_EXCEPTION.createWithContext(reader); + } + } else { + reader.setCursor(i); + throw Vec3ArgumentType.INCOMPLETE_EXCEPTION.createWithContext(reader); + } + } + + public static DefaultClientPosArgument absolute(double x, double y, double z) { + return new DefaultClientPosArgument(new CoordinateArgument(false, x), new CoordinateArgument(false, y), new CoordinateArgument(false, z)); + } + + public static DefaultClientPosArgument absolute(Vec2f vec) { + return new DefaultClientPosArgument(new CoordinateArgument(false, vec.x), new CoordinateArgument(false, vec.y), new CoordinateArgument(true, 0.0)); + } + + public static DefaultClientPosArgument zero() { + return new DefaultClientPosArgument(new CoordinateArgument(true, 0.0), new CoordinateArgument(true, 0.0), new CoordinateArgument(true, 0.0)); + } + + public int hashCode() { + int i = this.x.hashCode(); + i = 31 * i + this.y.hashCode(); + return 31 * i + this.z.hashCode(); + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/EggTypeArgumentType.java b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/EggTypeArgumentType.java new file mode 100644 index 00000000..3510e118 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/EggTypeArgumentType.java @@ -0,0 +1,36 @@ +package de.hysky.skyblocker.utils.command.argumenttypes; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import de.hysky.skyblocker.skyblock.chocolatefactory.EggFinder; +import net.minecraft.command.CommandSource; + +import java.util.Collection; +import java.util.concurrent.CompletableFuture; + +public class EggTypeArgumentType implements ArgumentType<EggFinder.EggType> { + @Override + public EggFinder.EggType parse(StringReader reader) throws CommandSyntaxException { + String name = reader.readUnquotedString(); + for (EggFinder.EggType type : EggFinder.EggType.entries) { + if (type.name().equalsIgnoreCase(name)) return type; + } + throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownArgument().create(); + } + + @Override + public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) { + return context.getSource() instanceof CommandSource + ? CommandSource.suggestMatching(EggFinder.EggType.entries.stream().map(EggFinder.EggType::name).map(String::toLowerCase), builder) + : Suggestions.empty(); + } + + @Override + public Collection<String> getExamples() { + return EggFinder.EggType.entries.stream().map(EggFinder.EggType::name).map(String::toLowerCase).toList(); + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/LookingClientPosArgument.java b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/LookingClientPosArgument.java new file mode 100644 index 00000000..0e9204e1 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/LookingClientPosArgument.java @@ -0,0 +1,106 @@ +package de.hysky.skyblocker.utils.command.argumenttypes; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.command.argument.CoordinateArgument; +import net.minecraft.command.argument.Vec3ArgumentType; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec2f; +import net.minecraft.util.math.Vec3d; + +import java.util.Objects; + +public class LookingClientPosArgument implements ClientPosArgument { + private final double x; + private final double y; + private final double z; + + public LookingClientPosArgument(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + @Override + public Vec3d toAbsolutePos(FabricClientCommandSource source) { + Vec2f vec2f = source.getRotation(); + Vec3d vec3d = source.getPlayer().getPos(); + float f = MathHelper.cos((vec2f.y + 90.0F) * (float) (Math.PI / 180.0)); + float g = MathHelper.sin((vec2f.y + 90.0F) * (float) (Math.PI / 180.0)); + float h = MathHelper.cos(-vec2f.x * (float) (Math.PI / 180.0)); + float i = MathHelper.sin(-vec2f.x * (float) (Math.PI / 180.0)); + float j = MathHelper.cos((-vec2f.x + 90.0F) * (float) (Math.PI / 180.0)); + float k = MathHelper.sin((-vec2f.x + 90.0F) * (float) (Math.PI / 180.0)); + Vec3d vec3d2 = new Vec3d(f * h, i, g * h); + Vec3d vec3d3 = new Vec3d(f * j, k, g * j); + Vec3d vec3d4 = vec3d2.crossProduct(vec3d3).multiply(-1.0); + double d = vec3d2.x * this.z + vec3d3.x * this.y + vec3d4.x * this.x; + double e = vec3d2.y * this.z + vec3d3.y * this.y + vec3d4.y * this.x; + double l = vec3d2.z * this.z + vec3d3.z * this.y + vec3d4.z * this.x; + return new Vec3d(vec3d.x + d, vec3d.y + e, vec3d.z + l); + } + + @Override + public Vec2f toAbsoluteRotation(FabricClientCommandSource source) { + return Vec2f.ZERO; + } + + @Override + public boolean isXRelative() { + return true; + } + + @Override + public boolean isYRelative() { + return true; + } + + @Override + public boolean isZRelative() { + return true; + } + + public static LookingClientPosArgument parse(StringReader reader) throws CommandSyntaxException { + int i = reader.getCursor(); + double d = readCoordinate(reader, i); + if (reader.canRead() && reader.peek() == ' ') { + reader.skip(); + double e = readCoordinate(reader, i); + if (reader.canRead() && reader.peek() == ' ') { + reader.skip(); + double f = readCoordinate(reader, i); + return new LookingClientPosArgument(d, e, f); + } else { + reader.setCursor(i); + throw Vec3ArgumentType.INCOMPLETE_EXCEPTION.createWithContext(reader); + } + } else { + reader.setCursor(i); + throw Vec3ArgumentType.INCOMPLETE_EXCEPTION.createWithContext(reader); + } + } + + private static double readCoordinate(StringReader reader, int startingCursorPos) throws CommandSyntaxException { + if (!reader.canRead()) { + throw CoordinateArgument.MISSING_COORDINATE.createWithContext(reader); + } else if (reader.peek() != '^') { + reader.setCursor(startingCursorPos); + throw Vec3ArgumentType.MIXED_COORDINATE_EXCEPTION.createWithContext(reader); + } else { + reader.skip(); + return reader.canRead() && reader.peek() != ' ' ? reader.readDouble() : 0.0; + } + } + + public boolean equals(Object o) { + if (this == o) return true; + + return o instanceof LookingClientPosArgument lookingPosArgument + && this.x == lookingPosArgument.x && this.y == lookingPosArgument.y && this.z == lookingPosArgument.z; + } + + public int hashCode() { + return Objects.hash(x, y, z); + } +} |