Page 1 of 1

Adding light output to entities

Posted: Sun Nov 09, 2014 10:10 am
by zackboe
I'm not sure if this is a bug, or I'm simply going about this the wrong way.

I'd like to add a light output to electric poles, and am attempting to do so using the following code:

Code: Select all

data.raw["electric-pole"]["small-electric-pole"].light = { intensity = 0.9, size = 5 }
The mod loads fine and produces no errors, but light does not emit from the object.

There's a couple threads here and here on the subject, but are quite a few months old.

Any ideas?

Re: Adding light output to entities

Posted: Sun Nov 09, 2014 11:11 am
by cartmen180
light is not a property of the electric pole, so you will have to do some lua magic to make it work

Re: Adding light output to entities

Posted: Tue Nov 11, 2014 9:37 am
by L0771
Hi, maybe with something like this
-

Code: Select all

game.oninit(function()
		glob.build = {}
end)
game.onevent(defines.events.onbuiltentity, function(event)
	if event.createdentity.name == "burner-mining-drill" then
		local newdrill = event.createdentity
		local newlight = game.createentity{name="small-lamp", position = newdrill.position, force=game.forces.player}
		
		table.insert(glob.build,{drill,light})
		i = 0
		for k,v in pairs(glob.build) do
			i = i + 1
		end
		
		glob.build[i].drill = newdrill
		glob.build[i].light = newlight
	end
end)
game.onevent(defines.events.onpreplayermineditem, function(event)
	if (event.entity.name == "burner-mining-drill") then
		for k,v in pairs(glob.build) do
			if (event.entity.equals(v.drill)) then
				v.light.destroy()
			end
		end
	end
end)
Where you build a burner mining drill, automatically create a light, and when you destroy this mining drill, automatically destroy that light.
You can make a light entity with transparent picture, light see from main entity...

i'm new here too, maybe can write a better code

Re: Adding light output to entities

Posted: Tue Nov 11, 2014 12:41 pm
by rk84
@ L0771 I would like to point some things in your code.

Code: Select all

table.insert(glob.build,{drill,light}) -- inserting array of 2 values (nils?) in glob.build, that are not used anywhere. Could use empty table here.
You don't have to measure length of array

Code: Select all

i = 0
for k,v in pairs(glob.build) do -- could be ipairs or should I say should be.
  i = i + 1
end
-- You use table.insert to build array. You can get length of array with # operator.
-- i = #glob.build
You could also use table.remote to keep your array tidy, but because order does not matter you could check for "empty" element before inserting tables in end of array.

Re: Adding light output to entities

Posted: Tue Nov 11, 2014 1:53 pm
by L0771
Thanks, I am using a similar code in my mod, it is helpful

Code: Select all

		local toadd = 0
		for k,v in ipairs(glob.build)
			if toadd == 0 and glob.build[k] == nil then
				toadd = k
			end
		end
		if toadd == 0 then
			toadd = #glob.build + 1
		end
		local newlight = game.createentity{name="small-lamp", position = newdrill.position, force=game.forces.player}
		glob.build[toadd] = {}
		glob.build[toadd].drill = event.createdentity
		glob.build[toadd].light = newlight
this is fine?

ipairs is only for table's order? or has another utility?

Re: Adding light output to entities

Posted: Wed Nov 12, 2014 2:55 pm
by rk84
At first, I was going to add couple minor changes, but in the end I desided to go through all of it and quick test it. :)

Code: Select all

require "defines"

game.oninit(function()
      glob.build = {}
end)

game.onevent(defines.events.onbuiltentity, function(event)
  if event.createdentity.name == "burner-mining-drill" then
    local build = glob.build -- to reduce global access time
    local newlight = game.createentity{name="small-lamp", position = event.createdentity.position, force=game.forces.player}
    for i=1, #build do
      if not build[i].drill.valid then -- Recycling old table 
        build[i].drill = event.createdentity
        build[i].light = newlight
        return
      end
    end
    
    --Creating new table
    build[#build + 1] = {drill = event.createdentity, light = newlight} -- equivalent to {["drill"] = event.createdentity, ["light"] = newlight}
  end
end)

game.onevent(defines.events.onpreplayermineditem, function(event)
  if (event.entity.name == "burner-mining-drill") then
    local build = glob.build
    for i=1, #build do
      if build[i].drill.valid and event.entity.equals(build[i].drill) and build[i].light.valid then
        build[i].light.destroy()
      end
    end
  end
end)
L0771 wrote:ipairs is only for table's order? or has another utility?
Its up to you which you use, but you should be aware that Lua table have 2 parts. Hash table and array. ipairs only access array part and pairs can access both. (Note: negative numbers and zero key belongs in hash table)
I would use table.insert, table.remove and ipairs together as they all access only array part. But lately I have not used ipairs with arrays, because plain "for i=1, #table do" is faster option.

Re: Adding light output to entities

Posted: Wed Nov 12, 2014 6:27 pm
by L0771
That's really helpful, thanks you, i'll rewrite all the code again.

Here you don't use remove?
this is build = { nil, nil } ? or by defaul remove the array?

Code: Select all

    local build = glob.build
    for i=1, #build do
      if build[i].drill.valid and event.entity.equals(build[i].drill) and build[i].light.valid then
        build[i].light.destroy()
      end
    end

Re: Adding light output to entities

Posted: Wed Nov 12, 2014 9:48 pm
by rk84
yea I did not implement anything to cut down array size. Array grows when it is full of valid entities and never goes down. This is because I wanted to re-use those tables in array. Counter could be added to keep count of mined entities and it could be compared against array length to see if array needs cutting.
L0771 wrote: this is build = { nil, nil } ? or by defaul remove the array?
Im sure about the question here, but everytime you use { } you create a new table. Sure it replaces old one, but you also do it like this

Code: Select all

build[1]=nil
build[2]=nil
Im glad if I have been helpful.