add sborka
This commit is contained in:
@@ -0,0 +1,384 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user