id Tech 4 : gui

Tout permuter

GUI

GUI signifie Graphic User Interface. Cette section traite de toutes les interfaces visibles dans Doom 3 : les menus, le HUD (Heads Up Display), et les écrans d'ordinateurs dans le jeu. Tous utilisent la même base : les fichiers .gui.

=Notes générales

  • Toutes les fonctions de gui disponibles sont définies dans neo/ui/GuiScript.cpp, ligne 247 (commandList[])
  • Le gui du menu principal se nomme mainmenu.gui ; le même fichier est utilisé pour le menu Pause
  • Dans plusieurs maps de Doom 3, certaines entités avec un gui ont aussi des propriétés supplémentaires, nommées gui_parm suivi d'un chiffre ; ces propriétés seront accessibles dans le gui
  • Les gui ont accès à des propriétés spéciales avec une syntaxe particulière : gui::propriété, où propriété appartient à l'entité sur laquelle le gui est affiché. Ces propriétés sont réglées dans le code C++ avec des méthodes de idUserInterfaceLocal : SetStateString(), SetStateBool(), etc.

    Toutefois, les variables de gui ne sont pas conservées quand on réinitialise les gui avec la commande de console reloadguis

  • On peut créer des propriétés personnalisées avec le mot clé float (float nom_propriete 1). Noter que si on ajoute cette propriété à la fenêtre principale (Desktop), en comptant de la modifier par après, il faudra dans tous les cas ajouter Desktop:: avant la propriété, même si le changement se fait dans le même windowDef :

    windowDef Desktop {
        onTrigger {
            set "Desktop::nom_propriete" 5;
        }
    }

    Cette approche est nécessaire pour assurer que la propriété soit interprétée correctement.

Quelques propriétés notables des windowDef:

backcolor La couleur d'arrière-plan. On doit entrer quatre chiffres entre 0 et 1, pour les valeurs rouge, vert, bleu et alpha (l'opacité).

Note : lorsque la propriété est définie, elle doit contenir des virgules (backcolor 0.9, 0.3, 0.8, 0.5), mais lorsqu'elle est redéfinie avec le mot-clé set, il ne doit y avoir aucune virgule (set "backcolor" "0.1 0.7 0.1 0.9").

text Le texte à afficher dans la fenêtre.
visible Avec une valeur de 0, le windowDef ne sera pas affiché.

=Éditeur de GUI

L'éditeur de GUI peut être visionné en ouvrant la console dans Doom 3, et en tapant editguis.

  • Raccourcis

    • Ctrl + T : tester le GUI

=Scripts de GUI (.gui)

  • Notes sur la syntaxe

    • Ne pas débuter un commentaire multiligne (/*) sur la même ligne qu'un commentaire uniligne (//), car le commentaire multiligne ne sera pas pris en compte
    • Quand on crée une fenêtre (windowDef, editDef, etc.) ou un événement pour une fenêtre (onTime, onNamedEvent, etc.), toujours mettre les capitales aux bons endroits ; sinon, le GUI fera planter l'application, car le code qui se charge de ces mots-clés en particulier (la fonction C++ idWindow::Parse()) est sensible à la casse, contrairement au code pour les propriétés de fenêtres (backcolor, textscale, etc.)
  • Commandes

    • printAfficher du texte dans la console.

      set "cmd" "print Bonjour";

      ou, pour imprimer plus d'un mot :

      set "cmd" "print 'Bonjour le monde'"; // avec des guillemets simples autour du texte

    • activateLorsque l'entité affichant le gui a une propriété target (ou target1, target2, etc. ), cette commande fera exécuter une action appropriée (par exemple, une porte verrouillée s'ouvrira). Si l'entité visée par la propriété target a un gui, celui-ci déclenchera son événement onTrigger.

      Note : une entité dans une map ne doit pas commencer par un chiffre. Si c'est le cas, le script sera mal interprété et certains événements ne seront pas déclenchés.

  • Événements de GUI (windowDef)

    Note : Le terme world GUI signifie un GUI qui se trouve sur un écran dans le jeu, plutôt qu'un menu.

    • OnActivate : chargement du gui complété ; dans un world GUI, lorsque le joueur commence à interagir avec le GUI
    • OnMouseEnter : survol de la souris

    Tous les événements sont visibles dans neo/ui/Window.cpp, ligne 93.

  • Événements nommés (named event)

    Les named event sont des événements personnalisés pour des windowDef. On les déclare ainsi :

    windowDef Desktop
    {
    onNamedEvent nom_evenement
    {
    set "cmd" "print NAMED EVENT";
    }
    }

    Par contre, je ne crois pas que ce soit possible d'utiliser un nouvel événement nommé sans passer par le code C++.

  • Appliquer un GUI personnalisé sur une entité

    1. Créer un fichier .gui, puis le déplacer avec toutes ses dépendances (fichiers .tga) dans un dossier nommé guis
    2. Compresser le dossier dans un fichier .zip ; changer l'extension de ce fichier à .pk4 et le placer dans le dossier principal du mod
    3. Dans DarkRadiant, placer dans la map un modèle capable d'afficher un gui :
      1. Clic droit dans une vue orthographique > Create model...
      2. Naviguer jusqu'au dossier mapobjects/guiobjects puis choisir un des modèles (un fichier .lwo) ; ceux-ci sont tous compatibles avec les gui
    4. Appliquer le gui à l'entité :
      1. Sélectionner l'entité
      2. Ouvrir la fenêtre Entity (touche N)
      3. Ajouter une nouvelle propriété, gui, avec comme valeur le gui voulu
      4. Sauvegarder et compiler la map
  • Afficher la souris dans un gui (testgui)

    Par défaut, la souris est désactivée lorsqu'on regarde un gui avec la commande testgui (mais elle est affichée lorsqu'elle est utilisée dans le jeu).

    Pour l'activer dans le visualisateur de gui, ajouter la propriété menugui 1 au windowDef Desktop dans le script du gui.

    Ensuite, utiliser la commande reloadguis pour voir les changements.

  • Cacher la souris dans un écran du jeu

    Pour ne jamais afficher la souris, utiliser la propriété nocursor :

    nocursor 1

    Pour cacher la souris à un temps précis, utiliser la fonction showcursor :

    showcursor "0";

  • Changer / enlever la musique du menu principal

    Dans mainmenu.gui, regarder dans le windowDef SoundrunMenu, puis trouver l'instruction suivante :

    set "cmd" "music guisounds_menu";

    Je crois que cette commande cherche l'objet son guisounds_menu du fichier pak003/sound/gui.sndshd (quoique ce son fasse référence à un certain d3theme.wav, qui ne se trouve pas parmi les fichiers de ressources ; il y a par contre un d3theme.ogg dans pak003/sound/ed/music. Je ne sais pas trop ce que ça signifie).

  • Afficher une propriété

    set "fenetre::text" "$fenetre::propriete";

    On doit utiliser un $ pour indiquer qu'il ne s'agit pas de simple texte.

  • Démarrer une partie

    Lorsque le bouton NOUVELLE PARTIE est appuyé dans le menu principal de Doom 3, on doit choisir la difficulté. Lorsqu'un des boutons de difficulté est sélectionné, le bouton exécutera cette ligne :

    resetTime "AnimNewGame" "0" ;

    Ceci démarre les actions de la fenêtre AnimNewGame, qui fermera l'interface, puis exécutera cette ligne :

    set "cmd" "startgame game/mars_city1" ;

  • Appeler une fonction de script à partir d'un gui

    Il y plus d'une syntaxe acceptable pour appeler une fonction, mais celle-ci est la plus dépendable :

    set "cmd" "runScript espaceDeNoms::fonction;";

    Les points-virgules ne sont pas nécessaires entre les guillemets, sauf pour séparer plusieurs instructions dans le dernier paramètre. Noter qu'on n'écrit pas de parenthèses ; il n'y a donc aucune façon de passer des paramètres aux fonctions.

    Pour appeler une fonction en lui passant des valeurs particulières, on peut simuler des paramètres en définissant une nouvelle valeur pour une entité quelque part dans la map, et en faisant référence à cette propriété dans le script.

    Par exemple, dans le gui :

    set "cmd" "setkeyval target_null_1 zombieCount 3; runScript namespace::spawnZombies;" ;

    Et ensuite, dans le script (dans une fonction nommée spawnZombies()) :

    float zombieCount = sys.strToFloat( $target_null_1.getKey( "zombieCount" ) );

  • Choisir le gui du hud du joueur

    Fichier : pak000/def/player.def

    Le fichier .gui du hud est indiqué dans la définition de l'entité player_base (~ligne 656 ) :

    entityDef player_base {
    "spawnclass" "idPlayer"
    "scriptobject" "player"
    "hud" "guis/hud.gui"
    ...
    }

    Changer la dernière ligne pour le gui voulu.