1111import java .util .function .Function ;
1212import java .util .stream .Stream ;
1313import net .minecraft .client .gui .screens .inventory .AbstractContainerScreen ;
14+ import net .minecraft .world .InteractionHand ;
1415import net .minecraft .world .entity .Entity ;
1516import net .minecraft .world .entity .LivingEntity ;
17+ import net .minecraft .world .phys .EntityHitResult ;
1618import net .minecraft .world .phys .Vec3 ;
1719import net .wurstclient .Category ;
1820import net .wurstclient .events .MouseUpdateListener ;
1921import net .wurstclient .events .UpdateListener ;
2022import net .wurstclient .hack .Hack ;
23+ import net .wurstclient .settings .AttackSpeedSliderSetting ;
2124import net .wurstclient .settings .AimAtSetting ;
2225import net .wurstclient .settings .CheckboxSetting ;
2326import net .wurstclient .settings .SliderSetting ;
@@ -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 ),
@@ -113,6 +138,11 @@ public AimAssistHack()
113138 addSetting (ignoreMouseInput );
114139 addSetting (checkLOS );
115140 addSetting (aimWhileBlocking );
141+ addSetting (rightClickLockOn );
142+ addSetting (rightClickLockOnRangeOverride );
143+ addSetting (rightClickLockOnRange );
144+ addSetting (rightClickAutoAttack );
145+ addSetting (rightClickAttackSpeed );
116146
117147 entityFilters .forEach (this ::addSetting );
118148 }
@@ -131,6 +161,7 @@ protected void onEnable()
131161 WURST .getHax ().protectHack .setEnabled (false );
132162 WURST .getHax ().tpAuraHack .setEnabled (false );
133163
164+ rightClickAttackSpeed .resetTimer ();
134165 EVENTS .add (UpdateListener .class , this );
135166 EVENTS .add (MouseUpdateListener .class , this );
136167 }
@@ -152,13 +183,15 @@ protected void onDisable()
152183 public void onUpdate ()
153184 {
154185 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,6 +214,9 @@ public void onUpdate()
181214 return ;
182215 }
183216
217+ updateRightClickVerticalAlignment ();
218+ updateRightClickAutoAttack ();
219+
184220 WURST .getHax ().autoSwordHack .setSlot (target );
185221
186222 // get needed rotation
@@ -301,15 +337,33 @@ 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 ();
@@ -332,4 +386,91 @@ private boolean isValidForcedTarget(Entity entity)
332386
333387 return true ;
334388 }
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 ));
475+ }
335476}
0 commit comments