Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --By Quaternions
- --localize
- local abs=math.abs
- local ceil=math.ceil
- local min,max=math.min,math.max
- local sqrt=math.sqrt
- local tan=math.tan
- local bit=bit
- local insert,remove=table.insert,table.remove
- local tick=SysTime
- local Angle=Angle
- local IsBtn=input.IsMouseDown
- local Degree=math.pi/180
- local IN_FORWARD=8
- local IN_BACK=16
- local IN_MOVELEFT=512
- local IN_MOVERIGHT=1024
- local IN_SPEED=131072
- local MOUSE_LEFT=107
- local P=LocalPlayer()
- local Aspect=ScrH()/ScrW()/tan(P:GetFOV()*Degree/2)
- --Settings
- local Calibrating=true
- local MaxAngleSeconds=0.07
- local AveragingDuration=0.1
- local MinAveragingFrames=8
- local DirectionBarWidth=30
- local DirectionBarHeight=300
- local DirectionBarColour=Color(75,191,50,128)
- --Ongoing collected data
- local Data={}
- local DataOverwrite=0
- local ConsecutiveValidFrames=0
- local _00,_01,_10,_11,_0,_1=0,0,0,0,0,0--Used to calculate linear least squares fit of equation constants
- --Previous frame data
- local Wiggling=false
- local LastTime=tick()
- local LastAngle=P:EyeAngles().y
- local LastVelocity=P:GetAbsVelocity():Length2D()
- local CurrentAveragingFrames=0
- --Previouse motion data
- local LastTime2=LastTime
- local TotalAngle
- local StrafeDirection=1
- local RealAngles
- local LastViewAngles
- --Make GUI
- local RealDirection=vgui.Create("DPanel")
- RealDirection:SetSize(DirectionBarWidth,DirectionBarHeight)
- RealDirection:SetPos(ScrW()/2-DirectionBarWidth/2,0)
- RealDirection:SetBackgroundColor(DirectionBarColour)
- RealDirection:SetAlpha(0)
- hook.Add("PreDrawHUD","UpdateWiggler",function()
- local CurrentTime=tick()
- local FramePeriod=CurrentTime-LastTime
- local DesiredAveragingFrames=max(MinAveragingFrames,ceil(AveragingDuration/FramePeriod))
- local Velocity=P:GetAbsVelocity()
- local CurrentAngle=P:EyeAngles().y
- local CurrentVelocity=Velocity:Length2D()
- local CurrentYawspeed=((CurrentAngle-LastAngle+180)%360-180)/FramePeriod
- local CurrentAcceleration=(CurrentVelocity-LastVelocity)/FramePeriod
- if DesiredAveragingFrames>CurrentAveragingFrames then
- CurrentAveragingFrames=CurrentAveragingFrames+1
- DataOverwrite=DataOverwrite+1
- insert(Data,DataOverwrite,{v=LastVelocity,w=abs(CurrentYawspeed),a=CurrentAcceleration})
- elseif DesiredAveragingFrames<CurrentAveragingFrames then
- remove(Data,DataOverwrite%CurrentAveragingFrames+1)
- CurrentAveragingFrames=CurrentAveragingFrames-1
- if DataOverwrite>=CurrentAveragingFrames then
- DataOverwrite=1
- else
- DataOverwrite=DataOverwrite+1
- end
- Data[DataOverwrite]={v=LastVelocity,w=abs(CurrentYawspeed),a=CurrentAcceleration}
- else
- DataOverwrite=DataOverwrite%CurrentAveragingFrames+1
- Data[DataOverwrite]={v=LastVelocity,w=abs(CurrentYawspeed),a=CurrentAcceleration}
- end
- if Calibrating then
- local EyeAngle=Angle(0,CurrentAngle,0)
- local ControlDirection=EyeAngle:Forward()*((P:KeyDown(IN_FORWARD)and 1 or 0)-(P:KeyDown(IN_BACK)and 1 or 0))+EyeAngle:Right()*((P:KeyDown(IN_MOVERIGHT)and 1 or 0)-(P:KeyDown(IN_MOVELEFT)and 1 or 0))
- local ValidFrame=false
- if CurrentYawspeed~=0 and CurrentAcceleration>0 and not P:OnGround() and CurrentVelocity>0 then
- local cx,cy=ControlDirection.x,ControlDirection.y
- local c2=cx*cx+cy*cy
- if c2>0 then
- local vc=Velocity.x*cx+Velocity.y*cy
- if vc*vc/(c2*CurrentVelocity*CurrentVelocity)<0.0025 then --If the control direction is (approximately) perpendicular to the velocity
- ValidFrame=true
- end
- end
- end
- if ValidFrame then
- ConsecutiveValidFrames=ConsecutiveValidFrames+1
- if ConsecutiveValidFrames>=CurrentAveragingFrames then
- local v,w,a=0,0,0
- for i=1,CurrentAveragingFrames do
- local d=Data[i]
- v,w,a=v+d.v,w+d.w,a+d.a
- end
- v,w,a=v/CurrentAveragingFrames,w/CurrentAveragingFrames,a/CurrentAveragingFrames
- local w2=w*w
- _0=_0-a*w
- _00=_00+w2
- _01=_01-v*w*w2
- _1=_1+a*v*w2
- _10=_10-v*w*w2
- _11=_11+v*v*w2*w2
- end
- elseif ConsecutiveValidFrames>0 then
- ConsecutiveValidFrames=0
- end
- end
- if TotalAngle and RealAngles then
- local RelativeAngle=(RealAngles.y-TotalAngle+180)%360-180
- RealDirection:SetAlpha(255)
- RealDirection:SetPos((ScrW()-DirectionBarWidth)*(0.5-Aspect*tan(RelativeAngle*Degree)/2),0)
- else
- RealDirection:SetAlpha(0)
- end
- LastTime,LastAngle,LastVelocity=CurrentTime,CurrentAngle,CurrentVelocity
- end)
- hook.Add("CreateMove","Wiggle",function(cmd)
- local CurrentTime=tick()
- local FramePeriod=CurrentTime-LastTime2
- --Autohop
- if not P:OnGround() then
- cmd:SetButtons(bit.band(cmd:GetButtons(),bit.bnot(IN_JUMP)))
- end
- if cmd:KeyDown(IN_SPEED) and (Wiggling or not P:OnGround()) then
- if Wiggling then
- local InputAngles=cmd:GetViewAngles()
- RealAngles=RealAngles+InputAngles-LastViewAngles
- else
- RealAngles=cmd:GetViewAngles()
- TotalAngle=RealAngles.y
- LastViewAngles=RealAngles
- Wiggling=true
- end
- local p=(_0*_11-_1*_01)/(_1*_00-_0*_10)
- local v=P:GetAbsVelocity():Length2D()
- if p==p and v>0 then
- local w=p/(2*v)
- local RelativeAngle=(RealAngles.y-TotalAngle+180)%360-180
- StrafeDirection=RelativeAngle>w*MaxAngleSeconds and 1 or RelativeAngle<-w*MaxAngleSeconds and -1 or StrafeDirection
- local AngleIncrement=StrafeDirection*abs(w*FramePeriod)
- TotalAngle=TotalAngle+AngleIncrement
- local NewAngle=Angle(RealAngles.p,TotalAngle,RealAngles.r)
- cmd:SetViewAngles(NewAngle)
- if StrafeDirection>0 then
- cmd:SetButtons(bit.bor(bit.band(cmd:GetButtons(),bit.bnot(IN_MOVELEFT)),IN_MOVERIGHT))
- else
- cmd:SetButtons(bit.bor(bit.band(cmd:GetButtons(),bit.bnot(IN_MOVERIGHT)),IN_MOVELEFT))
- end
- cmd:SetSideMove((StrafeDirection>0 and 1 or StrafeDirection<0 and -1 or 0)*-10000)
- LastViewAngles=NewAngle
- end
- elseif Wiggling then
- Wiggling=false
- RealAngles=nil
- TotalAngle=nil
- end
- LastTime2=CurrentTime
- end)
Advertisement
Add Comment
Please, Sign In to add comment