77 */
88package net .wurstclient .hacks ;
99
10- import java .util .Comparator ;
11- import java .util .function .Function ;
12- import java .util .stream .Stream ;
13- import net .minecraft .client .gui .screens .inventory .AbstractContainerScreen ;
14- import net .minecraft .world .entity .Entity ;
15- import net .minecraft .world .entity .LivingEntity ;
16- import net .minecraft .world .phys .Vec3 ;
17- import net .wurstclient .Category ;
18- import net .wurstclient .events .MouseUpdateListener ;
19- import net .wurstclient .events .UpdateListener ;
20- import net .wurstclient .hack .Hack ;
21- import net .wurstclient .settings .AimAtSetting ;
22- import net .wurstclient .settings .CheckboxSetting ;
23- import net .wurstclient .settings .SliderSetting ;
10+ import java .util .Comparator ;
11+ import java .util .function .Function ;
12+ import java .util .stream .Stream ;
13+ import net .minecraft .client .gui .screens .inventory .AbstractContainerScreen ;
14+ import net .minecraft .world .InteractionHand ;
15+ import net .minecraft .world .entity .Entity ;
16+ import net .minecraft .world .entity .LivingEntity ;
17+ import net .minecraft .world .phys .EntityHitResult ;
18+ import net .minecraft .world .phys .Vec3 ;
19+ import net .wurstclient .Category ;
20+ import net .wurstclient .events .MouseUpdateListener ;
21+ import net .wurstclient .events .UpdateListener ;
22+ import net .wurstclient .hack .Hack ;
23+ import net .wurstclient .settings .AttackSpeedSliderSetting ;
24+ import net .wurstclient .settings .AimAtSetting ;
25+ import net .wurstclient .settings .CheckboxSetting ;
26+ import net .wurstclient .settings .SliderSetting ;
2427import net .wurstclient .settings .SliderSetting .ValueDisplay ;
2528import net .wurstclient .settings .filterlists .EntityFilterList ;
2629import net .wurstclient .settings .filters .*;
@@ -33,7 +36,7 @@ public final class AimAssistHack extends Hack
3336 implements UpdateListener , MouseUpdateListener
3437{
3538 private final SliderSetting range =
36- new SliderSetting ("Range" , 4.5 , 1 , 6 , 0.05 , ValueDisplay .DECIMAL );
39+ new SliderSetting ("Range" , 4.5 , 1 , 128 , 0.05 , ValueDisplay .DECIMAL );
3740
3841 private final SliderSetting rotationSpeed =
3942 new SliderSetting ("Rotation Speed" , 600 , 10 , 7200 , 10 ,
@@ -62,6 +65,28 @@ public final class AimAssistHack extends Hack
6265 new CheckboxSetting ("Aim while blocking" ,
6366 "description.wurst.setting.aimassist.aim_while_blocking" , false );
6467
68+ private final CheckboxSetting rightClickLockOn = new CheckboxSetting (
69+ "Right-click lock-on" ,
70+ "While holding right-click, maintain full horizontal + vertical lock-on to the current target." ,
71+ false );
72+
73+ private final CheckboxSetting rightClickLockOnRangeOverride =
74+ new CheckboxSetting ("Right-click range override" ,
75+ "While holding right-click lock-on, use a separate range instead of AimAssist's normal range." ,
76+ false );
77+
78+ private final SliderSetting rightClickLockOnRange = new SliderSetting (
79+ "Right-click range" , "Range used while right-click lock-on is active." ,
80+ 12 , 1 , 128 , 0.05 , ValueDisplay .DECIMAL );
81+
82+ private final CheckboxSetting rightClickAutoAttack = new CheckboxSetting (
83+ "Right-click auto-attack" ,
84+ "Automatically attack while right-click lock-on is active. Uses crosshair target first, then AimAssist target." ,
85+ false );
86+
87+ private final AttackSpeedSliderSetting rightClickAttackSpeed =
88+ new AttackSpeedSliderSetting ();
89+
6590 private final EntityFilterList entityFilters =
6691 new EntityFilterList (FilterPlayersSetting .genericCombat (false ),
6792 FilterSleepingSetting .genericCombat (false ),
@@ -112,10 +137,15 @@ public AimAssistHack()
112137 addSetting (aimAt );
113138 addSetting (ignoreMouseInput );
114139 addSetting (checkLOS );
115- addSetting (aimWhileBlocking );
116-
117- entityFilters .forEach (this ::addSetting );
118- }
140+ addSetting (aimWhileBlocking );
141+ addSetting (rightClickLockOn );
142+ addSetting (rightClickLockOnRangeOverride );
143+ addSetting (rightClickLockOnRange );
144+ addSetting (rightClickAutoAttack );
145+ addSetting (rightClickAttackSpeed );
146+
147+ entityFilters .forEach (this ::addSetting );
148+ }
119149
120150 @ Override
121151 protected void onEnable ()
@@ -129,11 +159,12 @@ protected void onEnable()
129159 WURST .getHax ().killauraLegitHack .setEnabled (false );
130160 WURST .getHax ().multiAuraHack .setEnabled (false );
131161 WURST .getHax ().protectHack .setEnabled (false );
132- WURST .getHax ().tpAuraHack .setEnabled (false );
133-
134- EVENTS .add (UpdateListener .class , this );
135- EVENTS .add (MouseUpdateListener .class , this );
136- }
162+ WURST .getHax ().tpAuraHack .setEnabled (false );
163+
164+ rightClickAttackSpeed .resetTimer ();
165+ EVENTS .add (UpdateListener .class , this );
166+ EVENTS .add (MouseUpdateListener .class , this );
167+ }
137168
138169 @ Override
139170 protected void onDisable ()
@@ -149,16 +180,18 @@ protected void onDisable()
149180 }
150181
151182 @ Override
152- public void onUpdate ()
153- {
154- target = null ;
183+ public void onUpdate ()
184+ {
185+ target = null ;
186+ rightClickAttackSpeed .updateTimer ();
155187
156188 // don't aim when a container/inventory screen is open
157189 if (MC .screen instanceof AbstractContainerScreen )
158190 return ;
159191
192+ boolean useHeld = isUseKeyHeld ();
160193 boolean blockingAllowed =
161- aimWhileBlocking .isChecked () || temporaryAllowBlocking ;
194+ aimWhileBlocking .isChecked () || temporaryAllowBlocking || useHeld ;
162195 if (!blockingAllowed && MC .player .isUsingItem ())
163196 return ;
164197
@@ -181,7 +214,10 @@ public void onUpdate()
181214 return ;
182215 }
183216
184- WURST .getHax ().autoSwordHack .setSlot (target );
217+ updateRightClickVerticalAlignment ();
218+ updateRightClickAutoAttack ();
219+
220+ WURST .getHax ().autoSwordHack .setSlot (target );
185221
186222 // get needed rotation
187223 Rotation needed = RotationUtils .getNeededRotations (hitVec );
@@ -301,23 +337,41 @@ public Entity getCurrentTarget()
301337
302338 private double getRange ()
303339 {
340+ if (isRightClickLockOnActive ()
341+ && rightClickLockOnRangeOverride .isChecked ())
342+ return rightClickLockOnRange .getValue ();
343+
304344 return rangeOverride != null ? rangeOverride : range .getValue ();
305345 }
306346
307347 private boolean isLockOnEnabled ()
308348 {
349+ if (isRightClickLockOnActive ())
350+ return true ;
351+
309352 return lockOnOverride != null ? lockOnOverride .booleanValue ()
310353 : lockOn .isChecked ();
311354 }
312355
356+ private boolean isRightClickLockOnActive ()
357+ {
358+ return rightClickLockOn .isChecked () && isUseKeyHeld ();
359+ }
360+
361+ private boolean isUseKeyHeld ()
362+ {
363+ return MC .options != null && MC .options .keyUse != null
364+ && MC .options .keyUse .isDown ();
365+ }
366+
313367 private double getRangeSq ()
314368 {
315369 double value = getRange ();
316370 return value * value ;
317371 }
318372
319- private boolean isValidForcedTarget (Entity entity )
320- {
373+ private boolean isValidForcedTarget (Entity entity )
374+ {
321375 if (entity == null )
322376 return false ;
323377
@@ -330,6 +384,93 @@ private boolean isValidForcedTarget(Entity entity)
330384 if (!EntityUtils .IS_ATTACKABLE .test (entity ))
331385 return false ;
332386
333- return true ;
387+ return true ;
388+ }
389+
390+ private void updateRightClickAutoAttack ()
391+ {
392+ if (!rightClickAutoAttack .isChecked () || !isRightClickLockOnActive ()
393+ || target == null || MC .player == null || MC .gameMode == null )
394+ return ;
395+
396+ if (!rightClickAttackSpeed .isTimeToAttack ())
397+ return ;
398+
399+ Entity attackTarget = resolveRightClickAttackTarget ();
400+ if (attackTarget == null )
401+ return ;
402+
403+ WURST .getHax ().autoSwordHack .setSlot (attackTarget );
404+ MC .gameMode .attack (MC .player , attackTarget );
405+ MC .player .swing (InteractionHand .MAIN_HAND );
406+ rightClickAttackSpeed .resetTimer ();
407+ }
408+
409+ private Entity resolveRightClickAttackTarget ()
410+ {
411+ if (MC .hitResult instanceof EntityHitResult hit )
412+ {
413+ Entity hitEntity = hit .getEntity ();
414+ if (hitEntity != null && isValidForcedTarget (hitEntity )
415+ && MC .player .distanceToSqr (hitEntity ) <= getRangeSq ())
416+ return hitEntity ;
417+ }
418+
419+ return target ;
420+ }
421+
422+ private void updateRightClickVerticalAlignment ()
423+ {
424+ if (WURST .getHax ().flightHack .isEnabled ())
425+ return ;
426+
427+ Double step = getRightClickVerticalAlignmentStepInternal (null );
428+ if (step == null || MC .player == null )
429+ return ;
430+
431+ Vec3 motion = MC .player .getDeltaMovement ();
432+ MC .player .setDeltaMovement (motion .x , motion .y + step , motion .z );
433+ }
434+
435+ public Double getRightClickVerticalAlignmentStepForFlight ()
436+ {
437+ return getRightClickVerticalAlignmentStepInternal (
438+ WURST .getHax ().flightHack .verticalSpeed .getValue ());
439+ }
440+
441+ private Double getRightClickVerticalAlignmentStepInternal (
442+ Double maxStepOverride )
443+ {
444+ if (MC .player == null || target == null || !isRightClickLockOnActive ())
445+ return null ;
446+
447+ boolean flying = MC .player .getAbilities ().flying
448+ || WURST .getHax ().flightHack .isEnabled ();
449+ if (!flying )
450+ return null ;
451+
452+ if (target .onGround () && !MC .options .keyShift .isDown ())
453+ {
454+ double feetDelta = target .getY () - MC .player .getY ();
455+ if (feetDelta < 0 )
456+ return null ;
457+ }
458+
459+ double maxStep = maxStepOverride != null ? maxStepOverride
460+ : MC .player .getAbilities ().getFlyingSpeed ();
461+ if (maxStep <= 0 )
462+ return null ;
463+
464+ double targetY = target .getY ();
465+ double playerY = MC .player .getY ();
466+ double delta = targetY - playerY ;
467+
468+ if (MC .player .onGround () && delta < 0 && !MC .options .keyShift .isDown ())
469+ return null ;
470+
471+ if (Math .abs (delta ) < 0.02 )
472+ return null ;
473+
474+ return Math .max (-maxStep , Math .min (maxStep , delta ));
334475 }
335476}
0 commit comments