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,498 @@
-- Масштабирование для меню
local function GetScale()
local scale = ScrH() / 1080
return math.Clamp(scale, 0.5, 2.0)
end
local function ScaleSize(val)
return math.max(1, math.Round(val * GetScale()))
end
local function ScalePos(val)
return math.Round(val * GetScale())
end
local function CreateMenuFonts()
surface.CreateFont("ixMenuButtonFont_Adaptive", {
font = "Roboto",
size = math.max(ScaleSize(18), 12),
weight = 500,
antialias = true
})
surface.CreateFont("ixMenuButtonHugeFont_Adaptive", {
font = "Roboto",
size = math.max(ScaleSize(32), 20),
weight = 700,
antialias = true
})
end
CreateMenuFonts()
hook.Add("OnScreenSizeChanged", "CharMenu_UpdateFonts", CreateMenuFonts)
local CharMenu = {}
function CharMenu:Init()
if IsValid(ix.gui.characterMenu) then
ix.gui.characterMenu:Remove()
end
self:SetSize(ScrW(), ScrH())
self:SetPos(0, 0)
-- Переменные для совместимости
self.bClosing = false
self.currentAlpha = 255
self.bMenuShouldClose = false
-- Проверяем наличие персонажа
self:CheckCharacterAndLoad()
ix.gui.characterMenu = self
ix.gui.menu = self -- Для совместимости
self:MakePopup()
self:SetKeyboardInputEnabled(true)
self:SetMouseInputEnabled(true)
end
function CharMenu:CheckCharacterAndLoad()
-- Ждем немного пока загрузятся данные персонажей
timer.Simple(0.5, function()
if not IsValid(self) then return end
local hasCharacter = LocalPlayer().GetCharacter and LocalPlayer():GetCharacter()
if hasCharacter then
-- Если персонаж уже загружен, закрываем меню
print("Персонаж уже загружен, закрываем меню")
self:Close(true)
return
end
local characters = ix.characters
if (#characters > 0) then
local firstChar = characters[1]
if not firstChar then
return
end
net.Start("ixCharacterChoose")
net.WriteUInt(firstChar, 32)
net.SendToServer()
else
-- Если персонажей нет, показываем выбор стороны
print("Персонажей нет, показываем выбор фракции")
self:ShowFactionSelection()
end
end)
end
function CharMenu:ShowFactionSelection()
-- Очищаем предыдущие панели
if IsValid(self.currentPanel) then
self.currentPanel:Remove()
end
-- Создаем панель выбора фракции
self.currentPanel = vgui.Create("DPanel", self)
self.currentPanel:SetSize(ScrW(), ScrH())
self.currentPanel:SetPos(0, 0)
-- Фон
local backgroundImage = vgui.Create("DImage", self.currentPanel)
backgroundImage:SetSize(ScrW(), ScrH())
backgroundImage:SetPos(0, 0)
backgroundImage:SetImage("ft_ui/military/vnu/charcreate/bg.png")
-- Верхняя панель
CreateMenuFonts()
local topBar = vgui.Create("DPanel", self.currentPanel)
topBar:SetSize(ScrW() + 2, ScaleSize(100))
topBar:SetPos(-1, 0)
topBar.Paint = function(panel, w, h)
surface.SetDrawColor(Color(13, 13, 13))
surface.DrawRect(0, 0, w, h)
end
-- Логотип
local logo = vgui.Create("DImage", self.currentPanel)
logo:SetSize(ScaleSize(150), ScaleSize(53))
logo:SetPos(ScrW()/2 - ScaleSize(75), ScalePos(23))
logo:SetImage("ft_ui/military/vnu/charcreate/logo.png")
-- Заголовок
local title = vgui.Create("DLabel", self.currentPanel)
title:SetText("ВЫБОР СТОРОНЫ")
title:SetFont("ixMenuButtonHugeFont_Adaptive")
title:SetTextColor(color_white)
title:SizeToContents()
title:SetPos(ScrW()/2 - title:GetWide()/2, ScalePos(187))
-- Панель ВСУ
local ukrainePanel = vgui.Create("DPanel", self.currentPanel)
ukrainePanel:SetSize(ScaleSize(425), ScaleSize(500))
ukrainePanel:SetPos(ScrW()/2 - ScaleSize(425) - ScaleSize(25), ScalePos(310))
ukrainePanel.Paint = function(panel, w, h)
surface.SetDrawColor(Color(0, 0, 0, 180))
surface.DrawRect(0, 0, w, h)
surface.SetDrawColor(Color(1, 67, 29))
surface.DrawOutlinedRect(0, 0, w, h, 2)
end
-- Панель России
local russiaPanel = vgui.Create("DPanel", self.currentPanel)
russiaPanel:SetSize(ScaleSize(425), ScaleSize(500))
russiaPanel:SetPos(ScrW()/2 + ScaleSize(25), ScalePos(310))
russiaPanel.Paint = function(panel, w, h)
surface.SetDrawColor(Color(0, 0, 0, 180))
surface.DrawRect(0, 0, w, h)
surface.SetDrawColor(Color(1, 67, 29))
surface.DrawOutlinedRect(0, 0, w, h, 2)
end
-- Изображения фракций
local ukraineImage = vgui.Create("DImage", self.currentPanel)
ukraineImage:SetSize(ScaleSize(200), ScaleSize(200))
ukraineImage:SetPos(ScrW()/2 - ScaleSize(425) - ScaleSize(25) + ScaleSize(113), ScalePos(333))
ukraineImage:SetImage("ft_ui/military/vnu/charcreate/ukraine.png")
local russiaImage = vgui.Create("DImage", self.currentPanel)
russiaImage:SetSize(ScaleSize(295), ScaleSize(200))
russiaImage:SetPos(ScrW()/2 + ScaleSize(25) + ScaleSize(65), ScalePos(333))
russiaImage:SetImage("ft_ui/military/vnu/charcreate/russia.png")
-- Кнопки выбора
local ukraineButton = vgui.Create("DButton", self.currentPanel)
ukraineButton:SetSize(ScaleSize(425), ScaleSize(75))
ukraineButton:SetPos(ScrW()/2 - ScaleSize(425) - ScaleSize(25), ScalePos(818))
ukraineButton:SetText("")
ukraineButton.Paint = function(panel, w, h)
surface.SetDrawColor(Color(1, 67, 29))
surface.DrawRect(0, 0, w, h)
surface.SetDrawColor(Color(29, 29, 29))
surface.DrawOutlinedRect(0, 0, w, h, 3)
draw.SimpleText("УКРАИНА", "ixMenuButtonHugeFont_Adaptive", w/2, h/2, Color(255, 255, 255, 218), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
if panel:IsHovered() then
surface.SetDrawColor(Color(255, 255, 255, 30))
surface.DrawRect(0, 0, w, h)
end
end
ukraineButton.DoClick = function()
self:ShowCharacterCreation(FACTION_UKRAINE)
end
local russiaButton = vgui.Create("DButton", self.currentPanel)
russiaButton:SetSize(ScaleSize(425), ScaleSize(75))
russiaButton:SetPos(ScrW()/2 + ScaleSize(25), ScalePos(818))
russiaButton:SetText("")
russiaButton.Paint = function(panel, w, h)
surface.SetDrawColor(Color(1, 67, 29))
surface.DrawRect(0, 0, w, h)
surface.SetDrawColor(Color(29, 29, 29))
surface.DrawOutlinedRect(0, 0, w, h, 3)
draw.SimpleText("РОССИЯ", "ixMenuButtonHugeFont_Adaptive", w/2, h/2, Color(255, 255, 255, 218), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
if panel:IsHovered() then
surface.SetDrawColor(Color(255, 255, 255, 30))
surface.DrawRect(0, 0, w, h)
end
end
russiaButton.DoClick = function()
self:ShowCharacterCreation(FACTION_RUSSIAN)
end
end
function CharMenu:ShowCharacterCreation(faction)
-- Очищаем предыдущие панели
if IsValid(self.currentPanel) then
self.currentPanel:Remove()
end
self.currentPanel = vgui.Create("DPanel", self)
self.currentPanel:SetSize(ScrW(), ScrH())
self.currentPanel:SetPos(0, 0)
-- Фон
local backgroundImage = vgui.Create("DImage", self.currentPanel)
backgroundImage:SetSize(ScrW(), ScrH())
backgroundImage:SetPos(0, 0)
backgroundImage:SetImage("ft_ui/military/vnu/charcreate/bg.png")
-- Верхняя панель
CreateMenuFonts()
local topBar = vgui.Create("DPanel", self.currentPanel)
topBar:SetSize(ScrW() + 2, ScaleSize(100))
topBar:SetPos(-1, 0)
topBar.Paint = function(panel, w, h)
surface.SetDrawColor(Color(13, 13, 13))
surface.DrawRect(0, 0, w, h)
end
-- Логотип
local logo = vgui.Create("DImage", self.currentPanel)
logo:SetSize(ScaleSize(150), ScaleSize(53))
logo:SetPos(ScrW()/2 - ScaleSize(75), ScalePos(23))
logo:SetImage("ft_ui/military/vnu/charcreate/logo.png")
-- Основная панель
local mainPanel = vgui.Create("DPanel", self.currentPanel)
mainPanel:SetSize(ScaleSize(1500), ScaleSize(750))
mainPanel:SetPos(ScrW()/2 - ScaleSize(750), ScalePos(199))
mainPanel.Paint = function(panel, w, h)
surface.SetDrawColor(Color(13, 13, 13, 200))
surface.DrawRect(0, 0, w, h)
end
-- Заголовки
local title = vgui.Create("DLabel", self.currentPanel)
title:SetText("СОЗДАНИЕ ПЕРСОНАЖА")
title:SetFont("ixMenuButtonHugeFont_Adaptive")
title:SetTextColor(color_white)
title:SizeToContents()
title:SetPos(ScrW()/2 - title:GetWide()/2, ScalePos(224))
-- Разделители
local divider1 = vgui.Create("DPanel", self.currentPanel)
divider1:SetSize(ScaleSize(770), ScaleSize(2))
divider1:SetPos(ScrW()/2 - ScaleSize(385), ScalePos(314))
divider1.Paint = function(panel, w, h)
surface.SetDrawColor(Color(1, 67, 29))
surface.DrawRect(0, 0, w, h)
end
-- Поля ввода
local startX = ScrW()/2 - ScaleSize(420)
-- Имя
local nameLabel = vgui.Create("DLabel", self.currentPanel)
nameLabel:SetText("Ваше имя")
nameLabel:SetFont("ixMenuButtonFont_Adaptive")
nameLabel:SetTextColor(color_white)
nameLabel:SizeToContents()
nameLabel:SetPos(startX, ScalePos(360))
local nameEntry = vgui.Create("DTextEntry", self.currentPanel)
nameEntry:SetSize(ScaleSize(265), ScaleSize(50))
nameEntry:SetPos(startX, ScalePos(401))
nameEntry:SetFont("ixMenuButtonFont_Adaptive")
nameEntry:SetTextColor(Color(255, 255, 255, 230))
nameEntry:SetDrawBackground(false)
nameEntry.Paint = function(panel, w, h)
surface.SetDrawColor(Color(23, 23, 23))
surface.DrawRect(0, 0, w, h)
surface.SetDrawColor(Color(1, 67, 29))
surface.DrawOutlinedRect(0, 0, w, h, 1)
panel:DrawTextEntryText(Color(255, 255, 255, 230), Color(30, 130, 255), Color(255, 255, 255, 230))
end
-- Фамилия
local lastNameLabel = vgui.Create("DLabel", self.currentPanel)
lastNameLabel:SetText("Ваша фамилия")
lastNameLabel:SetFont("ixMenuButtonFont_Adaptive")
lastNameLabel:SetTextColor(color_white)
lastNameLabel:SizeToContents()
lastNameLabel:SetPos(startX + ScaleSize(285), ScalePos(360))
local lastNameEntry = vgui.Create("DTextEntry", self.currentPanel)
lastNameEntry:SetSize(ScaleSize(265), ScaleSize(50))
lastNameEntry:SetPos(startX + ScaleSize(285), ScalePos(401))
lastNameEntry:SetFont("ixMenuButtonFont_Adaptive")
lastNameEntry:SetTextColor(Color(255, 255, 255, 230))
lastNameEntry:SetDrawBackground(false)
lastNameEntry.Paint = nameEntry.Paint
-- Позывной
local callSignLabel = vgui.Create("DLabel", self.currentPanel)
callSignLabel:SetText("Ваш позывной")
callSignLabel:SetFont("ixMenuButtonFont_Adaptive")
callSignLabel:SetTextColor(color_white)
callSignLabel:SizeToContents()
callSignLabel:SetPos(startX + ScaleSize(570), ScalePos(360))
local callSignEntry = vgui.Create("DTextEntry", self.currentPanel)
callSignEntry:SetSize(ScaleSize(265), ScaleSize(50))
callSignEntry:SetPos(startX + ScaleSize(570), ScalePos(401))
callSignEntry:SetFont("ixMenuButtonFont_Adaptive")
callSignEntry:SetTextColor(Color(255, 255, 255, 230))
callSignEntry:SetDrawBackground(false)
callSignEntry.Paint = nameEntry.Paint
-- Кнопка создания
local createButton = vgui.Create("DButton", self.currentPanel)
createButton:SetSize(ScaleSize(300), ScaleSize(80))
createButton:SetPos(ScrW()/2 - ScaleSize(150), ScrH() - ScaleSize(120))
createButton:SetText("")
createButton.Paint = function(panel, w, h)
surface.SetDrawColor(Color(1, 67, 29))
surface.DrawRect(0, 0, w, h)
surface.SetDrawColor(Color(29, 29, 29))
surface.DrawOutlinedRect(0, 0, w, h, 3)
draw.SimpleText("СОЗДАТЬ", "ixMenuButtonHugeFont_Adaptive", w/2, h/2, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
if panel:IsHovered() then
surface.SetDrawColor(Color(255, 255, 255, 30))
surface.DrawRect(0, 0, w, h)
end
end
createButton.DoClick = function()
local name = nameEntry:GetText()
local lastName = lastNameEntry:GetText()
local callSign = callSignEntry:GetText()
if name == "" or lastName == "" or callSign == "" then
print("Ошибка: Заполните все поля!")
return
end
local fullName = name .. " " .. lastName .. " '" .. callSign .. "'"
print("Создание персонажа: " .. fullName)
self:CreateCharacter(faction, fullName)
end
self.selectedFaction = faction
end
function CharMenu:CreateCharacter(faction, name)
if self.awaitingResponse then
print("Уже ожидаем ответ от сервера...")
return
end
-- Подготавливаем данные для создания персонажа
local payload = {
name = name,
faction = faction,
model = "models/player/group01/male_04.mdl",
description = "Солдат"
}
print("Отправка запроса на создание персонажа...")
PrintTable(payload)
-- Отправляем запрос на создание персонажа
net.Start("ixCharacterCreate")
net.WriteUInt(table.Count(payload), 8)
for k, v in pairs(payload) do
net.WriteString(k)
net.WriteType(v)
end
net.SendToServer()
-- Ждем ответа от сервера
self.awaitingResponse = true
-- Таймаут на случай проблем с соединением
timer.Create("CharCreateTimeout", 10, 1, function()
if IsValid(ix.gui.characterMenu) and ix.gui.characterMenu.awaitingResponse then
ix.gui.characterMenu.awaitingResponse = false
Derma_Message("Таймаут создания персонажа! Проверьте соединение.", "Ошибка", "OK")
end
end)
end
-- Методы для совместимости с Helix
function CharMenu:IsClosing()
return self.bClosing or false
end
function CharMenu:GetAlpha()
return self.currentAlpha or 255
end
function CharMenu:GetCharacterOverview()
-- Заглушка для совместимости
return nil
end
function CharMenu:Close(bFromMenu)
self.bClosing = true
if ix.gui.loading then
ix.gui.loading:Remove()
end
self:Remove()
end
function CharMenu:Paint(w, h)
-- Черный фон
surface.SetDrawColor(Color(0, 0, 0, 255))
surface.DrawRect(0, 0, w, h)
end
vgui.Register("ixCharMenu", CharMenu, "EditablePanel")
-- Исправляем CalcView hook
hook.Add("CalcView", "MilitaryRPMenuFix", function(ply, origin, angles, fov)
local menu = ix.gui.characterMenu or ix.gui.menu
if IsValid(menu) and not menu:IsClosing() then
-- Возвращаем стандартный вид, чтобы избежать ошибок
return {
origin = origin,
angles = angles,
fov = fov,
drawviewer = false
}
end
end)
-- Глобальные сетевые обработчики (устанавливаются один раз при загрузке файла)
net.Receive("ixCharacterLoad", function()
local characters = net.ReadUInt(8)
local charList = {}
for i = 1, characters do
charList[i] = net.ReadUInt(32)
end
ix.characters = charList
print("Получен список персонажей: ", table.concat(charList, ", "))
-- Если меню открыто, обновляем его
if IsValid(ix.gui.characterMenu) then
ix.gui.characterMenu:CheckCharacterAndLoad()
end
end)
net.Receive("ixCharacterAuthed", function()
timer.Remove("CharCreateTimeout")
local id = net.ReadUInt(32)
local characters = net.ReadUInt(8)
local charList = {}
for i = 1, characters do
charList[i] = net.ReadUInt(32)
end
ix.characters = charList
print("Персонаж успешно создан! ID: " .. id)
print("Теперь доступно персонажей: " .. characters)
-- Автоматически выбираем созданного персонажа
if id then
print("Автовыбор персонажа ID: " .. id)
net.Start("ixCharacterChoose")
net.WriteUInt(id, 32)
net.SendToServer()
end
-- Закрываем меню если оно открыто
if IsValid(ix.gui.characterMenu) then
ix.gui.characterMenu.awaitingResponse = false
ix.gui.characterMenu:Close(true)
end
end)
net.Receive("ixCharacterAuthFailed", function()
timer.Remove("CharCreateTimeout")
local fault = net.ReadString()
local args = net.ReadTable()
print("Ошибка создания персонажа: " .. fault)
PrintTable(args)
-- Показываем ошибку пользователю
if IsValid(ix.gui.characterMenu) then
ix.gui.characterMenu.awaitingResponse = false
Derma_Message("Ошибка создания персонажа: " .. fault, "Ошибка", "OK")
end
end)