mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
175 lines
4.4 KiB
Lua
175 lines
4.4 KiB
Lua
--[[
|
|
| This file was obtained through the combined efforts
|
|
| of Madbluntz & Plymouth Antiquarian Society.
|
|
|
|
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
|
| Maloy, DrPepper10 @ RIP, Atle!
|
|
|
|
|
| Visit for more: https://plymouth.thetwilightzone.ru/
|
|
--]]
|
|
|
|
|
|
local sbox_search_maxresults = CreateClientConVar( "sbox_search_maxresults", "1024", true, false, "The maximum amount of results the spawnmenu search should show. Model amount limited to 1/2 of this value, entities are limited to 1/4", 1024 )
|
|
|
|
local totalCalls = 0
|
|
local expectedCalls = 1
|
|
|
|
local queuedSearch = {}
|
|
|
|
local function GetAllFiles( tab, folder, extension, path )
|
|
|
|
totalCalls = totalCalls + 1
|
|
|
|
local files, folders = file.Find( folder .. "*", path )
|
|
|
|
if ( !files ) then
|
|
MsgN( "Warning! Ignoring '" .. folder .. "' because we cannot search in it!" )
|
|
return
|
|
end
|
|
|
|
for k, v in ipairs( files ) do
|
|
|
|
if ( v:EndsWith( extension ) ) then
|
|
table.insert( tab, ( folder .. v ):lower() )
|
|
end
|
|
|
|
end
|
|
|
|
for k, v in ipairs( folders ) do
|
|
expectedCalls = expectedCalls + 1
|
|
table.insert( queuedSearch, { tab, folder .. v .. "/", extension, path } )
|
|
end
|
|
|
|
notification.AddProgress( "SandboxSearchIndexing", "#spawnmenu.searchindex", totalCalls / expectedCalls )
|
|
if ( totalCalls >= expectedCalls ) then notification.Kill( "SandboxSearchIndexing" ) end
|
|
|
|
end
|
|
|
|
hook.Add( "Think", "sandbox_queued_search", function()
|
|
|
|
if ( #queuedSearch < 1 ) then return end
|
|
|
|
local call = queuedSearch[ 1 ]
|
|
GetAllFiles( unpack( call ) )
|
|
table.remove( queuedSearch, 1 )
|
|
|
|
if ( !timer.Exists( "search_models_update" ) || #queuedSearch < 1 ) then
|
|
timer.Create( "search_models_update", 1, 1, function() hook.Run( "SearchUpdate" ) end )
|
|
end
|
|
|
|
end )
|
|
|
|
--
|
|
-- Model Search
|
|
--
|
|
local model_list = nil
|
|
search.AddProvider( function( str )
|
|
|
|
if ( model_list == nil ) then
|
|
|
|
model_list = {}
|
|
GetAllFiles( model_list, "models/", ".mdl", "GAME" )
|
|
|
|
end
|
|
|
|
local models = {}
|
|
|
|
for k, v in ipairs( model_list ) do
|
|
|
|
-- Don't search in the models/ and .mdl bit of every model, because every model has this bit, unless they are looking for direct model path
|
|
local modelpath = v
|
|
if ( modelpath:StartsWith( "models/" ) && modelpath:EndsWith( ".mdl" ) && !str:EndsWith( ".mdl" ) ) then modelpath = modelpath:sub( 8, modelpath:len() - 4 ) end
|
|
|
|
if ( modelpath:find( str, nil, true ) ) then
|
|
|
|
if ( IsUselessModel( v ) ) then continue end
|
|
|
|
local entry = {
|
|
text = v:GetFileFromFilename(),
|
|
func = function() RunConsoleCommand( "gm_spawn", v ) end,
|
|
icon = spawnmenu.CreateContentIcon( "model", g_SpawnMenu.SearchPropPanel, { model = v } ),
|
|
words = { v }
|
|
}
|
|
|
|
table.insert( models, entry )
|
|
|
|
end
|
|
|
|
if ( #models >= sbox_search_maxresults:GetInt() / 2 ) then break end
|
|
|
|
end
|
|
|
|
return models
|
|
|
|
end, "props" )
|
|
|
|
hook.Add( "GameContentChanged", "ResetModelSearchCache", function()
|
|
|
|
-- Addons got remounted, reset the model search cache
|
|
model_list = nil
|
|
|
|
-- Reset any ongoing search process
|
|
totalCalls = 0
|
|
expectedCalls = 1
|
|
queuedSearch = {}
|
|
|
|
end )
|
|
|
|
|
|
--
|
|
-- Entity, vehicles
|
|
--
|
|
local function AddSearchProvider( listname, ctype, stype )
|
|
search.AddProvider( function( str )
|
|
|
|
local results = {}
|
|
local entities = {}
|
|
|
|
for k, v in pairs( list.Get( listname ) ) do
|
|
if ( listname == "Weapon" && !v.Spawnable ) then continue end
|
|
|
|
v.ClassName = k
|
|
v.PrintName = v.PrintName or v.Name
|
|
v.ScriptedEntityType = ctype
|
|
table.insert( entities, v )
|
|
end
|
|
|
|
for k, v in ipairs( entities ) do
|
|
|
|
local name = v.PrintName
|
|
local name_c = v.ClassName
|
|
if ( !isstring( name ) && !isstring( name_c ) ) then continue end
|
|
|
|
if ( ( isstring( name ) && name:lower():find( str, nil, true ) ) || ( isstring( name_c ) && name_c:lower():find( str, nil, true ) ) ) then
|
|
|
|
local entry = {
|
|
text = v.PrintName or v.ClassName,
|
|
icon = spawnmenu.CreateContentIcon( v.ScriptedEntityType or "entity", nil, {
|
|
nicename = v.PrintName or v.ClassName,
|
|
spawnname = v.ClassName,
|
|
material = "entities/" .. v.ClassName .. ".png",
|
|
|
|
admin = v.AdminOnly
|
|
} ),
|
|
words = { v }
|
|
}
|
|
|
|
table.insert( results, entry )
|
|
|
|
end
|
|
|
|
if ( #results >= sbox_search_maxresults:GetInt() / 4 ) then break end
|
|
|
|
end
|
|
|
|
table.SortByMember( results, "text", true )
|
|
return results
|
|
|
|
end, stype )
|
|
end
|
|
|
|
AddSearchProvider( "SpawnableEntities", "entity", "entities" )
|
|
AddSearchProvider( "Vehicles", "vehicle", "vehicles" )
|
|
AddSearchProvider( "NPC", "npc", "npcs" )
|
|
AddSearchProvider( "Weapon", "weapon", "weapons" )
|