Volitio — 01/25/2024 1:25 PM
I'm interested in creating a mod that automatically labels empty containers as empty without the need to manually open them first. I tried calling some Osi functions to see if containers could be opened from afar and without opening the UI but, well, nothing actually happens.
My understanding is that this relates to the GUI elements and the value for the ContainerState property in the VMItem class, though I don't think that's accessible from the Script Extender side (that's why trying to silently open containers through scripting). In any case, do you have any opinions on this off the top of your head?
Additionally, an existing mod of mine could greatly benefit from detecting when inventories are open in the game. I don't think it's possible based on one of pavelk's answers but he mentioned there's an opened character panel check (link). I guess this can't be accessed from the SE side either.
Focus — 01/25/2024 1:58 PM
So, if it's anything like DOS2, there are 2 main issues:
- We don't have access to the osiris task manager, which handles things like resurrecting, using items, moving, and so on. Without that, you can't manually trigger, in isolation, a lot of engine actions.
- There is no isolated form of item use that I know of. If you want a character to open a container, the story commands require them to be able to reach and walk up to the object.
BG3 is a bit funkier in that the treasure generation isn't done when the container is created, but at some point when the container becomes activated, usually by a player being nearby.
You can manually force the container to generate items, but I don't know if that will stop it from generating items again when they become activated.
Attempting to establish some sort of link between Noesis and SE at the moment is pretty futile. SE doesn't have any Noesis hooks to read calls or events that are happening to or from the UI to the engine.
Volitio — 01/25/2024 2:05 PM
Alright, that's a bummer, but thank you so much for your insights!
Focus — 01/25/2024 2:11 PM
As of now, I think you would have to use a more metered approach
Something like creating an aura on the character that applies a dummy status to items. Capture when the status is applied in SE and then check if the container has any items in it.
You could skip the aura and check for all items around you on a timer
Volitio — 01/25/2024 2:12 PM
I know there's an auto looter that might do something like this, but I don't know if that would update the UI
Focus — 01/25/2024 2:22 PM
It depends on how you want it to update the UI, I guess. While we have access to some of the item components on the client, we don't have access to the main one, ecl::Item, which likely contains the flags that are used to determine the UI binding for the open/closed gray/gold chest icon
But you can rename the item, like append (Empty) or set Empty as the title text.
I diffed a dump of an unopened and opened version of the same item and there weren't any differences 😦
Volitio — 01/25/2024 2:25 PM
My main concern is hiding them while holding alt, or having them labeled if using the controller radius search (honestly, my main interest are those search results, since they did not order objects by distance, so your character ends up doing a lot of back and forth and I really doubt we could do anything about this specifically)
Yeah, changing the name would also work
Volitio — 01/26/2024 1:32 PM
By the way, what specific API call should I be looking for to do this?
Focus — 01/26/2024 1:43 PM
On the server, you can use Osi.SetStoryDisplayName(targetUUID, name).
name is not a handle, but the actual name, so you will want to retrieve the name first:
Focus — 01/26/2024 1:53 PM
This overwrites the name of the character to use a broken, temporary handle that doesn't have its contents get serialized. You'll need to set the names again whenever a save game is loaded so I recommend keeping a list of items and their names in ModVars/UserVars/PVars.
The handle name itself gets serialized with the object, so you can either update it with Ext.Loca.UpdateTranslatedString, or you can call Osi.SetStoryDisplayName a create a new temporary handle for the object.
Focus — 01/26/2024 2:13 PM
If you don't want to mess with the temporary handles at all, you can edit the DisplayName component of the entity.
This has the additional benefit of making it easy to reset the name of the name of the container if someone puts an item in it or whatever. All you need have to do is unset the Name property.