FURTHER ENHANCE:

-- Enhanced Roblox Script with Advanced Dynamic Slap Blocking System and Toggle Feature

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

-- Remotes
local LightsaberRemotes = ReplicatedStorage:WaitForChild("LightsaberRemotes")
local BlockRemote = LightsaberRemotes:WaitForChild("Block")
local UnblockRemote = LightsaberRemotes:WaitForChild("Unblock")

-- Settings
local Settings = {
    BlockDistance = 15,
    AutoCounterEnabled = false,
    AutoSlapDistance = 10,
    ReactionTimeThreshold = 0.15, -- Base reaction time
    BlockDuration = 0.3,
    Cooldown = 1.0,
    SlapAnimations = {
        ["Slap"] = 12625891544,
        ["SlappedLegs"] = 12671715182,
        ["SlappedArms"] = 12625896358,
        ["RightSwing"] = 12625891545,      -- Example additional animations
        ["LeftSwing"] = 12625891546,
        ["OverheadSwing"] = 12625891547,
        ["DoubleSlap"] = 12625891548
    }
}

-- State Management
local blockingPlayers = {} -- Tracks blocking state per opponent
local isBlockingEnabled = true -- Toggle state

-- GUI Setup for Visual Feedback
local function setupGUI()
    local screenGui = Instance.new("ScreenGui")
    screenGui.Name = "AdvancedAntiSlapIndicator"
    screenGui.ResetOnSpawn = false
    screenGui.Parent = Players.LocalPlayer:WaitForChild("PlayerGui")
    
    -- Block Indicator Frame
    local blockIndicator = Instance.new("Frame")
    blockIndicator.Size = UDim2.new(0, 250, 0, 120)
    blockIndicator.Position = UDim2.new(0.5, -125, 0, 10)
    blockIndicator.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
    blockIndicator.BackgroundTransparency = 0.5
    blockIndicator.BorderSizePixel = 0
    blockIndicator.Visible = false
    blockIndicator.Parent = screenGui
    
    -- Block Text Label
    local blockText = Instance.new("TextLabel")
    blockText.Size = UDim2.new(1, 0, 1, 0)
    blockText.Position = UDim2.new(0, 0, 0, 0)
    blockText.BackgroundTransparency = 1
    blockText.Text = "Blocking System:\nEnabled\nAgainst: None"
    blockText.TextColor3 = Color3.fromRGB(255, 255, 255)
    blockText.TextScaled = true
    blockText.TextWrapped = true
    blockText.Parent = blockIndicator
    
    -- Toggle Indicator Frame
    local toggleIndicator = Instance.new("Frame")
    toggleIndicator.Size = UDim2.new(0, 200, 0, 50)
    toggleIndicator.Position = UDim2.new(0.5, -100, 0, 140)
    toggleIndicator.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
    toggleIndicator.BackgroundTransparency = 0.5
    toggleIndicator.BorderSizePixel = 0
    toggleIndicator.Visible = false
    toggleIndicator.Parent = screenGui
    
    -- Toggle Text Label
    local toggleText = Instance.new("TextLabel")
    toggleText.Size = UDim2.new(1, 0, 1, 0)
    toggleText.Position = UDim2.new(0, 0, 0, 0)
    toggleText.BackgroundTransparency = 1
    toggleText.Text = "Blocking System Disabled"
    toggleText.TextColor3 = Color3.fromRGB(255, 0, 0)
    toggleText.TextScaled = true
    toggleText.TextWrapped = true
    toggleText.Parent = toggleIndicator
    
    return blockIndicator, blockText, toggleIndicator, toggleText
end

local blockIndicator, blockText, toggleIndicator, toggleText = setupGUI()

-- Tween for Smooth Appearance/Disappearance
local tweenInfoVisible = TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
local tweenInfoHidden = TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.In)

local showTween = TweenService:Create(blockIndicator, tweenInfoVisible, {BackgroundTransparency = 0.3, Visible = true})
local hideTween = TweenService:Create(blockIndicator, tweenInfoHidden, {BackgroundTransparency = 0.5, Visible = false})

local toggleShowTween = TweenService:Create(toggleIndicator, tweenInfoVisible, {BackgroundTransparency = 0.3, Visible = true})
local toggleHideTween = TweenService:Create(toggleIndicator, tweenInfoHidden, {BackgroundTransparency = 0.5, Visible = false})

-- Utility Function to Get Current Time
local function getCurrentTime()
    return tick()
end

-- Function to Get Closest Players within BlockDistance
local function getClosestPlayers()
    local players = {}
    local localPlayer = Players.LocalPlayer
    local localCharacter = localPlayer.Character

    if localCharacter and localCharacter:FindFirstChild("HumanoidRootPart") then
        local localPosition = localCharacter.HumanoidRootPart.Position

        for _, player in ipairs(Players:GetPlayers()) do
            if player ~= localPlayer and player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
                local playerPosition = player.Character.HumanoidRootPart.Position
                local distance = (playerPosition - localPosition).Magnitude

                if distance <= Settings.BlockDistance then
                    table.insert(players, {Player = player, Distance = distance})
                end
            end
        end
    end

    table.sort(players, function(a, b) return a.Distance < b.Distance end)
    return players
end

-- Function to Update GUI Indicators based on Blocking State
local function updateGUI()
    local blockingNames = {}
    for opponentName, _ in pairs(blockingPlayers) do
        table.insert(blockingNames, opponentName)
    end
    
    if isBlockingEnabled and #blockingNames > 0 then
        blockIndicator.Visible = true
        blockText.Text = "Blocking System:\nEnabled\nAgainst:\n" .. table.concat(blockingNames, ", ")
    else
        blockIndicator.Visible = false
        blockText.Text = "Blocking against:\nNone"
    end
end

-- Function to Toggle Blocking System
local function toggleBlockingSystem()
    isBlockingEnabled = not isBlockingEnabled
    if isBlockingEnabled then
        -- Enable Blocking System
        toggleIndicator.Visible = false
        toggleHideTween:Play()
        print("Blocking System Enabled")
    else
        -- Disable Blocking System
        toggleIndicator.Visible = true
        toggleShowTween:Play()
        blockingPlayers = {} -- Clear any existing blocking states
        UnblockRemote:FireServer()
        print("Blocking System Disabled")
    end
    updateGUI()
end

-- Key Binding for Toggle (R Key)
UserInputService.InputBegan:Connect(function(input, gameProcessed)
    if gameProcessed then return end
    if input.KeyCode == Enum.KeyCode.R then
        toggleBlockingSystem()
    end
end)

-- Handle Slap Animation with Advanced Blocking Logic
local function handleSlapAnimation(opponent, animTrack)
    if not isBlockingEnabled then return end

    local localPlayer = Players.LocalPlayer
    local character = localPlayer.Character
    if not character or not character:FindFirstChild("HumanoidRootPart") then return end

    local opponentRoot = opponent.Character:FindFirstChild("HumanoidRootPart")
    if not opponentRoot then return end

    local distance = (character.HumanoidRootPart.Position - opponentRoot.Position).Magnitude

    if distance > Settings.BlockDistance then return end

    local currentTime = getCurrentTime()
    local lastBlock = blockingPlayers[opponent.Name] or 0
    local timeSinceLastBlock = currentTime - lastBlock

    if timeSinceLastBlock < Settings.Cooldown then
        print("Block on cooldown for:", opponent.Name, "Time left:", string.format("%.2f", Settings.Cooldown - timeSinceLastBlock))
        return
    end

    -- Dynamic Reaction Time based on distance (closer opponents require faster reaction)
    local dynamicReactionTime = Settings.ReactionTimeThreshold * (Settings.BlockDistance / distance)
    dynamicReactionTime = math.clamp(dynamicReactionTime, 0.05, Settings.ReactionTimeThreshold)

    -- Determine if block should be initiated based on animation
    local shouldBlock = false
    local reactiveAnims = {"Slap", "RightSwing", "LeftSwing", "OverheadSwing", "DoubleSlap"}

    for _, animName in ipairs(reactiveAnims) do
        if animTrack.Animation.AnimationId == "rbxassetid://" .. Settings.SlapAnimations[animName] then
            shouldBlock = true
            break
        end
    end

    if shouldBlock then
        blockingPlayers[opponent.Name] = currentTime
        BlockRemote:FireServer()
        print("Blocking initiated against:", opponent.Name)

        updateGUI()

        -- Schedule Unblock
        task.delay(Settings.BlockDuration, function()
            UnblockRemote:FireServer()
            blockingPlayers[opponent.Name] = nil
            print("Blocking ended for:", opponent.Name)
            updateGUI()
        end)

        -- Auto Counter Slap if enabled and within AutoSlapDistance
        if Settings.AutoCounterEnabled and distance <= Settings.AutoSlapDistance then
            task.delay(dynamicReactionTime, function()
                VirtualInputManager:SendKeyEvent(true, Enum.KeyCode.E, false, game)
                task.wait(0.1)
                VirtualInputManager:SendKeyEvent(false, Enum.KeyCode.E, false, game)
                print("Automatic counter-slap performed against:", opponent.Name)
            end)
        end
    end
end

-- Monitor Opponent's Animations
local function onOpponentAnimationPlayed(opponent, animTrack)
    for animName, animId in pairs(Settings.SlapAnimations) do
        if animTrack.Animation and animTrack.Animation.AnimationId == "rbxassetid://" .. animId then
            print("Detected slap animation:", animName, "from:", opponent.Name)
            handleSlapAnimation(opponent, animTrack)
            break
        end
    end
end

-- Setup Character Connections
local function onCharacterAdded(character, player)
    local humanoid = character:WaitForChild("Humanoid")
    humanoid.AnimationPlayed:Connect(function(animTrack)
        onOpponentAnimationPlayed(player, animTrack)
    end)
end

-- Setup Player Connections
local function setupPlayer(player)
    if player == Players.LocalPlayer then return end
    if player.Character then
        onCharacterAdded(player.Character, player)
    end
    player.CharacterAdded:Connect(function(character)
        onCharacterAdded(character, player)
    end)
end

-- Initialize Existing Players
for _, player in ipairs(Players:GetPlayers()) do
    setupPlayer(player)
end

-- Listen for New Players
Players.PlayerAdded:Connect(setupPlayer)

-- Initial GUI Update
updateGUI()

-- Optional: Display Instructions in the Output
print("Advanced Dynamic Slap Blocking System Initialized.")
print("Press 'R' to toggle the blocking system on and off.")