-- Services
local userInputService = game:GetService("UserInputService")
local runService = game:GetService("RunService")

local tweenService = game:GetService("TweenService")
local playersService = game:GetService("Players")

-- Variables
local player = playersService.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

local camera = workspace.CurrentCamera

local pcButton = Enum.KeyCode.LeftShift
local xboxButton = Enum.KeyCode.ButtonL3

-- Settings
local normalSpeed = 16
local sprintSpeed = 26

local normalFov = 70
local sprintFov = 80

-- Boolean
local running = script:WaitForChild("Running")
local stamina = player.Stamina

-- Animation
local animation = script:WaitForChild("SprintAnim")
local sprintTrack = humanoid:LoadAnimation(animation)

-- // Functions

-- Camera tweening handler
local tween_fov = function(duration, value)
    
    local fov_tween = tweenService:Create(camera, TweenInfo.new(duration, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut), {FieldOfView = value})
    fov_tween:Play()
    
    return fov_tween
end

-- Input controller
userInputService.InputBegan:Connect(function(input, processed)
	if input.KeyCode == (pcButton or xboxButton) and not processed then
		if stamina.Value >= 0.01 then	
       		if humanoid.MoveDirection.Magnitude <= 0 then
           	 	running.Value = true
				tween_fov(0.5, sprintFov)
            	humanoid.WalkSpeed = sprintSpeed
      		else
            	running.Value = true
				for i = 0, 1, 0.05 do
					stamina.Value = i
				end
            	humanoid.WalkSpeed = sprintSpeed
				sprintTrack:Play(0.25)
				tween_fov(0.5, sprintFov)
			end
        end
    end
end)

userInputService.InputEnded:Connect(function(input, processed)
    if input.KeyCode == (pcButton or xboxButton) and not processed then
        running.Value = false
        
        humanoid.WalkSpeed = normalSpeed
		sprintTrack:Stop(0.25)
		tween_fov(0.5, normalFov)
    end
end)

-- Main loop controller
runService.RenderStepped:Connect(function()
    if running.Value then
        
        -- Check if player is moving
        if humanoid.MoveDirection.Magnitude <= 0 then
            if sprintTrack.IsPlaying then
				sprintTrack:Stop(0.25)
				
            end
        elseif humanoid.MoveDirection.Magnitude > 0 then
            if not sprintTrack.IsPlaying then
				sprintTrack:Play(0.25)
				tween_fov(0.5, sprintFov)
            end
        end
        
        -- Check if player is jumping
        if humanoid.FloorMaterial == Enum.Material.Air then
            if sprintTrack.IsPlaying then
                sprintTrack:Stop(0.1)
            end
        elseif humanoid.FloorMaterial ~= Enum.Material.Air and humanoid.MoveDirection.Magnitude > 0 then
            if not sprintTrack.IsPlaying then
                sprintTrack:Play(0.25)
            end
        end
    end
end)