Getting all Items out of allEntities(level)

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
Post Reply
sirK2005
Posts: 14
Joined: Wed Oct 10, 2012 3:26 pm

Getting all Items out of allEntities(level)

Post by sirK2005 »

Hi folks,

another problem I#ve stumpled upon.

I want an iterator for all Items on a given level. So I thought I could simply use the allEntities() function and test for Items in there. I did something like:

Code: Select all

	for i in allEntities(2) do
		if i.class == "Item" then
			i:destroy()
		end
	end
Sadly I had to realize that the class attribute is nil for each element (I guess it's simply not visible for the editor, for reasons unknown to me). I realy dont want to test the name of each element if it's a valid item name because that would be way unnecessary. There has to be a better way.

Has anyone an idea, or even already a solution for that?

Best
Chris
Best
Chris
BeNNyBiLL
Posts: 40
Joined: Mon Oct 08, 2012 11:00 pm

Re: Getting all Items out of allEntities(level)

Post by BeNNyBiLL »

The iterator will return you indicies of the entities so I imagine you would need to do something along these lines;

Code: Select all

for i in allEntities(2) do
      ent = findEntity(i)
      if ent.class == "Item" then
         ent :destroy()
      end
   end
sirK2005
Posts: 14
Joined: Wed Oct 10, 2012 3:26 pm

Re: Getting all Items out of allEntities(level)

Post by sirK2005 »

Well, I may be wrong but testing around with i within the loop makes me pretty sure that i is the actual entitiy, since

Code: Select all

   for i in allEntities(2) do
      print(i.id)
      i.destroy()
   end
will write down the id of each element on level2 and then destroy everything leaving behind an empty level, despite the walls. I tried your code, but I get the message
'findEntity' (string expected, got table))
So I would need to do something like

Code: Select all

ent = findEntity(i.id)
the get the entity, but I don't realy see the point since i obviously represents the entity.

Still the class attribute is always nill (I've tested i.class and ent = findEntity(i.id), ent.class). Doesnt matter if i is an alcove or a door or an Item. I am pretty sure that the editor simply is not allowed to read out the class attribute. I will check out if I can define an object that does the job within a hook.

Chris
Best
Chris
BeNNyBiLL
Posts: 40
Joined: Mon Oct 08, 2012 11:00 pm

Re: Getting all Items out of allEntities(level)

Post by BeNNyBiLL »

Sorry your right, I just made a stab in the dark at answering that one :? . I can only get the following attributes from an entity
“name” returns the name of the entity
“id” returns the unique identifier of the entity
“x” returns the x-coordinate of the entity on the map
“y” returns the y-coordinate of the entity on the map
“facing” returns the facing of the entity (0=north, 1=east, 2=south, 3=west)
“level” returns the dungeon level index of the entity
...so I don't know how to access the specific attributes of objectdefines in such a way. My best guess is at the moment you can't, but by no means quote me on that, I've been wrong once already!
User avatar
Kuningas
Posts: 268
Joined: Wed Apr 11, 2012 10:29 pm
Location: Northern Finland

Re: Getting all Items out of allEntities(level)

Post by Kuningas »

Wait, using a .class = "Item" worked on some script for me! I don't remember what it was (and frankly, I don't have the code anymore), but are you sure it doesn't work? I must admit that I may be mistaken -- since to me, your code looks fine....

EDIT: Found it, perchance, it was this:

Code: Select all

function itemrecover(item)
   for i in entitiesAt(1, 20, 6) do
      if i.class == Item then
         print("this works so far")
         ItemRecoverTeleport:activate()
         break
      else
      end
   end
end
And it worked just fine. Of course, I didn't directly approach the item -- I suppose putting "item:destroy()" in there wouldn't work?
BASILEUS
sirK2005
Posts: 14
Joined: Wed Oct 10, 2012 3:26 pm

Re: Getting all Items out of allEntities(level)

Post by sirK2005 »

Ah ok, I just compared my code with yours and the differnce is the following:
I check:

Code: Select all

i.class == "Item"
and you check

Code: Select all

i.class == Item
I thought the class attribute is of type string and thus contains a string to compare but I was obviously wrong. Item appears to be a sort of object. Well in any case it seems to work this way.
Thanks

EDIT: Had my hopes to high. Doing:

Code: Select all

	for i in allEntities(2) do
		if i.class == Item then
			print(i.name)
		end
	end
Prints almost every element on level 2 including pressure plates, mosnters and of course items. So the if part seems to be true for a lot of elements, not only Items, though that is very strange. I get the same when exhcanging "Item" with "Party":

Code: Select all

	for i in allEntities(2) do
		if i.class == Party then
			print(i.name)
		end
	end
Man, I don't get it... :(
Best
Chris
User avatar
JKos
Posts: 464
Joined: Wed Sep 12, 2012 10:03 pm
Location: Finland
Contact:

Re: Getting all Items out of allEntities(level)

Post by JKos »

All properties except these:

“name” returns the name of the entity
“id” returns the unique identifier of the entity
“x” returns the x-coordinate of the entity on the map
“y” returns the y-coordinate of the entity on the map
“facing” returns the facing of the entity (0=north, 1=east, 2=south, 3=west)
“level” returns the dungeon level index of the entity

are private and can't be accessed from code. I don't know why, but that's how it is.
If you want to check the type of entity, you have to do it by using name-property. You have to list all entities to table and check if entity names is in that table.

Example:

Code: Select all

local monstersList = {
	"crab"=true,"crowern"=true,"cube"=true,"goromorg""=true,"green_slime""=true,"herder""=true,"herder_big""=true,
...
}

function checkIfIsMonster(entity)
   return monstersList[entity.name] ~= nil
end
I have posted a list of almost all entity names in lua table format to useful scripts thread.
- LoG Framework 2http://sites.google.com/site/jkoslog2 Define hooks in runtime by entity.name or entity.id + multiple hooks support.
- cloneObject viewtopic.php?f=22&t=8450
Decayer
Posts: 65
Joined: Sat Oct 13, 2012 3:19 pm

Re: Getting all Items out of allEntities(level)

Post by Decayer »

The reason

Code: Select all

if i.class == Item then
"works" is because neither 'i.class' nor 'Item' are defined values, so you're actually checking if nil is equal to nil, which is true.

Something like this might work for items, though:

Code: Select all

for i in allEntities(level) do
	if i.setSubtileOffset ~= nil then
		if type(i.setSubtileOffset) == "function" then
			return true
		end
	end
	return false
end
This works by checking if the object has a function named setSubtileOffset, something that only items have according to the scripting reference.
sirK2005
Posts: 14
Joined: Wed Oct 10, 2012 3:26 pm

Re: Getting all Items out of allEntities(level)

Post by sirK2005 »

Ok, let's sum that up:
If you want to check the type of entity, you have to do it by using name-property. You have to list all entities to table and check if entity names is in that table.
Phew, I have feared for something like this. And already started to write code doing that. But here comes the good news.
I aswell have hoped to identify an item on another way, maybe by looking at something only items have. And it seems that Decayer has found it:
This works by checking if the object has a function named setSubtileOffset, something that only items have according to the scripting reference.
I have tested his code it appears to work.

Well, once again. Thanks everybody.

Oh, and to Almost Human: It would be nice to make at least the class-attribute visible for the editor. This way a script like this could be much easier to realize. I think it just makes sene that a modder would like to know if an entitiy is an item or a monster or something like that without looking at the actual name, don't you think?

Best
Chris
Best
Chris
Post Reply