Guest User

Server

a guest
Aug 7th, 2021
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.19 KB | None | 0 0
  1. util.AddNetworkString("send_ztable_cl")
  2. util.AddNetworkString("send_ztable_sr")
  3. util.AddNetworkString("zinv_changecvar")
  4. concommand.Add("zinv_reloadsettings", load_npc_info)
  5.  
  6. include( "shared.lua" )
  7. AddCSLuaFile( "shared.lua" )
  8.  
  9.  
  10. default_settings = [[
  11. "NPC_Settings"
  12. {
  13. "1"
  14. {
  15. "health" "-1"
  16. "chance" "100"
  17. "model" ""
  18. "scale" "1"
  19. "class_name" "npc_zombie"
  20. "weapon" ""
  21. "max" "10"
  22. "type" "Chaser"
  23. "explode" "true"
  24. }
  25. "2"
  26. {
  27. "health" "-1"
  28. "chance" "30"
  29. "model" ""
  30. "scale" "1"
  31. "class_name" "npc_fastzombie"
  32. "weapon" ""
  33. "max" "10"
  34. "type" "Chaser"
  35. "explode" "false"
  36. }
  37. "3"
  38. {
  39. "health" "-1"
  40. "chance" "40"
  41. "model" ""
  42. "scale" "1"
  43. "class_name" "npc_headcrab_fast"
  44. "weapon" ""
  45. "max" "10"
  46. "type" "Chaser"
  47. "explode" "false"
  48. }
  49. }]]
  50.  
  51. hook.Add("OnNPCKilled","NPC_Died_zinv", function(victim, killer, weapon)
  52. local class = classSettings(victim:GetClass())
  53. if !class or class["explode"] != "true" then
  54. return
  55. end
  56.  
  57. local explode = ents.Create( "env_explosion" )
  58. explode:SetPos( victim:GetPos() )
  59. explode:Spawn()
  60. explode:SetKeyValue( "iMagnitude", "35" )
  61. explode:Fire( "Explode", 0, 0 )
  62. explode:EmitSound( "weapon_AWP.Single", 400, 400 )
  63. end)
  64.  
  65. hook.Add("Initialize", "initializing_zinv", function()
  66. Nodes = {}
  67. total_chance = 0
  68. load_npc_info()
  69. found_ain = false
  70. ParseFile()
  71. end)
  72.  
  73. hook.Add("PlayerInitialSpawn", "pinitspawn_zinv", function(ply)
  74. net.Start("send_ztable_cl")
  75. net.WriteTable(zombie_list)
  76. net.Send(ply)
  77. end)
  78.  
  79. hook.Add("EntityKeyValue", "newkeyval_zinv", function(ent)
  80. if ent:GetClass() == "info_player_teamspawn" then
  81. local valid = true
  82. for k,v in pairs(Nodes) do
  83. if v["pos"] == ent:GetPos() then
  84. valid = false
  85. end
  86. end
  87.  
  88. if valid then
  89. local node = {
  90. pos = ent:GetPos(),
  91. yaw = 0,
  92. offset = 0,
  93. type = 0,
  94. info = 0,
  95. zone = 0,
  96. neighbor = {},
  97. numneighbors = 0,
  98. link = {},
  99. numlinks = 0
  100. }
  101. table.insert(Nodes, node)
  102. end
  103. end
  104. end)
  105.  
  106. --Taken from nodegraph addon - thx
  107. local SIZEOF_INT = 4
  108. local SIZEOF_SHORT = 2
  109. local AINET_VERSION_NUMBER = 37
  110. local function toUShort(b)
  111. local i = {string.byte(b,1,SIZEOF_SHORT)}
  112. return i[1] +i[2] *256
  113. end
  114. local function toInt(b)
  115. local i = {string.byte(b,1,SIZEOF_INT)}
  116. i = i[1] +i[2] *256 +i[3] *65536 +i[4] *16777216
  117. if(i > 2147483647) then return i -4294967296 end
  118. return i
  119. end
  120. local function ReadInt(f) return toInt(f:Read(SIZEOF_INT)) end
  121. local function ReadUShort(f) return toUShort(f:Read(SIZEOF_SHORT)) end
  122.  
  123. --Taken from nodegraph addon - thx
  124. --Types:
  125. --1 = ?
  126. --2 = info_nodes
  127. --3 = playerspawns
  128. --4 = wall climbers
  129. function ParseFile()
  130. if foundain then
  131. return
  132. end
  133.  
  134. f = file.Open("maps/graphs/"..game.GetMap()..".ain","rb","GAME")
  135. if(!f) then
  136. return
  137. end
  138.  
  139. found_ain = true
  140. local ainet_ver = ReadInt(f)
  141. local map_ver = ReadInt(f)
  142. if(ainet_ver != AINET_VERSION_NUMBER) then
  143. MsgN("ZINV: Unknown graph file")
  144. return
  145. end
  146.  
  147. local numNodes = ReadInt(f)
  148. if(numNodes < 0) then
  149. MsgN("ZINV: Error, Map Nodes, 0")
  150. return
  151. end
  152.  
  153. MsgN("ZINV: Map Nodes, ", numNodes)
  154. for i = 1,numNodes do
  155. local v = Vector(f:ReadFloat(),f:ReadFloat(),f:ReadFloat())
  156. local yaw = f:ReadFloat()
  157. local flOffsets = {}
  158. for i = 1,NUM_HULLS do
  159. flOffsets[i] = f:ReadFloat()
  160. end
  161. local nodetype = f:ReadByte()
  162. local nodeinfo = ReadUShort(f)
  163. local zone = f:ReadShort()
  164.  
  165. if nodetype == 4 then
  166. continue
  167. end
  168.  
  169. local node = {
  170. pos = v,
  171. yaw = yaw,
  172. offset = flOffsets,
  173. type = nodetype,
  174. info = nodeinfo,
  175. zone = zone,
  176. neighbor = {},
  177. numneighbors = 0,
  178. link = {},
  179. numlinks = 0
  180. }
  181.  
  182. table.insert(Nodes,node)
  183. end
  184. end
  185.  
  186. timer.Create("zombietimercheck_zinv", 10, 0, function()
  187. local status, err = pcall( function()
  188. local valid_nodes = {}
  189. local zombies = {}
  190.  
  191. if GetConVarNumber("zinv") == 0 or table.Count(player.GetAll()) <= 0 then
  192. return
  193. end
  194.  
  195. if !found_ain then
  196. ParseFile()
  197. end
  198.  
  199. if GetConVarNumber("zinv_maxdist") < GetConVarNumber("zinv_mindist") then
  200. print("ZINV: Zombies cannot spawn! Max spawn distance is less than Min!")
  201. end
  202.  
  203. if !zombie_list then
  204. print("ZINV: Error with zombie_list")
  205. return
  206. end
  207.  
  208. if !Nodes or table.Count(Nodes) < 1 then
  209. print("ZINV: No info_node(s) in map! NPCs will not spawn.")
  210. return
  211. end
  212.  
  213. if table.Count(Nodes) <= 35 then
  214. print("ZINV: Zombies may not spawn well on this map, please try another.")
  215. end
  216.  
  217. for k, v in pairs(zombie_list) do
  218. local zombies = table.Add(zombies, ents.FindByClass(v["class_name"]))
  219. end
  220.  
  221. --Check zombie
  222. for k, v in pairs(zombies) do
  223. local closest = -1
  224. local closest_plr = NULL
  225. local zombie_pos = v:GetPos()
  226.  
  227. for k2, v2 in pairs(player.GetAll()) do
  228. local dist = zombie_pos:Distance(v2:GetPos())
  229.  
  230. if dist < closest or closest == -1 then
  231. closest_plr = v2
  232. closest = dist
  233. end
  234. end
  235.  
  236. if closest > GetConVarNumber("zinv_maxdist")*1.25 then
  237. v:Remove()
  238. else
  239. local class = classSettings(v:GetClass())
  240. if !class or v.Base == "base_nextbot" then
  241. continue
  242. end
  243. if class["type"] == "Chaser" then
  244. v:SetLastPosition(closest_plr:GetPos())
  245. v:SetSaveValue("m_vecLastPosition", closest_plr:GetPos())
  246. v:SetTarget(closest_plr)
  247. if !v:IsCurrentSchedule(SCHED_TARGET_CHASE) then
  248. v:SetSchedule(SCHED_TARGET_CHASE)
  249. end
  250. elseif class["type"] == "Roamer" then
  251. if !v:IsCurrentSchedule(SCHED_RUN_RANDOM) and v:IsCurrentSchedule(SCHED_IDLE_STAND) then
  252. v:SetSchedule(SCHED_RUN_RANDOM)
  253. end
  254. end
  255. end
  256. end
  257.  
  258. end)
  259.  
  260. if !status then
  261. print(err)
  262. end
  263. end)
  264.  
  265. timer.Create("zombietimer_zinv", 1, 0, function()
  266. local status, err = pcall( function()
  267. local valid_nodes = {}
  268. local zombies = {}
  269.  
  270. if GetConVarNumber("zinv") == 0 or table.Count(player.GetAll()) <= 0 then
  271. return
  272. end
  273.  
  274. if !found_ain then
  275. ParseFile()
  276. end
  277.  
  278. if GetConVarNumber("zinv_maxdist") < GetConVarNumber("zinv_mindist") then
  279. print("ZINV: Zombies cannot spawn! Max spawn distance is less than Min!")
  280. end
  281.  
  282. if !zombie_list then
  283. print("ZINV: Error with zombie_list")
  284. return
  285. end
  286.  
  287. if !Nodes or table.Count(Nodes) < 1 then
  288. print("ZINV: No info_node(s) in map! NPCs will not spawn.")
  289. return
  290. end
  291.  
  292. if table.Count(Nodes) <= 35 then
  293. print("ZINV: Zombies may not spawn well on this map, please try another.")
  294. end
  295.  
  296. for k, v in pairs(zombie_list) do
  297. local zombies = table.Add(zombies, ents.FindByClass(v["class_name"]))
  298. end
  299.  
  300. --Get valid nodes
  301. for k, v in pairs(Nodes) do
  302. local valid = false
  303.  
  304. if table.Count(valid_nodes) >= 50*table.Count(player.GetAll()) then
  305. break
  306. end
  307.  
  308. for k2, v2 in pairs(player.GetAll()) do
  309. local dist = v["pos"]:Distance(v2:GetPos())
  310.  
  311. if dist <= GetConVarNumber("zinv_mindist") then
  312. valid = false
  313. break
  314. elseif dist < GetConVarNumber("zinv_maxdist") then
  315.  
  316. valid = true
  317.  
  318. if v2:VisibleVec(v["pos"]) then
  319.  
  320. valid = false
  321.  
  322. end
  323. end
  324. end
  325.  
  326. if !valid then
  327. continue
  328. end
  329.  
  330. for k2, v2 in pairs(zombies) do
  331. local dist = v["pos"]:Distance(v2:GetPos())
  332. if dist <= 100 then
  333. valid = false
  334. break
  335. end
  336. end
  337.  
  338. if valid then
  339. table.insert(valid_nodes, v["pos"])
  340. end
  341. end
  342.  
  343. --Spawn zombies if not enough
  344. for k, v in pairs(zombie_list) do
  345. local c = table.Count(ents.FindByClass(v["class_name"]))
  346. if c < v["max"] then
  347. local loopmax = math.min(5, v["max"]-c)
  348. for i = 0, loopmax-1 do
  349. if (v["chance"]/100.0) <= math.Rand(0, 1) then
  350. continue
  351. end
  352. local pos = table.Random(valid_nodes)
  353. if pos != nil then
  354. table.RemoveByValue(valid_nodes, pos)
  355. spawn_zombie(v, pos + Vector(0,0,30))
  356. end
  357. end
  358. end
  359. end
  360. end)
  361.  
  362. if !status then
  363. print(err)
  364. end
  365. end)
  366.  
  367. --returns false if classStr not in zombie_list, returns the entry if found
  368. function classSettings(classStr)
  369. for k, v in pairs(zombie_list) do
  370. if v["class_name"] == tostring(classStr) then
  371. return v
  372. end
  373. end
  374. return false
  375. end
  376.  
  377. function spawn_zombie(z_class, pos)
  378. --Spawn NPC
  379. if z_class then
  380. local zombie = ents.Create(z_class["class_name"])
  381. if zombie then
  382. if z_class["weapon"] then
  383. zombie:SetKeyValue("additionalequipment", z_class["weapon"])
  384. end
  385. zombie:SetPos(pos)
  386. zombie:SetAngles(Angle(0, math.random(0, 360), 0))
  387. zombie:Spawn()
  388. if z_class["model"] then
  389. zombie:SetModel(z_class["model"])
  390. end
  391. if z_class["scale"] then
  392. zombie:SetModelScale(z_class["scale"], 0)
  393. end
  394. if z_class["health"] and z_class["health"] > 0 then
  395. zombie:SetHealth(z_class["health"])
  396. zombie:SetMaxHealth(z_class["health"])
  397. end
  398. zombie:Activate()
  399. end
  400. end
  401. end
  402.  
  403. function load_npc_info()
  404. zombie_list = {}
  405. total_chance = 0
  406. local f = file.Read("zinv_settings.txt", "DATA")
  407. if f then
  408. Settings = util.KeyValuesToTable(f)
  409. for k, v in pairs(Settings) do
  410. table.insert(zombie_list, v)
  411. end
  412. end
  413.  
  414. if !f or table.Count(zombie_list) <= 0 then
  415. file.Write("zinv_settings.txt", default_settings)
  416. Settings = util.KeyValuesToTable(default_settings)
  417. for k, v in pairs(Settings) do
  418. table.insert(zombie_list, v)
  419. end
  420. print("ZINV: Initial File Created: data/zinv_settings.txt")
  421. end
  422.  
  423. --Check validity
  424. for k, v in pairs(zombie_list) do
  425. if tonumber(v["health"]) == nil then
  426. v["health"] = -1
  427. end
  428. if tonumber(v["chance"]) == nil then
  429. v["chance"] = 100
  430. end
  431. if tonumber(v["scale"]) == nil then
  432. v["scale"] = 1
  433. end
  434. if !v["model"] then
  435. v["model"] = ""
  436. end
  437. if !v["weapon"] then
  438. v["weapon"] = ""
  439. end
  440. if !v["class_name"] then
  441. v["class_name"] = ""
  442. end
  443. total_chance = total_chance + v["chance"]
  444. end
  445. print("--ZINV Settings--")
  446. PrintTable(zombie_list)
  447.  
  448. --Notify players
  449. net.Start("send_ztable_cl")
  450. net.WriteTable(zombie_list)
  451. net.Broadcast()
  452. end
  453.  
  454. net.Receive("send_ztable_sr", function(len, pl)
  455. if pl:IsValid() and pl:IsPlayer() and pl:IsSuperAdmin() then
  456. zombie_list = net.ReadTable()
  457. file.Write("zinv_settings.txt", util.TableToKeyValues(zombie_list))
  458. load_npc_info()
  459. print("ZINV: NPC waves edit by: "..pl:Nick())
  460.  
  461. end
  462. end)
Advertisement
Add Comment
Please, Sign In to add comment