GUI Scripting: Handles

From The DarkMod Wiki
Revision as of 16:26, 4 November 2022 by Geep (talk | contribs) (Add category tag)
Jump to navigationJump to search

This page is part of a series. See GUI Scripting Language for overview.

What is a GUI Handle?

When a .gui file is read in and instantiated in association with the player or an entity, a “GUI handle” is created. This is small integer (as usual, stored in a float). It is not a globally unique ID; it is only unique with regard to all GUIs currently associated with the player/entity. Indeed, a value of 1 is extremely common. GUI handles may also be called “overlay handles”, although they are not limited to GUIs providing full-screen overlays.

A handle is never used within a GUI script. It instead occurs within a .script file’s function, for two main purposes:

  • In the SetGui… and GetGui… family of functions, to specify which GUI - among possibly multiple on the player or entity - is intended for passing of GUI parameters.
  • To dispose of an overlay once no longer needed.

Predefined Handles

In tdm_base01\script\tdm_defs.script, which automatically and quietly is included at the start of .script file loading, the following GUI handle numbers are predefined:

#define GUI_INVALID                0
#define GUI_HUD                    1
#define GUI_ENTITY1                1
#define GUI_ENTITY2                2
#define GUI_ENTITY3                3

GUI_HUD should only be used on the player, while GUI_ENTITYn values are more general, e.g., used for entities with GUIs applied to their faces. See GUI Scripting: On Entity’s Surface for examples of the latter.

GUI_HUD Use Examples

Consider, in tdm_playertools.script, the playertools_holywater script object. Recall that if holy water is applied to certain weapons, they get special powers, but only for a limited time. The countdown is done in the script, and its value in seconds propagated to “WeaponTimeLeft”, a text field reserved for it in the HUD gui. In this call, the function parameter “userEntity” is the player1 entity:

userEntity.setGuiString(GUI_HUD, "WeaponTimeLeft", timeLeftStr);

Here’s another example, from the script object contained in widely-used tdm_numberwheel.script. In a function body called as a Stim response, handle GUI_HUD is predefined. The player is shown a message once, about how to use the combination-lock number wheel:

$player1.setGuiString(GUI_HUD,"MessageText","Use the mousewheel or your \n next/prev inventory keys to turn each dial");
$player1.callGui(GUI_HUD,"DisplayMessage"); // calls a named event in the GUI

Player’s Inventory Overlay Handle

The SDK’s getInventoryOverlay call retrieves the default inventory overlay handle for the player. All non-player entities will return an invalid value.

For example, at the beginning of the numberwheel script object:

object numberwheel {
  ...
  float inventoryHandle;
  ...
};

Then, in the object’s main function body, the first time a number wheel is frobbed, the inventory handle is fetched:

inventoryHandle=$player1.getInventoryOverlay();

The code uses it to tell the inventory’s GUI to hide itself:

$player1.setGuiFloat(inventoryHandle,"Inventory_ItemVisible",0);

(Why hide? Because numberwheel highjacks the inventory controls for its own purposes, and the gamer shouldn’t see artifacts of that monkeying around.)

A Handle to Your Own Overlay

Sometimes, a handle is easily available because you created it in your .script. Continuing with the tdm_numberwheel.script example, this is defined at the outset:

object numberwheel {
  ...
  float overlayHandle;
  ...
};

In the numberwheel object’s main function body, the first time a number wheel is frobbed, a custom overlay handle is created, using the GUI specified by the given file and a “layer” (e.g., suggested handle number):

overlayHandle=$player1.createOverlay("guis/numberwheel_handler.gui",-5);

(See GUI Scripting: GUI Parameters for what numberwheel does with this overlay.) When done with an overlay, the handle could be used to delete it, e.g.:

$player1.destroyOverlay(overlayHandle);

These create and destroy functions can only be called on the player.

If All Else Fails

You could do a search loop to retrieve a handle. Adjust the start and end scope values, and string comparison in the "if" clause, as you see fit:

void my_gui_scriptobject::init() {
  handle = -1;
  float i;
  string s;

  sys.println("handle hunt");
  for (i = 0; i < 1000; i++)
  {
     s = self.getGui(i); // returns name of .gui file
     if(s != "")
     {
       handle = i;
       sys.println(s);
       break;
     }
  }
  sys.println("handle =" + i);
};