Page 1 of 1

LuaEntity API call when entity target is zero

Posted: Tue May 21, 2013 4:27 pm
by ficolas

Code: Select all

	if glob.dynamite~=nil then
		for i,_ in pairs(glob.dynamite) do
			glob.dynamite[i][100]=glob.dynamite[i][100]+1 --the error is here--
			if glob.dynamite[i][100]==600 then
				for pos=0,10,2.5 do
					local entities=game.findentities({{glob.dynamite[i].position.x-pos,glob.dynamite[i].position.y-pos},{glob.dynamite[i].position.x+pos,glob.dynamite[i].position.y+pos}})
					for i,_ in pairs(entities) do
						if entities[i].health~=nil then
							if entities[i].health<=50 then
								entities[i].die()
							else
								entities[i].health=entities[i].health-50
							end
						end
					end
				end
				glob.dynamite[i].destroy()
				table.remove(glob.dynamite ,i) 
			end
		end
	end
The error is at like 3, and the weirdest thing, is that it happends in a random moment.

also the part where that is declared is here:

Code: Select all

	if event.createdentity.name=="dynamite" then
		if glob.dynamite==nil then
			glob.dynamite={}
			glob.dynamitecount=0
		end
		glob.dynamite[glob.dynamitecount]={}
		glob.dynamite[glob.dynamitecount]=event.createdentity
		table.insert(glob.dynamite[glob.dynamitecount], 100, 0)
		glob.dynamitecount=glob.dynamitecount+1		
	end

Re: LuaEntity API call when entity target is zero

Posted: Tue May 21, 2013 5:07 pm
by kovarex
The dynamite is an entity object, and you are accessing it as an array (and probably damaging the internal structure somehow this way)
I would just make

Code: Select all

... creation
dynamit[index].entity = event.createdentity
dynamit[index].time = 0

Code: Select all

... the loop

glob.dynamite[i].time = glob.dynamite[i].time+1 -- it works now, hooray

P.S. Few pointers how to write the code more simply:

1)It might be better to write the loop this way:

Code: Select all

for index, dynamite in pairs(glob.dynamite) do
  dynamit.time = dynamit.time + 1 -- the second value of the for is the item value, and you can operate directly on that, instead of using dynamit[i] everywhere
2) it is easier to write

Code: Select all

entity.damage(50)
, instead of manipulating the health.
Note that, later when we add other stuff (like damage sounds or some other effects) these will be connecting with calling damage, not changing the health value (obviously)
PPS. It is also probably nicer to call entity.hashealth() instead of checking entity.health ~= nil

Re: LuaEntity API call when entity target is zero

Posted: Tue May 21, 2013 5:26 pm
by ficolas
kovarex wrote: 2) it is easier to write

Code: Select all

entity.damage(50)
, instead of manipulating the health.
Note that, later when we add other stuff (like damage sounds or some other effects) these will be connecting with calling damage, not changing the health value (obviously)
PPS. It is also probably nicer to call entity.hashealth() instead of checking entity.health ~= nil
Not on the wiki :(
Also, I thought that lua didnt differentitate between object and array.

Thanx

Re: LuaEntity API call when entity target is zero

Posted: Tue May 21, 2013 5:56 pm
by ficolas
entity.hashealth() isnt a key in the array, and damage doesnt work with a single argument

Re: LuaEntity API call when entity target is zero

Posted: Tue May 21, 2013 6:02 pm
by kovarex
ficolas wrote:
kovarex wrote: 2) it is easier to write

Code: Select all

entity.damage(50)
, instead of manipulating the health.
Note that, later when we add other stuff (like damage sounds or some other effects) these will be connecting with calling damage, not changing the health value (obviously)
PPS. It is also probably nicer to call entity.hashealth() instead of checking entity.health ~= nil
Not on the wiki :(
Also, I thought that lua didnt differentitate between object and array.

Thanx
Good point, added it on wiki (and few other like hashealth, hasflag and clearentitiesinside)
https://forums.factorio.com/wiki/index.php/Lua/Entity

Re: LuaEntity API call when entity target is zero

Posted: Thu May 23, 2013 4:43 pm
by ficolas
now I tried to make tnt explote tnt near them, but the same happends, here is the code:

Code: Select all

	if glob.dynamite~=nil then
		for i,_ in pairs(glob.dynamite) do
			glob.dynamite[i].timer=glob.dynamite[i].timer+1
			if glob.dynamite[i].timer==600 or glob.dynamite[i].entity.health~=1000 then --error is here
				game.createentity({name="huge-explosion",position=glob.dynamite[i].entity.position})
				posi=glob.dynamite[i].entity.position
				for pos=0,10,2.5 do
					local entities=game.findentities({{posi.x-pos,posi.y-pos},{posi.x+pos,posi.y+pos}})
					for i,_ in pairs(entities) do
						if entities[i].health~=nil then
							if entities[i].health<=50 then
								entities[i].die()
							else
								entities[i].health=entities[i].health-50
							end
						end
					end
				end
				glob.dynamite[i].entity.destroy()
				table.remove(glob.dynamite ,i) 
			end
		end
	end
it seems like it doesnt remove the table, and it tries again, or something, idk :s

Re: LuaEntity API call when entity target is zero

Posted: Thu May 23, 2013 8:29 pm
by FreeER
ficolas wrote:now I tried to make tnt explote tnt near them, but the same happends, here is the code:

Code: Select all

				local entities=game.findentities({{posi.x-pos,posi.y-pos},{posi.x+pos,posi.y+pos}})
					for i,_ in pairs(entities) do
						if entities[i].health~=nil then
							if entities[i].health<=50 then
								entities[i].die()
							else
								entities[i].health=entities[i].health-50
						...
				glob.dynamite[i].entity.destroy()
				table.remove(glob.dynamite ,i)
it seems like it doesnt remove the table, and it tries again, or something, idk :s
It is probably caused because you are not removing the ones that were exploded by the initial dynamite from the glob.dynamite table, thus when it gets to them they do not exist and have no health. If this is in ontick just break the for loop when if it explodes nearby dynamite and let it pick up on the next tick.
I had the same issue when I created dynamite that let's you blast-mine ores :) (resources have an entity.amount that show how much iron/copper/etc they have). Also .damage(50,game.player.force) is probably better than .health-50 (though I had issues with the findentities also picking up further dynamite (shock wave) and the damage would destroy it, again leading to this error, so be careful of that). Or I suppose you could just wrap everything inside the for loop with if glob.dynamite.exists() else table.remove(glob.dynamite, i) end

Re: LuaEntity API call when entity target is zero

Posted: Thu May 23, 2013 8:38 pm
by ficolas
FreeER wrote:I had the same issue when I create dynamite that let's you blast-mine ores :) (resources have an entity.amount that show how much iron/copper/etc they have)
Lol I did that just after I uploaded this

Thanx

Re: LuaEntity API call when entity target is zero

Posted: Thu May 23, 2013 9:22 pm
by kovarex
Changing the nearby dynamite time to some lower number instead could result in nice effects.