Custom HUD elements (basics)
This tutorial teaches you how to implement a new custom gauge into FreeSpace Open.
- Basic modding skills (file structure, basic FREDding, modular tables)
- Some knowledge on HUD editing. If you haven't worked with HUDs before, I suggest you learn its basics first. At the very least, learn how to install your own primary weapon/afterburner energy recharge gauges, just to make sure you understand the FS engine's HUD handling logic.
- Very basic graphics editing (filling a picture with blue and drawing a gray border around it)
Goal of this tutorial
To create two custom HUD gauges: the HUD element graphics (a box) and the HUD element that displays the number of active enemy objects in the area.
Open a graphics editor and create some random HUD element. For this tutorial, use a simple box with these specifications:
Image size: 50x30 Border: 5-pixel wide, gray color Inside: pure blue (RGB: 0, 0, 255) Palette: same as used in 2_RADAR1
Now, if you know the basics of HUD editing, you are aware that any custom HUD graphics will do as far as the technicalities are concerned. If your box (sphere, triangle, or whatever shape you choose) is too big or too small, it will at most look bad.
I named my file hudbox50.ani. You can choose whatever name you want. It doesn't matter as long as you have an ani, with the proper palette. Place the file in mymod/data/hud.
The numeric HUD element
Just create a box with pure black blackground (RGB 0, 0, 0). BtA: Mefistofele uses a black box 25x21 px, so it's a safe bet to use this size.
Create the .ani and place in mymod/data/hud
Double-check whether you have used the correct palette for both anis. If the HUD elements don't display during testing, it may very well be due to using faulty palettes. One cannot emphasize the need for using the right palette.
You have to set up a hud_gauges.tbl or a similar modular table. The modular table is probably much better choice, because we just want to add new HUD elements.
This is what the modular table looks like:
#Gauge Config $Base: (1440, 900) $Required Aspect: Wide Screen ; Can be "Wide Screen" or "Full Screen" ATM $Min: (1280, 720) ; These Min and Max fields are Inclusive $Max: (1920, 1080) $Gauges: +Custom: Position: (825, 290) Name: EnemiesLeft Text: Targets to Destroy X Offset: 7 Y Offset: 4 Gauge Type: RETICLE_CIRCLE Slew: YES Active by default: NO Filename: emptyhud +Custom: Position: (815, 275) Name: EnemiesLeftBox Text: EOR X Offset: 7 Y Offset: 4 Gauge Type: RETICLE_CIRCLE Slew: YES Active by default: NO Filename: hudbox50 $End Gauges #End #Gauge Config $Base: (1024, 768) $Required Aspect: Full Screen ;$Min: (640, 480) $Gauges: +Custom: Position: (650, 235) Name: EnemiesLeft Text: Targets to Destroy X Offset: 7 Y Offset: 4 Gauge Type: RETICLE_CIRCLE Slew: YES Active by default: NO Filename: emptyhud +Custom: Position: (635, 225) Name: EnemiesLeftBox Text: EOR X Offset: 7 Y Offset: 4 Gauge Type: RETICLE_CIRCLE Slew: YES Active by default: NO Filename: hudbox50 $End Gauges #End
The name of the HUD (EnemiesLeft and EnemiesLeftBox) will be used in FRED. "EnemiesLeft" is the number, "EnemiesLeftBox" is the graphics. The text message is irrelevant to "EnemiesLeft", because it will be overriden immediately at mission start . The text of "EnemiesLeftBox" is EOR, which is a conjectural shorthand for "Enemy Objects Remaining." Something short needs to be applied here, because the 50x30 px box is quite small. If you have a 300x30 px box, then "Enemies Left to Destroy" will probably fit.
FRED a quick test mission, where Alpha 1 has something powerful (to facilitate testing), and is confronted with 3 enemy ships, belonging to Cancer wing.
Enter the Event editor, create the following variables:
0 "EnemiesLeftNum" "3" "number" 1 "EnemiesLeftString" "yes" "string"
Where EnemiesLeftNum is the number of remaining active enemies. EnemiesLeftString is any string data, which will be overwritten when the number of enemies changes from the default value.
Create these events:
$Formula: ( when ( true ) ( hud-gauge-set-active "EnemiesLeft" ( true ) ) ( hud-set-color "EnemiesLeft" 255 255 255 ) ( hud-set-text-num "EnemiesLeft" 3 ) ( hud-gauge-set-active "EnemiesLeftBox" ( true ) ) ) +Name: Start +Repeat Count: 1 +Interval: 1
$Formula: ( when-argument ( any-of "Cancer 1" "Cancer 2" "Cancer 3" ) ( is-destroyed-delay 0 "<argument>" ) ( modify-variable @EnemiesLeftNum ( - @EnemiesLeftNum 1 ) ) ( int-to-string @EnemiesLeftNum "@EnemiesLeftString[yes]" ) ( hud-set-text "EnemiesLeft" "@EnemiesLeftString[yes]" ) ( invalidate-argument "<argument>" ) ) +Name: Update EnemiesLeft +Repeat Count: -1 +Trigger Count: 3 +Interval: 1
What did I just do?
The "Start" event displays the two custom HUD gauges (hud-gauge-set-active) and colors the numeric HUD element white.
The "Update EnemiesLeft" updates the number to be displayed, whenever one of Cancer is destroyed, and the "EnemiesLeft" variable is reduced by one. Int-to-string transfers this number to the string variable, which will override the outdated number of enemies on the HUD (hud-set-text). Do not forget about the trigger count.
If you haven't worked with when-argument before, you can create three separate events for each destroyed Cancer.
Everything should work now. If not, first make sure the HUD elements are displayed at all. Rename hudbox50.ani to 2_reticle.ani and see if your custom HUD box becomes your reticle. If no reticle is displayed, your box uses the wrong palette. Otherwise you messed up something in FRED.