LuaEntity API call when entity target is zero

Place to get help with not working mods / modding interface.
ficolas
Smart Inserter
Smart Inserter
Posts: 1068
Joined: Sun Feb 24, 2013 10:24 am
Contact:

LuaEntity API call when entity target is zero

Post 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

kovarex
Factorio Staff
Factorio Staff
Posts: 8194
Joined: Wed Feb 06, 2013 12:00 am
Contact:

Re: LuaEntity API call when entity target is zero

Post 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

ficolas
Smart Inserter
Smart Inserter
Posts: 1068
Joined: Sun Feb 24, 2013 10:24 am
Contact:

Re: LuaEntity API call when entity target is zero

Post 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

ficolas
Smart Inserter
Smart Inserter
Posts: 1068
Joined: Sun Feb 24, 2013 10:24 am
Contact:

Re: LuaEntity API call when entity target is zero

Post by ficolas »

entity.hashealth() isnt a key in the array, and damage doesnt work with a single argument

kovarex
Factorio Staff
Factorio Staff
Posts: 8194
Joined: Wed Feb 06, 2013 12:00 am
Contact:

Re: LuaEntity API call when entity target is zero

Post 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

ficolas
Smart Inserter
Smart Inserter
Posts: 1068
Joined: Sun Feb 24, 2013 10:24 am
Contact:

Re: LuaEntity API call when entity target is zero

Post 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

User avatar
FreeER
Smart Inserter
Smart Inserter
Posts: 1266
Joined: Mon Feb 18, 2013 4:26 am
Contact:

Re: LuaEntity API call when entity target is zero

Post 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
<I'm really not active any more so these may not be up to date>
~FreeER=Factorio Modding
- Factorio Wiki
- My Factorio Modding Guide
- Wiki Modding Guide
Feel free to pm me :)
Or drop into #factorio on irc.esper.net

ficolas
Smart Inserter
Smart Inserter
Posts: 1068
Joined: Sun Feb 24, 2013 10:24 am
Contact:

Re: LuaEntity API call when entity target is zero

Post 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

kovarex
Factorio Staff
Factorio Staff
Posts: 8194
Joined: Wed Feb 06, 2013 12:00 am
Contact:

Re: LuaEntity API call when entity target is zero

Post by kovarex »

Changing the nearby dynamite time to some lower number instead could result in nice effects.

Post Reply

Return to “Modding help”