Загрузка данных


local rs = game:GetService("ReplicatedStorage")
local ss = game:GetService("ServerStorage")
local slashEvent = rs:WaitForChild("BloodSlashEvent")

-- Наши префабы
local beamPrefab = ss:WaitForChild("BloodBeam")
local ballPrefab = ss:WaitForChild("BloodBall") -- Тот самый шар зарядки
local holePrefab = ss:WaitForChild("CrackedHole")

local activeBeams = {}
local activeBalls = {} -- Для шаров зарядки

slashEvent.OnServerEvent:Connect(function(player, state, direction)
    local char = player.Character
    if not char or not char:FindFirstChild("HumanoidRootPart") then return end
    local root = char.HumanoidRootPart
    
    -------------------------------------------------------
    -- СОСТОЯНИЕ 2: НАЧАЛО ЗАРЯДКИ (Появляется шар)
    -------------------------------------------------------
    if state == 2 then
        -- Убираем старые эффекты, если они были
        if activeBalls[player.UserId] then activeBalls[player.UserId]:Destroy() end
        
        -- Спавним шар зарядки прямо перед игроком
        local ball = ballPrefab:Clone()
        ball.Anchored = false -- Важно: он должен крепиться к игроку
        ball.CanCollide = false
        ball.Parent = workspace
        
        -- Крепим шар к торсу (чтобы двигался за игроком)
        local weld = Instance.new("Weld")
        weld.Part0 = root
        weld.Part1 = ball
        weld.C0 = CFrame.new(0, 0, -2) -- Шар в 2 метрах перед игроком
        weld.Parent = ball
        
        activeBalls[player.UserId] = ball
        
        -- Анимация роста шара (от 0 до полного размера за 2 сек)
        task.spawn(function()
            for i = 1, 20 do
                if not ball.Parent then break end
                ball.Size = Vector3.new(0.1, 0.1, 0.1) * i -- Растет
                task.wait(0.1)
            end
        end)
        
    -------------------------------------------------------
    -- СОСТОЯНИЕ 1: САМ ЛУЧ (После зарядки)
    -------------------------------------------------------
    elseif state == 1 and direction then
        -- 1. Удаляем шар зарядки (он превратился в луч)
        if activeBalls[player.UserId] then
            activeBalls[player.UserId]:Destroy()
            activeBalls[player.UserId] = nil
        end
        
        -- 2. Логика луча (твоя старая, только с исправленным Raycast)
        local slash = activeBeams[player.UserId]
        if not slash then
            slash = beamPrefab:Clone()
            slash.Anchored = true
            slash.CanCollide = false
            slash.Parent = workspace
            activeBeams[player.UserId] = slash
        end
        
        local rayOrigin = root.Position + Vector3.new(0, 1.5, 0)
        local rayDirection = direction * 70
        
        -- Хак для Raycast: не бить самого себя
        local raycastParams = RaycastParams.new()
        raycastParams.FilterDescendantsInstances = {char}
        raycastParams.FilterType = Enum.RaycastFilterType.Exclude
        
        local result = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
        
        -- Визуализация луча (lookAt ставит луч концом вперед)
        if result then
            -- Ставим эффекты и укорачиваем
            if result.Instance.CanCollide then
                local hole = holePrefab:Clone()
                hole.CFrame = CFrame.new(result.Position, result.Position + result.Normal) * CFrame.Angles(math.rad(-90), 0, 0)
                hole.Parent = workspace
                game.Debris:AddItem(hole, 2)
            end
            
            local dist = (rayOrigin - result.Position).Magnitude
            slash.Size = Vector3.new(slash.Size.X, slash.Size.Y, dist)
            slash.CFrame = CFrame.lookAt(rayOrigin, result.Position) * CFrame.new(0, 0, -dist/2)
        else
            -- Стреляем в небо
            slash.Size = Vector3.new(slash.Size.X, slash.Size.Y, 70)
            slash.CFrame = CFrame.lookAt(rayOrigin, rayOrigin + rayDirection) * CFrame.new(0, 0, -35)
        end
        
    -------------------------------------------------------
    -- СОСТОЯНИЕ 0 / FALSE: ВЫКЛЮЧЕНИЕ
    -------------------------------------------------------
    elseif state == 0 or state == false then
        if activeBeams[player.UserId] then activeBeams[player.UserId]:Destroy() activeBeams[player.UserId] = nil end
        if activeBalls[player.UserId] then activeBalls[player.UserId]:Destroy() activeBalls[player.UserId] = nil end
    end
end)