Check if entity is already spawned on a certain vector.
10 replies, posted
Long title, I know...
So, i'm making a loot system for a friend's fallout server which has multiple entities. 3 of which being large, medium and small loot crates that give random weapons when you use them and the other entity spawns a random one of those 3 on it's vector, every 2 minutes (it says 5 seconds for testing, don't worry).
What i'm needing to do now is simply check whether one of those crates have already been spawned by that spawner, and if so it just restarts the timer with timer.start and checks again in 2 minutes and so on...
The catch is that there's going to be multiple spawners, so the only way I can think of doing it is to check for any of the entities being both spawned, and on the same vector as the spawner in which case it would restart the timer.
So, how would I do this? And is there a simpler way or a better way you can think of?
Spawner Entity's Init.lua
AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")
include("shared.lua")
function ENT:Initialize()
self:SetModel("models/hunter/blocks/cube025x025x025.mdl")
self:PhysicsInit(SOLID_VPHYSICS)
self:SetMoveType(MOVETYPE_NONE)
self:SetSolid(SOLID_VPHYSICS)
self:SetCollisionGroup(COLLISION_GROUP_WORLD)
self:SetUseType(SIMPLE_USE)
local phys = self:GetPhysicsObject()
if (phys:IsValid()) then
phys:Wake()
end
timer.Create( "spawnrandomtimer", 5, 0, function()
local randomcratetable = { "large_loot_crate", "medium_loot_crate", "small_loot_crate" } -- Change/add crate types here!
local randomcrate = randomcratetable[ math.random( #randomcratetable ) ]
local crate = ents.Create( randomcrate )
if ( !IsValid( crate ) ) then return end
crate:SetPos(self:GetPos())
crate:Spawn()
end )
end
function ENT:OnRemove()
timer.Remove( "spawnrandomtimer" )
end
function ENT:Think() end
Side Note: I know i've asked a hell of a lot of questions on here up to this point, and I only feel it's fair that I start to help out others too so aye... Sorry for the one sided stuff so far :/
One way to achieve this is by using this: ents.FindInSphere.
-- This is the spawn position of the crate
local crateSpawnPoint = Vector( 1, 2, 3 )
-- This is the entity name for your crate
local crateType = "my_ammo_crate"
-- Let's check if the crate was spawned at the position specified within a reasonable distance of 100 units
function itemSpawned( type, vectorPos )
for k,v in pairs( ents.FindInSphere( vectorPos, 100 ) ) do
if v:GetClass() == type then
return true
end
end
return
end
-- Now let's call the function (I assume that you would do this in your timer)
print( itemSpawned( crateType, crateSpawnPoint ) )
I hope that this helps!
You can also use a trace in place (startpos == endpos) or util.PointContents to check if an entity is on that exact spawn position.
Yes, thank you! I'll try it once I get the chance to.
I had considered using Find in sphere, but I both never got round to it, and in the past could never get it to work properly which frightened me a little but thank you for that, i'll test it out!
Sorry for the delayed response..
Yeah, it doesn't seem to have worked
Nevermind, i've fixed it! It works fine!
for k,v in pairs( ents.FindInSphere( self:GetPos(), 100 ) ) do if v:GetClass() == "large_loot_crate" then return true
end
end
for k,v in pairs( ents.FindInSphere( self:GetPos(), 100 ) ) do if v:GetClass() == "medium_loot_crate" then return true
end
end
for k,v in pairs( ents.FindInSphere( self:GetPos(), 100 ) ) do if v:GetClass() == "small_loot_crate" then return true
end
end
Glad I could help!
Aye! Thanks, buddy <3
I would like to ask though, how would I go about making it possible to have multiple spawners at the same time?
At the moment, it will only spawn an entity on the last spawner I spawned, if that makes any sense at all.
This is what I have so far
timer.Create( "spawnrandomtimer", 5, 0, function()
for k,v in pairs( ents.FindInSphere( self:GetPos(), 100 ) ) do if v:GetClass() == "large_loot_crate" then return true
end
end
for k,v in pairs( ents.FindInSphere( self:GetPos(), 100 ) ) do if v:GetClass() == "medium_loot_crate" then return true
end
end
for k,v in pairs( ents.FindInSphere( self:GetPos(), 100 ) ) do if v:GetClass() == "small_loot_crate" then return true
end
end
local randomcratetable = { "large_loot_crate", "medium_loot_crate", "small_loot_crate" } -- Change/add crate types here!
local randomcrate = randomcratetable[ math.random( #randomcratetable ) ]
local crate = ents.Create( randomcrate )
if ( !IsValid( crate ) ) then return end
crate:SetPos(self:GetPos())
crate:SetAngles( 0, 0, 90 )
crate:Spawn()
end )
Thanks for helping so far :3 <3
To do that, you would first have to create a table of vectors which you would use, then you would loop through the table of vectors and run the function on each vector.
This may be a good start.
-- Define all of your vectors
local myVectors = {
Vector(1,2,3),
Vector(2,3,4),
Vector(4,5,6)
}
timer.Create( "spawnrandomtimer", 5, 0, function()
-- Now loop through these vectors
for k,v in pairs(myVectors) do
-- Put all of the code that u have within you timer in here; just make sure to change the k and v to something such as key and val, so that Lua does not think you're referring to the k,v above
end
end)
Awesome, cheers mate!
Sorry, you need to Log In to post a reply to this thread.