SWEP.ClientFreeAimAng = Angle(0, 0, 0) SWEP.ClientLastAimAngle = Angle(0, 0, 0) function SWEP:ThinkFreeAim() if !TacRP.ConVars["freeaim"]:GetBool() or self:GetOwner():IsBot() then return Angle(0, 0, 0) end local eyeangles = self:GetOwner():EyeAngles() if self:GetValue("FreeAim") then local diff = eyeangles if SERVER then diff = diff - self:GetLastAimAngle() else diff = diff - self.ClientLastAimAngle end diff = LerpAngle(0.9, diff, angle_zero) local freeaimang = Angle(self:GetFreeAimAngle()) local max = self:GetValue("FreeAimMaxAngle") local sightdelta = self:Curve(self:GetSightDelta()) max = max * Lerp(sightdelta, 1, 0) if self:GetBlindFireMode() > 0 then max = max * 0.25 end if self:GetValue("Bipod") then local f = self:Curve(math.Clamp((CurTime() - self.LastBipodTime) / 0.25, 0, 1)) if self:GetInBipod() then max = Lerp(f, max, 0) else max = Lerp(f, 0, max) end end diff.p = math.NormalizeAngle(diff.p) diff.y = math.NormalizeAngle(diff.y) diff = diff * Lerp(sightdelta, 1, 0.25) freeaimang.p = math.Clamp(math.NormalizeAngle(freeaimang.p) + math.NormalizeAngle(diff.p), -max, max) freeaimang.y = math.Clamp(math.NormalizeAngle(freeaimang.y) + math.NormalizeAngle(diff.y), -max, max) local ang2d = math.atan2(freeaimang.p, freeaimang.y) local mag2d = math.sqrt(math.pow(freeaimang.p, 2) + math.pow(freeaimang.y, 2)) mag2d = math.min(mag2d, max) freeaimang.p = mag2d * math.sin(ang2d) freeaimang.y = mag2d * math.cos(ang2d) if CLIENT then self.ClientFreeAimAng = freeaimang else self:SetFreeAimAngle(freeaimang) end end if SERVER then self:SetLastAimAngle(eyeangles) else self.ClientLastAimAngle = eyeangles end end function SWEP:GetFreeAimOffset() if !TacRP.ConVars["freeaim"]:GetBool() or !self:GetValue("FreeAim") or self:GetOwner():IsBot() then return Angle(0, 0, 0) end if CLIENT and LocalPlayer() == self:GetOwner() then return self.ClientFreeAimAng elseif CLIENT and LocalPlayer() != self:GetOwner() then local ang = self:GetFreeAimAngle() ang:Normalize() -- Angles are networked as unsigned or something, so normalization converts it to what we expect return ang else return self:GetFreeAimAngle() end end