Загрузка данных
-- !!!Tab_kdm1eHvH.lua
-- Положи в lua/autorun/client/!!!Tab_kdm1eHvH.lua
-- ============ Настройки ============
local COL_BG = Color(10, 10, 15, 245)
local COL_HEADER = Color(35, 35, 48, 255)
local COL_ROW = Color(22, 22, 30, 220)
local COL_ROW_ALT = Color(28, 28, 36, 220)
local COL_ACCENT = Color(220, 40, 40)
local COL_TEXT = Color(235, 235, 235)
local COL_TEXT_DIM = Color(150, 150, 160)
local PANEL_W = 860
local HEADER_H = 48
local ROW_H = 54
local PAD_X = 20
local ACCENT_H = 4
-- ============ Шрифты ============
surface.CreateFont("tab_title", { font = "Roboto", size = 30, weight = 900, extended = true })
surface.CreateFont("tab_header", { font = "Roboto", size = 15, weight = 700, extended = true })
surface.CreateFont("tab_nick", { font = "Roboto", size = 18, weight = 600, extended = true })
surface.CreateFont("tab_value", { font = "Roboto", size = 18, weight = 700, extended = true })
surface.CreateFont("tab_small", { font = "Roboto", size = 14, weight = 500, extended = true })
-- ============ Утилиты ============
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 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 DrawAvatar(ply, x, y, size)
local avatar = ply:GetAvatar()
if avatar then
surface.SetDrawColor(255, 255, 255, 255)
surface.SetMaterial(avatar)
surface.DrawTexturedRect(x, y, size, size)
else
surface.SetDrawColor(50, 50, 60, 255)
surface.DrawRect(x, y, size, size)
end
surface.SetDrawColor(GetPingColor(ply:Ping()))
surface.DrawOutlinedRect(x - 1, y - 1, size + 2, size + 2, 2)
end
-- ============ Отрисовка таба ============
local function DrawScoreboard()
local players = GetSortedPlayers()
local count = #players
local rowTotal = math.max(1, count)
local panelH = HEADER_H + rowTotal * ROW_H + 30
local panelW = math.min(PANEL_W, ScrW() - 200)
local maxH = ScrH() - 260
if panelH > maxH then panelH = maxH end
local x = (ScrW() - panelW) / 2
local y = (ScrH() - panelH) / 2
-- ===== Заголовок kdm1eHvH над панелью =====
surface.SetFont("tab_title")
local t1, t2 = "kdm1e", "HvH"
local w1 = surface.GetTextSize(t1)
local w2 = surface.GetTextSize(t2)
local totalW = w1 + w2
local titleX = x + panelW / 2 - totalW / 2
local titleY = y - 46
draw.SimpleText(t1, "tab_title", titleX, titleY, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
draw.SimpleText(t2, "tab_title", titleX + w1, titleY, COL_ACCENT, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
-- ===== Тень =====
surface.SetDrawColor(0, 0, 0, 200)
surface.DrawRect(x + 5, y + 5, panelW, panelH)
-- ===== Фон =====
surface.SetDrawColor(COL_BG)
surface.DrawRect(x, y, panelW, panelH)
-- ===== Верхняя красная полоска =====
surface.SetDrawColor(COL_ACCENT)
surface.DrawRect(x, y, panelW, ACCENT_H)
-- ===== Шапка =====
surface.SetDrawColor(COL_HEADER)
surface.DrawRect(x, y + ACCENT_H, panelW, HEADER_H)
-- Координаты колонок
local colX_avatar = x + PAD_X
local colX_nick = x + PAD_X + ROW_H + 14
local colX_kills = x + panelW - 260
local colX_ping = x + panelW - 160
local colX_id = x + panelW - 70
-- Заголовки
local headerCY = y + ACCENT_H + HEADER_H / 2
draw.SimpleText("ИГРОК", "tab_header", colX_nick, headerCY, COL_TEXT_DIM, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
draw.SimpleText("УБИЙСТВА", "tab_header", colX_kills, headerCY, COL_TEXT_DIM, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
draw.SimpleText("ПИНГ", "tab_header", colX_ping, headerCY, COL_TEXT_DIM, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
draw.SimpleText("ID", "tab_header", colX_id, headerCY, COL_TEXT_DIM, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
-- ===== Строки =====
local rowsStartY = y + ACCENT_H + HEADER_H
local maxRows = math.floor((panelH - ACCENT_H - HEADER_H) / ROW_H)
local visible = math.min(count, maxRows)
if visible == 0 then
draw.SimpleText("На сервере никого нет", "tab_nick",
x + panelW / 2, rowsStartY + ROW_H / 2,
COL_TEXT_DIM, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
return
end
for i = 1, visible do
local ply = players[i]
local rowY = rowsStartY + (i - 1) * ROW_H
local isLocal = (ply == LocalPlayer())
-- Фон строки (чередование)
surface.SetDrawColor(i % 2 == 1 and COL_ROW or COL_ROW_ALT)
surface.DrawRect(x, rowY, panelW, ROW_H)
-- Своя строка — только слева тонкая красная полоска
if isLocal then
surface.SetDrawColor(COL_ACCENT)
surface.DrawRect(x, rowY, 3, ROW_H)
end
-- Разделитель
surface.SetDrawColor(0, 0, 0, 100)
surface.DrawRect(x, rowY + ROW_H - 1, panelW, 1)
local cy = rowY + ROW_H / 2
-- Аватар
local avSize = ROW_H - 14
DrawAvatar(ply, colX_avatar, rowY + 7, avSize)
-- Ник
local nickColor = isLocal and Color(255, 220, 220) or COL_TEXT
draw.SimpleText(ply:Nick(), "tab_nick", colX_nick, cy,
nickColor, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
-- Убийства
local kills = ply:GetNWInt("PersistentKills", ply:Frags())
draw.SimpleText(tostring(kills), "tab_value", colX_kills, cy,
COL_ACCENT, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
-- Пинг
local ping = ply:Ping()
draw.SimpleText(ping .. " ms", "tab_value", colX_ping, cy,
GetPingColor(ping), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
-- ID
draw.SimpleText(tostring(ply:UserID()), "tab_small", colX_id, cy,
COL_TEXT_DIM, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
end
-- ===== Футер =====
local footerY = y + panelH - 22
draw.SimpleText("Игроков: " .. count, "tab_small", x + PAD_X, footerY,
COL_TEXT_DIM, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
draw.SimpleText(GetHostName() or "", "tab_small", x + panelW - PAD_X, footerY,
COL_TEXT_DIM, TEXT_ALIGN_RIGHT, TEXT_ALIGN_TOP)
end
-- ============ Хуки ============
hook.Add("HUDPaint", "Tab_kdm1eHvH", function()
if not input.IsKeyDown(KEY_TAB) then return end
DrawScoreboard()
end)
-- Скрываем стандартный таб GMod
hook.Add("HUDShouldDraw", "Tab_kdm1eHvH_HideDefault", function(name)
if name == "CHudPlayerList" then return false end
end)
-- Отключаем scoreboard геймода (DarkRP + DarkRP-модификации + админ-моды)
hook.Add("InitPostEntity", "Tab_kdm1eHvH_BlockGMScoreboard", function()
timer.Simple(2, function()
if not GAMEMODE then return end
GAMEMODE.ScoreboardShow = function() end
GAMEMODE.ScoreboardHide = function() end
GAMEMODE.ScoreboardPaint = function() end
GAMEMODE.ScoreboardOpen = function() end
end)
end)