UI scripting question

I’m working on a UI mod and wonder if it is possible to make f.e. UI window 1 automatically close a already open UI window 2, when UI window 1 is opened. So only one of them can be open at a time.

The reason I want to achieve this is that I’m designing the mod like the Pillars of Eternity UI – the Character, inventory, journal, and map windows all have the same dimensions and the same placement on the screen, and they are not movable. So, when I open the Character screen, and then open the Inventory screen, I want the Character screen to be closed automatically, and if I then open the Journal, I want the Inventory to be closed, etc. etc.

2 Likes

Yes it’s doable, there are two approaches to this problem:

  1. the first one is to add to every UI out there an “OnAdd” script that closes down all other UIs, this is probably the faster and easier approach. Every time the UI is called, it runs a script that shuts down all other UIs.

  2. the other one would involve making only one “super UI” that contains all other UIs as TABS, now the problem with this apprach might be that, in addition to being particularly laborious, it might also make this UI very heavy and slow in-game. Probably great care would be needed to craft this UI in such a way that it’s not a burden on the engine.

I would suggest the first approach.

2 Likes

Thank you. I considered the second approach and decided against for the same reasons you name.

An OnAdd script sounds perfect. Would you mind giving an example of what that would look like? I understand the basics of editing the UI, but am not that well-versed in scripting (yet).

I don’t have access to the toolset anymore so I don’t exactly remember the functions and how they are called, but essentially its a script that simply shuts down all the UIs you want to close except the one you just called.

something like

void main()
{
 CloseUI("ui1.xml"); (note, this is not the correct name of the function, it's similar to this, but you can look it up on the toolset)
 CloseUI("ui2.xml";
 and so on until you close all the UIs you want to close 
}

It’s also possible to give the argument to the main if you put it on the OnAdd line of .xml file, that way you can use the same script for all UIs and just give a different argument to make sure it does not shut down the UI you just called.

At the moment I can’t be much of help sadly, it’s been a long while since I scripted, and, as I said, I don’t have access to the toolset to see for myself.
At least you get the logic behind it.

2 Likes

Thank you. I think that gives me enough to figure something out. I appreciate it!

@Lorfean Welcome!

In case it helps, here is a link to my XML tutorial …

https://neverwintervault.org/project/nwn2/other/gui/nwn2-xml-gui-coding-beginners

There is also a link to a Scripting tutorial there too.

I would go with option 1 for ease, but maybe option 2 once I had a bit more experience under my belt.

All the best.

1 Like

Thank you! I think I have made some progress. I found the function CloseGUIScreen in the toolset. It has the following notes:

//RWT-OEI 02/23/06
//This function will close a specific GUI panel on the client.
//The panel must be located within the [ScriptGUI] section of the ingamegui.ini
//in order to let this script close it.
void CloseGUIScreen( object oPlayer, string sScreenName );

So I created a script to be executed when the Inventory screen is opened. I named the script gui_Inventory_CloseOther because online research says any gui-related script that you want to execute needs to be prefaced by “gui_”. The script compiled successfully:

void CloseGUIScreen( object oPlayer, string SCREEN_AREAMAP );
void CloseGUIScreen( object oPlayer, string SCREEN_CHARACTER );
void CloseGUIScreen( object oPlayer, string SCREEN_JOURNAL );

I then added the following line to my custom inventoryscreen.xml that I know works in-game:

OnAdd0=UIObject_Misc_ExecuteServerScript(“gui_Inventory_CloseOther”)

I used OnAdd0 because the UIScene already had a OnAdd condition (which I turned into OnAdd1)

But, it doesn’t work. It doesn’t close any of the 3 windows in the script when I open the Inventory.

Have you set the “scriptloadable=true” parameter on all the UI xmls files?

Yes, I have.

How is oPlayer defined?

Sorry but I don’t understand the question.

I pasted the whole script in my post above.Is it missing something?

@Lorfean

You really need to learn the basics of scripting. :slightly_smiling_face: Try working through my scripting tutorial first. In case you missed the link from the link above, here is the direct link to the scripting tutorial:

https://neverwintervault.org/project/nwn2/other/scripting-tutorial-beginners-nwn2

You need to understand some basics so you can start to use it. For example, if you checked your script when you went to compile it, it would have told you there was an error. So you would have known it would not to work even before you tried it in game, if you understood the basic compiler feedback.

As a start for you, your gui_inventory_closeother (name fine) should be structured more like this …

void main()
{
	// DEFINE THE PLAYER
	object oPlayer = OBJECT_SELF;
	
	// CLOSE AREA MAP ON PLAYER
	CloseGUIScreen(oPlayer, SCREEN_AREAMAP);
}
1 Like

Yeah, sorry, I didn’t have a lot of time and was impatient. Thought I could just rush through it :no_mouth:

I didn’t miss your links and very much appreciate the tutorials and the help. I’ll take my time to learn the basics before I come back with more questions :wink:

2 Likes