Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- util.AddNetworkString("send_ztable_cl")
- util.AddNetworkString("send_ztable_sr")
- util.AddNetworkString("zinv_changecvar")
- concommand.Add("zinv_reloadsettings", load_npc_info)
- include( "shared.lua" )
- AddCSLuaFile( "shared.lua" )
- default_settings = [[
- "NPC_Settings"
- {
- "1"
- {
- "health" "-1"
- "chance" "100"
- "model" ""
- "scale" "1"
- "class_name" "npc_zombie"
- "weapon" ""
- "max" "10"
- "type" "Chaser"
- "explode" "true"
- }
- "2"
- {
- "health" "-1"
- "chance" "30"
- "model" ""
- "scale" "1"
- "class_name" "npc_fastzombie"
- "weapon" ""
- "max" "10"
- "type" "Chaser"
- "explode" "false"
- }
- "3"
- {
- "health" "-1"
- "chance" "40"
- "model" ""
- "scale" "1"
- "class_name" "npc_headcrab_fast"
- "weapon" ""
- "max" "10"
- "type" "Chaser"
- "explode" "false"
- }
- }]]
- hook.Add("OnNPCKilled","NPC_Died_zinv", function(victim, killer, weapon)
- local class = classSettings(victim:GetClass())
- if !class or class["explode"] != "true" then
- return
- end
- local explode = ents.Create( "env_explosion" )
- explode:SetPos( victim:GetPos() )
- explode:Spawn()
- explode:SetKeyValue( "iMagnitude", "35" )
- explode:Fire( "Explode", 0, 0 )
- explode:EmitSound( "weapon_AWP.Single", 400, 400 )
- end)
- hook.Add("Initialize", "initializing_zinv", function()
- Nodes = {}
- total_chance = 0
- load_npc_info()
- found_ain = false
- ParseFile()
- end)
- hook.Add("PlayerInitialSpawn", "pinitspawn_zinv", function(ply)
- net.Start("send_ztable_cl")
- net.WriteTable(zombie_list)
- net.Send(ply)
- end)
- hook.Add("EntityKeyValue", "newkeyval_zinv", function(ent)
- if ent:GetClass() == "info_player_teamspawn" then
- local valid = true
- for k,v in pairs(Nodes) do
- if v["pos"] == ent:GetPos() then
- valid = false
- end
- end
- if valid then
- local node = {
- pos = ent:GetPos(),
- yaw = 0,
- offset = 0,
- type = 0,
- info = 0,
- zone = 0,
- neighbor = {},
- numneighbors = 0,
- link = {},
- numlinks = 0
- }
- table.insert(Nodes, node)
- end
- end
- end)
- --Taken from nodegraph addon - thx
- local SIZEOF_INT = 4
- local SIZEOF_SHORT = 2
- local AINET_VERSION_NUMBER = 37
- local function toUShort(b)
- local i = {string.byte(b,1,SIZEOF_SHORT)}
- return i[1] +i[2] *256
- end
- local function toInt(b)
- local i = {string.byte(b,1,SIZEOF_INT)}
- i = i[1] +i[2] *256 +i[3] *65536 +i[4] *16777216
- if(i > 2147483647) then return i -4294967296 end
- return i
- end
- local function ReadInt(f) return toInt(f:Read(SIZEOF_INT)) end
- local function ReadUShort(f) return toUShort(f:Read(SIZEOF_SHORT)) end
- --Taken from nodegraph addon - thx
- --Types:
- --1 = ?
- --2 = info_nodes
- --3 = playerspawns
- --4 = wall climbers
- function ParseFile()
- if foundain then
- return
- end
- f = file.Open("maps/graphs/"..game.GetMap()..".ain","rb","GAME")
- if(!f) then
- return
- end
- found_ain = true
- local ainet_ver = ReadInt(f)
- local map_ver = ReadInt(f)
- if(ainet_ver != AINET_VERSION_NUMBER) then
- MsgN("ZINV: Unknown graph file")
- return
- end
- local numNodes = ReadInt(f)
- if(numNodes < 0) then
- MsgN("ZINV: Error, Map Nodes, 0")
- return
- end
- MsgN("ZINV: Map Nodes, ", numNodes)
- for i = 1,numNodes do
- local v = Vector(f:ReadFloat(),f:ReadFloat(),f:ReadFloat())
- local yaw = f:ReadFloat()
- local flOffsets = {}
- for i = 1,NUM_HULLS do
- flOffsets[i] = f:ReadFloat()
- end
- local nodetype = f:ReadByte()
- local nodeinfo = ReadUShort(f)
- local zone = f:ReadShort()
- if nodetype == 4 then
- continue
- end
- local node = {
- pos = v,
- yaw = yaw,
- offset = flOffsets,
- type = nodetype,
- info = nodeinfo,
- zone = zone,
- neighbor = {},
- numneighbors = 0,
- link = {},
- numlinks = 0
- }
- table.insert(Nodes,node)
- end
- end
- timer.Create("zombietimercheck_zinv", 10, 0, function()
- local status, err = pcall( function()
- local valid_nodes = {}
- local zombies = {}
- if GetConVarNumber("zinv") == 0 or table.Count(player.GetAll()) <= 0 then
- return
- end
- if !found_ain then
- ParseFile()
- end
- if GetConVarNumber("zinv_maxdist") < GetConVarNumber("zinv_mindist") then
- print("ZINV: Zombies cannot spawn! Max spawn distance is less than Min!")
- end
- if !zombie_list then
- print("ZINV: Error with zombie_list")
- return
- end
- if !Nodes or table.Count(Nodes) < 1 then
- print("ZINV: No info_node(s) in map! NPCs will not spawn.")
- return
- end
- if table.Count(Nodes) <= 35 then
- print("ZINV: Zombies may not spawn well on this map, please try another.")
- end
- for k, v in pairs(zombie_list) do
- local zombies = table.Add(zombies, ents.FindByClass(v["class_name"]))
- end
- --Check zombie
- for k, v in pairs(zombies) do
- local closest = -1
- local closest_plr = NULL
- local zombie_pos = v:GetPos()
- for k2, v2 in pairs(player.GetAll()) do
- local dist = zombie_pos:Distance(v2:GetPos())
- if dist < closest or closest == -1 then
- closest_plr = v2
- closest = dist
- end
- end
- if closest > GetConVarNumber("zinv_maxdist")*1.25 then
- v:Remove()
- else
- local class = classSettings(v:GetClass())
- if !class or v.Base == "base_nextbot" then
- continue
- end
- if class["type"] == "Chaser" then
- v:SetLastPosition(closest_plr:GetPos())
- v:SetSaveValue("m_vecLastPosition", closest_plr:GetPos())
- v:SetTarget(closest_plr)
- if !v:IsCurrentSchedule(SCHED_TARGET_CHASE) then
- v:SetSchedule(SCHED_TARGET_CHASE)
- end
- elseif class["type"] == "Roamer" then
- if !v:IsCurrentSchedule(SCHED_RUN_RANDOM) and v:IsCurrentSchedule(SCHED_IDLE_STAND) then
- v:SetSchedule(SCHED_RUN_RANDOM)
- end
- end
- end
- end
- end)
- if !status then
- print(err)
- end
- end)
- timer.Create("zombietimer_zinv", 1, 0, function()
- local status, err = pcall( function()
- local valid_nodes = {}
- local zombies = {}
- if GetConVarNumber("zinv") == 0 or table.Count(player.GetAll()) <= 0 then
- return
- end
- if !found_ain then
- ParseFile()
- end
- if GetConVarNumber("zinv_maxdist") < GetConVarNumber("zinv_mindist") then
- print("ZINV: Zombies cannot spawn! Max spawn distance is less than Min!")
- end
- if !zombie_list then
- print("ZINV: Error with zombie_list")
- return
- end
- if !Nodes or table.Count(Nodes) < 1 then
- print("ZINV: No info_node(s) in map! NPCs will not spawn.")
- return
- end
- if table.Count(Nodes) <= 35 then
- print("ZINV: Zombies may not spawn well on this map, please try another.")
- end
- for k, v in pairs(zombie_list) do
- local zombies = table.Add(zombies, ents.FindByClass(v["class_name"]))
- end
- --Get valid nodes
- for k, v in pairs(Nodes) do
- local valid = false
- if table.Count(valid_nodes) >= 50*table.Count(player.GetAll()) then
- break
- end
- for k2, v2 in pairs(player.GetAll()) do
- local dist = v["pos"]:Distance(v2:GetPos())
- if dist <= GetConVarNumber("zinv_mindist") then
- valid = false
- break
- elseif dist < GetConVarNumber("zinv_maxdist") then
- valid = true
- if v2:VisibleVec(v["pos"]) then
- valid = false
- end
- end
- end
- if !valid then
- continue
- end
- for k2, v2 in pairs(zombies) do
- local dist = v["pos"]:Distance(v2:GetPos())
- if dist <= 100 then
- valid = false
- break
- end
- end
- if valid then
- table.insert(valid_nodes, v["pos"])
- end
- end
- --Spawn zombies if not enough
- for k, v in pairs(zombie_list) do
- local c = table.Count(ents.FindByClass(v["class_name"]))
- if c < v["max"] then
- local loopmax = math.min(5, v["max"]-c)
- for i = 0, loopmax-1 do
- if (v["chance"]/100.0) <= math.Rand(0, 1) then
- continue
- end
- local pos = table.Random(valid_nodes)
- if pos != nil then
- table.RemoveByValue(valid_nodes, pos)
- spawn_zombie(v, pos + Vector(0,0,30))
- end
- end
- end
- end
- end)
- if !status then
- print(err)
- end
- end)
- --returns false if classStr not in zombie_list, returns the entry if found
- function classSettings(classStr)
- for k, v in pairs(zombie_list) do
- if v["class_name"] == tostring(classStr) then
- return v
- end
- end
- return false
- end
- function spawn_zombie(z_class, pos)
- --Spawn NPC
- if z_class then
- local zombie = ents.Create(z_class["class_name"])
- if zombie then
- if z_class["weapon"] then
- zombie:SetKeyValue("additionalequipment", z_class["weapon"])
- end
- zombie:SetPos(pos)
- zombie:SetAngles(Angle(0, math.random(0, 360), 0))
- zombie:Spawn()
- if z_class["model"] then
- zombie:SetModel(z_class["model"])
- end
- if z_class["scale"] then
- zombie:SetModelScale(z_class["scale"], 0)
- end
- if z_class["health"] and z_class["health"] > 0 then
- zombie:SetHealth(z_class["health"])
- zombie:SetMaxHealth(z_class["health"])
- end
- zombie:Activate()
- end
- end
- end
- function load_npc_info()
- zombie_list = {}
- total_chance = 0
- local f = file.Read("zinv_settings.txt", "DATA")
- if f then
- Settings = util.KeyValuesToTable(f)
- for k, v in pairs(Settings) do
- table.insert(zombie_list, v)
- end
- end
- if !f or table.Count(zombie_list) <= 0 then
- file.Write("zinv_settings.txt", default_settings)
- Settings = util.KeyValuesToTable(default_settings)
- for k, v in pairs(Settings) do
- table.insert(zombie_list, v)
- end
- print("ZINV: Initial File Created: data/zinv_settings.txt")
- end
- --Check validity
- for k, v in pairs(zombie_list) do
- if tonumber(v["health"]) == nil then
- v["health"] = -1
- end
- if tonumber(v["chance"]) == nil then
- v["chance"] = 100
- end
- if tonumber(v["scale"]) == nil then
- v["scale"] = 1
- end
- if !v["model"] then
- v["model"] = ""
- end
- if !v["weapon"] then
- v["weapon"] = ""
- end
- if !v["class_name"] then
- v["class_name"] = ""
- end
- total_chance = total_chance + v["chance"]
- end
- print("--ZINV Settings--")
- PrintTable(zombie_list)
- --Notify players
- net.Start("send_ztable_cl")
- net.WriteTable(zombie_list)
- net.Broadcast()
- end
- net.Receive("send_ztable_sr", function(len, pl)
- if pl:IsValid() and pl:IsPlayer() and pl:IsSuperAdmin() then
- zombie_list = net.ReadTable()
- file.Write("zinv_settings.txt", util.TableToKeyValues(zombie_list))
- load_npc_info()
- print("ZINV: NPC waves edit by: "..pl:Nick())
- end
- end)
Advertisement
Add Comment
Please, Sign In to add comment