Page 1 of 1
Tile age
Posted: Thu Apr 18, 2019 2:40 am
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.
Re: Tile age
Posted: Thu Apr 18, 2019 3:01 am
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
Re: Tile age
Posted: Thu Apr 18, 2019 3:06 am
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!
Re: Tile age
Posted: Thu Apr 18, 2019 4:45 am
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.
Re: Tile age
Posted: Thu Apr 18, 2019 6:55 pm
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)
Re: Tile age
Posted: Fri Apr 19, 2019 6:47 pm
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.
Re: Tile age
Posted: Fri Apr 19, 2019 7:15 pm
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)]