local PLUGIN = PLUGIN -- Цветовая схема (как в арсенале) local COLOR_BG_DARK = Color(3, 5, 4) local COLOR_BG_MEDIUM = Color(8, 12, 10) local COLOR_BG_LIGHT = Color(12, 18, 14) local COLOR_PRIMARY = Color(27, 94, 32) local COLOR_PRIMARY_DARK = Color(15, 60, 18) local COLOR_ACCENT = Color(56, 102, 35) local COLOR_TEXT_PRIMARY = Color(165, 214, 167) local COLOR_TEXT_SECONDARY = Color(102, 187, 106) local COLOR_DANGER = Color(136, 14, 14) local COLOR_WARNING = Color(191, 130, 0) local COLOR_BORDER = Color(15, 60, 18, 60) -- Вспомогательная функция для рисования кругов if not draw.Circle then function draw.Circle(x, y, radius, color) local segmentCount = math.max(16, radius) surface.SetDrawColor(color or color_white) local circle = {} for i = 0, segmentCount do local angle = math.rad((i / segmentCount) * 360) table.insert(circle, { x = x + math.cos(angle) * radius, y = y + math.sin(angle) * radius }) end surface.DrawPoly(circle) end end if not surface.DrawCircle then function surface.DrawCircle(x, y, radius, color) draw.Circle(x, y, radius, color) end end -- Открытие опроса net.Receive("ixMilitaryID_OpenQuiz", function() PLUGIN:OpenQuizMenu() end) -- Просмотр документа net.Receive("ixMilitaryID_ViewDocument", function() local data = net.ReadTable() PLUGIN:ShowDocument(data) end) -- UI для опроса function PLUGIN:OpenQuizMenu() if IsValid(self.quizFrame) then self.quizFrame:Remove() end local scrW, scrH = ScrW(), ScrH() local frame = vgui.Create("DFrame") frame:SetSize(scrW, scrH) frame:SetPos(0, 0) frame:SetTitle("") frame:SetDraggable(false) frame:ShowCloseButton(false) frame:MakePopup() -- Градиентный фон с зеленым оттенком (как в арсенале) frame.Paint = function(s, w, h) -- Основной фон surface.SetDrawColor(COLOR_BG_DARK) surface.DrawRect(0, 0, w, h) -- Градиент сверху local gradHeight = 300 for i = 0, gradHeight do local alpha = (1 - i/gradHeight) * 40 surface.SetDrawColor(COLOR_PRIMARY.r, COLOR_PRIMARY.g, COLOR_PRIMARY.b, alpha) surface.DrawRect(0, i, w, 1) end -- Верхняя панель surface.SetDrawColor(COLOR_BG_MEDIUM) surface.DrawRect(0, 0, w, 100) -- Акцентная линия surface.SetDrawColor(COLOR_PRIMARY) surface.DrawRect(0, 100, w, 3) -- Декоративные элементы surface.SetDrawColor(COLOR_BORDER) for i = 0, w, 200 do surface.DrawRect(i, 0, 1, 100) end -- Заголовок draw.SimpleText("◆ ВОЕННЫЙ ОПРОСНИК ◆", "ixMenuButtonFont", w/2, 35, COLOR_ACCENT, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) draw.SimpleText("ПРОХОЖДЕНИЕ ВОЕННОЙ КОМИССИИ", "ixSmallFont", w/2, 68, COLOR_TEXT_SECONDARY, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end -- Кнопка закрытия local closeBtn = vgui.Create("DButton", frame) closeBtn:SetText("") closeBtn:SetSize(42, 42) closeBtn:SetPos(scrW - 60, 18) closeBtn.Paint = function(s, w, h) local col = s:IsHovered() and COLOR_DANGER or Color(COLOR_DANGER.r * 0.7, COLOR_DANGER.g * 0.7, COLOR_DANGER.b * 0.7) draw.RoundedBox(4, 0, 0, w, h, col) surface.SetDrawColor(COLOR_BG_DARK) surface.DrawOutlinedRect(0, 0, w, h, 2) surface.SetDrawColor(COLOR_TEXT_PRIMARY) surface.DrawLine(w*0.3, h*0.3, w*0.7, h*0.7) surface.DrawLine(w*0.7, h*0.3, w*0.3, h*0.7) if s:IsHovered() then surface.SetDrawColor(255, 255, 255, 30) draw.RoundedBox(4, 0, 0, w, h, Color(255, 255, 255, 30)) end end closeBtn.DoClick = function() frame:Close() end -- Основная панель контента local contentPanel = vgui.Create("DPanel", frame) contentPanel:SetSize(1000, scrH - 240) contentPanel:SetPos((scrW - 1000) / 2, 140) contentPanel.Paint = function(s, w, h) draw.RoundedBox(8, 0, 0, w, h, COLOR_BG_MEDIUM) surface.SetDrawColor(COLOR_BORDER) surface.DrawOutlinedRect(0, 0, w, h, 2) end local currentQuestion = 1 local answers = {} -- Панель прогресса local progressPanel = vgui.Create("DPanel", contentPanel) progressPanel:Dock(TOP) progressPanel:DockMargin(0, 0, 0, 10) progressPanel:SetTall(60) progressPanel.Paint = function(s, w, h) draw.RoundedBox(6, 0, 0, w, h, COLOR_BG_LIGHT) surface.SetDrawColor(COLOR_PRIMARY) surface.DrawOutlinedRect(0, 0, w, h, 2) -- Прогресс бар local progress = currentQuestion / #self.quizQuestions local barWidth = (w - 40) * progress draw.RoundedBox(4, 20, h - 15, w - 40, 8, COLOR_BG_DARK) draw.RoundedBox(4, 20, h - 15, barWidth, 8, COLOR_ACCENT) -- Текст прогресса draw.SimpleText("ВОПРОС " .. currentQuestion .. " ИЗ " .. #self.quizQuestions, "ixSmallFont", w/2, 20, COLOR_TEXT_PRIMARY, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) end -- Панель вопроса local questionPanel = vgui.Create("DPanel", contentPanel) questionPanel:Dock(TOP) questionPanel:DockMargin(0, 0, 0, 20) questionPanel:SetTall(100) questionPanel.Paint = function(s, w, h) draw.RoundedBox(6, 0, 0, w, h, COLOR_BG_LIGHT) surface.SetDrawColor(COLOR_BORDER) surface.DrawOutlinedRect(0, 0, w, h, 2) end local questionLabel = vgui.Create("DLabel", questionPanel) questionLabel:Dock(FILL) questionLabel:DockMargin(20, 20, 20, 20) questionLabel:SetFont("DermaLarge") questionLabel:SetTextColor(COLOR_TEXT_PRIMARY) questionLabel:SetWrap(true) questionLabel:SetContentAlignment(5) -- Панель ответов local answersScroll = vgui.Create("DScrollPanel", contentPanel) answersScroll:Dock(FILL) answersScroll:DockMargin(0, 0, 0, 0) local sbar = answersScroll:GetVBar() sbar:SetHideButtons(true) function sbar:Paint(w, h) draw.RoundedBox(4, 0, 0, w, h, COLOR_BG_DARK) end function sbar.btnGrip:Paint(w, h) draw.RoundedBox(4, 0, 0, w, h, COLOR_PRIMARY) end local function ShowQuestion(index) if index > #self.quizQuestions then -- Все вопросы пройдены net.Start("ixMilitaryID_SubmitQuiz") net.WriteTable(answers) net.SendToServer() frame:Close() return end local question = self.quizQuestions[index] questionLabel:SetText(question.question) answersScroll:Clear() for i, answer in ipairs(question.answers) do local btn = vgui.Create("DButton", answersScroll) btn:Dock(TOP) btn:DockMargin(20, 10, 20, 10) btn:SetTall(60) btn:SetText("") local isHovered = false btn.Paint = function(s, w, h) local bgColor = isHovered and COLOR_PRIMARY_DARK or COLOR_BG_LIGHT draw.RoundedBox(6, 0, 0, w, h, bgColor) -- Рамка surface.SetDrawColor(isHovered and COLOR_ACCENT or COLOR_BORDER) surface.DrawOutlinedRect(0, 0, w, h, 2) -- Акцентная линия слева draw.RoundedBoxEx(6, 0, 0, 5, h, COLOR_PRIMARY, true, false, true, false) -- Номер ответа draw.SimpleText(tostring(i), "DermaLarge", 30, h/2, COLOR_ACCENT, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) -- Текст ответа draw.SimpleText(answer, "ixSmallFont", 60, h/2, COLOR_TEXT_PRIMARY, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) if isHovered then surface.SetDrawColor(255, 255, 255, 20) draw.RoundedBox(6, 0, 0, w, h, Color(255, 255, 255, 20)) end end btn.OnCursorEntered = function() isHovered = true end btn.OnCursorExited = function() isHovered = false end btn.DoClick = function() answers[index] = i currentQuestion = currentQuestion + 1 ShowQuestion(currentQuestion) end end end ShowQuestion(1) self.quizFrame = frame end -- UI для просмотра документа function PLUGIN:ShowDocument(data) if IsValid(self.documentFrame) then self.documentFrame:Remove() end -- Отладка: выводим полученные данные print("[MilitaryID] ShowDocument called with data:") PrintTable(data or {}) local frame = vgui.Create("DFrame") frame:SetSize(500, 400) frame:SetTitle("") frame:Center() frame:ShowCloseButton(false) frame:MakePopup() frame.Paint = function(s, w, h) -- Фон документа draw.RoundedBox(8, 0, 0, w, h, Color(230, 220, 200)) -- Рамка surface.SetDrawColor(100, 50, 0) surface.DrawOutlinedRect(5, 25, w - 10, h - 30, 3) -- Заголовок draw.SimpleText("ВОЕННЫЙ БИЛЕТ", "DermaLarge", w/2, 40, Color(100, 50, 0), TEXT_ALIGN_CENTER) end local infoPanel = vgui.Create("DPanel", frame) infoPanel:SetPos(30, 80) infoPanel:SetSize(440, 280) infoPanel.Paint = nil local yPos = 0 local fields = { {"Имя:", data and data.name or "Не указано"}, {"Фракция:", data and data.faction or "Не указано"}, {"Подразделение:", data and data.subdivision or "Не указано"}, {"Специализация:", data and data.specialization or "Не указано"}, {"Звание:", data and data.rank or "Не указано"}, {"Розыск:", (data and data.wanted_fsb and data.wanted_sbu) and "В РОЗЫСКЕ ФСБ И СБУ" or (data and data.wanted_fsb) and "В РОЗЫСКЕ ФСБ" or (data and data.wanted_sbu) and "В РОЗЫСКЕ СБУ" or "Чист"} } for _, field in ipairs(fields) do local label = vgui.Create("DLabel", infoPanel) label:SetPos(0, yPos) label:SetFont("DermaDefaultBold") label:SetText(field[1]) label:SetTextColor(Color(50, 50, 50)) label:SizeToContents() local value = vgui.Create("DLabel", infoPanel) value:SetPos(150, yPos) value:SetFont("DermaDefault") value:SetText(field[2]) -- Make the "Wanted" value red if wanted if field[1] == "Розыск:" and data and (data.wanted_fsb or data.wanted_sbu) then value:SetTextColor(Color(200, 0, 0)) value:SetFont("DermaDefaultBold") else value:SetTextColor(Color(0, 0, 0)) end value:SizeToContents() yPos = yPos + 35 end -- Visual Wanted Stamp if data and (data.wanted_fsb or data.wanted_sbu) then local stamp = vgui.Create("DPanel", frame) stamp:SetSize(180, 60) stamp:SetPos(300, 280) stamp.Paint = function(s, w, h) local x, y = s:LocalToScreen(0, 0) local matrix = Matrix() matrix:Translate(Vector(x + w / 2, y + h / 2, 0)) matrix:Rotate(Angle(0, 15, 0)) matrix:Translate(Vector(-(x + w / 2), -(y + h / 2), 0)) cam.PushModelMatrix(matrix) surface.SetDrawColor(200, 0, 0, 150) surface.DrawOutlinedRect(x, y, w, h, 4) draw.SimpleText("В РОЗЫСКЕ", "DermaLarge", x + w / 2, y + h / 2, Color(200, 0, 0, 200), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) cam.PopModelMatrix() end end local closeBtn = vgui.Create("DButton", frame) closeBtn:SetPos(175, 350) closeBtn:SetSize(150, 30) closeBtn:SetText("Закрыть") closeBtn.DoClick = function() frame:Close() end frame.OnRemove = function() net.Start("ixMilitaryID_StopView") net.SendToServer() end self.documentFrame = frame end