I asked this a long while ago, but never had any resolution. As it is still something I would like to resolve if possible, I will pose the query again, and see if anybody found (or has) a solution they can share.
Basically, is there a way we can force close the TARGET GUI (the GUI that shows the player’s current target object) via scripting? (It causes is a minor problem if a target is still selected when calling some scripts.)
Using something as simple as “CloseGUIScreen(OBJECT_SELF, “SCREEN_TARGETED_OBJECT”)” has not worked for me.
I believe I managed to achieve what you asked, if I understood correctly.
Instead of closing the screen, I just hid every pane/component of it.
Keep in mind I did this with modified XMLs from my UI mod, so it should be a bit different for the default UI.
As usual, check that the script begins with gui_ in its name:
Also make sure that the involved xmls have scriptloadable=“true” in the Scene parameters
Targeting is handled by TWO xmls, not just one. One for objects (target_object.xml) and one for enemies (target_enemy.xml), so both have to be called to make sure it always works.
Here’s how I impletemented it in a heartbeat script for a quick test module I made to make it work with the UI from my mod. It toggles the target UI off and on every 6 seconds, automatically. It was done this way just to show how it works in principle.
As I said before, some commands would be different for the standard UI because the panes/objects are named differently than the ones I used.
Unfortunately, I have a nasty feeling that this may only be “hiding” (as per what you say) as opposed to “closing” it completely. In other words, the “target” is still valid even when “hidden”, whereas “closing” (which is what I was after) would remove the target too.
The problem I am having, is that if a player keeps a target “open”, then some scripting keeps this target, which then interferes with some scripting calls I have.
i.e. When I call this function object oTarget = GetPlayerCurrentTarget(oPC); there are times when I would like to close/remove the object returned (which has been targetted at some point by the player and perhaps forgotten about), but other times leave it as the current target, which I may have automated. (Just tested a force examine on an OBJECT_INVALID, but it did not work. )
As an example, if you are able to write a small test script that returns the name/tag of oTarget using the above function, then “hide” the target GUI, and run the test script again - my guess would be that even though we no longer see the target window, the code would still return the oTarget object as it is still the current target even though we cannot see it via the GUI. If, however, it returns OBJECT_INVALID, then you will have indeed found a solution - although it would also mean the “hide” works differently from what I have seen in other GUI usage.
The only other possibility I am trying to track down is how the official code store this target - For example I know that a “player target” is retrieved with GetLocalObject(oFM, “N2_PLAYER_QUEUED_TARGET”);, maybe there is somewhere else (similar) where the official code stores the targets that can be manipulated somehow.
Thanks for helping - and do let me know if you do manage to make the object INVALID via scripting.
For other types of objects there’s a workaround that involves destroying and recreating immediatly a copy of it. It’s not really pretty to see, but I suppose that in the end it achieves what you ask for.
This subroutne appears to yield “satisfactory” results overall, by no means it’s perfect, there are situations that it doesn’t cover, like items in your inventory, and it might cause some issues with usable placeables if they are using certain on-spawn scripts or if their script set is different than their template resref (in that case they will stop working entirely).
However, I think it’s pretty much the closest you’ll come to what you’re looking for.
Thanks for taking a closer look at this for me Clangeddin.
This looks helpful, although I respect the fact that destroying and recreating objects can be “dodgy” especially objects that we still need for whatever reason - and especially if they contain some special variable or associated scripting.
However, I appreciate this gives me another approach to consider, especially if it removes the target - and thankfully, it may be enough to give me what I need change some aspects, even if I cannot fix all the areas it would have been good to do.
For now, I need to weigh up the advantages over any potential pitfalls for doing so, especially as the issue I am trying to fix is more “cosmetic” than anything else.
I am going to look over my own code and see if I can add any of your above code to my own situation where I can make use of it, so thanks for that.
I have been trying to work with these latest workarounds, but I am encountering problems with placeables that require their integrity when it comes to item drops, etc. i.e. Destroying and recreating does do what I need, but it causes other issues that I am not confident I would be able to iron all out.
In the meanwhile I tried working on the idea of refocussing a PC onto a new target, which I could then immediately destroy, but I was even unable to force the player to target something else, which would have appeared in the GUI.
However, I do wonder if this idea still holds potential: Somehow change the target, which can then be destroyed, thereby removing the target altogether. I know it seems we cannot pass an invalid object to try to make a PC lose a target, but I thought it might be possible to have them be forced to “target” another valid object - even if temporary?