aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de/hysky/skyblocker/utils/command
diff options
context:
space:
mode:
authorRime <81419447+Emirlol@users.noreply.github.com>2024-07-10 23:38:08 +0300
committerRime <81419447+Emirlol@users.noreply.github.com>2024-07-10 23:38:08 +0300
commit47b3679a1c490c585c4470341c736cc1eb4f6ae0 (patch)
tree131ab68ed18a0fdb97a738bb5a68f736c4054268 /src/main/java/de/hysky/skyblocker/utils/command
parentd3ca54c64fffc34fa0f100a2f51dbe5314b7b3e1 (diff)
downloadSkyblocker-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/skyblocker/utils/command')
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/ClientBlockPosArgumentType.java87
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/ClientPosArgument.java27
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/DefaultClientPosArgument.java113
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/EggTypeArgumentType.java36
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/command/argumenttypes/LookingClientPosArgument.java106
5 files changed, 369 insertions, 0 deletions
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);
+ }
+}