add sborka
This commit is contained in:
498
garrysmod/gamemodes/militaryrp/schema/derma/cl_character.lua
Normal file
498
garrysmod/gamemodes/militaryrp/schema/derma/cl_character.lua
Normal 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)
|
||||
|
||||
Reference in New Issue
Block a user