Improve the slap functions, and make them optimized into this roblox script:

```
-- Super Advanced Auto Block Script for Saber Showdown
-- Enhanced with Dynamic Auto-Blocking, Hitbox Detection, Animation State Detection,
-- Slap Lag Handling, Auto Directional Block (Aim-Lock), and Advanced Reaction-Based Auto-Block

-- === Services ===
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local StarterGui = game:GetService("StarterGui")
local VirtualInputManager = game:GetService("VirtualInputManager")
local CollectionService = game:GetService("CollectionService")

-- === Player Setup ===
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local camera = workspace.CurrentCamera

-- === Remotes ===
local LightsaberRemotes = ReplicatedStorage:WaitForChild("LightsaberRemotes")
local BlockRemote = LightsaberRemotes:WaitForChild("Block")
local UnblockRemote = LightsaberRemotes:WaitForChild("Unblock")
local UpdateManualBlockRemote = LightsaberRemotes:WaitForChild("UpdateManualBlock")
local UpdateBlockDirectionRemote = LightsaberRemotes:WaitForChild("UpdateBlockDirection")

-- === Settings ===
local Settings = {
    -- Blocking Settings
    blockDistance = 15,            -- Max distance to attempt a block
    autoBlockEnabled = true,       -- Enable/Disable dynamic auto-blocking
    blockCooldown = 0.5,           -- Cooldown between blocks (seconds)
    attackTypes = {                -- Attack animation IDs
        Slap = 12625891544,
        SlappedLegs = 12671715182,
        SlappedArms = 12625896358,
        Punch = 12625897000,       -- Example attack ID
        Kick = 12625897500,        -- Example attack ID
        KickUp = 12625897944,      -- Added KickUp
        KickBack = 12625899752      -- Added KickBack
    },
    
    -- Counter Attacking Settings
    autoCounterEnabled = true,     -- Enable/Disable auto counter attacks
    autoCounterDistance = 10,      -- Distance within which to auto counter
    counterCooldown = 1.5,         -- Cooldown between counters (seconds)
    counterKey = Enum.KeyCode.E,    -- Key to use for countering

    reactionTimeThreshold = 0.2,   -- Threshold for reaction time (in seconds)
    predictionFactor = 0.5,        -- Factor for predicting enemy movements (0-1)
    
    -- Slap Lag Handling
    slapLagCompensation = 0.2,     -- Additional delay to compensate for lag in slap attacks
    
    -- Aim-Lock Directional Block Settings
    aimLockEnabled = true,         -- Enable/Disable aim-lock directional blocking
    aimLockSmoothness = 0.1,       -- Smoothness factor for direction adjustment
    
    -- UI Settings
    ui = {
        ScreenGuiName = "AutoBlockUI",
        BlackBoxSize = UDim2.new(0.25, 0, 0.1, 0),
        BlackBoxPosition = UDim2.new(0, 0, 0.9, 0),
        BlackBoxColor = Color3.fromRGB(0, 0, 0),
        BlackBoxTransparency = 0.5,
        LoadingBarSize = UDim2.new(1, 0, 0.2, 0),
        LoadingBarPosition = UDim2.new(0, 0, -0.2, 0),
        LoadingBarColor = Color3.fromRGB(0, 255, 0),
        LoadingBarTransparency = 0.3,
        MessageBoxText = "Press 'Q' to toggle Auto Block",
        MessageBoxColor = Color3.fromRGB(255, 255, 255),
        MessageBoxTransparency = 1,
    }
}

-- === State Tracking ===
local isBlocking = false
local lastBlockTime = {}
local lastCounterTime = {}
local autoBlockEnabled = Settings.autoBlockEnabled
local currentBlockDirection = 1 -- Default to forward

-- === UI Setup ===
local screenGui = Instance.new("ScreenGui")
screenGui.Name = Settings.ui.ScreenGuiName
screenGui.Parent = player:WaitForChild("PlayerGui")
screenGui.ResetOnSpawn = false

-- Black Box Frame
local blackBox = Instance.new("Frame")
blackBox.Size = Settings.ui.BlackBoxSize
blackBox.Position = Settings.ui.BlackBoxPosition
blackBox.BackgroundColor3 = Settings.ui.BlackBoxColor
blackBox.BackgroundTransparency = Settings.ui.BlackBoxTransparency
blackBox.Parent = screenGui

-- Loading Bar
local loadingBar = Instance.new("Frame")
loadingBar.Size = Settings.ui.LoadingBarSize
loadingBar.Position = Settings.ui.LoadingBarPosition
loadingBar.BackgroundColor3 = Settings.ui.LoadingBarColor
loadingBar.BackgroundTransparency = Settings.ui.LoadingBarTransparency
loadingBar.Parent = blackBox

-- Message Box
local messageBox = Instance.new("TextLabel")
messageBox.Size = UDim2.new(1, 0, 1, 0)
messageBox.Position = UDim2.new(0, 0, 0, 0)
messageBox.BackgroundTransparency = Settings.ui.MessageBoxTransparency
messageBox.TextColor3 = Settings.ui.MessageBoxColor
messageBox.TextScaled = true
messageBox.Text = Settings.ui.MessageBoxText
messageBox.Parent = blackBox

-- === Utility Functions ===

-- Function to start blocking
local function startBlocking()
    if not isBlocking then
        isBlocking = true
        BlockRemote:FireServer()
        print("[AutoBlock] Blocking started")
    end
end

-- Function to stop blocking
local function stopBlocking()
    if isBlocking then
        isBlocking = false
        UnblockRemote:FireServer()
        print("[AutoBlock] Blocking stopped")
    end
end

-- Function to toggle blocking manually
local function toggleBlocking()
    if isBlocking then
        stopBlocking()
    else
        startBlocking()
    end
end

-- Function to predict enemy movement
local function predictEnemyMovement(enemy)
    local enemyHRP = enemy.Character and enemy.Character:FindFirstChild("HumanoidRootPart")
    if not enemyHRP then return nil end
    
    local currentPosition = enemyHRP.Position
    local velocity = enemyHRP.Velocity
    local predictedPosition = currentPosition + velocity * Settings.predictionFactor
    
    return predictedPosition
end

-- Function to determine hit direction based on the position of the attacker
local function getHitDirection(attackerPosition)
    local characterPosition = humanoidRootPart.Position
    local direction = (attackerPosition - characterPosition).Unit
    local camCFrame = camera.CFrame
    local camForward = camCFrame.LookVector
    local dotProduct = direction:Dot(camForward)

    if Settings.aimLockEnabled then
        -- Use camera direction to determine block direction
        if dotProduct > 0.707 then
            return 1 -- Forward
        elseif dotProduct < -0.707 then
            return 3 -- Backward
        else
            local rightDot = direction:Dot(camCFrame.RightVector)
            if rightDot > 0 then
                return 2 -- Right
            else
                return 4 -- Left
            end
        end
    else
        -- Original position-based direction
        local angle = math.deg(math.atan2(direction.Z, direction.X))
        if angle < 0 then angle = angle + 360 end

        if angle >= 0 and angle < 45 then
            return 1 -- Forward
        elseif angle >= 45 and angle < 135 then
            return 2 -- Right
        elseif angle >= 135 and angle < 225 then
            return 3 -- Backward
        elseif angle >= 225 and angle < 315 then
            return 4 -- Left
        else
            return 1 -- Forward (default wrap-around)
        end
    end
end

-- Function to smoothly update block direction based on aim-lock
local function getSmoothBlockDirection(attackerPosition)
    local desiredDirection = getHitDirection(attackerPosition)
    local currentDirection = player:GetAttribute("BlockDirection") or 1
    
    -- Implement smooth transition
    local smoothness = Settings.aimLockSmoothness
    local newDirection = currentDirection + (desiredDirection - currentDirection) * smoothness
    
    -- Round to nearest integer (1, 2, 3, or 4)
    return math.round(newDirection)
end

-- Function to update block direction
local function updateBlockDirection(direction)
    UpdateBlockDirectionRemote:FireServer(direction)
end

-- Function to handle incoming hits with optional lag compensation
local function handleIncomingHit(attacker, attackerPosition, isSlap)
    local currentTime = tick()

    -- Cooldown Check
    if lastBlockTime[attacker] and (currentTime - lastBlockTime[attacker]) < Settings.blockCooldown then
        return -- Still in cooldown; cannot block
    end

    -- Distance Check
    local distance = (humanoidRootPart.Position - attackerPosition).Magnitude
    if distance > Settings.blockDistance then
        return -- Attacker is too far; no need to block
    end

        -- Advanced Reaction-Based Autoblock
    local reactionDelay = math.random() * Settings.reactionTimeThreshold
    task.delay(reactionDelay, function()
        local predictedPosition = predictEnemyMovement(attacker)
        local blockDirection = getSmoothBlockDirection(predictedPosition or attackerPosition)
        updateBlockDirection(blockDirection)

        startBlocking()
        lastBlockTime[attacker] = currentTime

        -- Adaptive unblock timing
        local unblockDelay = isSlap and Settings.slapLagCompensation or 0.5
        task.delay(unblockDelay, function()
            stopBlocking()
    end)
end)

    -- Handle Auto Countering
    if Settings.autoCounterEnabled and distance <= Settings.autoCounterDistance then
        if not lastCounterTime[attacker] or (currentTime - lastCounterTime[attacker]) >= Settings.counterCooldown then
            -- Simulate Counter Key Press
            VirtualInputManager:SendKeyEvent(true, Settings.counterKey, false, game)
            task.wait(0.1)
            VirtualInputManager:SendKeyEvent(false, Settings.counterKey, false, game)
            lastCounterTime[attacker] = currentTime
            print("[AutoBlock] Countered attack from " .. attacker.Name)
        end
    end
end

-- === Animation State Detection ===
local function onCharacterAdded(characterInstance)
    local humanoidInstance = characterInstance:WaitForChild("Humanoid")
    local opponentPlayer = Players:GetPlayerFromCharacter(characterInstance)
    if not opponentPlayer or opponentPlayer == player then
        return -- Ignore self or non-player characters
    end

    -- Connect to AnimationPlayed
    local animationConnection
    animationConnection = humanoidInstance.AnimationPlayed:Connect(function(animTrack)
        -- Validate Animation ID
        if not animTrack.Animation or not animTrack.Animation.AnimationId then return end

        -- Check if the animation is an attack
        for attackType, animId in pairs(Settings.attackTypes) do
            if animTrack.Animation.AnimationId == "rbxassetid://" .. animId then
                print("[AutoBlock] Detected attack '" .. attackType .. "' from " .. opponentPlayer.Name)
                local attackerRoot = characterInstance:FindFirstChild("HumanoidRootPart")
                if attackerRoot then
                    local isSlap = (attackType == "Slap")
                    handleIncomingHit(opponentPlayer, attackerRoot.Position, isSlap)
                end
                break
            end
        end
    end)

    -- Cleanup when character is removed
    characterInstance.AncestryChanged:Connect(function(_, parent)
        if not parent then
            if animationConnection then
                animationConnection:Disconnect()
            end
        end
    end)
end

-- === Hitbox Detection ===
-- Assumes that attack hitboxes are parts tagged with "AttackHitbox"
local ATTACK_HITBOX_TAG = "AttackHitbox"

local function onHitboxTouched(hit)
    local attackerPart = hit.Parent
    local attackerPlayer = Players:GetPlayerFromCharacter(attackerPart.Parent)
    if not attackerPlayer or attackerPlayer == player then
        return -- Ignore self or non-player characters
    end

    local attackerRoot = attackerPart.Parent:FindFirstChild("HumanoidRootPart")
    if attackerRoot then
        print("[AutoBlock] Hitbox detected attack from " .. attackerPlayer.Name)
        handleIncomingHit(attackerPlayer, attackerRoot.Position, false)
    end
end

local function monitorHitboxes(characterInstance)
    -- Find all parts tagged as "AttackHitbox" within the character
    for _, hitbox in ipairs(CollectionService:GetTagged(ATTACK_HITBOX_TAG)) do
        if hitbox:IsDescendantOf(characterInstance) then
            -- Connect Touch event
            hitbox.Touched:Connect(onHitboxTouched)
        end
    end
end

-- === Advanced Reaction-Based Auto-Block ===
local function advancedReactionAutoBlock()
    RunService.Heartbeat:Connect(function()
        if not autoBlockEnabled then return end

        for _, plr in ipairs(Players:GetPlayers()) do
            if plr ~= player and plr.Character then
                local enemyHRP = plr.Character:FindFirstChild("HumanoidRootPart")
                if enemyHRP then
                    local distance = (humanoidRootPart.Position - enemyHRP.Position).Magnitude
                    if distance <= Settings.blockDistance then
                        local predictedPosition = predictEnemyMovement(plr)
                        local blockDirection = getSmoothBlockDirection(predictedPosition or enemyHRP.Position)
                        updateBlockDirection(blockDirection)

                        -- Check for potential attacks based on animations or other indicators
                        -- This is a simplified example and can be expanded based on game-specific logic
                        local enemyHumanoid = plr.Character:FindFirstChild("Humanoid")
                        if enemyHumanoid and enemyHumanoid:GetPlayingAnimationTracks()[1] then
                            local currentAnim = enemyHumanoid:GetPlayingAnimationTracks()[1].Animation
                            for _, animId in pairs(Settings.attackTypes) do
                                if currentAnim.AnimationId == "rbxassetid://" .. animId then
                                    handleIncomingHit(plr, enemyHRP.Position, false)
                                    break
                                end
                            end
                        end
                    end
                end
            end
        end
    end)
end

-- === Player Monitoring ===
local function monitorPlayer(plr)
    if plr == player then return end -- Ignore self

    -- Monitor existing character
    if plr.Character then
        onCharacterAdded(plr.Character)
        monitorHitboxes(plr.Character)
    end

    -- Connect to CharacterAdded for future character spawns
    plr.CharacterAdded:Connect(function(characterInstance)
        onCharacterAdded(characterInstance)
        monitorHitboxes(characterInstance)
    end)

    -- Cleanup when player leaves
    plr.AncestryChanged:Connect(function(_, parent)
        if not parent then
            -- Optionally handle any cleanup if needed
        end
    end)
end

-- === Initialize Monitoring for Existing and Future Players ===
for _, plr in ipairs(Players:GetPlayers()) do
    monitorPlayer(plr)
end

Players.PlayerAdded:Connect(monitorPlayer)

-- === Manual Blocking Toggle ===
UserInputService.InputBegan:Connect(function(input, gameProcessed)
    if gameProcessed then return end
    if input.KeyCode == Enum.KeyCode.Q then
        toggleBlocking()
    end
end)

-- === UI Feedback Update ===
RunService.RenderStepped:Connect(function()
    if isBlocking then
        messageBox.Text = "Blocking Active"
        loadingBar.BackgroundColor3 = Color3.fromRGB(0, 255, 0)
    else
        messageBox.Text = Settings.ui.MessageBoxText
        loadingBar.BackgroundColor3 = Color3.fromRGB(255, 0, 0)
    end
end)

-- === Aim-Lock Directional Block Update ===
RunService.RenderStepped:Connect(function()
    if Settings.aimLockEnabled and autoBlockEnabled and isBlocking then
        -- Continuously update block direction based on camera aim
        local mouseRay = camera:ScreenPointToRay(UserInputService:GetMouseLocation().X, UserInputService:GetMouseLocation().Y)
        local blockDirection = getSmoothBlockDirection(humanoidRootPart.Position + mouseRay.Direction * 10)
        updateBlockDirection(blockDirection)
    end
end)

-- === Cleanup on Character Death or Removal ===
local function onCharacterDied()
    stopBlocking()
end

humanoid.Died:Connect(onCharacterDied)

character.AncestryChanged:Connect(function(_, parent)
    if not parent then
        stopBlocking()
    end
end)

-- === Slap Lag Handler ===
-- This is already partially handled in the 'handleIncomingHit' function with the 'isSlap' parameter

-- === Initialize Advanced Reaction System ===
setupAdvancedReactionSystem()
advancedReactionAutoBlock()

-- Notify that the script is running
print("[AutoBlock] Advanced Auto Block Script is now running.")
```