1414import meteordevelopment .meteorclient .events .packets .PacketEvent ;
1515import meteordevelopment .meteorclient .events .world .ChunkOcclusionEvent ;
1616import meteordevelopment .meteorclient .events .world .TickEvent ;
17+ import meteordevelopment .meteorclient .pathing .PathManagers ;
1718import meteordevelopment .meteorclient .settings .BoolSetting ;
1819import meteordevelopment .meteorclient .settings .DoubleSetting ;
1920import meteordevelopment .meteorclient .settings .Setting ;
2829import meteordevelopment .meteorclient .utils .player .Rotations ;
2930import meteordevelopment .orbit .EventHandler ;
3031import meteordevelopment .orbit .EventPriority ;
32+ import net .minecraft .block .ShapeContext ;
3133import net .minecraft .client .option .Perspective ;
34+ import net .minecraft .client .render .Camera ;
3235import net .minecraft .entity .Entity ;
36+ import net .minecraft .entity .projectile .ProjectileUtil ;
3337import net .minecraft .network .packet .s2c .play .DeathMessageS2CPacket ;
3438import net .minecraft .network .packet .s2c .play .HealthUpdateS2CPacket ;
3539import net .minecraft .util .hit .BlockHitResult ;
3640import net .minecraft .util .hit .EntityHitResult ;
41+ import net .minecraft .util .hit .HitResult ;
3742import net .minecraft .util .math .BlockPos ;
43+ import net .minecraft .util .math .Box ;
3844import net .minecraft .util .math .MathHelper ;
3945import net .minecraft .util .math .Vec3d ;
46+ import net .minecraft .world .RaycastContext ;
47+ import org .jetbrains .annotations .Nullable ;
4048import org .joml .Vector3d ;
4149import org .lwjgl .glfw .GLFW ;
4250
4351public class Freecam extends Module {
4452 private final SettingGroup sgGeneral = settings .getDefaultGroup ();
53+ private final SettingGroup sgPathing = settings .createGroup ("Pathing" );
4554
4655 private final Setting <Double > speed = sgGeneral .add (new DoubleSetting .Builder ()
4756 .name ("speed" )
@@ -117,6 +126,20 @@ public class Freecam extends Module {
117126 .build ()
118127 );
119128
129+ private final Setting <Boolean > baritoneClick = sgPathing .add (new BoolSetting .Builder ()
130+ .name ("click-to-path" )
131+ .description ("Sets a pathfinding goal to any block/entity you click at." )
132+ .defaultValue (false )
133+ .build ()
134+ );
135+
136+ private final Setting <Boolean > requireDoubleClick = sgPathing .add (new BoolSetting .Builder ()
137+ .name ("double-click" )
138+ .description ("Require two clicks to start pathing." )
139+ .defaultValue (false )
140+ .build ()
141+ );
142+
120143 public final Vector3d pos = new Vector3d ();
121144 public final Vector3d prevPos = new Vector3d ();
122145
@@ -131,6 +154,8 @@ public class Freecam extends Module {
131154
132155 private boolean forward , backward , right , left , up , down , isSneaking ;
133156
157+ private long clickTs = 0 ;
158+
134159 public Freecam () {
135160 super (Categories .Render , "freecam" , "Allows the camera to move away from the player." );
136161 }
@@ -287,10 +312,71 @@ public void onKey(KeyEvent event) {
287312 if (onInput (event .key (), event .action )) event .cancel ();
288313 }
289314
315+ @ Nullable
316+ private BlockPos rayCastEntity (Vec3d posVec , Vec3d max , short maxDist ) {
317+ EntityHitResult res = ProjectileUtil .raycast (
318+ mc .player ,
319+ posVec ,
320+ max ,
321+ Box .enclosing (BlockPos .ofFloored (posVec .x , posVec .y , posVec .z ), BlockPos .ofFloored (max .x , max .y , max .z )),
322+ (entity ) -> true ,
323+ maxDist
324+ );
325+
326+ if (res == null ) return null ;
327+
328+ Vec3d vec = res .getPos ();
329+
330+ return BlockPos .ofFloored (vec .x , vec .y , vec .z );
331+ }
332+
333+ @ Nullable
334+ private BlockPos rayCastBlock (Vec3d posVec , Vec3d max ) {
335+ RaycastContext ctx = new RaycastContext (
336+ posVec ,
337+ max ,
338+ RaycastContext .ShapeType .VISUAL ,
339+ RaycastContext .FluidHandling .SOURCE_ONLY ,
340+ ShapeContext .absent ()
341+ );
342+
343+ BlockHitResult res = mc .world .raycast (ctx );
344+ if (res .getType () == HitResult .Type .MISS ) return null ;
345+
346+ // Don't move inside block
347+ return res .getBlockPos ().add (res .getSide ().getVector ());
348+ }
349+
350+ private void setGoal () {
351+ long prevClick = clickTs ;
352+ clickTs = System .currentTimeMillis ();
353+
354+ if (requireDoubleClick .get () && clickTs - prevClick > 500 ) return ;
355+
356+ Camera cam = mc .gameRenderer .getCamera ();
357+ Vec3d posVec = cam .getPos ();
358+ Vec3d lookVec = Vec3d .fromPolar (cam .getPitch (), cam .getYaw ());
359+ short maxDist = 256 ;
360+ Vec3d max = posVec .add (lookVec .multiply (maxDist ));
361+
362+ BlockPos pos = rayCastEntity (posVec , max , maxDist );
363+ if (pos == null ) {
364+ pos = rayCastBlock (posVec , max );
365+ }
366+
367+ if (pos == null ) return ;
368+
369+ PathManagers .get ().moveTo (pos );
370+ }
371+
290372 @ EventHandler (priority = EventPriority .HIGH )
291373 private void onMouseClick (MouseClickEvent event ) {
292374 if (checkGuiMove ()) return ;
293375
376+ if (baritoneClick .get () && event .action == KeyAction .Press && mc .options .attackKey .matchesMouse (event .click )) {
377+ setGoal ();
378+ }
379+
294380 if (onInput (event .button (), event .action )) event .cancel ();
295381 }
296382
0 commit comments