--[[ | 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" )