Данный код написан не мной и зависит от библиотеки CST и SAM . Позволяет блокировать пользователям вкладки в q меню и инструменты. И да это SH часть.
local BLOCKED = {
'#spawnmenu.category.your_spawnlists'
}
if (CLIENT) then
hook.Add('ChatText', 'cst', function(index, name, text, type)
if (type == 'joinleave') then
return true
end
end)
end
hook.Add('ContextMenuShowTool', 'cst', function()
-- return false
end)
if (CLIENT) then
favoriteCache = favoriteCache or {}
local function saveFavorites()
local encoded = pon.encode(favoriteCache)
file.Write('cst_prop_favorites.dat', encoded)
end
local function loadFavorites()
local name = 'cst_prop_favorites.dat'
if (file.Exists(name, 'DATA')) then
local encoded = file.Read(name, 'DATA')
local decoded = pon.decode(encoded)
favoriteCache = decoded
end
end
local function addFavorite(model)
favoriteCache[model] = true
saveFavorites()
if (IsValid(favoriteSpawnmenuLayout)) then
for _, child in ipairs(favoriteSpawnmenuLayout:GetChildren()) do
child:Remove()
end
favoriteSpawnmenuLayout:Build()
end
end
local function deleteFavorite(model)
favoriteCache[model] = nil
saveFavorites()
if (IsValid(favoriteSpawnmenuLayout)) then
for _, child in ipairs(favoriteSpawnmenuLayout:GetChildren()) do
child:Remove()
end
favoriteSpawnmenuLayout:Build()
end
end
local function isFavorite(model)
return favoriteCache[model]
end
hook.Add('gP:PostAddedDMenuOption', 'test', function(state, menu, name)
local hovered = vgui.GetHoveredPanel()
local data = IsValid(hovered) and hovered:GetTable() or {}
local model = data and data.m_strModelName
if (name == '#spawnmenu.menu.copy' and state == 'post' and model) then
menu:AddOption('Избранное', function()
addFavorite(model)
end):SetIcon('icon16/star.png')
end
end)
-- spawnmenu.AddCreationTab( 'Избранное', function()
-- local size = cst.util.Tall(64)
-- local scrollList = vgui.Create( 'DScrollPanel' )
-- local lblTitle = scrollList:Add('DLabel')
-- lblTitle:SetFont(cst.Font('Overpass@48'))
-- lblTitle:SetExpensiveShadow(2, color_black)
-- lblTitle:Dock(TOP)
-- lblTitle:SetText('Избранные пропы')
-- lblTitle:SizeToContentsY()
-- lblTitle:SetTextColor(color_white)
-- loadFavorites()
-- local layout = scrollList:Add('DIconLayout')
-- layout:Dock(FILL)
-- layout.Build = function(panel)
-- for model in pairs(favoriteCache) do
-- local icon = panel:Add('SpawnIcon')
-- icon:SetModel(model)
-- icon:SetSize(size, size)
-- icon.DoClick = function()
-- RunConsoleCommand('gm_spawn', model)
-- surface.PlaySound( "ui/buttonclickrelease.wav" )
-- end
-- icon.DoRightClick = function()
-- local dmenu = DermaMenu()
-- dmenu:AddOption('Удалить избранное', function()
-- deleteFavorite(model)
-- end):SetIcon('icon16/delete.png')
-- dmenu:Open()
-- end
-- end
-- panel:InvalidateParent(true)
-- panel:Layout()
-- end
-- favoriteSpawnmenuLayout = layout
-- layout:Build()
-- return scrollList
-- end, 'icon16/star.png', 200 )
end
if (CLIENT) then
historyCache = historyCache or {}
hook.Add( 'PopulateHistory', 'AddEntityContent', function( pnlContent )
local size = cst.util.Tall(64)
local lblTitle = pnlContent:Add('DLabel')
lblTitle:SetFont(cst.Font('Overpass@48'))
lblTitle:SetExpensiveShadow(2, color_black)
lblTitle:Dock(TOP)
lblTitle:SetText('Последние использованные пропы')
lblTitle:SizeToContentsY()
lblTitle:SetTextColor(color_white)
local layout = pnlContent:Add('DIconLayout')
layout:Dock(FILL)
layout.Build = function(panel)
for model in pairs(historyCache) do
local icon = panel:Add('SpawnIcon')
icon:SetModel(model)
icon:SetSize(size, size)
icon.DoClick = function()
RunConsoleCommand('gm_spawn', model)
surface.PlaySound( "ui/buttonclickrelease.wav" )
end
end
panel:InvalidateParent(true)
panel:Layout()
end
historySpawnmenuLayout = layout
layout:Build()
end )
net.Receive('cst.SendPropHistory', function(len)
local model = net.ReadString()
if (not historyCache[model]) then
historyCache[model] = true
if (IsValid(historySpawnmenuLayout)) then
for _, child in ipairs(historySpawnmenuLayout:GetChildren()) do
child:Remove()
end
historySpawnmenuLayout:Build()
end
end
end)
-- spawnmenu.AddCreationTab( 'История', function()
-- ctrl = vgui.Create( 'DScrollPanel' );
-- hook.Run('PopulateHistory', ctrl)
-- return ctrl
-- end, 'icon16/control_repeat_blue.png', 200 )
else
util.AddNetworkString('cst.SendPropHistory')
hook.Add('PlayerSpawnedProp', 'prop.history', function(ply, model)
-- net.Start('cst.SendPropHistory')
-- net.WriteString(model)
-- net.Send(ply)
end)
end
if (CLIENT) then
local permissions = {
['#spawnmenu.category.weapons'] = 'weapons',
['#spawnmenu.category.npcs'] = 'npcs',
['#spawnmenu.category.entities'] = 'entities'
}
local super = {
['GuthSCP'] = true,
['DrGBase'] = true,
['#spawnmenu.category.vehicles'] = true,
}
local function modifyCreationMenu()
cst.util.FindPanel('CreationMenu', function(panel)
for _, tab in ipairs(panel:GetItems()) do
local name = tab.Name
local pnl = tab.Tab
local isDisabled = {
["#spawnmenu.category.dupes"] = true,
["#spawnmenu.category.saves"] = true,
-- ["#spawnmenu.category.npcs"] = true,
-- ["#spawnmenu.category.vehicles"] = true,
["#spawnmenu.category.postprocess"] = true
}
pnl:SetVisible(true)
if (permissions[name] and not LocalPlayer():HasPermission(permissions[name])) then
pnl:SetVisible(false)
end
if isDisabled[name] then
pnl:SetVisible(false)
end
if (super[name] and not LocalPlayer():IsSuperAdmin()) then
pnl:SetVisible(false)
end
panel.tabScroller:InvalidateLayout()
end
end)
end
local function modifyTools()
local client = LocalPlayer()
cst.util.FindPanel('ToolPanel', function(panel)
for _, tab in ipairs(panel.List.pnlCanvas:GetChildren()) do
local count = 0
-- Remove tools
for _, child in ipairs(tab:GetChildren()) do
if child.ClassName == 'DButton' then
local toolID = child.Name
local isSuperadmin = {
['physprop'] = true,
}
local disabletool = {
["dynamite"] = false,
["motor"] = false,
["finger"] = false,
["trails"] = false,
["balloon"] = false,
["hoverball"] = false,
["thruster"] = false,
["inflator"] = false,
["eyeposer"] = false,
["faceposer"] = false,
["paint"] = false,
-- ["duplicator"] = false,
["emitter"] = false,
-- ["wheel"] = false,
["weld"] = false
}
if (
disabletool[toolID]
or (not client:HasPermission(toolID))
or (isSuperadmin[toolID] and not client:IsSuperAdmin())
) then
child:SetVisible(false)
else
child:SetVisible(true)
end
end
end
-- Count how many tools remained in category
for _, child in ipairs(tab:GetChildren()) do
if child.ClassName == 'DButton' and child:IsVisible() then
count = count + 1
end
end
-- Delete category if there's no tools
if count == 0 then
tab:SetVisible(false)
else
tab:SetVisible(true)
end
end
panel.List.pnlCanvas:InvalidateLayout()
end)
end
local cvShowProps = CreateClientConVar('cl_cst_show_default_props', '0', true, false)
local function modifySpawnmenu()
cst.util.FindPanel('SpawnmenuContentPanel', function(panel)
local navbar = panel.ContentNavBar
local tree = navbar.Tree
local node = tree.RootNode
for _, child in pairs(node:GetChildren()) do
if child.ClassName == 'DListLayout' then
for _, tab in pairs(child:GetChildren()) do
local text = tab:GetText()
if text == language.GetPhrase('#spawnmenu.category.your_spawnlists') then
tab:SetVisible(cvShowProps:GetBool())
elseif (text == language.GetPhrase('#spawnmenu.category.addon_spawnlists')) then
local children = tab.ChildNodes:GetChildren()
local tab1 = children[1]
if (IsValid(tab1) and not panel.switchedToFirst) then
tab1:InternalDoClick()
panel.switchedToFirst = true
end
end
end
child:InvalidateLayout()
end
end
end)
end
hook.Add('SpawnMenuOpened', 'cst.spawnmenu', function()
modifyCreationMenu()
modifyTools()
modifySpawnmenu()
end)
end
Результат :
