--Made by Luckymaxer

Figure = script.Parent
Humanoid = Figure:WaitForChild("Humanoid")
Torso = Figure:WaitForChild("Torso")

Creator = Figure:WaitForChild("Creator")

PathfindingService = game:GetService("PathfindingService")

FollowingPath = false
WalkRadius = 25
SuccessDistance = (Torso.Size.Y * 12)
MaxDistance = 500
MaximumAttemptTime = 5

Moving = false
CurrentWayPoint = nil

function RayCast(Position, Direction, MaxDistance, IgnoreList)
	return game:GetService("Workspace"):FindPartOnRayWithIgnoreList(Ray.new(Position, Direction.unit * (MaxDistance or 999.999)), IgnoreList) 
end

function Pathfind(StartPoint, TargetPoint, MaxDistance)
	local Path = PathfindingService:ComputeRawPathAsync(StartPoint, TargetPoint, MaxDistance)
	if not Path or Path.Status == Enum.PathStatus.FailStartNotEmpty or Path.Status == Enum.PathStatus.FailFinishNotEmpty then
		return {}
	end
	local PathWayPoints = Path:GetPointCoordinates()
	if not PathWayPoints or #PathWayPoints == 0 then
		return {}
	end
	return PathWayPoints
end

function GatherWapoints(StartPoint, TargetPoint, MaxDistance)
	local WayPoints = nil
	pcall(function()
		WayPoints = Pathfind(StartPoint, TargetPoint, MaxDistance)
	end)
	return WayPoints
end

function MoveAround(TargetPoint)
	if FollowingPath then
		return
	end
	FollowingPath = true
	TargetPoint = ((not TargetPoint and (Torso.Position + Vector3.new(math.random(-WalkRadius, WalkRadius), 0, math.random(-WalkRadius, WalkRadius))) or TargetPoint))
	local WayPoints = GatherWapoints(Torso.Position, TargetPoint, MaxDistance)
	if WayPoints and #WayPoints > 0 then
		for i, v in pairs(WayPoints) do
			CurrentWayPoint = v
			Humanoid:MoveTo(v)
			local TimeBegan = tick()
			while ((v - Torso.Position).magnitude > SuccessDistance and (tick() - TimeBegan) < MaximumAttemptTime) do
				
				wait(0.1)
			end
			if (v - Torso.Position).magnitude < SuccessDistance then
				WayPoints = GatherWapoints(Torso.Position, TargetPoint, MaxDistance)
				if WayPoints and #WayPoints > 0 then
					MoveAround(TargetPoint)
				end
			end
		end
		CurrentWayPoint = nil
	end
	FollowingPath = false
end

function SecureJump()
	if Humanoid.Jump then
		return
	end
	local TargetPoint = Humanoid.TargetPoint
	local GroundBelow, GroundPos
	if CurrentWayPoint then
		GroundBelow, GroundPos = RayCast((Torso.CFrame + CFrame.new(Torso.Position, Vector3.new(CurrentWayPoint.X, Torso.Position.Y, CurrentWayPoint.Z)).lookVector * (Torso.Size.Z * 4)).p, Vector3.new(0, -1, 0), (Torso.Size.Y * 4), {Character})
	end
	if CurrentWayPoint and not GroundBelow then
		Humanoid.TargetPoint = Torso.Position
		Humanoid:MoveTo(Torso.Position)
		TimeBegan = MaximumAttemptTime
	else
		local Blockage, BlockagePos = RayCast((Torso.CFrame + CFrame.new(Torso.Position, Vector3.new(TargetPoint.X, Torso.Position.Y, TargetPoint.Z)).lookVector * (Torso.Size.Z / 2)).p, Torso.CFrame.lookVector, (Torso.Size.Z * 2.5), {Figure})
		if not Humanoid.Jump and (Blockage and not Blockage.Parent:FindFirstChild("Humanoid")) then
			Humanoid.Jump = true
		end
	end
end

repeat
	Spawn(function()
		local CreatorValue = Creator.Value
		local CreatorCharacter, CreatorTorso
		if CreatorValue and CreatorValue:IsA("Player") and CreatorValue.Character then
			CreatorCharacter = CreatorValue.Character
			CreatorTorso = CreatorCharacter:FindFirstChild("Torso")
		end
		MoveAround((CreatorTorso and CreatorTorso.Position) or nil)
	end)
	SecureJump()
	wait(0.01)
until false