function serj.CircleMove(cmd, rotation)
    local prev_yaw = 0 
    local last_ground_pos = 0 
    local real_ang = Angle() 
    local cstrafe_predict_ticks = 64 
    local cstrafe_angle_step = 1 
    local cstrafe_angle_maxstep = 10 
    local cstrafe_dir = 0 
    local cstrafe_ground_diff = 5 
     
    local function MovementFix( cmd, wish_yaw ) 
     
     local pitch = math.NormalizeAngle( cmd:GetViewAngles().x ) 
     local inverted = -1 
     
     if ( pitch > 89 || pitch < -89 ) then 
     inverted = 1 
     end 
     
     local ang_diff = math.rad( math.NormalizeAngle( ( cmd:GetViewAngles().y - wish_yaw )*inverted ) ) 
     
        local forwardmove = cmd:GetForwardMove()
        local sidemove = cmd:GetSideMove()
     
        local new_forwardmove = forwardmove*-math.cos( ang_diff )*inverted + sidemove*math.sin( ang_diff )
        local new_sidemove = forwardmove*math.sin( ang_diff )*inverted + sidemove*math.cos( ang_diff )
     
        cmd:SetForwardMove( new_forwardmove )
        cmd:SetSideMove( new_sidemove )
     
    end
     
    local function PredictVelocity( velocity, viewangles, dir, maxspeed, accel, friction, interval_per_tick )
     
        local forward = viewangles:Forward()
        local right = viewangles:Right()
     
        local fmove = 0
        local smove = ( dir == 1 ) && -10000 || 10000
     
        forward.z = 0
        right.z = 0
     
        forward:Normalize()
        right:Normalize()
     
        local wishdir = Vector( forward.x*fmove + right.x*smove, forward.y*fmove + right.y*smove, 0 )
        local wishspeed = wishdir:Length()
     
        wishdir:Normalize()
     
        if ( wishspeed != 0 && wishspeed > maxspeed ) then
            wishspeed = maxspeed
        end
     
        local wishspd = wishspeed
     
        if ( wishspd > 30 ) then
            wishspd = 30
        end
     
        local currentspeed = velocity:Dot( wishdir )
        local addspeed = wishspd - currentspeed
     
        if ( addspeed <= 0 ) then
            return
        end
     
        local accelspeed = accel * interval_per_tick * wishspeed * friction
     
        if ( accelspeed > addspeed ) then
            accelspeed = addspeed
        end
     
        local new_vel = wishdir * accelspeed
     
        velocity:Add( new_vel )
     
    end
    
    local sv_tfa_bullet_penetration = GetConVar("sv_tfa_bullet_penetration")
	local sv_tfa_penetration_hardlimit = GetConVar("sv_tfa_penetration_hardlimit")
	local sv_tfa_bullet_penetration_power_mul = GetConVar("sv_tfa_bullet_penetration_power_mul")
    local sv_airaccelerate = GetConVar( "sv_airaccelerate" )
    local sv_gravity = GetConVar( "sv_gravity" )
    local sv_sticktoground = GetConVar( "sv_sticktoground" )
     
    local function PredictMovement( viewangles, dir, angle )
     
        local pm
     
        local local_ply = LocalPlayer()
        local maxspeed = local_ply:GetMaxSpeed()
        local jump_power = local_ply:GetJumpPower()
        local interval_per_tick = engine.TickInterval()
        local gravity_per_tick = sv_gravity:GetFloat() * interval_per_tick
        local accel = sv_airaccelerate:GetFloat()
        local stick_to_ground = sv_sticktoground:GetBool()
        local friction = local_ply:GetInternalVariable( "m_surfaceFriction" )
        local origin = local_ply:GetNetworkOrigin()
        local velocity = local_ply:GetAbsVelocity()
        local mins = local_ply:OBBMins()
        local maxs = local_ply:OBBMaxs()
        local on_ground = local_ply:IsFlagSet( FL_ONGROUND )
     
        for i = 1, cstrafe_predict_ticks do
     
            viewangles.y = math.NormalizeAngle( math.deg( math.atan2( velocity.y, velocity.x ) ) + angle )
     
            velocity.z = velocity.z - ( gravity_per_tick * 0.5 )
     
            if ( on_ground ) then
     
                velocity.z = velocity.z + jump_power
                velocity.z = velocity.z - ( gravity_per_tick * 0.5 )
     
            end
     
            PredictVelocity( velocity, viewangles, dir, maxspeed, accel, friction, interval_per_tick )
     
            local endpos = origin + ( velocity * interval_per_tick )
     
            pm = util.TraceHull( {
                start = origin,
                endpos = endpos,
                filter = local_ply,
                maxs = maxs,
                mins = mins,
                mask = MASK_PLAYERSOLID
            } )
     
            if ( ( pm.Fraction != 1 && pm.HitNormal.z <= 0.9 ) || pm.AllSolid || pm.StartSolid ) then
                return false
            end
     
            if ( pm.Fraction != 1 ) then
     
                local time_left = interval_per_tick
     
                for j = 1, 2 do
     
                    time_left = time_left - ( time_left * pm.Fraction )
     
                    local dot = velocity:Dot( pm.HitNormal )
     
                    velocity = velocity - ( pm.HitNormal * dot )
     
                    dot = velocity:Dot( pm.HitNormal )
     
                    if ( dot < 0 ) then
                        velocity = velocity - ( pm.HitNormal * dot )
                    end
     
                    endpos = pm.HitPos + ( velocity * time_left )
     
                    pm = util.TraceHull( {
                        start = pm.HitPos,
                        endpos = endpos,
                        filter = local_ply,
                        maxs = maxs,
                        mins = mins,
                        mask = MASK_PLAYERSOLID
                    } )
     
                    if ( ( pm.Fraction != 1 && pm.HitNormal.z <= 0.9 ) || pm.AllSolid || pm.StartSolid ) then
                        return false
                    end
     
                    if ( pm.Fraction == 1 ) then
                        break
                    end
     
                end
     
            end
     
            origin = pm.HitPos
     
            if ( ( last_ground_pos - origin.z ) > cstrafe_ground_diff ) then
                return false
            end
     
            friction = 1
     
            if ( velocity.z > 140 && !stick_to_ground ) then
     
                on_ground = false
     
            else
     
                pm = util.TraceHull( {
                    start =  Vector( origin.x, origin.y, origin.z + 2 ),
                    endpos = Vector( origin.x, origin.y, origin.z - 1 ),
                    filter = local_ply,
                    maxs = Vector( maxs.x, maxs.y, maxs.z * 0.5 ),
                    mins = mins,
                    mask = MASK_PLAYERSOLID
                } )
     
                on_ground = ( ( pm.Fraction < 1 || pm.AllSolid || pm.StartSolid ) && pm.HitNormal.z >= 0.7 )
     
                if ( !on_ground && velocity.z > 0 ) then
     
                    friction = 0.25
     
                end
     
            end
     
            velocity.z = velocity.z - ( gravity_per_tick * 0.5 )
     
            if ( on_ground ) then
                velocity.z = 0
            end
     
        end
     
        return true
     
    end
       
    
end