Skip to content

Commit b9cbdb0

Browse files
authored
Update waypoints (#5672)
- add option to hide/delete a waypoint when the player is close enough - fix the .waypoint command crashing
1 parent d6ba669 commit b9cbdb0

File tree

4 files changed

+397
-8
lines changed

4 files changed

+397
-8
lines changed
Lines changed: 341 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
1+
/*
2+
* This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client).
3+
* Copyright (c) Meteor Development.
4+
*/
5+
6+
package meteordevelopment.meteorclient.commands.arguments;
7+
8+
import com.mojang.brigadier.StringReader;
9+
import com.mojang.brigadier.arguments.ArgumentType;
10+
import com.mojang.brigadier.context.CommandContext;
11+
import com.mojang.brigadier.exceptions.CommandSyntaxException;
12+
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
13+
import com.mojang.brigadier.suggestion.Suggestions;
14+
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
15+
import net.minecraft.client.world.ClientWorld;
16+
import net.minecraft.command.CommandSource;
17+
import net.minecraft.command.argument.CoordinateArgument;
18+
import net.minecraft.command.argument.EntityAnchorArgumentType;
19+
import net.minecraft.command.argument.Vec3ArgumentType;
20+
import net.minecraft.server.command.CommandManager;
21+
import net.minecraft.text.Text;
22+
import net.minecraft.util.math.*;
23+
import net.minecraft.world.World;
24+
25+
import java.util.Arrays;
26+
import java.util.Collection;
27+
import java.util.Collections;
28+
import java.util.Objects;
29+
import java.util.concurrent.CompletableFuture;
30+
31+
import static meteordevelopment.meteorclient.MeteorClient.mc;
32+
33+
/**
34+
* Taken from <a href="https://github.com/xpple/clientarguments">clientarguments</a>
35+
* <p>
36+
* The MIT License (MIT)
37+
* <p>
38+
* Copyright (c) 2021 xpple
39+
* <p>
40+
* Permission is hereby granted, free of charge, to any person obtaining a copy
41+
* of this software and associated documentation files (the "Software"), to deal
42+
* in the Software without restriction, including without limitation the rights
43+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
44+
* copies of the Software, and to permit persons to whom the Software is
45+
* furnished to do so, subject to the following conditions:
46+
* <p>
47+
* The above copyright notice and this permission notice shall be included in
48+
* all copies or substantial portions of the Software.
49+
* <p>
50+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
51+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
52+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
53+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
54+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
55+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
56+
* THE SOFTWARE.
57+
*
58+
* @author Xpple
59+
* @see <a href="https://github.com/xpple/clientarguments/blob/master/src/main/java/dev/xpple/clientarguments/arguments/CBlockPosArgument.java">CBlockPosArgument.java</a>
60+
* @see <a href="https://github.com/xpple/clientarguments/blob/master/src/main/java/dev/xpple/clientarguments/arguments/CCoordinates.java">CCoordinates.java</a>
61+
* @see <a href="https://github.com/xpple/clientarguments/blob/master/src/main/java/dev/xpple/clientarguments/arguments/CWorldCoordinates.java">CWorldCoordinates.java</a>
62+
* @see <a href="https://github.com/xpple/clientarguments/blob/master/src/main/java/dev/xpple/clientarguments/arguments/CLocalCoordinates.java">CLocalCoordinates.java</a>
63+
*/
64+
public class BlockPosArgumentType implements ArgumentType<BlockPosArgumentType.PosArgument> {
65+
private static final BlockPosArgumentType INSTANCE = new BlockPosArgumentType();
66+
private static final Collection<String> EXAMPLES = Arrays.asList("0 0 0", "~ ~ ~", "^ ^ ^", "^1 ^ ^-5", "~0.5 ~1 ~-5");
67+
public static final SimpleCommandExceptionType UNLOADED_EXCEPTION = new SimpleCommandExceptionType(Text.translatable("argument.pos.unloaded"));
68+
public static final SimpleCommandExceptionType OUT_OF_WORLD_EXCEPTION = new SimpleCommandExceptionType(Text.translatable("argument.pos.outofworld"));
69+
public static final SimpleCommandExceptionType OUT_OF_BOUNDS_EXCEPTION = new SimpleCommandExceptionType(Text.translatable("argument.pos.outofbounds"));
70+
71+
private BlockPosArgumentType() {}
72+
73+
public static BlockPosArgumentType blockPos() {
74+
return INSTANCE;
75+
}
76+
77+
public static <S> BlockPos getLoadedBlockPos(CommandContext<S> context, String name) throws CommandSyntaxException {
78+
ClientWorld clientLevel = mc.world;
79+
return getLoadedBlockPos(context, clientLevel, name);
80+
}
81+
82+
public static <S> BlockPos getLoadedBlockPos(CommandContext<S> context, ClientWorld level, String name) throws CommandSyntaxException {
83+
BlockPos blockPos = getBlockPos(context, name);
84+
ChunkPos chunkPos = new ChunkPos(blockPos);
85+
if (!level.getChunkManager().isChunkLoaded(chunkPos.x, chunkPos.z)) {
86+
throw UNLOADED_EXCEPTION.create();
87+
} else if (!level.isInBuildLimit(blockPos)) {
88+
throw OUT_OF_WORLD_EXCEPTION.create();
89+
} else {
90+
return blockPos;
91+
}
92+
}
93+
94+
public static <S> BlockPos getBlockPos(CommandContext<S> context, String name) {
95+
return context.getArgument(name, PosArgument.class).getBlockPos(context.getSource());
96+
}
97+
98+
public static <S> BlockPos getValidBlockPos(CommandContext<S> context, String name) throws CommandSyntaxException {
99+
BlockPos blockPos = getBlockPos(context, name);
100+
if (!World.isValid(blockPos)) {
101+
throw OUT_OF_BOUNDS_EXCEPTION.create();
102+
} else {
103+
return blockPos;
104+
}
105+
}
106+
107+
public PosArgument parse(StringReader stringReader) throws CommandSyntaxException {
108+
return stringReader.canRead() && stringReader.peek() == '^' ? LookingPosArgument.parse(stringReader) : DefaultPosArgument.parse(stringReader);
109+
}
110+
111+
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
112+
if (!(context.getSource() instanceof CommandSource)) {
113+
return Suggestions.empty();
114+
} else {
115+
String string = builder.getRemaining();
116+
Collection<CommandSource.RelativePosition> collection;
117+
if (!string.isEmpty() && string.charAt(0) == '^') {
118+
collection = Collections.singleton(CommandSource.RelativePosition.ZERO_LOCAL);
119+
} else {
120+
collection = ((CommandSource) context.getSource()).getBlockPositionSuggestions();
121+
}
122+
123+
return CommandSource.suggestPositions(string, collection, builder, CommandManager.getCommandValidator(this::parse));
124+
}
125+
}
126+
127+
public Collection<String> getExamples() {
128+
return EXAMPLES;
129+
}
130+
131+
public interface PosArgument {
132+
<S> Vec3d getPosition(S var1);
133+
134+
<S> Vec2f getRotation(S var1);
135+
136+
default <S> BlockPos getBlockPos(S source) {
137+
return BlockPos.ofFloored(this.getPosition(source));
138+
}
139+
140+
boolean isXRelative();
141+
142+
boolean isYRelative();
143+
144+
boolean isZRelative();
145+
}
146+
147+
public static class DefaultPosArgument implements PosArgument {
148+
private final CoordinateArgument x;
149+
private final CoordinateArgument y;
150+
private final CoordinateArgument z;
151+
152+
public DefaultPosArgument(CoordinateArgument x, CoordinateArgument y, CoordinateArgument z) {
153+
this.x = x;
154+
this.y = y;
155+
this.z = z;
156+
}
157+
158+
@Override
159+
public <S> Vec3d getPosition(S source) {
160+
Vec3d vec3 = mc.player.getPos();
161+
return new Vec3d(this.x.toAbsoluteCoordinate(vec3.x), this.y.toAbsoluteCoordinate(vec3.y), this.z.toAbsoluteCoordinate(vec3.z));
162+
}
163+
164+
@Override
165+
public <S> Vec2f getRotation(S source) {
166+
Vec2f vec2 = mc.player.getRotationClient();
167+
return new Vec2f((float) this.x.toAbsoluteCoordinate(vec2.x), (float) this.y.toAbsoluteCoordinate(vec2.y));
168+
}
169+
170+
@Override
171+
public boolean isXRelative() {
172+
return this.x.isRelative();
173+
}
174+
175+
@Override
176+
public boolean isYRelative() {
177+
return this.y.isRelative();
178+
}
179+
180+
@Override
181+
public boolean isZRelative() {
182+
return this.z.isRelative();
183+
}
184+
185+
public boolean equals(Object o) {
186+
if (this == o) {
187+
return true;
188+
}
189+
if (!(o instanceof DefaultPosArgument defaultPosArgument)) {
190+
return false;
191+
}
192+
return this.x.equals(defaultPosArgument.x) && this.y.equals(defaultPosArgument.y) && this.z.equals(defaultPosArgument.z);
193+
}
194+
195+
public static DefaultPosArgument parse(StringReader reader) throws CommandSyntaxException {
196+
int cursor = reader.getCursor();
197+
CoordinateArgument worldCoordinate = CoordinateArgument.parse(reader);
198+
if (reader.canRead() && reader.peek() == ' ') {
199+
reader.skip();
200+
CoordinateArgument worldCoordinate2 = CoordinateArgument.parse(reader);
201+
if (reader.canRead() && reader.peek() == ' ') {
202+
reader.skip();
203+
CoordinateArgument worldCoordinate3 = CoordinateArgument.parse(reader);
204+
return new DefaultPosArgument(worldCoordinate, worldCoordinate2, worldCoordinate3);
205+
}
206+
}
207+
reader.setCursor(cursor);
208+
throw Vec3ArgumentType.INCOMPLETE_EXCEPTION.createWithContext(reader);
209+
}
210+
211+
public static DefaultPosArgument parse(StringReader reader, boolean centerIntegers) throws CommandSyntaxException {
212+
int cursor = reader.getCursor();
213+
CoordinateArgument worldCoordinate = CoordinateArgument.parse(reader, centerIntegers);
214+
if (reader.canRead() && reader.peek() == ' ') {
215+
reader.skip();
216+
CoordinateArgument worldCoordinate2 = CoordinateArgument.parse(reader, false);
217+
if (reader.canRead() && reader.peek() == ' ') {
218+
reader.skip();
219+
CoordinateArgument worldCoordinate3 = CoordinateArgument.parse(reader, centerIntegers);
220+
return new DefaultPosArgument(worldCoordinate, worldCoordinate2, worldCoordinate3);
221+
}
222+
}
223+
reader.setCursor(cursor);
224+
throw Vec3ArgumentType.INCOMPLETE_EXCEPTION.createWithContext(reader);
225+
}
226+
227+
public static DefaultPosArgument absolute(double x, double y, double z) {
228+
return new DefaultPosArgument(new CoordinateArgument(false, x), new CoordinateArgument(false, y), new CoordinateArgument(false, z));
229+
}
230+
231+
public static DefaultPosArgument absolute(Vec2f vec) {
232+
return new DefaultPosArgument(new CoordinateArgument(false, vec.x), new CoordinateArgument(false, vec.y), new CoordinateArgument(true, 0.0));
233+
}
234+
235+
public static DefaultPosArgument current() {
236+
return new DefaultPosArgument(new CoordinateArgument(true, 0.0), new CoordinateArgument(true, 0.0), new CoordinateArgument(true, 0.0));
237+
}
238+
239+
@Override
240+
public int hashCode() {
241+
int i = this.x.hashCode();
242+
i = 31 * i + this.y.hashCode();
243+
return 31 * i + this.z.hashCode();
244+
}
245+
}
246+
247+
public static class LookingPosArgument implements PosArgument {
248+
private final double x;
249+
private final double y;
250+
private final double z;
251+
252+
public LookingPosArgument(double x, double y, double z) {
253+
this.x = x;
254+
this.y = y;
255+
this.z = z;
256+
}
257+
258+
@Override
259+
public <S> Vec3d getPosition(S source) {
260+
Vec2f vec2 = mc.player.getRotationClient();
261+
Vec3d vec3 = EntityAnchorArgumentType.EntityAnchor.FEET.positionAt(mc.player);
262+
float f = MathHelper.cos((vec2.y + 90.0F) * (float) (Math.PI / 180.0));
263+
float g = MathHelper.sin((vec2.y + 90.0F) * (float) (Math.PI / 180.0));
264+
float h = MathHelper.cos(-vec2.x * (float) (Math.PI / 180.0));
265+
float i = MathHelper.sin(-vec2.x * (float) (Math.PI / 180.0));
266+
float j = MathHelper.cos((-vec2.x + 90.0F) * (float) (Math.PI / 180.0));
267+
float k = MathHelper.sin((-vec2.x + 90.0F) * (float) (Math.PI / 180.0));
268+
Vec3d vec32 = new Vec3d(f * h, i, g * h);
269+
Vec3d vec33 = new Vec3d(f * j, k, g * j);
270+
Vec3d vec34 = vec32.crossProduct(vec33).multiply(-1.0);
271+
double d = vec32.x * this.z + vec33.x * this.y + vec34.x * this.x;
272+
double e = vec32.y * this.z + vec33.y * this.y + vec34.y * this.x;
273+
double l = vec32.z * this.z + vec33.z * this.y + vec34.z * this.x;
274+
return new Vec3d(vec3.x + d, vec3.y + e, vec3.z + l);
275+
}
276+
277+
@Override
278+
public <S> Vec2f getRotation(S source) {
279+
return Vec2f.ZERO;
280+
}
281+
282+
@Override
283+
public boolean isXRelative() {
284+
return true;
285+
}
286+
287+
@Override
288+
public boolean isYRelative() {
289+
return true;
290+
}
291+
292+
@Override
293+
public boolean isZRelative() {
294+
return true;
295+
}
296+
297+
public static LookingPosArgument parse(StringReader reader) throws CommandSyntaxException {
298+
int cursor = reader.getCursor();
299+
double d = readCoordinate(reader, cursor);
300+
if (!reader.canRead() || reader.peek() != ' ') {
301+
reader.setCursor(cursor);
302+
throw Vec3ArgumentType.INCOMPLETE_EXCEPTION.createWithContext(reader);
303+
}
304+
reader.skip();
305+
double e = readCoordinate(reader, cursor);
306+
if (!reader.canRead() || reader.peek() != ' ') {
307+
reader.setCursor(cursor);
308+
throw Vec3ArgumentType.INCOMPLETE_EXCEPTION.createWithContext(reader);
309+
}
310+
reader.skip();
311+
double f = readCoordinate(reader, cursor);
312+
return new LookingPosArgument(d, e, f);
313+
}
314+
315+
private static double readCoordinate(StringReader reader, int startingCursorPos) throws CommandSyntaxException {
316+
if (!reader.canRead()) {
317+
throw CoordinateArgument.MISSING_COORDINATE.createWithContext(reader);
318+
}
319+
if (reader.peek() != '^') {
320+
reader.setCursor(startingCursorPos);
321+
throw Vec3ArgumentType.MIXED_COORDINATE_EXCEPTION.createWithContext(reader);
322+
}
323+
reader.skip();
324+
return reader.canRead() && reader.peek() != ' ' ? reader.readDouble() : 0.0;
325+
}
326+
327+
public boolean equals(Object o) {
328+
if (this == o) {
329+
return true;
330+
}
331+
if (!(o instanceof LookingPosArgument lookingPosArgument)) {
332+
return false;
333+
}
334+
return this.x == lookingPosArgument.x && this.y == lookingPosArgument.y && this.z == lookingPosArgument.z;
335+
}
336+
337+
public int hashCode() {
338+
return Objects.hash(this.x, this.y, this.z);
339+
}
340+
}
341+
}

src/main/java/meteordevelopment/meteorclient/commands/commands/WaypointCommand.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,12 @@
99
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
1010
import com.mojang.brigadier.context.CommandContext;
1111
import meteordevelopment.meteorclient.commands.Command;
12+
import meteordevelopment.meteorclient.commands.arguments.BlockPosArgumentType;
1213
import meteordevelopment.meteorclient.commands.arguments.WaypointArgumentType;
1314
import meteordevelopment.meteorclient.systems.waypoints.Waypoint;
1415
import meteordevelopment.meteorclient.systems.waypoints.Waypoints;
1516
import meteordevelopment.meteorclient.utils.player.PlayerUtils;
1617
import net.minecraft.command.CommandSource;
17-
import net.minecraft.command.argument.PosArgument;
18-
import net.minecraft.command.argument.Vec3ArgumentType;
1918
import net.minecraft.util.Formatting;
2019
import net.minecraft.util.math.BlockPos;
2120

@@ -47,7 +46,7 @@ public void build(LiteralArgumentBuilder<CommandSource> builder) {
4746
})));
4847

4948
builder.then(literal("add")
50-
.then(argument("pos", Vec3ArgumentType.vec3())
49+
.then(argument("pos", BlockPosArgumentType.blockPos())
5150
.then(argument("waypoint", StringArgumentType.greedyString()).executes(context -> addWaypoint(context, true)))
5251
)
5352

@@ -84,7 +83,7 @@ private String waypointFullPos(Waypoint waypoint) {
8483
private int addWaypoint(CommandContext<CommandSource> context, boolean withCoords) {
8584
if (mc.player == null) return -1;
8685

87-
BlockPos pos = withCoords ? context.getArgument("pos", PosArgument.class).toAbsoluteBlockPos(mc.player.getCommandSource(mc.getServer().getOverworld())) : mc.player.getBlockPos().up(2);
86+
BlockPos pos = withCoords ? BlockPosArgumentType.getBlockPos(context, "pos") : mc.player.getBlockPos().up(2);
8887
Waypoint waypoint = new Waypoint.Builder()
8988
.name(StringArgumentType.getString(context, "waypoint"))
9089
.pos(pos)

0 commit comments

Comments
 (0)