local function f()return Player and Player.Character end local function N()local f=findPlayerHumanoid(Player)return f and f.Torso end local function o(f)return f and(f.Parent and f.Parent:FindFirstChild("\072\117\109\097\110\111\105\100")~=nil)end local function r()local r=f()if r==nil then return end local y=findPlayerHumanoid(Player)if y==nil then return end local B=1.5 local S=7.0 local E=N()if E==nil then return end local I=E.CFrame local K=I.lookVector local P=I.p local L=Ray.new(P+Vector3_new(0,-E.Size.Y/2,0),K*B)local H=Ray.new(P+Vector3_new(0,S-E.Size.Y,0),K*B)local l,G=RayCastIgnoreList(workspace,L,{r},false)local j,A=RayCastIgnoreList(workspace,H,{r},false)if l and(j==nil and l.CanCollide==true)then if not o(l)then y.Jump=true end end end local y={[Enum.HumanoidStateType.FallingDown]=false;[Enum.HumanoidStateType.Flying]=false;[Enum.HumanoidStateType.Freefall]=false;[Enum.HumanoidStateType.GettingUp]=false;[Enum.HumanoidStateType.Ragdoll]=false,[Enum.HumanoidStateType.Running]=false;[Enum.HumanoidStateType.Seated]=false,[Enum.HumanoidStateType.Swimming]=false;[Enum.HumanoidStateType.Climbing]=false}local function B()local f=findPlayerHumanoid(Player)local N=f and f:GetState()if N then return y[N]==nil end return false end local function S()return true end local function E(f)return f.magnitude<.05 end


local function GetCharacter()
	return Player and Player.Character
end

local function GetTorso()
	local humanoid = findPlayerHumanoid(Player)
	return humanoid and humanoid.Torso
end

local function IsPartAHumanoid(part)
	return part and part.Parent and (part.Parent:FindFirstChild('Humanoid') ~= nil)
end

local function doAutoJump()
	local character = GetCharacter()
	if (character == nil) then
		return;
	end

	local humanoid = findPlayerHumanoid(Player)
	if (humanoid == nil) then
		return;
	end

	local rayLength = 1.5;
	-- This is how high a ROBLOXian jumps from the mid point of his torso
	local jumpHeight = 7.0;

	local torso = GetTorso()
	if (torso == nil) then
		return;
	end

	local torsoCFrame = torso.CFrame;
	local torsoLookVector = torsoCFrame.lookVector;
	local torsoPos = torsoCFrame.p;

	local torsoRay = Ray.new(torsoPos + Vector3_new(0, -torso.Size.Y/2, 0), torsoLookVector * rayLength);
	local jumpRay = Ray.new(torsoPos + Vector3_new(0, jumpHeight - torso.Size.Y, 0), torsoLookVector * rayLength);

	local hitPart, _ = RayCastIgnoreList(workspace, torsoRay, {character}, false)
	local jumpHitPart, _ = RayCastIgnoreList(workspace, jumpRay, {character}, false)

	if (hitPart and jumpHitPart == nil and hitPart.CanCollide == true) then
		 -- NOTE: this follow line is not in the C++ impl, but an improvement  in Click to Move
		if not IsPartAHumanoid(hitPart) then
			humanoid.Jump = true;
		end
	end
end

local NO_JUMP_STATES =
{
	[Enum.HumanoidStateType.FallingDown] = false;
	[Enum.HumanoidStateType.Flying] = false;
	[Enum.HumanoidStateType.Freefall] = false;
	[Enum.HumanoidStateType.GettingUp] = false;
	[Enum.HumanoidStateType.Ragdoll] = false;
	[Enum.HumanoidStateType.Running] = false;
	[Enum.HumanoidStateType.Seated] = false;
	[Enum.HumanoidStateType.Swimming] = false;

	-- Special case to detect if we are on a ladder
	[Enum.HumanoidStateType.Climbing] = false;
}

local function enableAutoJump()
	local humanoid = findPlayerHumanoid(Player)
	local currentState = humanoid and humanoid:GetState()
	if currentState then
		return NO_JUMP_STATES[currentState] == nil
	end
	return false
end

local function getAutoJump()
	return true
end

local function vec3IsZero(vec3)
	return vec3.magnitude < 0.05
end
