• Zombie Spawner
    6 replies, posted
Hey all,recently I've started making a Zombie kind of Game mode. I have only being using lua for a bit under a week although I do have experience in other code languages so some of the syntax may be wrong and things may be in wrong order etc. OK, so firstly my goal is to produce a master entity that spawns zombies at a random zombie spawn. The zombie spawns are named info_zspawn which I'll place into my maps using hammer. Also, I want to set the relationship of the zombie towards prop_physics and each current player so that the Zombie hates them. The base of the code is in init.lua I've commented the code A LOT to help you help me. There is also a few other questions in the comments which I'd like some help with. Last question, what is "ply"(I did try and find it in gmod wiki and google). Thank you :) [lua]AddCSLuaFile("cl_init.lua") -------------------------------Tel client to download the client side lua file AddCSLuaFile("shared.lua") -------------------------------Tel client to download the shared lua file include("shared.lua") -------------------------------Tel client and/or server (I think?) to load the shared file function ENT:Initialize() -------------------------------Initialize the master entity, the one that controls spawning and relations. self:SetModel("") -------------------------------Set the model to nothing as it's a logic entity(point entity) Do I have to do this or not? self:SetSolid(SOLID_NONE) -------------------------------Set the model's physical properties to nothing as it's a logic entity(point entity) Do I have to do this or not? end function ZombieSpawnPos() -------------------------------This function calculates which info_zspawn entity the zombie should spawn at. (info_zspawn entitys will be placed in map using hammer) ZombieSpawnPlaces={ ents.FindByClass("info_zspawn") } -------------------------------Finds all of the info_zspawn entitys in the current map and adds to an index/array. count = math.random(1,ZombieSpawnPlaces.Count) -------------------------------Picks a random info_zspawn entitys for the zombie to spawn at SpawnPos = ZombieSpawnPlaces[Count] -------------------------------Simply sets a variable to the entity indexed at the postion "Count" SpawnPosVec = SpawnPos:GetPos( ) -------------------------------Sets the zombie spawn pos end function ZombieTarget(data) -------------------------------This function is used to get, but not set the zombies target. We will make the npc hate/attack this target later on. target_prop = ents.FindInSphere( data,5000) -------------------------------data =='s the function argument which is the zombies position end data = -------------------------------zombie position, I need help setting this var pelase Zombies={} -------------------------------Make an array/index named Zombies, amm i alowed to define it here, outside of a codeblock as i don't want it to be run with the function. function ZombieSpawn() -------------------------------This function deals with setting up the zombies position, relations and other and also spawns the entity local ply = zombie -------------------------------In words, I have issues explainign this line, lol local zombie = ents.Create("npc_zombie") -------------------------------I want to make a npc_zombie with teh following attributes defined below. zombie:SetPos(SpawnPosVec) -------------------------------Where the Zombie will spawn, defined several lines up. do return Entity end -------------------------------Returns the zombie I ahve spawned Index=0 -------------------------------Sets A variable anmed Index to 0, for use with adding the zombies to an array/index for i=index,Zombies.count do -------------------------------A For statement for adding zombies to a array/index Index++ -------------------------------Increases the Variable index so that each time the for statement runs thorugh it adds the enxt zombie to a different slot of teh index/array Zombies[index]= Entity -------------------------------Adds "Entity", the zombie we returned previously 4 lines up to the Zombies index. Does this work? returning tog et the zombie as entity end for k,v in pairs(Zombies) do -------------------------------A for in statement to set the relationship of all the zombies in the array to hate "Target" which we defiend earlier k:AddEntityRelationship(Target, D_FR, 99 ) -------------------------------yeah, umm... yeah zombie:Spawn() -------------------------------Finaly spawns the zombie with above attributes end end end[/lua]
I don't really get what you're asking but, here is some commented code that will do what you want ( I think.. untested ) with those info_zspawn entities. Make sure to read the comments or you won't learn. [lua] hook.Add( "InitPostEntity", "LoadZombies", function( ) -- Called when the map is initialized^ for k, v in pairs( ents.GetAll( ) ) -- Loops through all entities^ if v:GetClass( ) == "info_zspawn" -- Is it info_zspawn?^ local zombie = ents.Create( "npc_zombie" ); -- Create our zombie^ zombie:SetPos( v:GetPos( ) + Vector( 0, 0, 20 ) ) -- Set our zombies position and make it spawn slightly above the info_zspawn entity^ zombie:Spawn( ) -- Spawn our zombie^ end; end; end ); [/lua] Also, ply is just another alias of the _R.Player metatable.
[QUOTE=Helix Alioth;23611144]I don't really get what you're asking but, here is some commented code that will do what you want ( I think.. untested ) with those info_zspawn entities. Make sure to read the comments or you won't learn. [lua] hook.Add( "InitPostEntity", "LoadZombies", function( ) -- Called when the map is initialized^ for k, v in pairs( ents.GetAll( ) ) -- Loops through all entities^ if v:GetClass( ) == "info_zspawn" -- Is it info_zspawn?^ local zombie = ents.Create( "npc_zombie" ); -- Create our zombie^ zombie:SetPos( v:GetPos( ) + Vector( 0, 0, 20 ) ) -- Set our zombies position and make it spawn slightly above the info_zspawn entity^ zombie:Spawn( ) -- Spawn our zombie^ end; end; end ); [/lua] Also, ply is just another alias of the _R.Player metatable.[/QUOTE] Thanks Helix, your code will spawn a zombie at every spawn, how ever I only want to spawn 1 zombie, at a random spawn. Then every 1 secs or so another will spawn at another random spawn point. As the round goes on, zombies will spawn more frequently. I'm also having difficulties getting the zombies spawned via the master entity into a table/array so that I can manipulate them. My next step will be getting them to attack a prop_physics or a player(Whichever is closest) *EDIT* Thats why I had this to spawn at a random info_zspawn: [lua]# function ZombieSpawnPos() -------------------------------This function calculates which info_zspawn entity the zombie should spawn at. (info_zspawn entitys will be placed in map using hammer) # # ZombieSpawnPlaces={ ents.FindByClass("info_zspawn") } -------------------------------Finds all of the info_zspawn entitys in the current map and adds to an index/array. # # count = math.random(1,ZombieSpawnPlaces.Count) -------------------------------Picks a random info_zspawn entitys for the zombie to spawn at # # SpawnPos = ZombieSpawnPlaces[Count] -------------------------------Simply sets a variable to the entity indexed at the postion "Count" # # SpawnPosVec = SpawnPos:GetPos( ) -------------------------------Sets the zombie spawn pos # # end[/lua]
You can store basically anything in tables. Even entities. You can also create a think hook to spawn these zombies one at a time. [lua] Zombies = { }; -- This variable is global^ local zinit = false; -- Create a variable in the normal Lua scope^ hook.Add( "InitPostEntity", "LoadZombies", function( ) -- Called when the map is initialized^ zinit = true; end ); local NextZombieSpawn = CurTime( ) + math.random( 5 ) -- math.random automatically has 1 as the minimum if only one argument is passed^ hook.Add( "Think", "SpawnZombies", function( ) -- Called every tick^ if zinit then -- Have we set up the map yet?^ if CurTime( ) >= NextZombieSpawn then for k, v in pairs( ents.GetAll( ) ) -- Loops through all entities^ if v:GetClass( ) == "info_zspawn" -- Is it info_zspawn?^ local zombie = ents.Create( "npc_zombie" ); -- Create our zombie^ zombie:SetPos( v:GetPos( ) + Vector( 0, 0, 20 ) ) -- Set our zombies position and make it spawn slightly above the info_zspawn entity^ zombie:Spawn( ) -- Spawn our zombie^ Zombies[ #Zombies + 1 ] = zombie; NextZombieSpawn = CurTime( ) + math.random( 5 ); end; end; end; end; end ); [/lua]
Ok, I've fixed several errors that I was getting from Helix's code but now I've come to a standstill. [lua]ddCSLuaFile("cl_init.lua") --Tel client to download the client side lua file AddCSLuaFile("shared.lua") --Tel client to download the shared lua file include("shared.lua") --Tel client and/or server (I think?) to load the shared file Zombies = { }; local zinit = false; hook.Add( "InitPostEntity", "LoadZombies", function( ) -- Called when the map is initialized zinit = true; end ); local NextZombieSpawn = CurTime( ) + math.random( 5 ) hook.Add( "Think", "SpawnZombies", function( ) -- Called every tick^ if zinit then -- Have we set up the map yet? if CurTime( ) >= NextZombieSpawn then for k, v in pairs( ents.GetAll( ) ) do -- Loops through all entities^ if v:GetClass( ) == "info_zspawn" then-- Is it info_zspawn? local zombie = ents.Create( "npc_zombie" ); -- Create our zombie zombie:SetPos( v:GetPos( ) + Vector( 0, 0, 20 ) ) -- Set our zombies position and make it spawn slightly above the info_zspawn entity zombie:Spawn( ) -- Spawn our zombie^ // Zombies[ Zombies + 1 ] = zombie; -- Wont let me use arithmatic on this :( ZombiesIndex = Zombies.count; index = 1; for i=1,zombiesIndex do --So instead we do this index++ Zombies[ index ] = zombie; end; NextZombieSpawn = CurTime( ) + math.random( 6 ); end; end; end; end; end ); [/lua] The error I'm getting is: [code] gamemodes\outbreak\entities\entities\zombie_spawner\init.lua:27: '=' expected near '+' Folder = entities/zombie_spawner Couldn't register Scripted Entity zombie_spawner - the Type field is empty! [/code] How ever, if i comment out this:[code] index++ --(Line 27) [/code] Then the error doesn't appear, but I get a new one when I spawn the entity at which the zombie spawns at. The error is: [code] Hook 'SpawnZombies' Failed: ...s\outbreak\entities\entities\zombie_spawner\init.lua:26: 'for' limit must be a number [/code] Thanks to anyone with an idea as to why I'm getting these.
First of all, You are missing an 'A' in the AddCSLuaFile in the first line. Second, you cannot use ++ in Lua. You have to do value = value + 1. [lua] ddCSLuaFile("cl_init.lua") --Tel client to download the client side lua file AddCSLuaFile("shared.lua") --Tel client to download the shared lua file include("shared.lua") --Tel client and/or server (I think?) to load the shared file Zombies = { }; local zinit = false; hook.Add( "InitPostEntity", "LoadZombies", function( ) -- Called when the map is initialized zinit = true; end ); local NextZombieSpawn = CurTime( ) + math.random( 5 ) hook.Add( "Think", "SpawnZombies", function( ) -- Called every tick^ if zinit then -- Have we set up the map yet? if CurTime( ) >= NextZombieSpawn then for k, v in pairs( ents.GetAll( ) ) do -- Loops through all entities^ if v:GetClass( ) == "info_zspawn" then-- Is it info_zspawn? local zombie = ents.Create( "npc_zombie" ); -- Create our zombie zombie:SetPos( v:GetPos( ) + Vector( 0, 0, 20 ) ) -- Set our zombies position and make it spawn slightly above the info_zspawn entity zombie:Spawn( ) -- Spawn our zombie^ // Zombies[ Zombies + 1 ] = zombie; -- Wont let me use arithmatic on this :( ZombiesIndex = Zombies.count; index = 1; for i=1,zombiesIndex do Zombies[ i ] = zombie; end; NextZombieSpawn = CurTime( ) + math.random( 6 ); end; end; end; end; end ); [/lua] I also don't get why your using an 'index'. You can just loop through all zombies with [lua] for k, v in pairs( ents.GetAll( ) ) do if v:GetClass( ) == "npc_zombie" then -- Do stuff^ end; end; [/lua] Also, at this comment [lua]// Zombies[ Zombies + 1 ] = zombie; -- Wont let me use arithmatic on this :([/lua] To get the length of a table you do #TABLENAME so.. [lua] local lol = { "a", "s", "d" } print( #lol ); [/lua] The output would be three.
OK, so just to get everyone on the same track. 1. This entity will spawn a npc_zombie on top of a info_zspawn entity every couple of seconds. 2. The info_zspawn entity that the zombie will spawn at is randomized by this entity. 3.Add the spawned zombies to a table. 4.Set the spawned zombies relationship towards a human and prop_physics so that it hates them. I'm not receiving any errors in console, but no zombies are spawning... Here is the code: [lua] AddCSLuaFile("cl_init.lua") AddCSLuaFile("shared.lua") include("shared.lua") Zombies = { } spawnPoints = {} local zinit = false hook.Add( "InitPostEntity", "LoadZombies", function( ) -- Called when the map is initialized zinit = true end ) local NextZombieSpawn = CurTime( ) + math.random( 6 ) hook.Add( "Think", "SpawnZombies", function( ) -- Called every tick if zinit then -- Have we set up the map yet? if CurTime( ) >= NextZombieSpawn then spawns = 1 for k, v in pairs( ents.GetAll( ) ) do -- Loops through all entities if v:GetClass( ) == "info_zspawn" then -- Is it info_zspawn? spawns = spawns + 1 end; end whichSpawn = math.random( spawns ) --picks a random spawn for k, v in pairs(spawnPoints) do -- Loops through all entities if k == WhichSpawn then -- Is it info_zspawn? local zombie = ents.Create( "npc_zombie" ) -- Create our zombie zombie:SetPos( v:GetPos( ) + Vector( 0, 0, 20 ) ) -- Set our zombies position and make it spawn slightly above the info_zspawn entity zombie:Spawn( ) -- Spawn our zombie NextZombieSpawn = CurTime( ) + math.random( 6 ) end; end; end; end; end ); [/lua]
Sorry, you need to Log In to post a reply to this thread.