Detect Floor being built or removed/destroyed

Place to get help with not working mods / modding interface.
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1456
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Detect Floor being built or removed/destroyed

Post by TheSAguy »

How can I detect when a floor is built?

Does not seem to work like other entities. I tried:

Code: Select all

function On_Built(event)

    local entity = event.created_entity  
    if entity and entity.name == "bi-floor" then
       ....
Same with remove

Code: Select all

function On_Remove(event)
	
	local entity = event.entity	
	if entity and entity.name == "bi-floor" then
       ....
Thanks.
User avatar
darkfrei
Smart Inserter
Smart Inserter
Posts: 2905
Joined: Thu Nov 20, 2014 11:11 pm
Contact:

Re: Detect Floor being built or removed/destroyed

Post by darkfrei »

Floor is tiles, not the entities.

http://lua-api.factorio.com/latest/events.html
on_player_built_tile
Called after a player builds tiles.

Contains
player_index :: uint
positions :: array of Position: The tile positions.


on_player_mined_tile
Called after a player mines tiles.

Contains
player_index :: uint
positions :: array of Position: The tile positions.

---

http://lua-api.factorio.com/latest/LuaS ... e.get_tile
get_tile(x, y) → LuaTile
Get the tile at a given position.

Parameters
x :: int
y :: int
Note: The input position params can also be a single tile position.
set_tiles(tiles, correct_tiles)
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1456
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Detect Floor being built or removed/destroyed

Post by TheSAguy »

Okay, this is above my paygrade... I can't figure it out and can'f find any examples in other mods.
Can someone please help out.

This is what I have, and I know it's totally wrong...

Tried to define my functions here:

Code: Select all

script.on_event({defines.events.on_player_built_tile,}, function(event) Tile_Built(player_index, positions) end)
script.on_event({defines.events.on_robot_built_tile,}, function(event) Tile_Built(event) end)
script.on_event({defines.events.on_player_mined_tile,}, function(event) Tile_Remove(event) end)
script.on_event({defines.events.on_robot_mined_tile,}, function(event) Tile_Remove(event) end)

Code once function is called: Most of this is not updated, since I can't get past defining the position

Code: Select all

function Tile_Built(player_index, positions)

	local player_index = player.index
	local positions = positions
    --local entity = event.created_entity
	local surface = game.surfaces['nauvis']  
	--local surface = event.entity.surface
	--local surface = event.surface
	
	local force = event.force
	--local position = event.position		   
	local currentTilename = surface.get_tile(positions.x,positions.y).name

	if currentTilename == "bi-solar-mat" then
--	if entity and entity.name == "bi-floor" then
	writeDebug("Solar Mat has been built")
		local surface = entity.surface
		local force = entity.force
		local position = entity.position		   
		local solar_mat = entity
		local sm_pole_name = "bi_solar_pole"  
		local sm_panel_name = "bi_solar-panel_for_Solar-Mat"  
		  
		local create_sm_pole = surface.create_entity({name = sm_pole_name, position = position, force = force})
		local create_sm_panel = surface.create_entity({name = sm_panel_name, position = position, force = force})
		  
		create_sm_pole.minable = false
		create_sm_pole.destructible = false
		create_sm_panel.minable = false
		create_sm_panel.destructible = false
		
		group_entities(cantor(position.x,position.y), { solar_mat, create_sm_pole, create_sm_panel })	  

	end


Thanks.
Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: Detect Floor being built or removed/destroyed

Post by Nexela »

script.on_event({defines.events.on_player_built_tile,}, function(event) Tile_Built(player_index, positions) end)

Firstly you are not getting the index or positions they are in the event. table, secondly just pass the event

script.on_event({defines.events.on_player_built_tile,}, Tile_Built)
Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: Detect Floor being built or removed/destroyed

Post by Nexela »

Code: Select all

local build_events = {defines.events.on_player_built_tile, defines.events.on_robot_built_tile}
script.on_event(build_events, Tile_Built)
local remove_events = {defines.events.on_player_mined_tile, defines.events.on_robot_mined_tile}
script.on_event(remove_events, Tile_Remove)

Code: Select all

local function Tile_Built(event)
local player = game.players[event.player_index]
local robot = event.robot
local surface = player and player.surface or robot.surface
local position = event.positions

--If you need player make sure to do if check in case it was robot built
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1456
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Detect Floor being built or removed/destroyed

Post by TheSAguy »

Thanks Nexela,

So I have my code like the below, but it seems like the Tile_Built function does not get called.
I don't get any errors when building floors, but also not messages I'm telling it to display. Am I missing something?
Thanks.,

Code: Select all


local build_events = {defines.events.on_player_built_tile, defines.events.on_robot_built_tile}
script.on_event(build_events, Tile_Built)
local remove_events = {defines.events.on_player_mined_tile, defines.events.on_robot_mined_tile}
script.on_event(remove_events, Tile_Remove)

	
function Tile_Built(event)
	writeDebug("HELLO")
	local player = game.players[event.player_index]
	local robot = event.robot
	local surface = player and player.surface or robot.surface
	local position = event.positions

	local currentTilename = surface.get_tile(positions.x,positions.y).name
		writeDebug(currentTilename)
		if currentTilename == "bi-solar-mat" then
	--	if entity and entity.name == "bi-solar-mat" then
		writeDebug("Solar Mat has been built")
		
		end
	
	
end
Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: Detect Floor being built or removed/destroyed

Post by Nexela »

Code: Select all

surface.get_tile(positions.x,positions.y)
positions is an array of positions

Code: Select all

for i, position in ipairs(position) do
    game.print(player.surface.get_tile(position).name .. " #"..i)
end
Appending the ..i is just so factorio flood control doesn't eat the message
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1456
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Detect Floor being built or removed/destroyed

Post by TheSAguy »

Tried that, it's not the issue.
It does not seem to reach that part. Even printing, "Hello" does not show up.

Current code:

Code: Select all

local build_events = {defines.events.on_player_built_tile, defines.events.on_robot_built_tile}
script.on_event(build_events, Tile_Built)
local remove_events = {defines.events.on_player_mined_tile, defines.events.on_robot_mined_tile}
script.on_event(remove_events, Tile_Remove)

	
function Tile_Built(event)
	writeDebug("HELLO")
	local player = game.players[event.player_index]
	local robot = event.robot
	local surface = player and player.surface or robot.surface
	local position = event.positions

		
	local currentTilename = surface.get_tile(positions.x,positions.y).name
		writeDebug(currentTilename)
		for i, position in ipairs(position) do
			game.print(player.surface.get_tile(position).name .. " #"..i)
		end
		if currentTilename == "bi-solar-mat" then

		writeDebug("Solar Mat has been built")
		
		end
	
	
end
	
When I change

Code: Select all

local build_events = {defines.events.on_player_built_tile, defines.events.on_robot_built_tile}
script.on_event(build_events, Tile_Built)
to

Code: Select all

script.on_event({defines.events.on_player_built_tile, defines.events.on_robot_built_tile}, function(events) Tile_Built(Event) end)
It crashes, BUT at least I get to the part where it prints "Hello". So must be something I need to tweak with the script command.
Image
Thanks.
Attachments
control.lua
Control File
(20.73 KiB) Downloaded 88 times
Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: Detect Floor being built or removed/destroyed

Post by Nexela »

The reason my example doesn't work for you has to do with code flow

You are telling it to do Tile_Built but Tile_Built isn't declared until later in the file. So essentially you are passing nil which de-registers the handler.

Doing it the second way works because the event is raising an anonymous function which calls Tile_Built which at the point of the event will have been decleared

As for the last error, event and events is the issue
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1456
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Detect Floor being built or removed/destroyed

Post by TheSAguy »

Okay, I'm getting very close now.
the problem now is the position.

The line 65:

Code: Select all

	local tile_pos = event.position	
I get this error.
Image
When I change "event" to "player" it works, but I get the tile that the player is standing on, not the tile built.
So what should "event" be?

Also, will:
local currentTilename = surface.get_tile(tile_pos.x,tile_pos.y).name
give me the value of the new tile placed, or the tile I'm placing the new tile on?
I need get the value of the new tile...

Current code:

Code: Select all

script.on_event({defines.events.on_player_built_tile, defines.events.on_robot_built_tile}, function(event) Tile_Built(event) end)
script.on_event({defines.events.on_player_mined_tile, defines.events.on_robot_mined_tile}, function(event) Tile_Remove(event) end)

	
function Tile_Built(event)
	writeDebug("HELLO")
	local player = game.players[event.player_index]
	local robot = event.robot
	local surface = player and player.surface or robot.surface
	local tile_pos = event.position	
	local currentTilename = surface.get_tile(tile_pos.x,tile_pos.y).name
	writeDebug(currentTilename)

		if currentTilename == "bi-solar-mat" then
			writeDebug("Solar Mat has been built")
		end

end
	
Thanks!
User avatar
darkfrei
Smart Inserter
Smart Inserter
Posts: 2905
Joined: Thu Nov 20, 2014 11:11 pm
Contact:

Re: Detect Floor being built or removed/destroyed

Post by darkfrei »

positions :: array of Position: The tile positions.
Positions, not position.
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1456
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Detect Floor being built or removed/destroyed

Post by TheSAguy »

darkfrei wrote:
positions :: array of Position: The tile positions.
Positions, not position.
When I change it to positions, I get this error:
local tile_pos = event.positions
Image
Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: Detect Floor being built or removed/destroyed

Post by Nexela »

It is an array of positions, you will need to iterate them, see my examples above
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1456
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Detect Floor being built or removed/destroyed

Post by TheSAguy »

Thanks guys!!
Took me forever, but I got there :)
Works as I hoped it would.
THANKS again!

Code: Select all


script.on_event({defines.events.on_player_built_tile, defines.events.on_robot_built_tile}, function(event) Tile_Built(event) end)
script.on_event({defines.events.on_player_mined_tile, defines.events.on_robot_mined_tile}, function(event) Tile_Remove(event) end)

	
function Tile_Built(event)
	writeDebug("HELLO")
	local player = game.players[event.player_index]
	local robot = event.robot
	local surface = player and player.surface or robot.surface
	local position = event.positions

	for i, position in ipairs(position) do
		local currentTilename = surface.get_tile(position.x,position.y).name
		writeDebug(currentTilename)
		
		if currentTilename == "bi-solar-mat" then
			writeDebug("Solar Mat has been built")
		end
	end	
		
end
Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: Detect Floor being built or removed/destroyed

Post by Nexela »

Awesome. Now move your functions above the script. Make them local and remove the anonymous function fr9m the script.
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1456
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Detect Floor being built or removed/destroyed

Post by TheSAguy »

Nexela wrote:Awesome. Now move your functions above the script. Make them local and remove the anonymous function fr9m the script.
Done, what is the benefit of doing this?


Okay, now I have another issue....
The functions I used with my Entities do now work for my tiles.
When I build my custom tile, I create some hidden entities. When I remove the Solar tile, I want to also destroy the hidden entities I created.

Here is my code for creating and grouping stuff together.

Code: Select all

		if currentTilename == "bi-solar-mat" then
			writeDebug("Solar Mat has been built")
			
			local force = event.force
			local solar_mat = surface.get_tile(position.x,position.y)
			local sm_pole_name = "bi_solar_pole"  
			local sm_panel_name = "bi_solar-panel_for_Solar-Mat"  
			  
			local create_sm_pole = surface.create_entity({name = sm_pole_name, position = position, force = force})
			local create_sm_panel = surface.create_entity({name = sm_panel_name, position = position, force = force})
			  
			create_sm_pole.minable = false
			create_sm_pole.destructible = false
			create_sm_panel.minable = false
			create_sm_panel.destructible = false
				  
			group_entities(cantor(position.x,position.y), { solar_mat, create_sm_pole, create_sm_panel })	  			
			
		end
	end	
Now when I pick up the tile, I need to destroy those other entities also. This part is not working.
My problem is that I'm detecting the tile under the tile I'm picking up and not the tile mined, using this code:

Code: Select all

local function Tile_Remove(event)
	

	local player = game.players[event.player_index]
	local robot = event.robot
	local surface = player and player.surface or robot.surface
	local position = event.positions

	for i, position in ipairs(position) do
		local currentTilename = surface.get_tile(position.x,position.y).name
		writeDebug(currentTilename)

	end	
			
end

How do I get the name of the tile I picked up?
Since I need to see if that a "solar mat" in order to then look for the other hidden entities.



Attempt 1:

Code: Select all

local function Tile_Remove(event)
	

	local player = game.players[event.player_index]
	local robot = event.robot
	local surface = player and player.surface or robot.surface
	local position = event.positions

	for i, position in ipairs(position) do
		local currentTilename = surface.get_tile(position.x,position.y).name
		writeDebug(currentTilename)
		if currentTilename == "bi-solar-mat" then
			writeDebug("Solar Mat Removed")
		--- Solar Map has been removed
			--local pos_hash = cantor(entity.position.x,entity.position.y)
			local pos_hash = cantor(event.position.x,event.position.y)
			local entity_group = getGroup_entities(pos_hash)
			if entity_group then
				for ix, vx in ipairs(entity_group) do
					if vx == entity then
                    --vx.destroy()
					else
						vx.destroy()
					end
				end
			end
        ungroup_entities(pos_hash)
			
		end
	end	
			
end

Attempt 2:

Code: Select all

	
	local entity = event.entity	
	

	--- Solar Map has been removed
   	if entity and entity.name == "bi-solar-mat" then
		local pos_hash = cantor(entity.position.x,entity.position.y)
        local entity_group = getGroup_entities(pos_hash)
        if entity_group then
            for ix, vx in ipairs(entity_group) do
                if vx == entity then
                    --vx.destroy()
                else
                    vx.destroy()
                end
            end
        end
        ungroup_entities(pos_hash)
	end

I'm not 100% sure the grouping worked, since it was done on entities before and not tile/entity combo.
Post Reply

Return to “Modding help”