Page 1 of 1

Place entity behind ore when it is generated

Posted: Fri Apr 01, 2016 6:28 pm
by Vulcan
I am trying to make a new ore glow by adding an invisible rail signal behind it when the game generates it, but i am having difficulty with the Lua script to spawn these in. It has been ages since I did any Lua coding, and at some point all the event have been totally overhauled and I no longer have any idea how it all works
The original code I wanted to use was taken from this thread viewtopic.php?f=25&t=13164:

Code: Select all

-- Make sure our functions get called for specific events.
-- A robot built one.
game.onevent(defines.events.onrobotbuiltentity, function(event) OnBuilt(event.createdentity) end)
-- A player built one.
game.onevent(defines.events.onbuiltentity, function(event) OnBuilt(event.createdentity) end)

-- A player removed one.
game.onevent(defines.events.onpreplayermineditem, function(event) OnRemoved(event.entity) end)
-- A robot removed one.
game.onevent(defines.events.onrobotpremined, function(event) OnRemoved(event.entity) end)
-- It died.
game.onevent(defines.events.onentitydied, function(event) OnRemoved(event.entity) end)

function OnBuilt(entity)
   -- We've just built the pole.
   if entity.name == "small-electric-pole-with-lights" then
      -- Spawn a light source at its position.
      game.createentity{name = "pole-light", position = entity.position, force = entity.force}
   end
end

function OnRemoved(entity)
   -- The pole died, remove the "pole-light".
   if entity.name == "small-electric-pole-with-lights" then
      -- Search the area around the pole for the light.
      res = game.findentitiesfiltered{name="pole-light", area=GetArea(entity.position, 0.5)}
      if #res then
         -- If we've found it, destroy it.
         res[1].destroy()
      end
   end
   -- The "pole-light" died, remove the pole.
   if entity.name == "pole-light" then
      res = game.findentitiesfiltered{name="small-electric-pole-with-lights", area=GetArea(entity.position, 0.5)}
      if #res then
         res[1].destroy()
      end
   end
end

function GetArea(pos, radius)
   -- This calculates a box of the given radius around the given position.
   return {{x = pos.x - radius, y = pos.y - radius}, {x = pos.x + radius, y = pos.y + radius}}
end
I have modified this to :

Code: Select all

script.on_event(defines.events.on_chunk_generated, function(event) OnBuilt(event.createdentity) end)

-- A player mines the ore out.
script.on_event(defines.events.on_resource_depleted, function(event) OnRemoved(event.entity) end)

function OnBuilt(entity)
   -- When ore spawned
   if entity.name == "glow-ore" then
      -- Spawn a light source at its position.
      game.createentity{name = "ore-light", position = entity.position, force = entity.force}
   end
end

function OnRemoved(entity)
   -- The ore is mined out, remove the "ore-light".
   if entity.name == "glow-ore" then
      -- Search the area around the ore for the light.
      res = game.findentitiesfiltered{name="ore-light", area=GetArea(entity.position, 0.5)}
      if #res then
         -- If we've found it, destroy it.
         res[1].destroy()
      end
   end
end

function GetArea(pos, radius)
   -- This calculates a box of the given radius around the given position.
   return {{x = pos.x - radius, y = pos.y - radius}, {x = pos.x + radius, y = pos.y + radius}}
end
This works more than the original does, but lines 8 and 16 do not work, I don't know what entity.name should be replaced with

Any help will be much appreciated!

Re: Place entity behind ore when it is generated

Posted: Fri Apr 01, 2016 7:11 pm
by prg
The event argument of the on_chunk_generated handler only contains information about the chunk itself (i.e. area and surface), not about possible entities therein. Use something like find_entities_filtered with the chunk's area to see if any of the ore you care about has been generated.

Re: Place entity behind ore when it is generated

Posted: Sat Apr 02, 2016 12:01 pm
by Vulcan
Thanks for the pointer, it was very helpful. I wish I'd known about http://lua-api.factorio.com/0.12.29/index.html before!
However, I'm still having some trouble that I could use some direction on. I have (considerably) modified the code, it now looks like this:

Code: Select all

script.on_event(defines.events.on_chunk_generated, function(event) 
	if game.get_surface(1).find_entities_filtered{area=event.area,name="glow-ore",type="resource"} then
		game.get_surface(1).create_entity{name="ore-light",position={0,0}}
	end
end)
Using position=entity.position on line 3 where I have out position={0,0} does not work, I have had it set up with math.random(-10,10) to check that the rest of the code works, but I can't get the game to place the light on the ore specifically.

Another issue I have encountered that is unconnected to this is that the 'ore-light' still collides with buildings on the map, despite it having no collision-box, no selection-box and no building-collision-box. Why is this, and how do I make it stop?
Thanks again

Re: Place entity behind ore when it is generated

Posted: Sat Apr 02, 2016 12:36 pm
by Arch666Angel
For the collision issue try this, I think I got this from the logistics turrets mod.

Code: Select all

collision_mask = {"ghost-layer"},

Re: Place entity behind ore when it is generated

Posted: Sat Apr 02, 2016 12:41 pm
by Klonan
Vulcan wrote:Thanks for the pointer, it was very helpful. I wish I'd known about http://lua-api.factorio.com/0.12.29/index.html before!
However, I'm still having some trouble that I could use some direction on. I have (considerably) modified the code, it now looks like this:

Code: Select all

script.on_event(defines.events.on_chunk_generated, function(event) 
	if game.get_surface(1).find_entities_filtered{area=event.area,name="glow-ore",type="resource"} then
		game.get_surface(1).create_entity{name="ore-light",position={0,0}}
	end
end)
Using position=entity.position on line 3 where I have out position={0,0} does not work, I have had it set up with math.random(-10,10) to check that the rest of the code works, but I can't get the game to place the light on the ore specifically.
The find entities returns an array of all the entities, so you'll need to do something like this

Code: Select all

script.on_event(defines.events.on_chunk_generated, function(event) 
  local s =event.surface --Makes it multi-surface support
	for k, r in pairs (s.find_entities_filtered{area=event.area,name="glow-ore"}) do --iterates over every value in the array
		s.create_entity{name="ore-light",position=r.position} --creates the light with each iteration, with the position at that entities position
        end
end)
Another issue I have encountered that is unconnected to this is that the 'ore-light' still collides with buildings on the map, despite it having no collision-box, no selection-box and no building-collision-box. Why is this, and how do I make it stop?
Thanks again
You can use the flag "not-on-map"

Code: Select all

flags = {"placeable-off-grid", "not-on-map"},
and it should not collide with anything