---Lets huntable monsters drop loot. -- Register what monsters drop what loot --@server sv_huntingspawner.lua --@alias o --[[ This file spawns the huntable npc's in their zones. ]] if not nrequire("sh_zones.lua") then return end 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) e:Spawn() 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) --print(randnum) 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 = {} ---Register a monster's loot. -- Register a table of loot to probability of dropping to a monster. Will warn if you try to register the same monster twice. An npc can define it's own drops, but if you're using npcs from elsewhere, use this function to tell the gamemode what to drop on each npc's death. --@tparam string npcname The name of the npc to give loot to --@tparam table tbl The table of {"item\_name"=number\_drop_chance}, drop chance should be in the range 0 < x <= 100. 100 is always drop, 0 is never drop. function o.RegisterDrops(npcname,tbl) if not external_drops[npcname] == nil then MsgC(Color(255,255,0),"WARNING: Tried to register 2 drop tables for " .. npcname) end --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] if rng < itemchance then local drop = itm.GetItemByName(itemname) print("Createing a drop of",drop) track.DropItem(drop, npc:GetPos()) end end end) return o