Anyway to tell from the object if its in a container?
Anyway to tell from the object if its in a container?
This question has probably been asked before. And 10 to 1, I know the answer is NO but maybe I am wrong. I want to know if there is a way to tell if an object is held from the object's components, not its container. Let's say my object's id is "gold_key_1". Is there any way I can check a component or data value of "gold_key_1" to tell me if it is in a chest, or held by the party, etc.... You'd think since its the ItemComponent that gets put in a container, there would something on ItemComponent to tell this but I can't seem to find any. If not, maybe this is a good 2.1.9 idea.
UPDATE:
So objects held by the party or a monster are easy to tell. Any reference to the ID of object is gone. When you drop the object, it is back again. Of course, there is still no way to tell what is holding the object. Not the best answer but at least it is something.
However, my question still holds for items in containers like chests. There doesn't seem to be any way I can tell if its in the chest without looking at the chest's contents. Maybe getWorldPosition()? It seems the data returned is a position in the chest but that is far from ideal.
UPDATE:
So objects held by the party or a monster are easy to tell. Any reference to the ID of object is gone. When you drop the object, it is back again. Of course, there is still no way to tell what is holding the object. Not the best answer but at least it is something.
However, my question still holds for items in containers like chests. There doesn't seem to be any way I can tell if its in the chest without looking at the chest's contents. Maybe getWorldPosition()? It seems the data returned is a position in the chest but that is far from ideal.
Re: Anyway to tell from the object if its a container?
If gold_key_1 is not on a map (i.e. it is in a container or held by the party) then it will evaluate to nil as if it didn't exist, so the way you've posed the question is actually nonsensical - you can't get to gold_key_1 from its id without finding its container first.
But if you do have a reference to the item, you can do the following tests. Let's say your reference is to the ItemComponent and named "keyItem". You can do the following tests:
- If findEntity(keyItem.go.id) returns nil, then the item is not on the map; it is in a container or held by the party. If it doesn't, then you know the object is on the map.
- If it's not on the map, iterate through all champions' inventories, including containers, and the mouse item, to compare it. If you find the item you will then obviously know which container the item is held in, if any.
- If it's not on the map and not in any champions' inventory or the mouse item, then it is either in a container that is not carried by the party, or in a monster's inventory. You would then have to iterate over every component in the entire dungeon, and the contents of every ContainerItemComponent and MonsterComponent, until you find the item. The overhead on this is prohibitive and it's hard to imagine a case where you'd be okay with it.
- If it is on the map, it's not in a container.
- You asked about chests. Chests are not containers, they are surfaces. If you want to determine whether the item is in a surface or a socket, just iterate through all components on the item's square and the contents of all SurfaceComponents or SocketComponents there.
Remember that storing a reference will break your mod!
But if you do have a reference to the item, you can do the following tests. Let's say your reference is to the ItemComponent and named "keyItem". You can do the following tests:
- If findEntity(keyItem.go.id) returns nil, then the item is not on the map; it is in a container or held by the party. If it doesn't, then you know the object is on the map.
- If it's not on the map, iterate through all champions' inventories, including containers, and the mouse item, to compare it. If you find the item you will then obviously know which container the item is held in, if any.
- If it's not on the map and not in any champions' inventory or the mouse item, then it is either in a container that is not carried by the party, or in a monster's inventory. You would then have to iterate over every component in the entire dungeon, and the contents of every ContainerItemComponent and MonsterComponent, until you find the item. The overhead on this is prohibitive and it's hard to imagine a case where you'd be okay with it.
- If it is on the map, it's not in a container.
- You asked about chests. Chests are not containers, they are surfaces. If you want to determine whether the item is in a surface or a socket, just iterate through all components on the item's square and the contents of all SurfaceComponents or SocketComponents there.
Remember that storing a reference will break your mod!
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Re: Anyway to tell from the object if its a container?
My bad when I said container, not Surface. Chest is a surface, agreed. By containers that would be sacks, boxes etc... I didn't test those but the reference being gone like how it is when the object is held does not surprise me. You know though, when an object is destroyed, the reference is gone as well. Add that to the complexity of how to tell who/what holds it as well as IF an object is in the gameminmay wrote:If gold_key_1 is not on a map (i.e. it is in a container or held by the party) then it will evaluate to nil as if it didn't exist, so the way you've posed the question is actually nonsensical - you can't get to gold_key_1 from its id without finding its container first.
But if you do have a reference to the item, you can do the following tests. Let's say your reference is to the ItemComponent and named "keyItem". You can do the following tests:
- If findEntity(keyItem.go.id) returns nil, then the item is not on the map; it is in a container or held by the party. If it doesn't, then you know the object is on the map.
- If it's not on the map, iterate through all champions' inventories, including containers, and the mouse item, to compare it. If you find the item you will then obviously know which container the item is held in, if any.
- If it's not on the map and not in any champions' inventory or the mouse item, then it is either in a container that is not carried by the party, or in a monster's inventory. You would then have to iterate over every component in the entire dungeon, and the contents of every ContainerItemComponent and MonsterComponent, until you find the item. The overhead on this is prohibitive and it's hard to imagine a case where you'd be okay with it.
- If it is on the map, it's not in a container.
- You asked about chests. Chests are not containers, they are surfaces. If you want to determine whether the item is in a surface or a socket, just iterate through all components on the item's square and the contents of all SurfaceComponents or SocketComponents there.
Remember that storing a reference will break your mod!
The answer to my post's question is NO, like I thought. For getting whether the object is on a surface, all there seems to be is calling findEntity() on the square. When I find a surface component, iterate it to see if the key is in it. This is ugly but doable.
The fact that when an object is held or in a container and is gone from the map with no way to tell who/what has it is much more of a problem. Though, maybe I am aware of a function or two that you are not to make this easier:
To tell if the party is holding an object, you can call isCarrying(string). string = the name of the object, not its ID. Even though when you drop the object, the same ID is re-used.
To tell if a monster has an object, his brain has a function called carrying(string). This time string is the object's ID, not its name. It's inconsistent.
For a container, since there can be many of them in the game, we are out of luck if we need to find which container has the item. Like you say, iterating through all squares in the game is not feasible.
Re: Anyway to tell from the object if its a container?
I am aware of those but the first one doesn't really help (if it returns true you have to iterate through all inventories anyway since it might not be the right object) and I did not know MonsterComponent:isCarrying() checks id rather than name.MrChoke wrote:The fact that when an object is held or in a container means and is gone from the map with no way to tell who/what has it is much more of a problem. Though, maybe I am aware of a function or two that you are not to make this easier:
To tell if the party is holding an object, you can call isCarrying(string). string = the name of the object, not its ID. Even though when you drop the object, the same ID is re-used.
To tell if a monster has an object, his brain has a function called carrying(string). This time string is the object's ID, not its name. It's inconsistent.
Well, there is an alternate approach that is used in my mod for the item search functionality: a table of the ids of all containers is kept in memory, and iterated through when an item that is not on the map needs to be found. You could use that method to easily search all containers not in monster inventories; just put an onInit hook in your ContainerItemComponents that adds them to the table.MrChoke wrote:For a container, since there can be many of them in the game, we are out of luck if we need to find which container has the item. Like you say, iterating through all squares in the game is not feasible.
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Re: Anyway to tell from the object if its a container?
[quote="minmay]Well, there is an alternate approach that is used in my mod for the item search functionality: a table of the ids of all containers is kept in memory, and iterated through when an item that is not on the map needs to be found. You could use that method to easily search all containers not in monster inventories; just put an onInit hook in your ContainerItemComponents that adds them to the table.[/quote]
I may need to do that. I find that using onInit() can be problematic though at times. If its an object spawned at game start, it may be in a weird state as everything is being initialized. I'll have to try it out. Thanks.
I may need to do that. I find that using onInit() can be problematic though at times. If its an object spawned at game start, it may be in a weird state as everything is being initialized. I'll have to try it out. Thanks.
Re: Anyway to tell from the object if its in a container?
Check go's getFullID(). It may help.
Re: Anyway to tell from the object if its in a container?
...Goddammit.
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Re: Anyway to tell from the object if its in a container?
Yes, that is exactly what I was looking for to tell if an item is in a chest (assume any surface component). Everytime I tried that command before I got the same thing as id back. But if "gold_key_1" is in a chest, here is what I get for getFullId() on gold_key_1:petri wrote:Check go's getFullID(). It may help.
chest_23.gold_key_1
Very cool.
NOTE: It does not help with any object held by a player, monster or in a container. getFullId() cannot be called because the object reference is still nil.
I will update the Github doco site with this info.
Thanks
Re: Anyway to tell from the object if its in a container?
It works for items carried by monsters and items in containers.MrChoke wrote:NOTE: It does not help with any object held by a player, monster or in a container. getFullId() cannot be called because the object reference is still nil.
Re: Anyway to tell from the object if its in a container?
I tested this, unless I messed up I cannot call getFullId() on the game object because it is null. I have been testing gold_key_1. If gold_key_1 is anywhere on the map, including on a surface, gold_key_1:getFullId() works great. If gold_key_1 is held or in a container, I do the same command I get a LUA error because gold_key_1 is nil.petri wrote:It works for items carried by monsters and items in containers.MrChoke wrote:NOTE: It does not help with any object held by a player, monster or in a container. getFullId() cannot be called because the object reference is still nil.
Am I missing another way to do this?
UPDATE:
I even tried findEntity("gold_key_1") and that returns nil.