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


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

local MAP_SIZE = 200
local MAP_MARGIN = 20
local WORLD_SIZE = 16384
local PANEL_GAP = 10

-- ============ Отключение HUD DarkRP ============
hook.Add("InitPostEntity", "OverrideDarkRPHUD", function()
    timer.Simple(2, function()
        if not GAMEMODE then return end
        GAMEMODE.HUDPaint = function() end
        GAMEMODE.HUDPaintBackground = function() end
    end)
end)

-- ============ Миникарта ============
local function DrawMinimap(x, y, w, h)
    surface.SetDrawColor(0, 0, 0, 180)
    surface.DrawRect(x, y, w, h)

    surface.SetDrawColor(255, 255, 255, 80)
    surface.DrawOutlinedRect(x, y, w, h, 1)

    local scaleX = w / WORLD_SIZE
    local scaleY = h / WORLD_SIZE
    local lp = LocalPlayer()

    for _, ply in ipairs(player.GetAll()) do
        if not IsValid(ply) then continue end

        local pos = ply:GetPos()
        local px = x + (pos.x + WORLD_SIZE / 2) * scaleX
        local py = y + (WORLD_SIZE / 2 - pos.y) * scaleY

        if px < x or px > x + w or py < y or py > y + h then continue end

        if ply == lp then
            -- ===== Стрелка направления для локального игрока =====
            local ang = lp:EyeAngles().yaw
            local rad = math.rad(ang)

            -- Направление "вперёд" на миникарте (y инвертирован)
            local dx = math.sin(rad)
            local dy = -math.cos(rad)

            -- Перпендикуляр
            local px_dir = -dy
            local py_dir = dx

            local size = 6

            local tipX = px + dx * size
            local tipY = py + dy * size
            local leftX = px - dx * size * 0.5 + px_dir * size * 0.6
            local leftY = py - dy * size * 0.5 + py_dir * size * 0.6
            local rightX = px - dx * size * 0.5 - px_dir * size * 0.6
            local rightY = py - dy * size * 0.5 - py_dir * size * 0.6

            surface.SetDrawColor(0, 255, 0, 255)
            surface.DrawPoly({
                { x = tipX,   y = tipY   },
                { x = leftX,  y = leftY  },
                { x = rightX, y = rightY },
            })
        elseif ply:Team() == lp:Team() then
            surface.SetDrawColor(100, 150, 255, 255)
            surface.DrawRect(px - 2, py - 2, 4, 4)
        else
            surface.SetDrawColor(255, 60, 60, 255)
            surface.DrawRect(px - 2, py - 2, 4, 4)
        end
    end
end

-- ============ Полоска HP ============
local function DrawHealthBar(x, y, w, h, hp, maxhp)
    local frac = math.Clamp(hp / maxhp, 0, 1)

    -- фон
    surface.SetDrawColor(0, 0, 0, 200)
    surface.DrawRect(x, y, w, h)

    -- заполнение (цвет от красного к зелёному)
    local r = math.Round(255 * (1 - frac))
    local g = math.Round(255 * frac)
    surface.SetDrawColor(r, g, 0, 230)
    surface.DrawRect(x + 1, y + 1, (w - 2) * frac, h - 2)

    -- рамка
    surface.SetDrawColor(255, 255, 255, 80)
    surface.DrawOutlinedRect(x, y, w, h, 1)

    -- текст
    draw.SimpleText(
        math.max(0, math.floor(hp)) .. " HP",
        "DermaDefaultBold",
        x + w / 2, y + h / 2,
        Color(255, 255, 255),
        TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER
    )
end

-- ============ HUD патронов ============
local function DrawAmmoHUD()
    local ply = LocalPlayer()
    local wep = ply:GetActiveWeapon()
    if not IsValid(wep) then return end

    local clip = wep:Clip1()
    local reserve = ply:GetAmmoCount(wep:GetPrimaryAmmoType())

    -- если оружие без патронов (например кулаки) — не показываем
    if clip < 0 and reserve < 0 then return end

    local boxW, boxH = 180, 70
    local boxX = ScrW() - boxW - MAP_MARGIN
    local boxY = ScrH() - boxH - MAP_MARGIN

    -- фон
    surface.SetDrawColor(0, 0, 0, 180)
    surface.DrawRect(boxX, boxY, boxW, boxH)

    -- рамка
    surface.SetDrawColor(255, 255, 255, 80)
    surface.DrawOutlinedRect(boxX, boxY, boxW, boxH, 1)

    -- название оружия
    local wepName = wep:GetPrintName() or wep:GetClass()
    draw.SimpleText(
        wepName,
        "DermaDefault",
        boxX + boxW / 2, boxY + 8,
        Color(180, 180, 180),
        TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP
    )

    -- патроны в обойме (крупно)
    draw.SimpleText(
        tostring(clip),
        "DermaLarge",
        boxX + boxW / 2 - 20, boxY + 30,
        Color(255, 255, 255),
        TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP
    )

    -- слэш
    draw.SimpleText(
        "/",
        "DermaLarge",
        boxX + boxW / 2 + 10, boxY + 30,
        Color(120, 120, 120),
        TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP
    )

    -- запас
    draw.SimpleText(
        tostring(reserve),
        "DermaLarge",
        boxX + boxW / 2 + 40, boxY + 30,
        Color(200, 200, 200),
        TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP
    )
end

-- ============ Логотип справа сверху ============
local function DrawLogo()
    local text1 = "kdm1e"
    local text2 = "HvH"

    local font = "DermaDefaultBold"

    surface.SetFont(font)
    local w1 = surface.GetTextSize(text1)
    local w2 = surface.GetTextSize(text2)
    local totalW = w1 + w2

    local x = ScrW() - totalW - MAP_MARGIN
    local y = MAP_MARGIN

    draw.SimpleText(text1, font, x, y, Color(255, 255, 255), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
    draw.SimpleText(text2, font, x + w1, y, Color(255, 40, 40), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
end

-- ============ Основной HUD ============
hook.Add("HUDPaint", "MyCustomHUD", function()
    local ply = LocalPlayer()
    if not IsValid(ply) then return end

    -- Координаты
    local mapX = MAP_MARGIN
    local mapY = ScrH() - MAP_SIZE - MAP_MARGIN

    -- Миникарта
    DrawMinimap(mapX, mapY, MAP_SIZE, MAP_SIZE)

    -- Инфо-панель справа от карты
    local boxX = mapX + MAP_SIZE + PANEL_GAP
    local boxY = mapY
    local boxW = 240
    local boxH = MAP_SIZE

    surface.SetDrawColor(0, 0, 0, 180)
    surface.DrawRect(boxX, boxY, boxW, boxH)

    surface.SetDrawColor(255, 255, 255, 80)
    surface.DrawOutlinedRect(boxX, boxY, boxW, boxH, 1)

    -- Ник
    draw.SimpleText("Ник:", "DermaDefaultBold",
        boxX + 12, boxY + 12, Color(180, 180, 180),
        TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)

    draw.SimpleText(ply:Nick(), "DermaDefaultBold",
        boxX + 12, boxY + 32, Color(255, 255, 255),
        TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)

    -- Разделитель
    surface.SetDrawColor(255, 255, 255, 40)
    surface.DrawRect(boxX + 10, boxY + 60, boxW - 20, 1)

    -- Убийства
    draw.SimpleText("Убийств:", "DermaDefaultBold",
        boxX + 12, boxY + 75, Color(180, 180, 180),
        TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)

    draw.SimpleText(
        tostring(ply:GetNWInt("PersistentKills", ply:Frags())),
        "DermaDefaultBold",
        boxX + 12, boxY + 95, Color(255, 90, 90),
        TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)

    -- Разделитель
    surface.SetDrawColor(255, 255, 255, 40)
    surface.DrawRect(boxX + 10, boxY + 125, boxW - 20, 1)

    -- Полоска HP
    local hp = ply:Health()
    local maxhp = ply:GetMaxHealth()

    draw.SimpleText("Здоровье:", "DermaDefaultBold",
        boxX + 12, boxY + 138, Color(180, 180, 180),
        TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)

    DrawHealthBar(boxX + 12, boxY + 160, boxW - 24, 20, hp, maxhp)

    -- HUD патронов
    DrawAmmoHUD()

    -- Логотип справа сверху
    DrawLogo()
end)

-- ============ Скрываем стандартный HUD GMod ============
hook.Add("HUDShouldDraw", "HideDefaultHUD", function(name)
    -- Оставляем чат, уведомления, тим-чат и т.д.
    if name == "CHudHealth" then return false end
    if name == "CHudBattery" then return false end
    if name == "CHudAmmo" then return false end
    if name == "CHudSecondaryAmmo" then return false end
    -- можно добавить ещё, если что-то мешает
end)