Tes3Mod:ToggleMenus and HUD workarounds

The UESPWiki – Your source for The Elder Scrolls since 1995
Jump to: navigation, search

Introduction[edit]

The ToggleMenus function can be useful to force the game engine out of Menu Mode, but some scripters (myself included) have had real issues with using it.

Remember that a second ToggleMenus call is always necessary. Without this, menus do not "have permission" to display at all. Attempting to force menus to open by script, while the general Menus state is toggled "off", will often cause freezing/CTD.


As others have found, however, using a double ToggleMenus call has the nasty side effect of completely disabling the HUD. Once disabled, the HUD will not reappear until it is reinitialized.

There are only two events, that I know of, that will force the game engine to reinitialize the HUD without the player's intervention. There may be others, but these are the ones I have tested and which I know work:-

Cell Load[edit]

Any new cell load (interior or exterior) forces the game engine to reinitialize the game interface completely, including the HUD.

e.g.

Begin nigedo_hidemove

If ( OnActivate )
    ToggleMenus
    Player->COE 0 0
    ToggleMenus
Endif

End

This means that it is entirely safe to use ToggleMenus to hide the cell load progress bar in the case of scripts that teleport the player by means of multiple cell loads. Delaying the second ToggleMenus call until the same frame that the player arrives in their destination cell will hide the transportation and still reinitialize the HUD.

ForceGreeting[edit]

This is the other, and more useful, means of reinitializing the HUD.

a) If you use ToggleMenus to immediately exit dialogue, you should add follow on code to initiate a ForceGreeting from the same NPC and then call ToggleMenus twice, to restart the HUD and safely leave Menu Mode respectively.


e.g. Call this script from a StartScript in the required dialogue Results field:-

Begin nigedo_exit_dialogue

Short step

If ( step == 0 )
     ToggleMenus
     ToggleMenus
     Set step to 1

Elseif ( step == 1 )
     ForceGreeting
     ToggleMenus
     Set step to 2

Elseif ( step == 2 )
     ToggleMenus
     MenuTest
     StopScript nigedo_exit_dialogue
Endif

End

Notes:

  • The functions must be called in separate frames in this order to work successfully.
  • Calling ForceGreeting in the same frame as the first of the second set of ToggleMenus calls (step 1), allows the HUD to remain active despite menus state being toggled "off". I believe this is because the ForceGreeting is already in the process of reinitializing the HUD as the ToggleMenus call processes. The ToggleMenus call catches the dialogue window, but not the HUD.
  • The MenuTest call (step 2) eliminates an inventory view Menu Mode state that appears to underlie dialogue Menu Mode states.

b) If you want to use this method to safely exit Menu Mode states other than dialogue, you will need to create a custom NPC that you can use to initiate a ForceGreeting call, as required.

To do this:

  • Create a new race with default attributes - call it "race_invisible"
  • Create a new NPC using the race "race_invisible" and call him "npc_HUD_reset"
  • Create a new dialogue entry towards the start of the "Greetings 0" section. Filter it by ID = "npc_HUD_reset" and enter the text "." (this isn't strictly necessary, but it's cleaner)

Then add this script to "npc_HUD_reset":-

Begin nigedo_reset_HUD

Short step

If ( GetDisabled )
     SetDelete 1
     Return
Endif

If ( step == 0 )
     ForceGreeting
     ToggleMenus
     Set step to 1

Elseif ( step == 1 )
     ToggleMenus
     MenuTest
     Disable
     Set step to 0
Endif

End

Now, whenever you create a script that uses ToggleMenus calls to exit Menu Mode, add a follow on section that places an instance of "npc_HUD_reset" at the player.

e.g. This example exits the inventory share Menu Mode state, when activating a container:-

Begin nigedo_container_shutDown

Short step

If ( step == 0 )
     If ( OnActivate )
          Activate
          Set step to 1
     Endif

Elseif ( step == 1 )
     MenuTest
     ToggleMenus
     ToggleMenus
     Set step to 2

Elseif ( step == 2 )
     If ( MenuMode )
          Return
     Endif
     PlaceAtPC npc_HUD_reset 1 0 0
     Set step to 0
Endif

End

Note that, in this case, a MenuTest call is necessary at step 1, in order to exit an underlying inventory view Menu Mode state. This is not always necessary and MenuTest can cause problems if called unnecessarily. Experiment with your specific needs and determine whether you may need additional MenuTest calls to assist the process.