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,357 @@
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