MyEntity = {
name,
position = {x, y},
direction,
force,
health,
surface = {index},
fluidbox = {type, amount, temperature=25},
new = function(self, o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
}
script.on_event(defines.events.on_preplayer_mined_item, function(event)
local entity = event.entity
local player = game.players[event.player_index]
if entity.name == "storage-tank" then
local fluid = entity.fluidbox[1]
if fluid ~= nil and math.floor(fluid.amount) > 0 then
tank_had_fluid = true
entity_transfer = MyEntity:new(entity)
entity_transfer.fluidbox = fluid
entity_transfer.fluidbox.amount = math.floor(entity_transfer.fluidbox.amount)
end
entity.fluidbox[1] = nil
else tank_had_fluid = false end
end)
Now, the problem. As you can see, I have a class (MyEntity) that allows me to partially copy entity parameters (entity_transfer = deepcopy(entity) seems to break the game, sadly). All fields are copied according to their keys, except health. When I try to copy (and use it in math lib) entity.health - it returns nil value. Even when I explicitly set entity_transfer.health = entity.health it still is a nil value. Only thing that comes to mind is that entity stops being entity with health right before it is mined. Do you people have anything to say about this? Maybe (and I really hope so) I'm just not very smart and I'm missing something. I really don't want to write another event handler, just to copy entity.health...
I'm using Factorio 0.14.8, no other mods except mine, WIN 7.
EDIT: All's well now, big thanks to aubergine18
Re: Entity.health returns nil on entity with health
Posted: Thu Sep 22, 2016 8:39 pm
by aubergine18
Do you do a lot of JavaScript programming? The Lua tables don't work the same way, for example:
Instead, it thinks you're defining an array, and looks for the values of the a, b and c variables. If those values are nil, or the entries will not exist in the Lua tables (which behave like a weak map). You'd have to set them to false or some other non-nil value for them to be retained in the table.
A good place to test stuff out is the online Lua demo: https://www.lua.org/cgi-bin/demo (note; it's Lua 5.3 on that demo, whereas Factorio uses Lua 5.2).
Re: Entity.health returns nil on entity with health
Posted: Thu Sep 22, 2016 8:41 pm
by aubergine18
Put another way, this is what Lua sees your table as:
MyEntity = {
position = {x, y}, -- this table will be empty of x and y have nil value
surface = {index}, -- same here
fluidbox = {type, amount, temperature=25}, -- problems here as well
new = function(self, o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
}
Re: Entity.health returns nil on entity with health
Posted: Thu Sep 22, 2016 9:29 pm
by Reinard-kun
Hmmmm. Ok, so I have to explicitly set values when I define a class. And lua doesn't even have a proper class.
When I try this:
MyEntity = {
name = "",
position = {x = 0, y = 0},
direction = 0,
force = "",
health = 0,
surface = {index = 0},
fluidbox = {{type = "", amount = 0, temperature = 25}},
new = function(self, o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
}
it says attempt to index field '?' (a nil value), when I try to read MyEntity.fluidbox[1].type. I guess I's not correct in some way. I guess I just have to make a MyEntity:copy, but this feels dumb.
I used this:
Liquid = {
type = "",
amount = 0,
temperature = 25,
new = function(self, o)
o = o or {}
setmetatable(o, self)
self.__index = self
self.type = ""
self.amount = 0
self.temperature = 25
return o
end
}
liquid_transfer = Liquid:new()
liquid_transfer.type = string.sub(item.name, 1, _ch-2)
liquid_transfer.amount = item.durability
entity.fluidbox[1] = liquid_transfer
and it worked fine. But there was no table fields.
EDIT: I wrote MyEntity:copy and made things much easier for myself. However, it's still not perfect. But it works, so it can be considered solved, I guess?..
Re: [solved] Entity.health returns nil on entity with health
Posted: Fri Sep 23, 2016 12:12 am
by Adil
Uhm, what are you doing?
Self, as in first argument of the colon-call, refers to the table, which field you're trying to call.
So
in the second example is repeatedly resetting those fields in the Liquid table.
What does it mean 'there was no table fields'?
Re: [solved] Entity.health returns nil on entity with health
Posted: Fri Sep 23, 2016 12:35 am
by Reinard-kun
Adil wrote:Uhm, what are you doing?
No idea. Well, actually, that is a table constructor, but I'm dumb and instead of setting it as x or y, I just reset everything. Yes, this is retarded, I know. I fixed it three days ago, but it was the only example that I had at hand.
Adil wrote:What does it mean 'there was no table fields'?
It means I can't english. What I was trying to say is this table doesn't containn embedded tables. It's not entity = {a=1, b=2, c={d=3, e=4}}.
But all of this doesn't really matter now, because I rtfm, wrote a :copy that explicitly sets variables with given keys, and fixed the problem.