Files
VnUtest/garrysmod/gamemodes/militaryrp/plugins/whitelistmenu/cl_plugin.lua
2026-03-31 10:27:04 +03:00

385 lines
14 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
local menuFrame = nil
local factions = {}
local function GetPlayerBySteamID(steamID)
for _, ply in ipairs(player.GetAll()) do
if ply:SteamID() == steamID then
return ply
end
end
return nil
end
local function GetDisplayName(input)
if isstring(input) then
return input
elseif istable(input) then
return input[1] or tostring(input)
else
return tostring(input)
end
end
local selectedPlayer = nil
local selectedFaction = nil
local selectedPodr = nil
local selectedSpec = nil
local selectedRank = nil
local playerButtons = {}
local factionButtons = {}
local podrButtons = {}
local specButtons = {}
local rankButtons = {}
local originalPlayers = {}
net.Receive("ixWhitelistMenuOpen", function()
if menuFrame and menuFrame:IsValid() then menuFrame:Close() end
net.Start("ixWhitelistMenuDataRequest")
net.SendToServer()
end)
net.Receive("ixWhitelistMenuData", function()
if menuFrame and menuFrame:IsValid() then menuFrame:Close() end
originalPlayers = net.ReadTable()
factions = net.ReadTable()
selectedPlayer = nil
selectedFaction = nil
selectedPodr = nil
selectedSpec = nil
selectedRank = nil
playerButtons = {}
factionButtons = {}
podrButtons = {}
specButtons = {}
rankButtons = {}
local scrW, scrH = ScrW(), ScrH()
menuFrame = vgui.Create("DFrame")
menuFrame:SetSize(900, 650)
menuFrame:SetPos(scrW/2 - 450, scrH/2 - 325)
menuFrame:SetTitle("")
menuFrame:SetDraggable(false)
menuFrame:ShowCloseButton(false)
menuFrame:MakePopup()
menuFrame.Paint = function(s, w, h)
-- Фон
surface.SetDrawColor(Color(13, 13, 13, 240))
surface.DrawRect(0, 0, w, h)
-- Обводка
surface.SetDrawColor(Color(1, 67, 29))
surface.DrawOutlinedRect(0, 0, w, h, 2)
-- Верхняя панель
surface.SetDrawColor(Color(1, 67, 29))
surface.DrawRect(0, 0, w, 40)
-- Заголовок
draw.SimpleText("МЕНЕДЖЕР ВАЙТЛИСТА", "ixMenuButtonFont", w/2, 20, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
end
local closeBtn = vgui.Create("DButton", menuFrame)
closeBtn:SetText("")
closeBtn:SetSize(30, 30)
closeBtn:SetPos(menuFrame:GetWide() - 40, 5)
closeBtn.Paint = function(s, w, h)
surface.SetDrawColor(Color(200, 50, 50))
surface.DrawRect(0, 0, w, h)
surface.SetDrawColor(Color(29, 29, 29))
surface.DrawOutlinedRect(0, 0, w, h, 2)
draw.SimpleText("×", "ixSmallFont", w/2, h/2, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
if s:IsHovered() then
surface.SetDrawColor(Color(255, 255, 255, 30))
surface.DrawRect(0, 0, w, h)
end
end
closeBtn.DoClick = function()
menuFrame:Close()
end
local function CreateRow(parent, text, onSelect, data, buttonGroup)
local btn = parent:Add("DButton")
btn:SetText("")
btn:SetTall(30)
btn:SetFont("ixSmallFont")
btn.Paint = function(s, w, h)
if s.isSelected then
surface.SetDrawColor(Color(1, 67, 29, 200))
surface.DrawRect(0, 0, w, h)
else
surface.SetDrawColor(Color(23, 23, 23))
surface.DrawRect(0, 0, w, h)
end
surface.SetDrawColor(Color(1, 67, 29))
surface.DrawOutlinedRect(0, 0, w, h, 1)
local textColor = s.isSelected and color_white or Color(200, 200, 200)
draw.SimpleText(text, "ixSmallFont", 8, h/2, textColor, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
if s:IsHovered() and not s.isSelected then
surface.SetDrawColor(Color(255, 255, 255, 20))
surface.DrawRect(0, 0, w, h)
end
end
btn.DoClick = function()
for _, otherBtn in ipairs(buttonGroup) do
if otherBtn ~= btn then
otherBtn.isSelected = false
end
end
btn.isSelected = true
if onSelect then onSelect(data) end
end
btn:DockMargin(2, 2, 2, 2)
btn:Dock(TOP)
table.insert(buttonGroup, btn)
return btn
end
local colWidth = 160
local colSpacing = 10
local colX = 20
local headerHeight = 30
local scrollHeight = 500
local totalHeight = headerHeight + scrollHeight
local startY = 60
local buttonHeight = 40
local function CreateColumnPanel(name, x)
local panel = vgui.Create("DPanel", menuFrame)
panel:SetSize(colWidth, totalHeight)
panel:SetPos(x, startY)
panel.Paint = function(s, 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)
end
local header = vgui.Create("DLabel", panel)
header:SetText(name)
header:SetPos(0, 5)
header:SetSize(colWidth, 20)
header:SetFont("ixSmallFont")
header:SetTextColor(color_white)
header:SetContentAlignment(5)
local scroll = vgui.Create("DScrollPanel", panel)
scroll:SetSize(colWidth - 4, scrollHeight)
scroll:SetPos(2, headerHeight)
return scroll
end
-- Панель игроков с поиском
local playerPanel = vgui.Create("DPanel", menuFrame)
playerPanel:SetSize(colWidth, totalHeight)
playerPanel:SetPos(colX, startY)
playerPanel.Paint = function(s, 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)
end
local playerHeader = vgui.Create("DLabel", playerPanel)
playerHeader:SetText("ИГРОКИ")
playerHeader:SetPos(0, 5)
playerHeader:SetSize(colWidth, 20)
playerHeader:SetFont("ixSmallFont")
playerHeader:SetTextColor(color_white)
playerHeader:SetContentAlignment(5)
local searchBox = vgui.Create("DTextEntry", playerPanel)
searchBox:SetPos(5, 30)
searchBox:SetSize(colWidth - 10, 25)
searchBox:SetPlaceholderText("Поиск...")
searchBox:SetFont("ixSmallFont")
searchBox:SetUpdateOnType(true)
searchBox.Paint = function(s, 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)
s:DrawTextEntryText(color_white, Color(30, 130, 255), color_white)
end
local playerScroll = vgui.Create("DScrollPanel", playerPanel)
playerScroll:SetSize(colWidth - 4, scrollHeight - 40)
playerScroll:SetPos(2, 60)
-- Создаем колонки
local factionScroll = CreateColumnPanel("ФРАКЦИИ", colX + (colWidth + colSpacing) * 1)
local podrScroll = CreateColumnPanel("ПОДРАЗДЕЛЕНИЯ", colX + (colWidth + colSpacing) * 2)
local specScroll = CreateColumnPanel("СПЕЦИАЛИЗАЦИИ", colX + (colWidth + colSpacing) * 3)
local rankScroll = CreateColumnPanel("ЗВАНИЯ", colX + (colWidth + colSpacing) * 4)
local function UpdatePlayerList(filterText)
playerScroll:Clear()
playerButtons = {}
local lowerFilter = string.lower(filterText or "")
for _, p in ipairs(originalPlayers) do
if filterText == "" or string.find(string.lower(p.name), lowerFilter, 1, true) then
CreateRow(playerScroll, p.name, function(data)
selectedPlayer = data
factionScroll:Clear()
podrScroll:Clear()
specScroll:Clear()
rankScroll:Clear()
selectedFaction = nil
selectedPodr = nil
selectedSpec = nil
selectedRank = nil
factionButtons = {}
podrButtons = {}
specButtons = {}
rankButtons = {}
for id, f in pairs(factions) do
CreateRow(factionScroll, GetDisplayName(f.name), function(factionData)
selectedFaction = factionData
local f = factions[factionData.id]
podrScroll:Clear()
specScroll:Clear()
rankScroll:Clear()
selectedPodr = nil
selectedSpec = nil
selectedRank = nil
podrButtons = {}
specButtons = {}
rankButtons = {}
for podId, podr in pairs(f.Podr) do
CreateRow(podrScroll, podr.name, function(podrData)
selectedPodr = podrData
local f2 = factions[selectedFaction.id]
-- Update specialties
specScroll:Clear()
selectedSpec = nil
specButtons = {}
for specId, spec in pairs(f2.Spec) do
if spec.podr == podrData.id then
CreateRow(specScroll, spec.name, function(specData)
selectedSpec = specData
end, { id = specId }, specButtons)
end
end
-- Update ranks based on subdivision
rankScroll:Clear()
selectedRank = nil
rankButtons = {}
local targetRanks = (f2.Podr[podrData.id] and f2.Podr[podrData.id].ranks) or f2.Ranks
if targetRanks then
local keys = {}
for k in pairs(targetRanks) do table.insert(keys, k) end
table.sort(keys)
for _, rankId in ipairs(keys) do
local rank = targetRanks[rankId]
CreateRow(rankScroll, GetDisplayName(rank[1]), function(rankData)
selectedRank = rankData
end, { id = rankId }, rankButtons)
end
end
end, { id = podId }, podrButtons)
end
local factionRanks = f.Ranks
if factionRanks then
local keys = {}
for k in pairs(factionRanks) do table.insert(keys, k) end
table.sort(keys)
for _, rankId in ipairs(keys) do
local rank = factionRanks[rankId]
CreateRow(rankScroll, GetDisplayName(rank[1]), function(rankData)
selectedRank = rankData
end, { id = rankId }, rankButtons)
end
end
end, { id = id }, factionButtons)
end
end, { steamID = p.steamID }, playerButtons)
end
end
end
searchBox.OnValueChange = function(_, value)
UpdatePlayerList(value)
end
UpdatePlayerList("")
-- Кнопка назначения
local applyBtn = vgui.Create("DButton", menuFrame)
applyBtn:SetText("")
applyBtn:SetSize(200, 40)
applyBtn:SetPos(menuFrame:GetWide()/2 - 100, startY + totalHeight + 10)
applyBtn.Paint = function(s, 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, 2)
draw.SimpleText("НАЗНАЧИТЬ", "ixSmallFont", w/2, h/2, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
if s:IsHovered() then
surface.SetDrawColor(Color(255, 255, 255, 30))
surface.DrawRect(0, 0, w, h)
end
end
applyBtn.DoClick = function()
if not (selectedPlayer and selectedFaction and selectedPodr and selectedSpec and selectedRank) then
LocalPlayer():Notify("Выберите все поля!")
return
end
net.Start("ixWhitelistMenuApply")
net.WriteString(selectedPlayer.steamID)
net.WriteUInt(selectedFaction.id, 16)
net.WriteUInt(selectedPodr.id, 8)
net.WriteUInt(selectedSpec.id, 8)
net.WriteUInt(selectedRank.id, 8)
net.SendToServer()
menuFrame:Close()
LocalPlayer():Notify("Вайтлист успешно назначен!")
end
-- Статус выбора
local statusPanel = vgui.Create("DPanel", menuFrame)
statusPanel:SetSize(400, 30)
statusPanel:SetPos(menuFrame:GetWide()/2 - 200, startY + totalHeight - 553.5)
statusPanel.Paint = function(s, w, h)
local statusText = "Выберите игрока и все параметры"
local statusColor = Color(200, 200, 200)
if selectedPlayer and selectedFaction and selectedPodr and selectedSpec and selectedRank then
statusText = "Готово к назначению"
statusColor = Color(84, 147, 90)
end
draw.SimpleText(statusText, "ixSmallFont", w/2, h/2, statusColor, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
end
menuFrame.OnCursorEntered = function(s)
s:MoveToFront()
end
end)