Spawning NPCs

Hello everyone! Rather new at this whole lua thing…

I am working on a gmod gamemode just for the fun of trying new things. I am currently trying to build zombie NPC spawn points. I have some code that will allow me to use a Vector table for the NPC pos. It even uses a timer to respawn the NPC after its killed.

My problem is that I cannot find a way to allow me to make more then one spawn point. Reguardless of what I do it will only spawn one NPC. Here is what my current code looks like…


function zombieSpawn()
  local zombieLocations = {
    Vector( -5635.888672, -6815.846191, 128.031250 ),
  }
  local zombieTypes = {
    ents.Create( "npc_zombie" ),
    ents.Create( "npc_fastzombie" ),
	ents.Create( "npc_poisonzombie" ),
  }
  local zombiePos = table.Random( zombieLocations )
  local zombieType = table.Random( zombieTypes )
  
  zombieType:SetPos( zombiePos )
  zombieType:Spawn()
  
  print("Zombie has spawned.")

hook.Add("OnNPCKilled", "zombieSpawn", function( npc, killer )
	local Rand = math.random( 1, 3 )
	local SpawnHeight = 100
	local NpcPos = npc:GetPos()
	local Drop
	  
	if Rand == 1 then
	  Drop = ents.Create( "weapon_shotgun" )
	  Drop:SetPos( NpcPos+Vector( 0, 0, SpawnHeight ) )
	  Drop:Spawn()
	 elseif Rand == 2 then
	  Drop = ents.Create( "weapon_smg1" )
	  Drop:SetPos( NpcPos+Vector( 0, 0, SpawnHeight ) )
	  Drop:Spawn()  
	 elseif Rand == 3 then
	  Drop = ents.Create( "weapon_crossbow" )
	  Drop:SetPos( NpcPos+Vector( 0, 0, SpawnHeight ) )
	  Drop:Spawn()  
	 end
	 timer.Create( "zombieType", 15, 1, zombieSpawn )
end)
  
end
timer.Create( "zombieType", 15, 1, zombieSpawn )

Ideas and insight would be helpful.

Thank you for you time.

  • Ignore

Do not make tables inside a function when the function is going to be called more than once unless you seriously have to make that table or edit that table.
Please learn to indent your code with **TAB **it makes code a lot cleaner and easier to read.
I would advise you get notepad++ or something with a lua highlighter.

Since you want to make a zombie spawn I would advise using hooks not a timer since it is unnecessary.
You can use the “InitPostEntity” to spawn the NPCs when your server starts up and all the map entities are created. After that I would use the “OnNPCKilled” hook to check if the NPC that was killed was a part of your spawners table/data structure. This can easily be achieved by creating the NPC and putting a variable on it such as:


mynpc.CSpawned = true

Once you’re inside of your OnNPCKilled hook you can do something like:
[lua]
if npc.CSpawned then – check if it is Customly Spawned
–Remove npc from table/data then spawn another
end
[/lua]

If you have given up, post back here and I can show you exactly how you can efficiently create an npc spawner.

You can rate me dumb all you want but this is a correct way.

Ok, you could do this



local CreateSpawn = { }
CreateSpawn[1] = { }
CreateSpawn[1].Vector = Vector(-5635.888672, -6815.846191, 128.031250)

CreateSpawn[2] = { }
CreateSpawn[2].Vector = Vector(-5635.888672, -6815.846191, 128.031250)

function zombieSpawn()
	for k, v in pairs( CreateSpawn ) do -- For every CreateSpawn[number] it will create a spawn
		local zombieLocations = {
			Spawn[k].Vector,
		}
		local zombieTypes = {
			ents.Create( "npc_zombie" ),
			ents.Create( "npc_fastzombie" ),
			ents.Create( "npc_poisonzombie" ),
		}
		local zombiePos = table.Random( zombieLocations )
		local zombieType = table.Random( zombieTypes )
		  
		zombieType:SetPos( zombiePos )
		zombieType:Spawn()
		  
		print("Zombie has spawned.")

		hook.Add("OnNPCKilled", "zombieSpawn", function( npc, killer )
			local Rand = math.random( 1, 3 )
			local SpawnHeight = 100
			local NpcPos = npc:GetPos()
			local Drop
			  
			if Rand == 1 then
				Drop = ents.Create( "weapon_shotgun" )
				Drop:SetPos( NpcPos+Vector( 0, 0, SpawnHeight ) )
				Drop:Spawn()
			elseif Rand == 2 then
				Drop = ents.Create( "weapon_smg1" )
				Drop:SetPos( NpcPos+Vector( 0, 0, SpawnHeight ) )
				Drop:Spawn()  
			elseif Rand == 3 then
				Drop = ents.Create( "weapon_crossbow" )
				Drop:SetPos( NpcPos+Vector( 0, 0, SpawnHeight ) )
				Drop:Spawn()  
			end
			timer.Create( "zombieType", 15, 1, zombieSpawn )
		end)
	end
end

timer.Create( "zombieType", 15, 1, zombieSpawn )


Ohh, wait, didn’t update the side, the same thing as brandonj4 said basicly…

What I did there was making more than one spawn point :slight_smile:

Annnnd, do you self a favor and get Notepad++

Thank you both for your rather quick reply.

Errolight, I worked a little with the code you posted and it worked wonders, however, once one zombie is killed, all spawn points are called by the timer. I was trying to make it as if zombie a was killed zombie a would respawn not zombie b, c and d.

brandonj4, I tried to pull up some examples online using the “InitPostEntity” but wasn’t able to find much to would help me better understand the feature. Me being new at this lua business (I know not a very good excuse) its hard to rap my head around some of these things. I’m sorry for my ignorance but a example of what you stated above would help me out a lot.

Add me on steam and I’ll go into further detail. I already added you, you just have to add me back.

Well, you want to make a table name for each pairs, and then put the timer under the pairs function… I guess? Idk. But brandonj4 might know some about that.

That depends on what he want to make…

Thank you brandonj4 for not only helping me, but helping me understand the code.

This is what it came to…

It works wonders. I’m going to go back and built loot tables to the NPCs drop things on death.