@@ -595,6 +595,32 @@ bool CAimbotHitscan::ShouldFire(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUser
595595 return true ;
596596}
597597
598+ void CAimbotHitscan::ClearLegitAimStepVars ()
599+ {
600+ m_bReachedLegitAimStepTarget = false ;
601+ m_flLegitAimStepIncTimeOverShoot = 0 .0f ;
602+ m_flCurAimTime = 0 .0f ;
603+ m_bInitializedLegitAimStepDirection = false ;
604+ int nRandom = rand () % 3 ;
605+ m_nLegitAimCurveType = nRandom != m_nLegitAimCurveType ? nRandom : rand () % 3 ;
606+ }
607+
608+ static void SmoothAngle (const Vec3& vFrom, Vec3& vTo, float flPercent)
609+ {
610+ Vec3 vDelta = vFrom - vTo;
611+ Math::NormalizeAngle (vDelta.x );
612+ Math::NormalizeAngle (vDelta.y );
613+ vDelta.x *= flPercent;
614+ vDelta.y *= flPercent;
615+ vTo = vFrom - vDelta;
616+ Math::ClampAngles (vTo);
617+ }
618+
619+ static inline float RandFloatRange (float flMin, float flMax)
620+ {
621+ return ((float )rand () / (float )RAND_MAX) * (flMax - flMin) + flMin;
622+ }
623+
598624bool CAimbotHitscan::Aim (Vec3 vCurAngle, Vec3 vToAngle, Vec3& vOut, int iMethod)
599625{
600626 auto pLocal = H::Entities.GetLocal ();
@@ -616,9 +642,217 @@ bool CAimbotHitscan::Aim(Vec3 vCurAngle, Vec3 vToAngle, Vec3& vOut, int iMethod)
616642 vOut = vToAngle;
617643 break ;
618644 case Vars::Aimbot::General::AimTypeEnum::Smooth:
619- vOut = vCurAngle.LerpAngle (vToAngle, Vars::Aimbot::General::AssistStrength.Value / 100 .f );
645+ {
646+ // MutinyFixed-style smooth aimbot with curves and humanization
647+ Vec3 vOldAngles = vCurAngle;
648+
649+ // Calculate delta for initialization
650+ Vec3 vDelta = vToAngle - vCurAngle;
651+ Math::NormalizeAngle (vDelta.x );
652+ Math::NormalizeAngle (vDelta.y );
653+ Math::ClampAngles (vDelta);
654+
655+ // Initialize direction if not set
656+ if (!m_bInitializedLegitAimStepDirection)
657+ {
658+ m_LegitAimStartDirection = vDelta.y > 0 ? LEFT : RIGHT;
659+ m_vLegitAimStepInitialDelta = vDelta;
660+ m_bInitializedLegitAimStepDirection = true ;
661+ }
662+
663+ // Check if we've reached the target
664+ if (m_bReachedLegitAimStepTarget)
665+ {
666+ if (fabsf (vDelta.y ) > 15 .0f || fabsf (vDelta.x ) > 15 .0f )
667+ {
668+ ClearLegitAimStepVars ();
669+ }
670+ }
671+
672+ // Calculate frame time
673+ static float flLastAimStepTime = 0 .0f ;
674+ if (flLastAimStepTime == 0 .0f )
675+ flLastAimStepTime = I::GlobalVars->curtime ;
676+
677+ float flFrameTime = std::min (I::GlobalVars->curtime - flLastAimStepTime, 0 .1f );
678+ flLastAimStepTime = I::GlobalVars->curtime ;
679+
680+ m_flCurAimTime += flFrameTime;
681+
682+ // Calculate FOV to target
683+ float flFOV = std::max (0 .001f , Math::CalcFov (vOldAngles, vToAngle));
684+
685+ // Calculate smooth time based on speed setting
686+ float flSmoothScale = std::max (0 .1f , Vars::Aimbot::General::AssistStrength.Value );
687+ float flSmoothTime = m_flCurAimTime * flSmoothScale + (m_bReachedLegitAimStepTarget ? 0 .1f / flFOV : 0 .33f / flFOV);
688+
689+ // Apply velocity-based randomization when target reached
690+ if (m_bReachedLegitAimStepTarget)
691+ {
692+ auto pLocal = H::Entities.GetLocal ();
693+ if (pLocal)
694+ {
695+ float flLocalVel = pLocal->m_vecVelocity ().Length ();
696+ if (flLocalVel > 0 .0f )
697+ {
698+ flSmoothTime *= RandFloatRange (0 .35f , 0 .45f );
699+ }
700+ }
701+ }
702+
703+ // Clamp smooth time
704+ if (flSmoothTime > 0 .92f )
705+ flSmoothTime = 1 .0f ;
706+
707+ // Detect mouse input and reduce smoothing
708+ if (G::CurrentUserCmd && (abs (G::CurrentUserCmd->mousedx ) > 2 || abs (G::CurrentUserCmd->mousedy ) > 2 ))
709+ {
710+ flSmoothTime *= 0 .25f ;
711+ m_flCurAimTime = std::max (0 .0f , m_flCurAimTime - (flFrameTime * 2 .0f ));
712+ }
713+
714+ // Apply smoothing
715+ vOut = vToAngle;
716+ SmoothAngle (vOldAngles, vOut, flSmoothTime);
717+
718+ // Apply curve-specific pitch adjustments
719+ Vec3 vDeltaAngle = (vOut - vOldAngles);
720+ Math::NormalizeAngle (vDeltaAngle.x );
721+ Math::NormalizeAngle (vDeltaAngle.y );
722+
723+ switch (m_nLegitAimCurveType)
724+ {
725+ case 0 :
726+ if (vDeltaAngle.y > 0 .4f )
727+ {
728+ float flInc = RandFloatRange (0 .265f , 0 .291f ) - std::min (0 .0f , (1 .0f / flFOV)) - flSmoothTime;
729+ if (m_vLegitAimStepInitialDelta.x < 0 )
730+ vOut.x -= flInc;
731+ else
732+ vOut.x += flInc;
733+ vOut.x = std::clamp (Math::NormalizeAngle (vOut.x ), -89 .f , 89 .f );
734+ }
735+ else if (vDeltaAngle.y < -0 .4f )
736+ {
737+ float flInc = RandFloatRange (0 .252f , 0 .294f ) - std::min (0 .0f , (1 .0f / flFOV)) - flSmoothTime;
738+ if (m_vLegitAimStepInitialDelta.x < 0 )
739+ vOut.x -= flInc;
740+ else
741+ vOut.x += flInc;
742+ vOut.x = std::clamp (Math::NormalizeAngle (vOut.x ), -89 .f , 89 .f );
743+ }
744+ else if (vDeltaAngle.y > 0 .2f )
745+ {
746+ float flInc = RandFloatRange (-0 .002f , 0 .0385f ) - std::min (0 .0f , (1 .0f / flFOV)) - flSmoothTime;
747+ if (m_vLegitAimStepInitialDelta.x < 0 )
748+ vOut.x -= flInc;
749+ else
750+ vOut.x += flInc;
751+ vOut.x = std::clamp (Math::NormalizeAngle (vOut.x ), -89 .f , 89 .f );
752+ }
753+ else if (vDeltaAngle.y < -0 .2f )
754+ {
755+ float flInc = RandFloatRange (-0 .00212f , 0 .032f ) - std::min (0 .0f , (1 .0f / flFOV)) - flSmoothTime;
756+ if (m_vLegitAimStepInitialDelta.x < 0 )
757+ vOut.x -= flInc;
758+ else
759+ vOut.x += flInc;
760+ vOut.x = std::clamp (Math::NormalizeAngle (vOut.x ), -89 .f , 89 .f );
761+ }
762+ else
763+ {
764+ m_bReachedLegitAimStepTarget = true ;
765+ }
766+ break ;
767+ case 1 :
768+ if (vDeltaAngle.y > 0 .4f )
769+ {
770+ float flInc = RandFloatRange (0 .265f , 0 .331f ) - std::min (0 .0f , (1 .0f / flFOV)) - flSmoothTime;
771+ if (m_vLegitAimStepInitialDelta.x < 0 )
772+ vOut.x -= flInc;
773+ else
774+ vOut.x += flInc;
775+ vOut.x = std::clamp (Math::NormalizeAngle (vOut.x ), -89 .f , 89 .f );
776+ }
777+ else if (vDeltaAngle.y < -0 .4f )
778+ {
779+ float flInc = RandFloatRange (0 .252f , 0 .324f ) - std::min (0 .0f , (1 .0f / flFOV)) - flSmoothTime;
780+ if (m_vLegitAimStepInitialDelta.x < 0 )
781+ vOut.x -= flInc;
782+ else
783+ vOut.x += flInc;
784+ vOut.x = std::clamp (Math::NormalizeAngle (vOut.x ), -89 .f , 89 .f );
785+ }
786+ else if (vDeltaAngle.y > 0 .2f )
787+ {
788+ float flInc = RandFloatRange (-0 .002f , 0 .0385f ) - std::min (0 .0f , (1 .0f / flFOV)) - flSmoothTime;
789+ if (m_vLegitAimStepInitialDelta.x < 0 )
790+ vOut.x -= flInc;
791+ else
792+ vOut.x += flInc;
793+ vOut.x = std::clamp (Math::NormalizeAngle (vOut.x ), -89 .f , 89 .f );
794+ }
795+ else if (vDeltaAngle.y < -0 .2f )
796+ {
797+ float flInc = RandFloatRange (-0 .00212f , 0 .032f ) - std::min (0 .0f , (1 .0f / flFOV)) - flSmoothTime;
798+ if (m_vLegitAimStepInitialDelta.x < 0 )
799+ vOut.x -= flInc;
800+ else
801+ vOut.x += flInc;
802+ vOut.x = std::clamp (Math::NormalizeAngle (vOut.x ), -89 .f , 89 .f );
803+ }
804+ else
805+ {
806+ m_bReachedLegitAimStepTarget = true ;
807+ }
808+ break ;
809+ case 2 :
810+ if (vDeltaAngle.y > 0 .4f )
811+ {
812+ float flInc = RandFloatRange (0 .2f , 0 .25f ) - std::min (0 .0f , (1 .0f / flFOV)) - flSmoothTime;
813+ if (m_vLegitAimStepInitialDelta.x < 0 )
814+ vOut.x -= flInc;
815+ else
816+ vOut.x += flInc;
817+ vOut.x = std::clamp (Math::NormalizeAngle (vOut.x ), -89 .f , 89 .f );
818+ }
819+ else if (vDeltaAngle.y < -0 .4f )
820+ {
821+ float flInc = RandFloatRange (0 .15f , 0 .20f ) - std::min (0 .0f , (1 .0f / flFOV)) - flSmoothTime;
822+ if (m_vLegitAimStepInitialDelta.x < 0 )
823+ vOut.x -= flInc;
824+ else
825+ vOut.x += flInc;
826+ vOut.x = std::clamp (Math::NormalizeAngle (vOut.x ), -89 .f , 89 .f );
827+ }
828+ else if (vDeltaAngle.y > 0 .2f )
829+ {
830+ float flInc = RandFloatRange (-0 .005f , 0 .018f ) - std::min (0 .0f , (1 .0f / flFOV)) - flSmoothTime;
831+ if (m_vLegitAimStepInitialDelta.x < 0 )
832+ vOut.x -= flInc;
833+ else
834+ vOut.x += flInc;
835+ vOut.x = std::clamp (Math::NormalizeAngle (vOut.x ), -89 .f , 89 .f );
836+ }
837+ else if (vDeltaAngle.y < -0 .2f )
838+ {
839+ float flInc = RandFloatRange (-0 .001f , 0 .04f ) - std::min (0 .0f , (1 .0f / flFOV)) - flSmoothTime;
840+ if (m_vLegitAimStepInitialDelta.x < 0 )
841+ vOut.x -= flInc;
842+ else
843+ vOut.x += flInc;
844+ vOut.x = std::clamp (Math::NormalizeAngle (vOut.x ), -89 .f , 89 .f );
845+ }
846+ else
847+ {
848+ m_bReachedLegitAimStepTarget = true ;
849+ }
850+ break ;
851+ }
852+
620853 bReturn = true ;
621854 break ;
855+ }
622856 case Vars::Aimbot::General::AimTypeEnum::Assistive:
623857 Vec3 vMouseDelta = G::CurrentUserCmd->viewangles .DeltaAngle (G::LastUserCmd->viewangles );
624858 Vec3 vTargetDelta = vToAngle.DeltaAngle (G::LastUserCmd->viewangles );
0 commit comments