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


--============================================================--
--     Custom ESP + Tracers GUI  |  Roblox LocalScript        --
--============================================================--
local Players      = game:GetService("Players")
local RunService   = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local LocalPlayer  = Players.LocalPlayer
local Camera       = workspace.CurrentCamera

--=============== НАСТРОЙКИ =================================--
local Settings = {
    Enabled       = false,
    ShowName      = true,
    ShowHealth    = true,
    ShowDistance  = true,
    ShowTracers   = false,
    ChamColor     = Color3.fromRGB(255, 60, 60),
    TracerColor   = Color3.fromRGB(60, 255, 120),
}

local ESPObjects  = {}   -- [Player] = {Highlight, Billboard, ...}
local TracerObjs  = {}   -- [Player] = Drawing (Line)
local Connections = {}

--=============== ПРОВЕРКА DRAWING API ======================--
local hasDrawing = (typeof(Drawing) == "table" and typeof(Drawing.new) == "function")
if not hasDrawing then
    warn("[ESP] Drawing API недоступен — трейсеры отключены.")
end

--=============== ESP ЛОГИКА =================================--
local function applyVisibility()
    for _, obj in pairs(ESPObjects) do
        if obj.Highlight  then obj.Highlight.Enabled  = Settings.Enabled end
        if obj.Billboard  then obj.Billboard.Enabled  = Settings.Enabled end
        if obj.NameLabel  then obj.NameLabel.Visible  = Settings.ShowName end
        if obj.HpLabel    then obj.HpLabel.Visible    = Settings.ShowHealth end
        if obj.DistLabel  then obj.DistLabel.Visible  = Settings.ShowDistance end
    end
    -- трейсеры
    for _, line in pairs(TracerObjs) do
        if line then
            line.Visible = Settings.Enabled and Settings.ShowTracers
            line.Color   = Settings.TracerColor
        end
    end
end

local function removeESP(player)
    local obj = ESPObjects[player]
    if obj then
        if obj.Highlight then obj.Highlight:Destroy() end
        if obj.Billboard then obj.Billboard:Destroy() end
        ESPObjects[player] = nil
    end
    local line = TracerObjs[player]
    if line and line.Remove then line:Remove() end
    TracerObjs[player] = nil
end

local function createESP(player)
    if player == LocalPlayer then return end
    if ESPObjects[player] then return end
    if not player.Character then return end
    local char = player.Character

    -- Чамс
    local highlight = Instance.new("Highlight")
    highlight.Adornee             = char
    highlight.FillColor           = Settings.ChamColor
    highlight.FillTransparency    = 0.5
    highlight.OutlineColor        = Settings.ChamColor
    highlight.OutlineTransparency = 0
    highlight.DepthMode           = Enum.HighlightDepthMode.AlwaysOnTop
    highlight.Parent              = game.CoreGui

    -- Billboard
    local billboard = Instance.new("BillboardGui")
    billboard.Size        = UDim2.new(0, 220, 0, 60)
    billboard.StudsOffset = Vector3.new(0, 3, 0)
    billboard.AlwaysOnTop = true
    billboard.Adornee     = char:FindFirstChild("Head") or char
    billboard.Parent      = game.CoreGui

    local nameLabel = Instance.new("TextLabel")
    nameLabel.Size = UDim2.new(1, 0, 0, 18)
    nameLabel.BackgroundTransparency = 1
    nameLabel.Text = player.Name
    nameLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
    nameLabel.TextStrokeTransparency = 0
    nameLabel.Font = Enum.Font.GothamBold
    nameLabel.TextSize = 14
    nameLabel.Parent = billboard

    local hpLabel = Instance.new("TextLabel")
    hpLabel.Size = UDim2.new(1, 0, 0, 14)
    hpLabel.Position = UDim2.new(0, 0, 0, 18)
    hpLabel.BackgroundTransparency = 1
    hpLabel.Text = "HP: 100"
    hpLabel.TextColor3 = Color3.fromRGB(0, 255, 0)
    hpLabel.TextStrokeTransparency = 0
    hpLabel.Font = Enum.Font.Gotham
    hpLabel.TextSize = 12
    hpLabel.Parent = billboard

    local distLabel = Instance.new("TextLabel")
    distLabel.Size = UDim2.new(1, 0, 0, 14)
    distLabel.Position = UDim2.new(0, 0, 0, 32)
    distLabel.BackgroundTransparency = 1
    distLabel.Text = "[0m]"
    distLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
    distLabel.TextStrokeTransparency = 0
    distLabel.Font = Enum.Font.Gotham
    distLabel.TextSize = 12
    distLabel.Parent = billboard

    ESPObjects[player] = {
        Highlight = highlight,
        Billboard = billboard,
        NameLabel = nameLabel,
        HpLabel   = hpLabel,
        DistLabel = distLabel,
    }

    -- Трейсер (Drawing API)
    if hasDrawing then
        local line = Drawing.new("Line")
        line.Thickness = 1.5
        line.Color     = Settings.TracerColor
        line.Transparency = 1
        line.Visible   = Settings.Enabled and Settings.ShowTracers
        line.ZIndex    = 2
        TracerObjs[player] = line
    end

    applyVisibility()
end

local function updateESP()
    if not Settings.Enabled then
        -- спрятать трейсеры если ESP выключен
        for _, line in pairs(TracerObjs) do
            if line then line.Visible = false end
        end
        return
    end

    local myChar = LocalPlayer.Character
    local myRoot = myChar and myChar:FindFirstChild("HumanoidRootPart")
    local viewportSize = Camera.ViewportSize
    local originX = viewportSize.X / 2
    local originY = viewportSize.Y

    for player, obj in pairs(ESPObjects) do
        local char = player.Character
        local root = char and char:FindFirstChild("HumanoidRootPart")
        local hum  = char and char:FindFirstChildOfClass("Humanoid")

        -- HP
        if obj.HpLabel then
            if hum then
                local hp = math.floor(hum.Health)
                obj.HpLabel.Text = "HP: " .. hp
                local pct = math.clamp(hp / math.max(hum.MaxHealth, 1), 0, 1)
                obj.HpLabel.TextColor3 = Color3.fromRGB(255 * (1 - pct), 255 * pct, 0)
            else
                obj.HpLabel.Text = "HP: ?"
            end
        end

        -- Дистанция
        if obj.DistLabel then
            if root and myRoot then
                local d = (root.Position - myRoot.Position).Magnitude
                obj.DistLabel.Text = "[" .. math.floor(d) .. "m]"
            else
                obj.DistLabel.Text = "[--]"
            end
        end

        -- Трейсер
        local line = TracerObjs[player]
        if line and hasDrawing then
            if root and Settings.ShowTracers then
                local screenPos, onScreen = Camera:WorldToViewportPoint(root.Position)
                if onScreen then
                    local head = char:FindFirstChild("Head") or root
                    local headScreen = Camera:WorldToViewportPoint(head.Position + Vector3.new(0, 0.5, 0))
                    line.From = Vector2.new(originX, originY)
                    line.To   = Vector2.new(headScreen.X, headScreen.Y)
                    line.Color = Settings.TracerColor
                    line.Visible = true
                else
                    line.Visible = false
                end
            else
                line.Visible = false
            end
        end
    end
end

-- Обработка игроков
local function onCharacterAdded(player)
    removeESP(player)
    task.wait(0.3)
    if Settings.Enabled then createESP(player) end
end

local function onPlayerAdded(player)
    player.CharacterAdded:Connect(function()
        onCharacterAdded(player)
    end)
    if player.Character and Settings.Enabled then
        createESP(player)
    end
end

for _, p in ipairs(Players:GetPlayers()) do onPlayerAdded(p) end
table.insert(Connections, Players.PlayerAdded:Connect(onPlayerAdded))
table.insert(Connections, Players.PlayerRemoving:Connect(removeESP))
table.insert(Connections, RunService.RenderStepped:Connect(updateESP))

--============================================================--
--                      GUI                                    --
--============================================================--
local ScreenGui = Instance.new("ScreenGui")
ScreenGui.Name = "CustomESP"
ScreenGui.ResetOnSpawn = false
ScreenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
ScreenGui.Parent = game.CoreGui

local MainFrame = Instance.new("Frame")
MainFrame.Size = UDim2.new(0, 260, 0, 420)
MainFrame.Position = UDim2.new(0, 20, 0, 100)
MainFrame.BackgroundColor3 = Color3.fromRGB(28, 28, 34)
MainFrame.BorderSizePixel = 0
MainFrame.Active = true
MainFrame.Draggable = true
MainFrame.Parent = ScreenGui
Instance.new("UICorner", MainFrame).CornerRadius = UDim.new(0, 10)

-- Title bar
local TitleBar = Instance.new("Frame")
TitleBar.Size = UDim2.new(1, 0, 0, 32)
TitleBar.BackgroundColor3 = Color3.fromRGB(18, 18, 24)
TitleBar.BorderSizePixel = 0
TitleBar.Parent = MainFrame
Instance.new("UICorner", TitleBar).CornerRadius = UDim.new(0, 10)

local TitleCover = Instance.new("Frame")
TitleCover.Size = UDim2.new(1, 0, 0, 12)
TitleCover.Position = UDim2.new(0, 0, 1, -12)
TitleCover.BackgroundColor3 = Color3.fromRGB(18, 18, 24)
TitleCover.BorderSizePixel = 0
TitleCover.Parent = TitleBar

local TitleLabel = Instance.new("TextLabel")
TitleLabel.Size = UDim2.new(1, -80, 1, 0)
TitleLabel.Position = UDim2.new(0, 12, 0, 0)
TitleLabel.BackgroundTransparency = 1
TitleLabel.Text = "ESP Menu"
TitleLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
TitleLabel.Font = Enum.Font.GothamBold
TitleLabel.TextSize = 14
TitleLabel.TextXAlignment = Enum.TextXAlignment.Left
TitleLabel.Parent = TitleBar

local function makeTitleBtn(text, xOff, col)
    local b = Instance.new("TextButton")
    b.Size = UDim2.new(0, 26, 0, 26)
    b.Position = UDim2.new(1, xOff, 0.5, -13)
    b.BackgroundColor3 = col
    b.Text = text
    b.TextColor3 = Color3.fromRGB(255, 255, 255)
    b.Font = Enum.Font.GothamBold
    b.TextSize = 14
    b.Parent = TitleBar
    Instance.new("UICorner", b).CornerRadius = UDim.new(0, 6)
    return b
end

local CloseBtn = makeTitleBtn("X", -32, Color3.fromRGB(200, 55, 55))
local MinBtn   = makeTitleBtn("−", -64, Color3.fromRGB(210, 160, 50))

-- Content
local Content = Instance.new("Frame")
Content.Size = UDim2.new(1, -20, 1, -45)
Content.Position = UDim2.new(0, 10, 0, 40)
Content.BackgroundTransparency = 1
Content.Parent = MainFrame

--=============== Toggle factory ============================--
local function createToggle(text, yPos, getter, setter)
    local row = Instance.new("Frame")
    row.Size = UDim2.new(1, 0, 0, 28)
    row.Position = UDim2.new(0, 0, 0, yPos)
    row.BackgroundTransparency = 1
    row.Parent = Content

    local lbl = Instance.new("TextLabel")
    lbl.Size = UDim2.new(0.65, 0, 1, 0)
    lbl.BackgroundTransparency = 1
    lbl.Text = text
    lbl.TextColor3 = Color3.fromRGB(230, 230, 235)
    lbl.Font = Enum.Font.Gotham
    lbl.TextSize = 13
    lbl.TextXAlignment = Enum.TextXAlignment.Left
    lbl.Parent = row

    local toggle = Instance.new("TextButton")
    toggle.Size = UDim2.new(0, 46, 0, 22)
    toggle.Position = UDim2.new(1, -46, 0.5, -11)
    toggle.BackgroundColor3 = getter() and Color3.fromRGB(80, 180, 80) or Color3.fromRGB(55, 55, 62)
    toggle.Text = ""
    toggle.Parent = row
    Instance.new("UICorner", toggle).CornerRadius = UDim.new(0, 11)

    local knob = Instance.new("Frame")
    knob.Size = UDim2.new(0, 16, 0, 16)
    knob.Position = getter() and UDim2.new(1, -19, 0.5, -8) or UDim2.new(0, 3, 0.5, -8)
    knob.BackgroundColor3 = Color3.fromRGB(230, 230, 230)
    knob.Parent = toggle
    Instance.new("UICorner", knob).CornerRadius = UDim.new(1, 0)

    toggle.MouseButton1Click:Connect(function()
        local newState = not getter()
        setter(newState)
        TweenService:Create(knob, TweenInfo.new(0.15), {
            Position = newState and UDim2.new(1, -19, 0.5, -8) or UDim2.new(0, 3, 0.5, -8)
        }):Play()
        TweenService:Create(toggle, TweenInfo.new(0.15), {
            BackgroundColor3 = newState and Color3.fromRGB(80, 180, 80) or Color3.fromRGB(55, 55, 62)
        }):Play()
    end)
end

createToggle("Включить ESP", 0,
    function() return Settings.Enabled end,
    function(v)
        Settings.Enabled = v
        if v then
            for _, p in ipairs(Players:GetPlayers()) do createESP(p) end
        end
        applyVisibility()
    end)

createToggle("Ник", 34,
    function() return Settings.ShowName end,
    function(v) Settings.ShowName = v; applyVisibility() end)

createToggle("HP (здоровье)", 68,
    function() return Settings.ShowHealth end,
    function(v) Settings.ShowHealth = v; applyVisibility() end)

createToggle("Дистанция (метры)", 102,
    function() return Settings.ShowDistance end,
    function(v) Settings.ShowDistance = v; applyVisibility() end)

createToggle("Трейсеры (линии)", 136,
    function() return Settings.ShowTracers end,
    function(v) Settings.ShowTracers = v; applyVisibility() end)

--=============== Утилита для выбора цвета ==================--
local colorPalette = {
    Color3.fromRGB(255, 60, 60),    -- красный
    Color3.fromRGB(255, 140, 40),   -- оранжевый
    Color3.fromRGB(255, 230, 60),   -- жёлтый
    Color3.fromRGB(60, 255, 60),    -- зелёный
    Color3.fromRGB(60, 180, 255),   -- голубой
    Color3.fromRGB(60, 100, 255),   -- синий
    Color3.fromRGB(180, 60, 255),   -- фиолетовый
    Color3.fromRGB(255, 80, 255),   -- розовый
    Color3.fromRGB(255, 255, 255),  -- белый
}

local function createColorPicker(titleText, yPos, onPick)
    local lbl = Instance.new("TextLabel")
    lbl.Size = UDim2.new(1, 0, 0, 18)
    lbl.Position = UDim2.new(0, 0, 0, yPos)
    lbl.BackgroundTransparency = 1
    lbl.Text = titleText
    lbl.TextColor3 = Color3.fromRGB(230, 230, 235)
    lbl.Font = Enum.Font.Gotham
    lbl.TextSize = 13
    lbl.TextXAlignment = Enum.TextXAlignment.Left
    lbl.Parent = Content

    local row = Instance.new("Frame")
    row.Size = UDim2.new(1, 0, 0, 26)
    row.Position = UDim2.new(0, 0, 0, yPos + 20)
    row.BackgroundTransparency = 1
    row.Parent = Content

    local btns = {}
    local function refresh()
        for _, b in ipairs(btns) do
            b.UIStroke.Transparency = b.Tag and b.Tag.Active and 0 or 0.85
        end
    end

    for i, c in ipairs(colorPalette) do
        local btn = Instance.new("TextButton")
        btn.Size = UDim2.new(0, 22, 0, 22)
        btn.Position = UDim2.new(0, (i - 1) * 26, 0, 2)
        btn.BackgroundColor3 = c
        btn.Text = ""
        btn.Parent = row
        Instance.new("UICorner", btn).CornerRadius = UDim.new(0, 5)

        local stroke = Instance.new("UIStroke", btn)
        stroke.Thickness = 2
        stroke.Color = Color3.fromRGB(255, 255, 255)
        stroke.Transparency = 0.85

        btn.Tag = { Active = false }
        table.insert(btns, btn)

        btn.MouseButton1Click:Connect(function()
            for _, b in ipairs(btns) do b.Tag.Active = false end
            btn.Tag.Active = true
            refresh()
            onPick(c)
        end)
    end

    return { buttons = btns, refresh = refresh, setActive = function(c)
        for _, b in ipairs(btns) do
            b.Tag.Active = (b.BackgroundColor3 == c)
        end
        refresh()
    end }
end

--=============== Палитра Cham ==============================--
local chamPicker = createColorPicker("Цвет Cham'а:", 174, function(c)
    Settings.ChamColor = c
    for _, obj in pairs(ESPObjects) do
        if obj.Highlight then
            obj.Highlight.FillColor = c
            obj.Highlight.OutlineColor = c
        end
    end
end)
chamPicker.setActive(Settings.ChamColor)

--=============== Палитра Трейсеров =========================--
local tracerPicker = createColorPicker("Цвет Трейсеров:", 224, function(c)
    Settings.TracerColor = c
    for _, line in pairs(TracerObjs) do
        if line then line.Color = c end
    end
end)
tracerPicker.setActive(Settings.TracerColor)

--============================================================--
--       Кнопка Свернуть  /  Кнопка Закрыть                    --
--============================================================--
local FULL_H = 420
local minimized = false
MinBtn.MouseButton1Click:Connect(function()
    minimized = not minimized
    Content.Visible = not minimized
    TweenService:Create(MainFrame, TweenInfo.new(0.2), {
        Size = minimized and UDim2.new(0, 260, 0, 32) or UDim2.new(0, 260, 0, FULL_H)
    }):Play()
end)

CloseBtn.MouseButton1Click:Connect(function()
    -- Отключаем ВСЕ функции
    Settings.Enabled = false
    for player, _ in pairs(ESPObjects) do removeESP(player) end
    for _, line in pairs(TracerObjs) do
        if line and line.Remove then line:Remove() end
    end
    TracerObjs = {}
    for _, conn in ipairs(Connections) do
        pcall(function() conn:Disconnect() end)
    end
    ScreenGui:Destroy()
end)

print("[ESP] Загружено ✔ | Drawing API: " .. tostring(hasDrawing))