add sborka

This commit is contained in:
2026-03-31 10:27:04 +03:00
commit f5e5f56c84
2345 changed files with 382127 additions and 0 deletions

View File

@@ -0,0 +1,492 @@
surface.CreateFont("MilitaryHUD_Small", {
font = "Montserrat",
size = 16,
weight = 400
})
surface.CreateFont("MilitaryHUD_SmallBold", {
font = "Montserrat",
size = 16,
weight = 500
})
surface.CreateFont("MilitaryHUD_Medium", {
font = "Montserrat",
size = 18,
weight = 400
})
surface.CreateFont("MilitaryHUD_MediumBold", {
font = "Montserrat",
size = 18,
weight = 500
})
surface.CreateFont("MilitaryHUD_Large", {
font = "Montserrat",
size = 28,
weight = 500
})
local Colors = {
white = Color(255, 255, 255),
white_half = Color(255, 255, 255, 128),
green = Color(84, 147, 90),
dark_green = Color(52, 91, 60),
darker_green = Color(35, 53, 29),
gray = Color(193, 193, 193),
gray_dark = Color(94, 94, 94),
gray_light = Color(213, 213, 213)
}
local PLUGIN = PLUGIN
-- Масштабирование HUD
function GetScale()
local scale = ScrH() / 1080
return math.Clamp(scale, 0.5, 2.0)
end
function ScaleSize(val)
return math.max(1, math.Round(val * GetScale()))
end
function ScalePos(val)
return math.Round(val * GetScale())
end
Colors = {
white = Color(255, 255, 255),
white_half = Color(255, 255, 255, 128),
green = Color(84, 147, 90),
dark_green = Color(52, 91, 60),
darker_green = Color(35, 53, 29),
gray = Color(193, 193, 193),
gray_dark = Color(94, 94, 94),
gray_light = Color(213, 213, 213),
overlay = Color(0, 0, 0, 180)
}
local cachedScale = 0
function CreateHUDFonts()
local currentScale = GetScale()
if math.abs(currentScale - cachedScale) < 0.01 then return end
cachedScale = currentScale
surface.CreateFont("MilitaryHUD_Small", {
font = "Montserrat",
size = ScaleSize(16),
weight = 400
})
surface.CreateFont("MilitaryHUD_SmallBold", {
font = "Montserrat",
size = ScaleSize(16),
weight = 500
})
surface.CreateFont("MilitaryHUD_Medium", {
font = "Montserrat",
size = ScaleSize(18),
weight = 400
})
surface.CreateFont("MilitaryHUD_MediumBold", {
font = "Montserrat",
size = ScaleSize(18),
weight = 500
})
surface.CreateFont("MilitaryHUD_Large", {
font = "Montserrat",
size = ScaleSize(28),
weight = 500
})
end
CreateHUDFonts()
hook.Add("OnScreenSizeChanged", "MilitaryHUD_UpdateFonts", CreateHUDFonts)
local healthLerp = 100
local armorLerp = 100
local ammoLerp = 30
local hungerLerp = 100
local thirstLerp = 100
local staminaLerp = 100
-- Материалы (пути будут заполнены позже)
local logoMaterial = Material("materials/ft_ui/military/vnu/hud/logo.png")
local radioMaterial = Material("materials/ft_ui/military/vnu/hud/radio.png")
local clockMaterial = Material("materials/ft_ui/military/vnu/hud/cloak.png")
local rankMaterial = Material("materials/ft_ui/military/vnu/hud/rank.png")
local foodMaterial = Material("materials/ft_ui/military/vnu/hud/food.png")
local thirstMaterial = Material("materials/ft_ui/military/vnu/hud/thirst.png")
function PLUGIN:GetRadioStatus()
if ix.plugin and ix.plugin.list and ix.plugin.list["radio"] then
return ix.plugin.list["radio"]:IsListening(LocalPlayer())
end
return false
end
function PLUGIN:GetFormattedTime()
if StormFox2 and StormFox2.Time then
local hours = StormFox2.Time.GetHours() or 12
local minutes = StormFox2.Time.GetMinutes() or 0
local seconds = StormFox2.Time.GetSeconds() or 0
return string.format("%02d:%02d:%02d", hours, minutes, seconds)
else
-- Fallback на системное время
return os.date("%H:%M:%S")
end
end
function PLUGIN:LerpColor(progress, color1, color2)
return Color(
Lerp(progress, color1.r, color2.r),
Lerp(progress, color1.g, color2.g),
Lerp(progress, color1.b, color2.b),
Lerp(progress, color1.a, color2.a)
)
end
function PLUGIN:DrawHealthBar(x, y, w, h)
local health = LocalPlayer():Health()
healthLerp = Lerp(FrameTime() * 5, healthLerp, health)
local healthPercent = math.Clamp(healthLerp / 100, 0, 1)
draw.SimpleText("Здоровье", "MilitaryHUD_Small", x, y - ScalePos(25), Colors.white_half, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
draw.SimpleText(math.Round(healthLerp), "MilitaryHUD_SmallBold", x + w, y - ScalePos(25), Colors.white, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER)
local barWidth = w * healthPercent
surface.SetDrawColor(Colors.gray)
surface.DrawRect(x, y, w, h)
for i = 0, barWidth - 1 do
local progress = i / w
local color = self:LerpColor(progress, Colors.darker_green, Colors.dark_green)
surface.SetDrawColor(color)
surface.DrawRect(x + i, y, 1, h)
end
local segmentWidth = w / 3
for i = 1, 2 do
surface.SetDrawColor(Color(0, 0, 0, 100))
surface.DrawRect(x + segmentWidth * i, y, 1, h)
end
end
function PLUGIN:DrawArmorBar(x, y, w, h)
local armor = LocalPlayer():Armor()
armorLerp = Lerp(FrameTime() * 5, armorLerp, armor)
local armorPercent = math.Clamp(armorLerp / 100, 0, 1)
draw.SimpleText("Броня", "MilitaryHUD_Small", x, y - ScalePos(25), Colors.white_half, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
draw.SimpleText(math.Round(armorLerp), "MilitaryHUD_SmallBold", x + w, y - ScalePos(25), Colors.white, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER)
local barWidth = w * armorPercent
surface.SetDrawColor(Colors.gray)
surface.DrawRect(x, y, w, h)
for i = 0, barWidth - 1 do
local progress = i / w
local color = self:LerpColor(progress, Colors.darker_green, Colors.dark_green)
surface.SetDrawColor(color)
surface.DrawRect(x + i, y, 1, h)
end
local segmentWidth = w / 3
for i = 1, 2 do
surface.SetDrawColor(Color(0, 0, 0, 100))
surface.DrawRect(x + segmentWidth * i, y, 1, h)
end
end
function PLUGIN:DrawStaminaBar(x, y, w, h)
local stamina = LocalPlayer():GetLocalVar("stm", 100)
staminaLerp = Lerp(FrameTime() * 5, staminaLerp, stamina)
local staminaPercent = math.Clamp(staminaLerp / 100, 0, 1)
draw.SimpleText("Выносливость", "MilitaryHUD_Small", x, y - ScalePos(25), Colors.white_half, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
draw.SimpleText(math.Round(staminaLerp), "MilitaryHUD_SmallBold", x + w, y - ScalePos(25), Colors.white, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER)
local barWidth = w * staminaPercent
surface.SetDrawColor(Colors.gray)
surface.DrawRect(x, y, w, h)
local staminaColor = Color(0, 67, 28) -- #00431c
local staminaColorDark = Color(0, 30, 10)
for i = 0, barWidth - 1 do
local progress = i / w
local color = self:LerpColor(progress, staminaColorDark, staminaColor)
surface.SetDrawColor(color)
surface.DrawRect(x + i, y, 1, h)
end
local segmentWidth = w / 3
for i = 1, 2 do
surface.SetDrawColor(Color(0, 0, 0, 100))
surface.DrawRect(x + segmentWidth * i, y, 1, h)
end
end
function PLUGIN:DrawRankInfo(x, y, w, h)
local iconSize = ScaleSize(32)
if rankMaterial then
surface.SetMaterial(rankMaterial)
surface.SetDrawColor(Colors.white)
surface.DrawTexturedRect(x, y, iconSize, iconSize)
else
surface.SetDrawColor(Colors.gray_light)
surface.DrawRect(x, y, iconSize, iconSize)
draw.SimpleText("R", "MilitaryHUD_Medium", x + iconSize/2, y + iconSize/2, Colors.gray_dark, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
end
draw.SimpleText(LocalPlayer():GetSpecName(), "MilitaryHUD_SmallBold", x + iconSize + ScalePos(10), y + iconSize/2, Colors.white, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
end
function PLUGIN:DrawHungerIndicator(x, y)
local hunger = LocalPlayer():GetLocalVar("hunger", 100)
hungerLerp = Lerp(FrameTime() * 5, hungerLerp, hunger)
-- Иконка голода
local iconSize = ScaleSize(24)
if foodMaterial then
surface.SetMaterial(foodMaterial)
surface.SetDrawColor(255, 255, 255, 255)
surface.DrawTexturedRect(x, y, iconSize, iconSize)
else
surface.SetDrawColor(Color(205, 133, 63))
surface.DrawRect(x, y, iconSize, iconSize)
end
-- Значение
local hungerColor = hungerLerp > 50 and Colors.white or Color(200, 50, 50)
draw.SimpleText(math.Round(hungerLerp) .. "%", "MilitaryHUD_SmallBold", x + iconSize + ScalePos(5), y + iconSize/2, hungerColor, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
end
function PLUGIN:DrawThirstIndicator(x, y)
local thirst = LocalPlayer():GetLocalVar("thirst", 100)
thirstLerp = Lerp(FrameTime() * 5, thirstLerp, thirst)
-- Иконка жажды
local iconSize = ScaleSize(24)
if thirstMaterial then
surface.SetMaterial(thirstMaterial)
surface.SetDrawColor(255, 255, 255, 255)
surface.DrawTexturedRect(x, y, iconSize, iconSize)
else
surface.SetDrawColor(Color(30, 144, 255))
surface.DrawRect(x, y, iconSize, iconSize)
end
-- Значение
local thirstColor = thirstLerp > 50 and Colors.white or Color(200, 50, 50)
draw.SimpleText(math.Round(thirstLerp) .. "%", "MilitaryHUD_SmallBold", x + iconSize + ScalePos(5), y + iconSize/2, thirstColor, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
end
function PLUGIN:DrawRadio()
local x, y = ScalePos(40), ScalePos(240)
local iconSize = ScaleSize(32)
local radioStatus = self:GetRadioStatus()
if radioMaterial then
surface.SetMaterial(radioMaterial)
surface.SetDrawColor(Colors.white)
surface.DrawTexturedRect(x, y, iconSize, iconSize)
else
surface.SetDrawColor(Colors.gray_light)
surface.DrawRect(x, y, iconSize, iconSize)
draw.SimpleText("R", "MilitaryHUD_Medium", x + iconSize/2, y + iconSize/2, Colors.gray_dark, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
end
local radioText = radioStatus and "Включена" or "Выключена"
local radioColor = radioStatus and Colors.green or Color(200, 50, 50)
draw.SimpleText("Рация:", "MilitaryHUD_MediumBold", x + iconSize + ScalePos(10), y + ScalePos(11), Colors.white, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
draw.SimpleText(radioText, "MilitaryHUD_MediumBold", x + iconSize + ScalePos(78), y + ScalePos(11), radioColor, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
end
function PLUGIN:DrawTime()
local x, y = ScalePos(40), ScalePos(290)
local iconSize = ScaleSize(32)
local timeText = self:GetFormattedTime()
if clockMaterial then
surface.SetMaterial(clockMaterial)
surface.SetDrawColor(Colors.white)
surface.DrawTexturedRect(x, y, iconSize, iconSize)
else
surface.SetDrawColor(Colors.gray_light)
surface.DrawRect(x, y, iconSize, iconSize)
draw.SimpleText("T", "MilitaryHUD_Medium", x + iconSize/2, y + iconSize/2, Colors.gray_dark, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
end
draw.SimpleText(timeText, "MilitaryHUD_MediumBold", x + iconSize + ScalePos(10), y + iconSize/2, Color(255, 255, 255, 165), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
end
function PLUGIN:DrawLogo()
local x, y = ScalePos(20), ScalePos(39)
local logoWidth, logoHeight = ScaleSize(128), ScaleSize(72)
if logoMaterial then
surface.SetMaterial(logoMaterial)
surface.SetDrawColor(Colors.white)
surface.DrawTexturedRect(x, y, logoWidth, logoHeight)
else
surface.SetDrawColor(Colors.dark_green)
surface.DrawRect(x, y, logoWidth/2, logoHeight)
draw.SimpleText("ЛОГО", "MilitaryHUD_Small", x + logoWidth/4, y + logoHeight/2, Colors.white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
end
--draw.SimpleText("Война на Украине", "MilitaryHUD_MediumBold", x + ScalePos(120), y + ScalePos(35), Colors.white, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
end
function PLUGIN:DrawAmmoInfo()
local weapon = LocalPlayer():GetActiveWeapon()
if not IsValid(weapon) then return end
local clip = weapon:Clip1()
local ammoType = weapon:GetPrimaryAmmoType()
local reserve = LocalPlayer():GetAmmoCount(ammoType)
-- Пропускаем оружие без патронов (например, руки, граната)
if clip < 0 and (ammoType == -1 or reserve == 0) then return end
local x, y = ScrW() - ScalePos(90), ScrH() - ScalePos(50)
-- Отображаем патроны в обойме
if clip >= 0 then
draw.SimpleText(clip, "MilitaryHUD_Large", x, y, Colors.white, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER)
-- Разделитель
draw.SimpleText("/", "MilitaryHUD_Medium", x + ScalePos(10), y, Colors.white_half, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
-- Запасные патроны
draw.SimpleText(reserve, "MilitaryHUD_Medium", x + ScalePos(30), y, Colors.white_half, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
else
-- Если нет обоймы (например, РПГ), показываем только запас
draw.SimpleText(reserve, "MilitaryHUD_Large", x, y, Colors.white, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER)
end
-- Название оружия
local weaponName = weapon:GetPrintName() or weapon:GetClass()
draw.SimpleText(weaponName, "MilitaryHUD_Small", x + ScalePos(15), y - ScalePos(30), Colors.white_half, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER)
end
function PLUGIN:DrawPlayerInfo()
local x, y = ScalePos(40), ScrH() - ScalePos(210)
local infoWidth = ScaleSize(420)
-- Индикаторы голода и жажды НАД здоровьем
self:DrawHungerIndicator(x, y - ScalePos(35))
self:DrawThirstIndicator(x + ScalePos(100), y - ScalePos(35))
-- Полоски здоровья, брони и выносливости
self:DrawHealthBar(x, y + ScalePos(22), infoWidth, ScaleSize(12))
self:DrawArmorBar(x, y + ScalePos(74), infoWidth, ScaleSize(12))
self:DrawStaminaBar(x, y + ScalePos(126), infoWidth, ScaleSize(12))
-- Информация о ранге
self:DrawRankInfo(x, y + ScalePos(152), ScaleSize(223), ScaleSize(32))
end
function PLUGIN:HUDPaint()
local lp = LocalPlayer()
if (!lp:GetCharacter() or !lp:Alive() or ix.option.Get("disablehud", false)) then
return
end
CreateHUDFonts()
self:DrawPlayerInfo()
self:DrawAmmoInfo()
self:DrawRadio()
self:DrawTime()
self:DrawLogo()
end
function PLUGIN:PostDrawTranslucentRenderables()
local target = self:GetLookTarget()
if IsValid(target) then
self:DrawTargetPlayerInfo(target)
end
end
-- Шрифты для информации о цели
surface.CreateFont("TargetInfo_Name", {
font = "Montserrat",
size = 38,
weight = 600
})
surface.CreateFont("TargetInfo_Detail", {
font = "Montserrat",
size = 30,
weight = 400
})
surface.CreateFont("TargetInfo_Rank", {
font = "Montserrat",
size = 26,
weight = 500
})
-- Получение цели
function PLUGIN:GetLookTarget()
local trace = LocalPlayer():GetEyeTrace()
if not trace.Hit then return nil end
if not IsValid(trace.Entity) then return nil end
if not trace.Entity:IsPlayer() then return nil end
if trace.Entity == LocalPlayer() then return nil end
if trace.Entity:Team() != LocalPlayer():Team() then return nil end
local distance = LocalPlayer():GetPos():Distance(trace.Entity:GetPos())
if distance > 250 then return nil end
return trace.Entity
end
-- Отрисовка информации о цели
function PLUGIN:DrawTargetPlayerInfo()
-- Проверка настройки
if ix.option.Get("disableplayerinfo", false) then
return
end
local target = self:GetLookTarget()
if not target then return end
local char = target:GetCharacter()
if not char then return end
-- Получаем данные
local name = target:Name()
local podrName = target:GetPodrName()
if not podrName or podrName == false then
podrName = "Неизвестно"
end
local specName = target:GetSpecName()
if not specName or specName == false then
specName = "Неизвестно"
end
local rankName = target:GetRankName()
if not rankName or rankName == false then
rankName = "Неизвестно"
end
-- Позиция 3D2D над головой
local pos = target:GetPos() + Vector(0, 0, 85)
-- Угол всегда смотрит на игрока
local ang = Angle(0, LocalPlayer():EyeAngles().y - 90, 90)
-- Масштаб для 3D2D
local scale = 0.1
cam.Start3D2D(pos, ang, scale)
-- Настройки текста
local lineHeight = 42
local yOffset = 0
-- Имя (крупно, по центру)
draw.SimpleText(name, "TargetInfo_Name", 0, yOffset, Color(0, 146, 12), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
yOffset = yOffset + lineHeight
if podrName and podrName != "Новоприбывшие" then
local unitText = podrName .. " | " .. specName
draw.SimpleText(unitText, "TargetInfo_Detail", 0, yOffset, Color(0, 146, 12), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
yOffset = yOffset + lineHeight
-- Звание
draw.SimpleText(rankName, "TargetInfo_Rank", 0, yOffset, Color(0, 146, 12), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
else
draw.SimpleText(rankName, "TargetInfo_Rank", 0, yOffset, Color(0, 146, 12), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
end
cam.End3D2D()
end

View File

@@ -0,0 +1,13 @@
NAME = "English"
LANGUAGE = {
-- Category
optHUD = "HUD",
-- Settings
optDisableHUD = "Hide HUD",
optDisableHUDDesc = "Completely hide the game interface",
optDisablePlayerInfo = "Hide Player Info",
optDisablePlayerInfoDesc = "Hide player information when looking at them",
}

View File

@@ -0,0 +1,13 @@
NAME = "Русский"
LANGUAGE = {
-- Category
optHUD = "HUD",
-- Settings
optDisableHUD = "Скрыть HUD",
optDisableHUDDesc = "Полностью скрыть игровой интерфейс",
optDisablePlayerInfo = "Скрыть инфо игроков",
optDisablePlayerInfoDesc = "Скрыть информацию о игроках при взгляде на них",
}

View File

@@ -0,0 +1,34 @@
local PLUGIN = PLUGIN
PLUGIN.name = "Military RP HUD"
PLUGIN.author = "Military RP Team"
PLUGIN.desc = "Military-themed HUD for Military RP"
ix.util.Include("cl_plugin.lua")
function PLUGIN:CanDrawAmmoHUD()
return false
end
function PLUGIN:ShouldHideBars()
return true
end
-- Настройки для HUD (using localization)
ix.option.Add("disablehud", ix.type.bool, false, {
category = "optHUD",
name = "optDisableHUD",
description = "optDisableHUDDesc"
})
ix.option.Add("disableplayerinfo", ix.type.bool, false, {
category = "optHUD",
name = "optDisablePlayerInfo",
description = "optDisablePlayerInfoDesc"
})
if CLIENT then
-- Обновление ранга
net.Receive("MilitaryRP_RankUpdate", function()
-- Здесь можно обновить ранг игрока
end)
end