---Various functions for npcs. -- Helps you spawn monsters, townies, and shopkeepers --@module sv_npcsystem.lua local f = nrequire("concommands.lua") local n = {} local npcs = {} --Master table of npcs local autocompletef ---Registers an NPC. -- Adds an npc to the global table. NPC's should have unique .Name fields, if they don't, this function will error. --@see npc --@tparam table npc The npc's table. function n.RegisterNPC(npc) assert(npc ~= nil, "Attempted to register a nil npc") assert(npc.Name ~= nil, "Attempted to register an npc without a name") npcs[npc.Name] = npc autocompletef = f.AutocompleteFunction(npcs) end ---Creates an NPC. -- Creates an npc, by name --@tparam string npcname The npc's name --@tparam vector3 pos The position to spawn the npc function n.CreateNPCByName(npcname, pos) assert(npcs[npcname],string.format("No npc named %q, valid names are:\n%s",npcname,table.concat(table.GetKeys(npcs),"\n"))) --print("Createing a ", npcname, " at ", pos) local npctbl = npcs[npcname] local npc = ents.Create("npc_huntable") npc:SetPos(pos) for k, v in pairs(npctbl) do npc[k] = v end npc:Spawn() return npc end ---Creats a shop npc. -- Creates a shop npc from a shop npc table --@see shopnpctbl --@tparam table npc The shop npc's table. function n.CreateShop(npc) --print("Createing shop npc") local npcent = ents.Create("npc_shop") for k,v in pairs(npc) do npcent[k] = v end npcent:Spawn() --print("Called spawn") end ---Creates a townie. -- Creates a new townie that wanders around his areas of intrest --@see townienpctbl --@tparam table npc The townie npc's table. function n.CreateTownie(tbl) local npcent = ents.Create("npc_townie") for k, v in pairs(tbl) do npcent[k] = v end npcent:Spawn() end ---Create an area of intrest. -- Creates an point that you can use in a townie's locations of intrest. --@see navnodetbl --@tparam table tbl The table for the nav node function n.CreateNavNode(tbl) local nodeent = ents.Create("info_townienode") assert(tbl ~= nil, "Tried to create a nil navnode") for k, v in pairs(tbl) do nodeent[k] = v end nodeent:Spawn() end --Ents to remove when refreshing the npc map local removeents = {"npc_townie", "info_townienode", "npc_shop"} -- "art_chest", for k, v in pairs(removeents) do local eot = ents.FindByClass(v) for i, j in pairs(eot) do j:Remove() end end local function ExecuteOnFolder(dir, recursive, func) local path = "" local fpath = table.concat({path,dir,"/*"}) local files, directories = file.Find(fpath,"DATA") for k,v in pairs(files) do local callpath = table.concat({path,dir,"/",v}) func(callpath) end if not recursive then return end for k,v in pairs(directories) do local npath = table.concat({dir,"/",v}) ExecuteOnFolder(npath,true,func) end end local function loadMap() local mapname = game.GetMap() local foldername = "artery/maps/" .. mapname ExecuteOnFolder(foldername,true,function(path) print("I want to run",path) local filetxt = file.Read(path,"DATA") --print("File text is", filetxt) CompileString(filetxt,path)() --print("I want to execute",path) end) end hook.Add("InitPostEntity", "artery_spawnmapnpcs", function() loadMap() end) ---Reloads the entities on the map -- Removes and then reload all of the entities on the level ![Requires admin](./req_admin) --@concommand artery_reloadmap concommand.Add("artery_reloadmap", function(ply,cmd,args) if not ply:IsAdmin() then return end for k, v in pairs(removeents) do local eot = ents.FindByClass(v) for i, j in pairs(eot) do j:Remove() end end loadMap() end) ---Create a new npc -- Creates a new npc a the point the player is looking ![Requires admin](./req_admin) --@concommand artery_makenpc concommand.Add("artery_makenpc", function(ply, cmd, args) if not ply:IsAdmin() then return end local na = args[1] n.CreateNPCByName(na, ply:GetEyeTrace().HitPos) end, autocompletef) return n