zeh@Posted: Sat Sep 04, 2004 9:22 pm :
Hi, and welcome back to lesson number eight in the GUI scripting series.

This time, we'll make the GUI script respond to a named event - the weapon pickup - and update the HUD accordingly. Following the tradition of having small topics covered in each lesson (so you can skip them individually if it's covering a topic you already know), this will be a pretty short article.

Complete GUI Scripting - 8: Using named events

One of the features that add the most power to the GUI system is the ability to respond to certain built-in events. These events include not only GUI events - onAction, onTime, etc - but also 'external' events triggered by the system. They're called "named events", and we can defined them by using onNamedEvent blocks.

Simply enough, a named event works like this:

Code:
onNamedEvent <event name> {
   <statements to execute>
}


Of course, the <event name> is the name of the event we want to capture. This is an special name, and depends on the scope you're running your GUI script. Since we're using a HUD GUI script, there are certain built in named events we can work with.

The first thing we'll do is open up the HUD script we created in the previous lesson, which is as follows.

Code:
windowDef Desktop {
   rect   0,0,640,480
   visible   1
   noevents   1
   nocursor  1

//=============================================================================
// Main bar
//=============================================================================

   windowDef base {
      rect   0,416,1024,64
      visible   1
      background   "guis/assets/hud_base"
      matcolor   1,1,1,1
   }

//-----------------------------------------------------------------------------
// Standard indications: ammo, armor, health
//-----------------------------------------------------------------------------

   windowDef bar_health {
      rect   110,420,60,49
      visible   1
      forecolor   1,1,1,1
      text   "gui::player_health"
      textscale   0.6
      textalign   2
      font   "fonts/english"
   }
   windowDef bar_health_percent {
      rect   170,420,40,49
      visible   1
      forecolor   1,1,1,1
      text   "%"
      textscale   0.6
      textalign   0
      font   "fonts/english"
   }
   windowDef bar_armor {
      rect   370,420,60,49
      visible   1
      forecolor   1,1,1,1
      text   "gui::player_armor"
      textscale   0.6
      textalign   2
      font   "fonts/english"
   }
   windowDef bar_armor_percent {
      rect   430,420,40,49
      visible   1
      forecolor   1,1,1,1
      text   "%"
      textscale   0.6
      textalign   0
      font   "fonts/english"
   }
   windowDef bar_ammo {
      rect   15,420,60,49
      visible   1
      forecolor   1,1,1,1
      text   "gui::player_ammo"
      textscale   0.6
      textalign   2
      font   "fonts/english"
   }

//-----------------------------------------------------------------------------
// Weapon numbers
//-----------------------------------------------------------------------------

   windowDef gun_2 {
      rect   218, 416, 40, 40
      visible   1
      forecolor   1,1,0,1
      text   "2"
      textscale   0.25
      font   "fonts/micro"
   }

   windowDef gun_3 {
      rect   242, 416, 40, 40
      visible   1
      forecolor   1,1,1,0.4
      text   "3"
      textscale   0.25
      font   "fonts/micro"
   }

   windowDef gun_4 {
      rect   266, 416, 40, 40
      visible   1
      forecolor   1,1,1,0.4
      text   "4"
      textscale   0.25
      font   "fonts/micro"
   }

   windowDef gun_5 {
      rect   218, 436, 40, 40
      visible   1
      forecolor   1,1,1,0.4
      text   "5"
      textscale   0.25
      font   "fonts/micro"
   }

   windowDef gun_6 {
      rect   242, 436, 40, 40
      visible   1
      forecolor   1,1,1,0.4
      text   "6"
      textscale   0.25
      font   "fonts/micro"
   }

   windowDef gun_7 {
      rect   266, 436, 40, 40
      visible   1
      forecolor   1,1,1,0.4
      text   "7"
      textscale   0.25
      font   "fonts/micro"
   }

//=============================================================================
// Marine faces
//=============================================================================

//-----------------------------------------------------------------------------
// Normal face
//-----------------------------------------------------------------------------

   windowDef marineFace {
      rect   290,418,64,64
      visible   1
      background   "guis/assets/hud_face_100_center"
      matcolor   1,1,1,1
   }

}


Now, we're going to add a new event to it. Right after the desktop windowDef properties are declared, we add a new event block.

Code:
windowDef Desktop {
   rect   0,0,640,480
   visible   1
   noevents   1
   nocursor  1

//=============================================================================
// Events
//=============================================================================

   onNamedEvent newWeapon {
   
   }

(...strip...)


This is the basics of our new event block. Since we're trying to update the weapon numbers on the HUD, we want to capture the "newWeapon" event, which is fired when a new weapon has been picked up. This event name came from the original HUD file, of course - reading the original script sources, from the original game, is the best way to learn how to accomplish certain goals in DOOM 3 modding. Reverse engineering is your friend.

Anyway, remember our "gun_*" windowDef declarations? They had the numbers of the weapons available for the player. Like I said on the previous lesson, most of the weapons numbers have a "forecolor" property of "1,1,1,0.4" - 40% black. When they are available, they turn into "1,1,0,1" - yellow. What we need to do, then, is discover which weapon was picked up and update the text color accordingly.

That will be accomplished by using the "gui::newweapon" variable inside of the newWeapon named event block. Just like the "gui::player_health" we discussed on the previous lesson, "gui::newweapon" is an special variable which has the number of the last weapon picked up, so it's easy to find out which weapon number should be highlighted. Let's start with a simple conditional statement.

Code:
(...strip...)

//=============================================================================
// Events
//=============================================================================

   onNamedEvent newWeapon {
      // Now turns on the correct number when a new weapon is picked
      if ("gui::newweapon" == 2) {
      }
   }

(...strip...)


the "if" statement compares the "gui::newweapon" to 2. If this is true -- meaning, the last weapon picked up was weapon 2 - the statements inside of the "if" block will be executed.

One thing to notice here is that the weapon indexing inside of the GUI system start with the pistol. So, weapon 1 is the pistol, not the fists; weapon 2 is the shotgun, not the pistol.

So, since the code inside of the if block will be executed when the shotgun has been picked up, we just need to update the "forecolor" property of the correct "gun_*" windowDef to make it bright yellow. That's easy, using the "set" command we used previously.

Code:
(...strip...)

//=============================================================================
// Events
//=============================================================================

   onNamedEvent newWeapon {
      // Now turns on the correct number when a new weapon is picked
      if ("gui::newweapon" == 1) {
         set "gun_2::forecolor" "1,1,0,1";
      }
   }

(...strip...)


Easier than taking candy from a baby. So we just need to add if statements for the other guns; we're just going up to gun 6, or the plasma gun, so...

Code:
(...strip...)

//=============================================================================
// Events
//=============================================================================

   onNamedEvent newWeapon {
      // Now turns on the correct number when a new weapon is picked
      if ("gui::newweapon" == 2) {
         set "gun_3::forecolor" "1,1,0,1";
      }
      if ("gui::newweapon" == 3) {
         set "gun_4::forecolor" "1,1,0,1";
      }
      if ("gui::newweapon" == 4) {
         set "gun_5::forecolor" "1,1,0,1";
      }
      if ("gui::newweapon" == 5) {
         set "gun_6::forecolor" "1,1,0,1";
      }
      if ("gui::newweapon" == 6) {
         set "gun_7::forecolor" "1,1,0,1";
      }
   }

(...strip...)


Let's test it. Fire up our DOOM 3 shortcut - or do a reloadguis command if you already had it running.

We have a pistol on hand...

Image

...going to grab the shotgun...

Image

...and voila, the corresponding number - 3 - has been lit on the HUD bar. Simple, and easy.

That's it for now. We'll use a few more named events on the next lessons.

Download source and example files (8kb)



b0ksah@Posted: Mon Sep 06, 2004 6:31 pm :
;) You are da God mate ;) *bump*



MNeMiC@Posted: Mon Sep 06, 2004 6:38 pm :
bumpetiBUMP!



Luigi@Posted: Fri Jan 06, 2006 7:41 pm :
*Topic revival*
I've been trying to fix this for three hours and I just can't figure it out:

Code:
   onNamedEvent newWeapon {
         if ("gui::newweapon" == 0) {
         set "gun_1::forecolor" "1,1,0,1";
      }
    if ("gui::newweapon" == 1) {
         set "gun_2::forecolor" "1,1,0,1";
      }
         if ("gui::newweapon" == 2) {
         set "gun_3::forecolor" "1,1,0,1";
      }
      if ("gui::newweapon" == 3) {
         set "gun_4::forecolor" "1,1,0,1";
      }
      if ("gui::newweapon" == 4) {
         set "gun_5::forecolor" "1,1,0,1";
      }
      if ("gui::newweapon" == 5) {
         set "gun_6::forecolor" "1,1,0,1";
      }
      if ("gui::newweapon" == 6) {
         set "gun_7::forecolor" "1,1,0,1";
      }
      if ("gui::newweapon" == 7) {
         set "gun_8::forecolor" "1,1,0,1";
      }
      if ("gui::newweapon" == 8) {
         set "gun_9::forecolor" "1,1,0,1";

    }
   }

(strip)

  windowDef gun_1 {
      rect   450,10, 40, 40
      visible   1
      forecolor   1,1,0,1
      text   "1"
      textscale   0.2
      font   "fonts/micro"
   }


   windowDef gun_2 {
      rect   465,10, 40, 40
      visible   1
      forecolor   1,1,0,1
      text   "2"
      textscale   0.2
      font   "fonts/micro"
   }

   windowDef gun_3 {
      rect   480, 10, 40, 40
      visible   1
      forecolor   1,1,1,0.4
      text   "3"
      textscale   0.2
      font   "fonts/micro"
   }

   windowDef gun_4 {
      rect   495, 10, 40, 40
      visible   1
      forecolor   1,1,1,0.4
      text   "4"
      textscale   0.2
      font   "fonts/micro"
   }

   windowDef gun_5 {
      rect   510, 10, 40, 40
      visible   1
      forecolor   1,1,1,0.4
      text   "5"
      textscale   0.2
      font   "fonts/micro"
   }

   windowDef gun_6 {
      rect   525,10, 40, 40
      visible   1
      forecolor   1,1,1,0.4
      text   "6"
      textscale   0.2
      font   "fonts/micro"
   }

   windowDef gun_7 {
      rect   540, 10, 40, 40
      visible   1
      forecolor   1,1,1,0.4
      text   "7"
      textscale   0.2
      font   "fonts/micro"
   }

   windowDef gun_8 {
      rect   555, 10, 40, 40
      visible   1
      forecolor   1,1,1,0.4
      text   "8"
      textscale   0.2
      font   "fonts/micro"
   }

   windowDef gun_9 {
      rect   570, 10, 40, 40
      visible   1
      forecolor   1,1,1,0.4
      text   "9"
      textscale   0.2
      font   "fonts/micro"
   }



I have no problems with the shotgun and all of the weapons after it but when it comes to the chainsaw and pistol for some reason the chainsaw will always be highlighted as "picked up" even when it isn't, same for the pistol. This is really annoying me.

Thanks in advance.



Luigi@Posted: Tue Jan 10, 2006 11:12 pm :
Gee, thanks a lot for the help. :roll:



zeh@Posted: Tue Jan 10, 2006 11:21 pm :
I'm sorry, I haven't been able to use the computer that much as of lately.

Anyways, unless I'm missing something big from your question, it's a very simple problem. You'll notice from the source that both weapons are pre-lighted as being picked up. Watch for this line on the first two gun windowdefs:

Code:
forecolor   1,1,0,1


That's hardcoded and you might have to change that if both your weapons aren't automatically available to the player. Then it should be:

Code:
forecolor   1,1,1,0.4


This is the default for non-picked weapons.



Luigi@Posted: Tue Jan 10, 2006 11:41 pm :
Oh my god, how could I have missed that? I'm such an idiot. :oops:

Another problem I noticed is that if there are two or more "new weapons" and the player picks them up quickly then the first weapon the player picks up will register, but the others won't and the numbers will stay in the grey color.