-
Notifications
You must be signed in to change notification settings - Fork 3
/
ClipCommand.java
233 lines (187 loc) · 8.82 KB
/
ClipCommand.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
package com.jorianwoltjer.liveoverflowmod.command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket;
import net.minecraft.network.packet.c2s.play.VehicleMoveC2SPacket;
import net.minecraft.text.Text;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import static com.jorianwoltjer.liveoverflowmod.client.ClientEntrypoint.*;
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.*;
public class ClipCommand {
private static void interactAt(BlockPos pos) {
if (client.interactionManager == null) return;
client.interactionManager.interactBlock(client.player, Hand.MAIN_HAND, new BlockHitResult(
new Vec3d(pos.getX(), pos.getY(), pos.getZ()),
Direction.DOWN,
pos,
false
));
}
public static void register(CommandDispatcher<FabricClientCommandSource> dispatcher) {
dispatcher.register(literal("vault")
.executes(context -> {
PlayerEntity player = context.getSource().getPlayer();
Vec3d pos = player.getPos();
interactAt(new BlockPos(4729, 125, 1337)); // Start button
// y += 53.0
for (int i = 0; i < 5; i++) {
pos = pos.add(0, 9.9, 0);
networkHandler.sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(pos.x, pos.y, pos.z, true));
}
pos = pos.add(0, 3.5, 0);
networkHandler.sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(pos.x, pos.y, pos.z, true));
// x += 53.0
for (int i = 0; i < 5; i++) {
pos = pos.add(9.9, 0, 0);
networkHandler.sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(pos.x, pos.y, pos.z, true));
}
pos = pos.add(3.0, 0, 0);
networkHandler.sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(pos.x, pos.y, pos.z, true));
// y -= 53.0 (through box)
pos = pos.add(0, -53, 0);
networkHandler.sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(pos.x, pos.y, pos.z, true));
player.setPosition(pos);
interactAt(new BlockPos(4780, 125, 1336)); // End button
return 1;
})
);
dispatcher.register(literal("vclip") // Vertical clip
.then(argument("distance", integer())
.executes(context -> {
int distance = context.getArgument("distance", Integer.class);
PlayerEntity player = context.getSource().getPlayer();
Vec3d pos = player.getPos();
Vec3d targetPos = pos.add(0, distance, 0);
clipStraight(targetPos);
return 1;
})
)
);
dispatcher.register(literal("hclip") // Horizontal clip (up -> horizontal -> down: to go through walls)
.then(argument("distance", integer())
.executes(context -> {
int distance = context.getArgument("distance", Integer.class);
assert client.player != null;
// Move `direction` blocks into viewing direction
Vec3d targetPos = client.player.getPos().add(
client.player.getRotationVector().multiply(1, 0, 1).normalize().multiply(distance)
);
clipUpDown(targetPos);
return 1;
})
)
);
dispatcher.register(literal("dclip") // Directional clip
.then(argument("distance", integer())
.executes(context -> {
int distance = context.getArgument("distance", Integer.class);
PlayerEntity player = context.getSource().getPlayer();
Vec3d pos = player.getPos();
// Move into players viewing direction
Vec3d targetPos = pos.add(player.getRotationVector().normalize().multiply(distance));
clipStraight(targetPos);
return 1;
})
)
);
dispatcher.register(literal("autoclip")
.then(literal("up")
.executes(context -> executeAutoClip(context, 1))
)
.then(literal("down")
.executes(context -> executeAutoClip(context, -1))
)
);
dispatcher.register(literal("clubmate")
.executes(context -> {
clipStraight(new Vec3d(1331, 89, 1330)); // Next to chest
assert client.player != null;
interactAt(new BlockPos(1331, 89, 1331)); // Chest
return 1;
})
);
}
public static void moveTo(Vec3d pos) {
if (client.player == null) return;
if (client.player.getVehicle() != null) {
client.player.getVehicle().setPosition(pos);
networkHandler.sendPacket(new VehicleMoveC2SPacket(client.player.getVehicle()));
} else {
client.player.setPosition(pos);
networkHandler.sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(pos.x, pos.y, pos.z, true));
}
}
public static void moveTo(Vec3d pos, float yaw, float pitch) {
if (client.player == null) return;
if (client.player.getVehicle() != null) {
client.player.getVehicle().setPosition(pos);
networkHandler.sendPacket(new VehicleMoveC2SPacket(client.player.getVehicle()));
} else {
client.player.setPosition(pos);
networkHandler.sendPacket(new PlayerMoveC2SPacket.Full(
pos.x, pos.y, pos.z,
yaw, pitch,
client.player.isOnGround()));
}
}
public static void clipStraight(Vec3d targetPos) {
if (client.player == null) return;
Vec3d pos = client.player.getPos();
for (int i = 0; i < 18; i++) { // Send a lot of the same movement packets to increase max travel distance
moveTo(pos);
}
// Send one big movement packet to actually move the player
moveTo(targetPos);
}
// TODO: maybe refactor this to be the same as ClipReach#hitEntity
public static void clipUpDown(Vec3d targetPos) {
if (client.player == null) return;
Vec3d pos = client.player.getPos();
for (int i = 0; i < 15; i++) { // Send a lot of the same movement packets to increase max travel distance
moveTo(pos);
}
pos = pos.add(0, 100, 0); // Up
moveTo(pos);
pos = new Vec3d(targetPos.x, pos.y, targetPos.z); // Horizontal
moveTo(pos);
moveTo(targetPos); // Down
}
public static int executeAutoClip(CommandContext<FabricClientCommandSource> context, int direction) {
if (client.player == null) return 0;
Vec3d pos = getAutoClipPos(direction);
if (pos == null) {
context.getSource().sendFeedback(Text.of("§cNo valid position found within 150 blocks"));
return 0;
} else {
context.getSource().sendFeedback(Text.of(String.format("§7Clipping §a%.0f§7 blocks", pos.y - (int) client.player.getPos().y)));
clipStraight(pos);
return 1;
}
}
/**
* Automatically go through the nearest blocks in the given direction.
* Credits to @EnderKill98 for the original code.
*/
public static Vec3d getAutoClipPos(int direction) {
if (client.player == null || client.world == null) return null;
boolean inside = false;
for (float i = 0; i < 150; i += 0.25) {
Vec3d pos = client.player.getPos();
Vec3d targetPos = pos.add(0, direction * i, 0);
boolean collides = !client.world.isSpaceEmpty(client.player, client.player.getBoundingBox().offset(targetPos.subtract(pos)));
if (!inside && collides) { // Step 1: Into the blocks
inside = true;
} else if (inside && !collides) { // Step 2: Out of the blocks
return targetPos;
}
}
return null; // Nothing found
}
}