aboutsummaryrefslogtreecommitdiff
path: root/gamemode/core/npc/sv_npcsystem.lua
blob: 7c75f90a72d6c68216ff97b65aad7d096611a1a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
---Various functions for npcs.
-- Helps you spawn monsters, townies, and shopkeepers
--@server sv_npcsystem.lua
--@alias n

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 npctbl
--@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)
--@usage artery_makenpc <npc_name>
--@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