Further improve and enhance this roblox half-swing script, and make it dynamically swing faster with surreal handler.

```
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local LocalPlayer = Players.LocalPlayer
local Mouse = LocalPlayer:GetMouse()

local LightsaberRemotes = ReplicatedStorage:WaitForChild("LightsaberRemotes")
local SwingRemote = LightsaberRemotes:WaitForChild("Swing")

-- Configuration
local HALF_SWING_DELAY = 0.15  -- Adjust this value to change the timing of the half-swing
local MAX_DISTANCE = 20  -- Maximum distance to consider for half-swinging
local PREDICTION_MULTIPLIER = 1.5  -- Multiplier for position prediction

-- Swing types and their corresponding animation IDs
local SWING_TYPES = {
    ["RightSwing"] = 12625839385,
    ["OverheadSwing"] = 12625841878,
    ["LeftSwing"] = 12625843823,
    ["BackLeftSwing"] = 12625846167,
    ["FrontRightSwing"] = 12625848489,
    ["BackRightSwing"] = 12625851115,
    ["FrontLeftSwing"] = 12625853257,
}

-- Function to get the closest visible player
local function getClosestVisiblePlayer()
    local closestPlayer, closestDistance = nil, math.huge
    local myPosition = LocalPlayer.Character and LocalPlayer.Character.PrimaryPart.Position

    for _, player in ipairs(Players:GetPlayers()) do
        if player ~= LocalPlayer and player.Character and player.Character.PrimaryPart then
            local playerPosition = player.Character.PrimaryPart.Position
            local distance = (myPosition - playerPosition).Magnitude

            if distance < closestDistance and distance <= MAX_DISTANCE then
                local ray = Ray.new(myPosition, (playerPosition - myPosition).Unit * MAX_DISTANCE)
                local hit = workspace:FindPartOnRayWithIgnoreList(ray, {LocalPlayer.Character})

                if hit and hit:IsDescendantOf(player.Character) then
                    closestPlayer = player
                    closestDistance = distance
                end
            end
        end
    end

    return closestPlayer
end

-- Function to predict player's position
local function predictPlayerPosition(player, timeAhead)
    local character = player.Character
    if not character or not character.PrimaryPart then return nil end

    local currentPosition = character.PrimaryPart.Position
    local velocity = character.PrimaryPart.Velocity

    return currentPosition + (velocity * timeAhead * PREDICTION_MULTIPLIER)
end

-- Function to perform a half-swing
local function performHalfSwing()
    local closestPlayer = getClosestVisiblePlayer()
    if not closestPlayer then return end

    local predictedPosition = predictPlayerPosition(closestPlayer, HALF_SWING_DELAY)
    if not predictedPosition then return end

    local myPosition = LocalPlayer.Character and LocalPlayer.Character.PrimaryPart.Position
    if not myPosition then return end

    local direction = (predictedPosition - myPosition).Unit
    local swingType = "RightSwing"  -- Default swing type

    -- Determine the best swing type based on the direction
    local dot = direction:Dot(LocalPlayer.Character.PrimaryPart.CFrame.LookVector)
    if dot > 0.7 then
        swingType = "FrontRightSwing"
    elseif dot < -0.7 then
        swingType = "BackRightSwing"
    elseif direction:Dot(LocalPlayer.Character.PrimaryPart.CFrame.RightVector) > 0 then
        swingType = "RightSwing"
    else
        swingType = "LeftSwing"
    end

    -- Perform the swing
    SwingRemote:FireServer(SWING_TYPES[swingType])

    -- Schedule the half-swing
    task.delay(HALF_SWING_DELAY, function()
        Mouse1Click()  -- Simulate a mouse click to perform the half-swing
    end)
end

-- Main loop
RunService.Heartbeat:Connect(function()
    if UserInputService:IsKeyDown(Enum.KeyCode.R) then  -- You can change this key as needed
        performHalfSwing()
    end
end)

-- UI for enabling/disabling the script
local Rayfield = loadstring(game:HttpGet('https://raw.githubusercontent.com/shlexware/Rayfield/main/source'))()

local Window = Rayfield:CreateWindow({
    Name = "Advanced Half-Swing",
    LoadingTitle = "Saber Showdown Script",
    LoadingSubtitle = "by Your Name",
})

local MainTab = Window:CreateTab("Main")

local Toggle = MainTab:CreateToggle({
    Name = "Enable Half-Swing",
    CurrentValue = false,
    Flag = "HalfSwingToggle",
    Callback = function(Value)
        -- You can add additional logic here if needed
    end,
})

local Slider = MainTab:CreateSlider({
    Name = "Half-Swing Delay",
    Range = {0.05, 0.3},
    Increment = 0.01,
    Suffix = "seconds",
    CurrentValue = HALF_SWING_DELAY,
    Flag = "HalfSwingDelay",
    Callback = function(Value)
        HALF_SWING_DELAY = Value
    end,
})

print("Advanced Half-Swing script loaded!")
```

Reference Function:

```
local function onCharacterAdded(character)
    local humanoid = character:WaitForChild("Humanoid")
    local player = Players:GetPlayerFromCharacter(character)
    
    local espObjects = createPlayerESP(player)
    local slapTimerESP = espObjects[4]
    local canSlap = true
    local blockEndTime = 0
    
    humanoid.AnimationPlayed:Connect(function(animTrack)
        for animName, animId in pairs(animIDs) do
            if animTrack.Animation.AnimationId == "rbxassetid://" .. animId then
                print(player.Name .. " used animation: " .. animName)
                
                if animName == "Slap" and slapTimerEnabled then
                    canSlap = false
                    local startTime = tick()
                    
                    task.spawn(function()
                        while tick() - startTime < 3 and slapTimerEnabled do
                            local timeLeft = math.ceil(3 - (tick() - startTime))
                            slapTimerESP.Text = string.format("%d cannot slap", timeLeft)
                            slapTimerESP.Color = slapTimerColor
                            slapTimerESP.Visible = true
                            task.wait(0.1)
                        end
                        
                        canSlap = true
                        slapTimerESP.Text = "Can slap"
                        slapTimerESP.Color = Color3.new(1, 0, 0)
                        slapTimerESP.Visible = true
                    end)
                end
                
                if (animName:find("Swing") or animName == "Slap") and autoBlockEnabled then
                    local localPlayer = Players.LocalPlayer
                    local localCharacter = localPlayer.Character
                    if localCharacter then
                        local localPosition = localCharacter.PrimaryPart.Position
                        local playerPosition = player.Character.PrimaryPart.Position
                        local distance = (playerPosition - localPosition).Magnitude
                        
                        if distance < blockDistance then 
                            BlockRemote:FireServer()
                            
                            task.wait(animTrack.Length)
                            
                            UnblockRemote:FireServer()
                            
                            if autoCounterEnabled and animName == "Slap" then
                                if distance < autoSlapDistance then
                                    VirtualInputManager:SendKeyEvent(true, Enum.KeyCode.E, false, game)
                                    task.wait(0.1)
                                    VirtualInputManager:SendKeyEvent(false, Enum.KeyCode.E, false, game)
                                end
                            end
                        end
                    end
                end
                
                if animName:find("Swing") and player == Players.LocalPlayer and autoHalfSwingEnabled then
                    task.delay(autoHalfSwingDelay, function()
                        mouse1click()
                    end)
                end
                
                break
            end
        end
    end)
end

local function monitorClosestPlayer()
    local closestPlayer = getClosestPlayer()
    if closestPlayer and closestPlayer.Character then
        local humanoid = closestPlayer.Character:FindFirstChild("Humanoid")
        if humanoid then
            humanoid.AnimationPlayed:Connect(function(animTrack)
                for animName, animId in pairs(animIDs) do
                    if animTrack.Animation.AnimationId == "rbxassetid://" .. animId then
                        if animName:find("Block") then
                            blockEndTime = tick() + 0.5
                        end
                    end
                end
            end)
        end
    end
end
```

List of Anim ID's:

```
local animIDs = {
    ["RightSwing"] = 12625839385,
    ["OverheadSwing"] = 12625841878,
    ["LeftSwing"] = 12625843823,
    ["BackLeftSwing"] = 12625846167,
    ["FrontRightSwing"] = 12625848489,
    ["BackRightSwing"] = 12625851115,
    ["FrontLeftSwing"] = 12625853257,
    ["RightBlock"] = 12625856098,
    ["LeftBlock"] = 12625858434,
    ["FrontLeftBlock"] = 12625860439,
    ["FrontRightBlock"] = 12625862519,
    ["FrontBlock"] = 12625864413,
    ["BackLeftBlock"] = 12625866538,
    ["BackRightBlock"] = 12625868684,
    ["Grab"] = 12625870437,
    ["Slap"] = 12625891544,
    ["SlappedLegs"] = 12671715182,
    ["SlappedArms"] = 12625896358,
    ["KickUp"] = 12625897944,
    ["KickBack"] = 12625899752,
    ["LeftRoll"] = 12625901874,
    ["RightRoll"] = 12625904322,
    ["Aerial"] = 12625908201,
    ["Idle"] = 13956175510,
    ["Throw"] = 12626569448,
    ["ForcePush"] = 12645928786,
    ["CrouchWalkRight"] = 12699256551,
    ["CrouchWalkLeft"] = 12699989478,
    ["CrouchWalkBack"] = 12699390244,
    ["CrouchWalkForward"] = 12699464592,
    ["FrontRoll"] = 12708915962,
    ["RightCrouchRoll"] = 12713661639,
    ["LeftCrouchRoll"] = 12713663289,
    ["Kata"] = 12735531097,
    ["Choking"] = 12814275189,
    ["Choke"] = 12815930160,
}