Tile age

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

Tile age

Post by TheSAguy »

Hi,

I'd like place a tile, and then maybe after an hour of game time, switch that tile out.
Is there a way to do this that won't be to CPU intensive?

Would I do it the same way I did it with a mine entity in my mod:

Code: Select all

	if game.tick % (60 * 60 * 10) == 0 then -- Check every 10 min for old mines, Expansion settings

		--- Check for Old Mines
		if global.deployed_mine ~= nil then
		
			for k, Old_Mines in pairs(global.deployed_mine) do
				if  Old_Mines.time and Old_Mines.time + (3600 * 30) < game.tick then -- 3600 is 1 min, remove mines older than 30min
					Old_Mines.mine.destroy()
					Old_Mines.time = nil
					Old_Mines.mine = nil
					
				end
				
			end
			
		end
Thanks.

User avatar
AmatorPhasma
Fast Inserter
Fast Inserter
Posts: 126
Joined: Sat Aug 05, 2017 8:20 pm
Contact:

Re: Tile age

Post by AmatorPhasma »

Limit the iterrations per tick?
this is what I would do

somthing like this (not tested code) with 10 iterrations per tick

Code: Select all

function deployed_mine.on_build(entity)
    if entity.valid == false then return end
    if entity.type == "mine" then
        if not deployed_mine then
            global.deployed_mine = {}
            global.deployed_mine_size = 0
            global.deployed_mine_index = 0
         end
         table.insert(deployed_mine, {entity=entity, deploy_time=game.tick()})
         global.deployed_mine_size = #deployed_mine_size 
     end
end

function deployed_mine.get()
    if global.deployed_mine_index > global.deployed_mine_size or global.deployed_mine_index <= 0 then
        global.deployed_mine_index = 1
    end

    if not t_object then
        table.remove(global.deployed_mine, global.deployed_mine_index)
        global.deployed_mine_index = global.deployed_mine_index -1
        global.deployed_mine_size = #global.deployed_mine
        return nil
    end

    if not t_object.entity.valid then
        table.remove(global.deployed_mine, global.deployed_mine_index)
        global.deployed_mine_index = global.deployed_mine_index -1
        global.deployed_mine_size = #global.deployed_mine
        return nil
    end

    return t_object
end

function deployed_mine.on_tick()
    if global.deployed_mine_size == 0 then
        return
    end

    local iterrations = 10

    for i=0, iterations, 1 do 

        local t_object = deployed_mine.get()
        if t_object then
            --[[ 
                do stuff here 
            ]]--
        end
        
        global.deployed_mine_index = global.deployed_mine_index + 1
        if global.deployed_mine_index >= global.deployed_mine_size then
            return
        end
    end
end

User avatar
AmatorPhasma
Fast Inserter
Fast Inserter
Posts: 126
Joined: Sat Aug 05, 2017 8:20 pm
Contact:

Re: Tile age

Post by AmatorPhasma »

I do somthing like this in my inserter script:
https://www.dropbox.com/s/uwz9gglj3l2lh ... r.lua?dl=0
This code works, my clipping above, I have no idea if it is correct :)

EDIT to me: This was not EDIT! :|

User avatar
mrudat
Fast Inserter
Fast Inserter
Posts: 222
Joined: Fri Feb 16, 2018 5:21 am
Contact:

Re: Tile age

Post by mrudat »

I solved a similar problem in grid fuel manager; I load fuel into generator in an equipment grid, and check back later when about half the fuel is expected to be used.

I maintain a priority queue sorted by next tick, and use on_nth_tick to get a callback when it's time for the next thing.

If you always check back in an hour, you could just use a queue, of which there is one in stdlib.

TheSAguy
Smart Inserter
Smart Inserter
Posts: 1449
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Tile age

Post by TheSAguy »

AmatorPhasma, I tried your code, but just could not figure it out... Thanks for trying to help.

Okay, I'm having a hard time with tiles. They are not the same as entities.
I'm trying to add tiles to a table and then delete them from the table if the tile is mined.

I realize the below is a little messy...
I really don't understand how "player.mining_state.position" does not match the position form "function pheromone_concrete_removed_at(surface, position)"

Help appreciated....

Code: Select all

----- Pheromone Concrete stuff
--------------------------------------------------------------------
local function laid_pheromone_concrete (event, surface)

	for i, vv in ipairs(event.tiles) do
		local position = vv.position
		local currentTilename = surface.get_tile(position.x,position.y).name
		
		if currentTilename == "pheromone_concrete" then
				
			if event.force ~= nil then
				local force = event.force
			else
				local force = "player"
			end	
		
			local Pheromone_Concrete_Position = surface.get_tile(position.x,position.y)
			global.ne.layed_pheromone_concrete[Pheromone_Concrete_Position] = {p_concrete=vv, time=event.tick}		
			--table.insert(global.ne.layed_pheromone_concrete, {position = vv.position, time = event.tick, surface = surface})
			--table.sort(global.ne.layed_pheromone_concrete, function(a, b) return a.time < b.time end)			
			writeDebug("Tile Added to table")
		else	
			writeDebug("Something Else Happened...")			
		end
		
	end	

end


local function Player_Tile_Built(event)

	local player = game.players[event.player_index]
	local surface = player and player.surface

	writeDebug("Tile Built")		
	if event.tiles then laid_pheromone_concrete (event, surface) end

	
end

	
local function Robot_Tile_Built(event)


	local robot = event.robot
	local surface = robot.surface
	
	-- fix #2 Error while running event Bio_Industries::on_robot_built_tile
	if surface == nil then
		return
	end
	
	if event.tiles then laid_pheromone_concrete (event, surface) end

end


--------------------------------------------------------------------
local function pheromone_concrete_removed_at(surface, position)

			writeDebug(position)

	for k, v in pairs(global.ne.layed_pheromone_concrete) do
		if v.position.x == position.x and v.position.y == position.y then
		
			table.remove(global.ne.layed_pheromone_concrete, k)					
			writeDebug("Tile Deleted from table")
			
			return
		end
		
	end
		
end


local function Player_Tile_Remove(event)
   local player = game.players[event.player_index]


	if event.item_stack.name == "exhausted_pheromone_concrete" and player.mining_state.mining then
	writeDebug("player.mining_state.position:")
	writeDebug(player.mining_state.position)
	return pheromone_concrete_removed_at(player.surface, player.mining_state.position)

	end
	  
end

local function Robot_Tile_Remove(event)
   local robot = event.robot 
	if event.item_stack.name == "exhausted_pheromone_concrete" then
		return pheromone_concrete_removed_at(robot.surface,robot.position)
	end
end
--------------------------------------------------------------------

local player_build_event = {defines.events.on_player_built_tile}
script.on_event(player_build_event, Player_Tile_Built)

local robot_build_event = {defines.events.on_robot_built_tile}
script.on_event(robot_build_event, Robot_Tile_Built)

local remove_events = {defines.events.on_player_mined_item}
script.on_event(remove_events, Player_Tile_Remove)

local remove_events = {defines.events.on_robot_mined}
script.on_event(remove_events, Robot_Tile_Remove)

TheSAguy
Smart Inserter
Smart Inserter
Posts: 1449
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Tile age

Post by TheSAguy »

Anyone out there can help me how to put Tiles in a table?
With an entity, I can use unit_number, but tile does not have it.

Code: Select all

global.bi_bio_farm_table[b_farm.unit_number]
My ultimate goal is to have tiles decay.
How I'm thinking of going about this is:
When you build a tile read it into a table. with the time built.
When you remove a tile, delete it from the table.
At set time, check table and swap out all tiles with a new tile if the tile is older than x time.

Thanks.

keyboardhack
Filter Inserter
Filter Inserter
Posts: 478
Joined: Sat Aug 23, 2014 11:43 pm
Contact:

Re: Tile age

Post by keyboardhack »

According to this stackoverflow question tables shouldn't be used as keys in another table. The issue is that two identical tables won't return the same value if used as a key.
One solution to this problem is to convert the tables content into a string and then use the string as a key. So for a tile you could do something like this.

Code: Select all

function tile_to_key(tile)
	return pos_to_key(tile.position)
end
function pos_to_key(pos)
	return tostring(pos.x)..":"..tostring(pos.y)
end
Then you can store a tile like this

Code: Select all

local storedTiles = {}
storedTiles[tile_to_key(tile)] = tile
And if you only have the position and want to get the tile out from the table.

Code: Select all

local tile = storedTiles[pos_to_key(position)]
Waste of bytes : P

Post Reply

Return to “Modding help”