Page 1 of 1

[solved] Entity.health returns nil on entity with health

Posted: Thu Sep 22, 2016 8:30 pm
by Reinard-kun
Greetings, fellow factorians! I seek your help.

Let's begin with the code listing:
Code listing
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:

Code: Select all

{a, b, c}
Does not behave like recent JavaScript which would become:

Code: Select all

{a = a, b = b, c = c}
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:

Code: Select all

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:

Code: Select all

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:

Code: Select all

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

Code: Select all

      
      setmetatable(o, self)
      self.__index = self
      self.type = ""
      self.amount = 0
      self.temperature = 25
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.