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


-- Tab_kdm1eHvH.lua
-- Положи в lua/autorun/client/Tab_kdm1eHvH.lua

-- ============ Настройки ============
local TAB_BG        = Color(15, 15, 20, 240)      -- фон панели
local ROW_COLOR     = Color(30, 30, 40, 200)      -- цвет строк
local ROW_COLOR_ALT = Color(25, 25, 33, 200)      -- цвет строк (чередование)
local HEADER_COLOR  = Color(40, 40, 55, 255)      -- цвет шапки
local ACCENT        = Color(220, 40, 40)          -- красный акцент (HvH)
local TEXT_COLOR    = Color(230, 230, 230)
local TEXT_DIM      = Color(160, 160, 160)

-- ============ Шрифты ============
surface.CreateFont("Tab_Title", {
    font = "Roboto", size = 26, weight = 800, extended = true
})
surface.CreateFont("Tab_Header", {
    font = "Roboto", size = 17, weight = 700, extended = true
})
surface.CreateFont("Tab_Text", {
    font = "Roboto", size = 16, weight = 500, extended = true
})
surface.CreateFont("Tab_Ping", {
    font = "Roboto", size = 15, weight = 600, extended = true
})

-- ============ Утилиты ============
local function GetSortedPlayers()
    local tbl = {}

    for _, ply in ipairs(player.GetAll()) do
        if not IsValid(ply) then continue end
        if ply:IsBot() then continue end
        table.insert(tbl, ply)
    end

    table.sort(tbl, function(a, b)
        local ka = a:GetNWInt("PersistentKills", a:Frags())
        local kb = b:GetNWInt("PersistentKills", b:Frags())
        if ka ~= kb then return ka > kb end
        return a:Nick() < b:Nick()
    end)

    return tbl
end

local function GetPingColor(ping)
    if ping < 60 then return Color(80, 220, 120) end
    if ping < 120 then return Color(240, 200, 60) end
    return Color(240, 80, 80)
end

local function DrawAvatar(ply, x, y, size)
    local avatar = ply:GetAvatar()
    if not avatar then return end

    surface.SetDrawColor(255, 255, 255)
    surface.SetMaterial(avatar)
    surface.DrawTexturedRect(x, y, size, size)
end

local function DrawAvatarRounded(ply, x, y, size)
    -- Рисуем аватарку внутри рамки с обводкой
    surface.SetDrawColor(255, 255, 255, 255)
    DrawAvatar(ply, x, y, size)

    -- Обводка (цвет по пингу)
    local ping = ply:Ping()
    surface.SetDrawColor(GetPingColor(ping))
    surface.DrawOutlinedRect(x - 1, y - 1, size + 2, size + 2, 2)
end

-- ============ Таб ============
local function DrawScoreboard()
    local players = GetSortedPlayers()

    -- Размеры панели
    local width = math.min(900, ScrW() - 100)
    local rowH = 44
    local headerH = 50
    local padding = 20
    local topOffset = 100
    local bottomOffset = 100

    local height = headerH + padding * 2 + #players * (rowH + 4)
    if height > ScrH() - topOffset - bottomOffset then
        height = ScrH() - topOffset - bottomOffset
    end

    local x = (ScrW() - width) / 2
    local y = (ScrH() - height) / 2

    -- ===== Заголовок сверху: kdm1eHvH =====
    surface.SetFont("Tab_Title")
    local title1 = "kdm1e"
    local title2 = "HvH"
    local w1 = surface.GetTextSize(title1)
    local w2 = surface.GetTextSize(title2)
    local titleW = w1 + w2

    local titleY = y - 45
    draw.SimpleText(title1, "Tab_Title", x + (width / 2) - (titleW / 2), titleY,
        Color(255, 255, 255), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
    draw.SimpleText(title2, "Tab_Title", x + (width / 2) - (titleW / 2) + w1, titleY,
        ACCENT, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)

    -- ===== Задний фон с тенью =====
    surface.SetDrawColor(0, 0, 0, 180)
    surface.DrawRect(x + 4, y + 4, width, height)

    surface.SetDrawColor(TAB_BG)
    surface.DrawRect(x, y, width, height)

    -- Верхняя красная полоса (акцент)
    surface.SetDrawColor(ACCENT)
    surface.DrawRect(x, y, width, 3)

    -- Рамка
    surface.SetDrawColor(60, 60, 80, 255)
    surface.DrawOutlinedRect(x, y, width, height, 1)

    -- ===== Шапка таблицы =====
    surface.SetDrawColor(HEADER_COLOR)
    surface.DrawRect(x, y + 3, width, headerH)

    -- Заголовки колонок
    local colAvatar   = x + 20
    local colNick     = x + 20 + 60
    local colKills    = x + width - 220
    local colPing     = x + width - 110
    local colID       = x + width - 50

    draw.SimpleText("ИГРОК", "Tab_Header", colNick, y + 3 + headerH / 2,
        TEXT_DIM, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
    draw.SimpleText("УБИЙСТВА", "Tab_Header", colKills, y + 3 + headerH / 2,
        TEXT_DIM, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
    draw.SimpleText("ПИНГ", "Tab_Header", colPing, y + 3 + headerH / 2,
        TEXT_DIM, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
    draw.SimpleText("ID", "Tab_Header", colID, y + 3 + headerH / 2,
        TEXT_DIM, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)

    -- ===== Строки =====
    local startY = y + 3 + headerH + padding / 2
    local maxRows = math.floor((height - headerH - padding) / (rowH + 4))

    for i = 1, math.min(#players, maxRows) do
        local ply = players[i]
        local rowY = startY + (i - 1) * (rowH + 4)

        -- Фон строки (чередование)
        surface.SetDrawColor(i % 2 == 1 and ROW_COLOR or ROW_COLOR_ALT)
        surface.DrawRect(x + padding / 2, rowY, width - padding, rowH)

        -- Подсветка для локального игрока
        if ply == LocalPlayer() then
            surface.SetDrawColor(ACCENT.r, ACCENT.g, ACCENT.b, 30)
            surface.DrawRect(x + padding / 2, rowY, width - padding, rowH)

            surface.SetDrawColor(ACCENT)
            surface.DrawRect(x + padding / 2, rowY, 3, rowH)
        end

        -- Аватарка
        local avSize = rowH - 12
        DrawAvatarRounded(ply, colAvatar, rowY + 6, avSize)

        -- Ник
        local nickColor = ply == LocalPlayer() and Color(255, 220, 220) or TEXT_COLOR
        draw.SimpleText(ply:Nick(), "Tab_Text", colNick, rowY + rowH / 2,
            nickColor, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)

        -- Убийства
        local kills = ply:GetNWInt("PersistentKills", ply:Frags())
        draw.SimpleText(tostring(kills), "Tab_Text", colKills, rowY + rowH / 2,
            Color(255, 90, 90), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)

        -- Пинг
        local ping = ply:Ping()
        draw.SimpleText(tostring(ping) .. " ms", "Tab_Ping", colPing, rowY + rowH / 2,
            GetPingColor(ping), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)

        -- ID
        draw.SimpleText(tostring(ply:UserID()), "Tab_Ping", colID, rowY + rowH / 2,
            TEXT_DIM, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
    end

    -- ===== Футер =====
    local footerY = y + height - 22
    draw.SimpleText("Игроков: " .. #players, "Tab_Ping", x + 20, footerY,
        TEXT_DIM, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)

    local serverName = GetHostName() or "Garry's Mod"
    draw.SimpleText(serverName, "Tab_Ping", x + width - 20, footerY,
        TEXT_DIM, TEXT_ALIGN_RIGHT, TEXT_ALIGN_TOP)
end

-- ============ Хук отрисовки ============
hook.Add("HUDPaint", "Tab_kdm1eHvH", function()
    if not input.IsKeyDown(KEY_TAB) then return end
    -- Не показываем таб, если у игрока открыто меню/чат
    if gui.IsGameUIVisible() then return end

    DrawScoreboard()
end)

-- Скрываем стандартный таб GMod
hook.Add("HUDShouldDraw", "Tab_kdm1eHvH_Hide", function(name)
    if name == "CHudPlayerList" then return false end
end)