Selecting a Random Prop from Map

Hello Facepunch! So I am developing a small addon for myself and have run into a block.
I am trying to select a random prop_physics from the map so I can ignite it.
[lua]if i:GetClass() == “prop_physics” then
i:Ignite(15)
end[/lua]
I already know that the lua shown above will ignite every prop in the map, but I am hoping that somebody could give me advice on how to modify this script (or replace it) so that it will only ignite one random prop from the map.
Please keep your answers semi-detailed as I am a lua noob.
Thanks in advance!


local tEnts = ents.FindByClass( "prop_physics" )
tEnts[math.random( 1, #tEnts )]:Ignite()

It works like a charm, thanks so much.
Two small questions (directed to anybody)

  1. How could I modify this so it scans for not only prop_physics, but prop_physics_multiplayer and prop_dynamic too?
    I know I could copy this code and change the prop_physics part but I only want one thing to be ignited at once, not one from prop_physics and one from prop_physics_multiplayer.

  2. Also, how do I make it so that the function can’t happen if there are no props on the map?
    I tried this
    [lua]if IsValid(tEnts) then
    tEnts[math.random( 1, #tEnts )]:Ignitee() end
    end)[/lua]
    but I get an error.

The least hacky way, but probably the most inefficient would be to FindByClass all three of those types and run math.random twice: once for the class and the other for the specific entity. Otherwise, you could just use ents.GetAll and try some bias distributions.

I think



local burnclasses = {
    'prop_physics',
    'prop_dynamic',
    'prop_physics_multiplayer'
}

local burnents = {}

for k,v in pairs(ents.GetAll()) do
    if burnclasses[v:GetClass()] then
        table.insert( burnents, v )
    end
end

if next(burnents) == nil then return end -- don't do anything if there are no props to burn

burnents[math.random( 1, #burnents )]:Ignite()


I thought so, but was hoping for a less messy method. It’ll do just fine though, thanks again!
(I edited my post during your response, oops)

[editline]3rd August 2016[/editline]

Thank you, but unfortunately, nothing seems to ignite.


local tEnts = ents.FindByClass( "prop_physics" )
local iLen = #tEnts

if ( iLen ~= 0 ) then
   tEnts[math.random( 1, iLen )]:Ignite()
end

[editline]3rd August 2016[/editline]

For multiple types:


local tEntTypes = {
   "prop_physics",
   -- etc
}

function DoIgnite()
   local tEnts = ents.FindByClass( math.random( 1, #tEntTypes ))
   local iLen = #tEnts
   
   if ( iLen ~= 0 ) then
      tEnts[math.random( 1, iLen )]:Ignite()
   end
end

For some odd reason I can’t seem to get it to work.
I’m using this under my entity’s Initialize function.
[lua]timer.Create( “Ignition”, 5, 2, function()
self:DoIgnite()
end)[/lua]
And after my Init function
[lua]local tEntTypes = {
‘prop_physics’,
‘prop_dynamic’,
‘prop_physics_multiplayer’
}

function ENT:DoIgnite()
local tEnts = ents.FindByClass( math.random( 1, #tEntTypes ))
local iLen = #tEnts

if ( iLen ~= 0 ) then
tEnts[math.random( 1, iLen )]:Ignite(15)
end
end[/lua]
But when I spawn the entity, nothing seems to ignite at all. Any advice?



ents.FindByClass( math.random( 1, #tEntTypes ))


math.random returns a number and ent.FindByClass expects a string

[editline]3rd August 2016[/editline]

Try this:



local tEnts = ents.FindByClass( tEntTypes[ math.random( 1, #tEntTypes )] )


For some odd reason, the prop ignitions seem to be delayed a second or 2 longer than specified in the timer.
Regardless, you fixed the issue. Thanks a lot to the both of you! :joy:


ents.FindByClass( "prop_physics*" ) 

Try this.