Page 1 of 1
Add a field on each entity in game.
Posted: Tue Mar 09, 2021 1:40 pm
by yagaodirac
TL;DR
Now I need something to link the in game entity and the lua data in backend from my scenario in BOTH direction.
What ?
It's very easy to assign an entity to a variable in lua:
local entities = surface.find_entities_filtered(...)
(some directive to find out the entity I want, then)
some_lua_table.in_game_entity = the_entity_I_want
Then it's very easy to call any function from backend:
script.bla bla bla(on_tick, function(event)
some_lua_table.in_game_entity.some built in function from the cpp code.
But it's very hard to find the lua table from the entity.
Now I made a container to do this for me. But this container works only for the non-moveable entities with integer coordinate.
If I what to find some data associated to a moveable entity, or some entity with floating number as coordinate, I have to iterate from the backend, which is always way slower than a direct dereference with a pointer from entity returned from some function in luasurface.
Or, do people do this with tag system?
Re: Add a field on each entity in game.
Posted: Tue Mar 09, 2021 1:45 pm
by bormand
Most entities have unique unit_number, as far as I remember. Would it be enough in this case?
Re: Add a field on each entity in game.
Posted: Tue Mar 09, 2021 2:05 pm
by yagaodirac
bormand wrote: ↑Tue Mar 09, 2021 1:45 pm
Most entities have unique unit_number, as far as I remember. Would it be enough in this case?
I doesn't seem very enough. In the official docs downloaded with game, "The unit number or nil if the entity doesn't have one.". It doesn't guarantee.
I'm about to post my code.
Re: Add a field on each entity in game.
Posted: Tue Mar 09, 2021 2:09 pm
by yagaodirac
bormand wrote: ↑Tue Mar 09, 2021 1:45 pm
For now, my container looks something like this:
A folder named FObject. Inside it are 2 files.
Code: Select all
--FObject.lua:
-------------- INCLUDE ----------------
require "coord-to-FObject-index"
--------------MEMBER FUNCTION----------------
--------------MEMBER FUNCTION----------------
--------------MEMBER FUNCTION----------------
local FObject = {}
function FObject:add(data_table)--object, pos, name
self.data:add({object=data_table.object, name=data_table.name})
local pos = data_table.object.position
static.coord_to_FObject_index:add(self, pos.x, pos.y)
end
function FObject:name_to_object(name)
for k, v in pairs(self.data.data)
do
if v.name == name
then return v.object
end
end
end
function FObject:add_key(name, func)
rawset(self, name, func);
end
function FObject:print()
--Do not use this print function in data.lua stage.
game.print(serpent.block(self))
end
function FObject:log()
log(serpent.block(self))
end
-------------- CTOR n DTOR ----------------
-------------- CTOR n DTOR ----------------
-------------- CTOR n DTOR ----------------
new = new or {}
new.FObject = new.FObject or {}
new.FObject[1] = function()
local self = {}
self.data = new.array_simple[1]()
setmetatable(self, mt.FObject)
return self
end
function FObject:destroy()
for k,v in pairs(self.data.data)
do
v.destroy()
end
self = nil
end
-------------- MT ----------------
-------------- MT ----------------
-------------- MT ----------------
mt = mt or {}
mt.FObject = {}
mt.FObject.__newindex = function()end
mt.FObject.__index = FObject
And the second:
Code: Select all
--coord-to-FObject-index.lua(which is required in the former one):
--------------MEMBER FUNCTION----------------
--------------MEMBER FUNCTION----------------
--------------MEMBER FUNCTION----------------
local coord_to_FObject_index = {}
function coord_to_FObject_index:get(x,y)--object is an FObject.
if self[x] then return self[x][y] end
return nil
end
function coord_to_FObject_index:add(object,x,y)--object is an FObject.
if not self[x] then rawset(self, x, {}) end
self[x][y] = object
end
function coord_to_FObject_index:remove(x,y)--object is an FObject.
self[x][y] = nil
end
function coord_to_FObject_index:print()
--Do not use this print function in data.lua stage.
game.print(serpent.block(self))
end
function coord_to_FObject_index:log()
log(serpent.block(self))
end
-------------- CTOR n DTOR ----------------
-------------- CTOR n DTOR ----------------
-------------- CTOR n DTOR ----------------
new = new or {}
new.coord_to_FObject_index = new.coord_to_FObject_index or {}
new.coord_to_FObject_index[1] = function()
local self = {}
setmetatable(self, mt.coord_to_FObject_index)
return self
end
function coord_to_FObject_index:destroy()
--for k,v in pairs(self.data.data)
--do
-- v.destroy()
--end
self = nil
end
-------------- MT ----------------
-------------- MT ----------------
-------------- MT ----------------
mt = mt or {}
mt.coord_to_FObject_index = {}
mt.coord_to_FObject_index.__newindex = function()end
mt.coord_to_FObject_index.__index = coord_to_FObject_index
-------------- STATIC ----------------
-------------- STATIC ----------------
-------------- STATIC ----------------
static = static or {}
static.coord_to_FObject_index = new.coord_to_FObject_index[1]()
Re: Add a field on each entity in game.
Posted: Tue Mar 09, 2021 2:41 pm
by Xorimuth
yagaodirac wrote: ↑Tue Mar 09, 2021 2:05 pm
bormand wrote: ↑Tue Mar 09, 2021 1:45 pm
Most entities have unique unit_number, as far as I remember. Would it be enough in this case?
I doesn't seem very enough. In the official docs downloaded with game, "The unit number or nil if the entity doesn't have one.". It doesn't guarantee.
I'm about to post my code.
Pretty much everything has a unit_number. I think the only exceptions are trees and rocks, which are instances of SimpleEntity.
Re: Add a field on each entity in game.
Posted: Wed Mar 10, 2021 1:51 am
by yagaodirac
Oh, really? This is very good. But it's not direct enough. I still have to maintain a container, or a dictionary to store all the index which is somehow similar to the code I post upon.
Re: Add a field on each entity in game.
Posted: Wed Mar 10, 2021 7:10 am
by ssilk
You just need to check every time, if the object still exists. It could be destroyed meanwhile.