--[[ This file spawns the huntable npc's in their zones. ]] local track = nrequire("core/inventory/sv_invtracker.lua") local itm = nrequire("core/inventory/item.lua") local o = {} local huntablenodes = {} function o.CreateSpawnNode(tbl) huntablenodes[#huntablenodes+1] = tbl local e = ents.Create("info_huntablespawn") e:SetPos(tbl.Position) end local function SpawnMonsterFor(ply,zone) --Check what hunting ground we're in print("I want to attack",ply) if zone == nil then return end print("I am in a zone!") local possiblenpcs = zone.npctbl PrintTable(possiblenpcs) local randnum = math.random(0,100) print("Random num was",randnum) local npctype for k,v in pairs(possiblenpcs) do randnum = randnum - v print("Subtracting ", v , " for ",k) if randnum < 0 then npctype = k break end end if npctype == nil then print(ply,"got lucky this time...") return end print("I will spawn a ",npctype,"to attack ",ply,"!") --Find a place for the npc to spawn that's out of sight! local potentialspots = ents.FindInSphere( ply:GetPos(), 4000 ) for k,v in pairs(potentialspots) do print("Checking spot",v) if v:GetClass() ~= "info_huntablespawn" then print("Was not an info_huntablespawn") potentialspots[k] = nil else local tr = util.TraceLine({ start = v:GetPos() + Vector(0,0,50), endpos = ply:GetPos() + Vector(0,0,64), }) if tr.Hit and tr.Entity == ply then potentialspots[k] = nil print("Player could see this point") end end end local a = {} for k,v in pairs(potentialspots) do a[#a+1] = v end --Choose a random spot! local spawnpos = a[math.random(1,#a)] print("I want to spawn a monster at", spawnpos) if spawnpos == nil then print("Couldn't find a spot to spawn an NPC around",ply,"at",ply:GetPos(),"make sure there are enough info_huntablespawn entities around in little corners and stuff") return end --Do a trace up to hit the skybox, local npc = ents.Create(npctype) npc:SetPos(spawnpos:GetPos()) npc:SetEnemy(ply) npc:Spawn() end local lastspawned = {} for k,v in pairs(player.GetAll()) do lastspawned[v] = CurTime() end hook.Add("PlayerInitialSpawn","add_to_huntable_tbl",function(ply) lastspawned[ply] = CurTime() end) hook.Add("Tick","occasionally_spawn_monsters",function() for _,ply in pairs(player.GetAll()) do local zone = ply:GetCurrentZone( "artery_huntingground" ) if zone == nil then continue end if CurTime() - lastspawned[ply] > zone.SpawnRate then SpawnMonsterFor(ply,zone) lastspawned[ply] = CurTime() end end end) local external_drops = {} function o.RegisterDrops(npcname,tbl) assert(external_drops[npcname] == nil, string.format("Tried to register 2 drop tables for the npc %q",npcname)) external_drops[npcname] = tbl end hook.Add("OnNPCKilled","droplootforexnpcs",function(npc,attacker,inflictor) local d = external_drops[npc:GetClass()] if d == nil then return end for k, v in pairs(d) do local rng = math.random(0, 100) local itemname = v[1] local itemchance = v[2] local heightoffset = 10 if rng < itemchance then local drop = itm.GetItemByName(itemname) print("Createing a drop of",drop) track.CreateDroppedItem(drop, self:GetPos()+Vector(math.random(20),math.random(20),20)) end end end) return o