Cholmondely wrote: ↑Sun Mar 13, 2022 12:03 pm
must be the plist differently named than hud.plist ... ?
Yes.
Cholmondely wrote: ↑Sun Mar 13, 2022 12:03 pm
set your HUD in startUp and add your HUD and plist name into HUDSelector:
In Xenon HUD, the code which does this is:
Code: Select all
var h = worldScripts.hudselector;
if (h) h.$HUDSelectorAddHUD("Xenon HUD", this.name);
Cholmondely wrote: ↑Sun Mar 13, 2022 12:03 pm
Can anybody explain the relevant bits of this to me please (and possibly even provide an example!)?
Coluber HUD is probably the simplest example (Xenon and Vimana are both "everything and the kitchen sink" types of HUDs, so the actual HUD Selector code can get a little lost in the mix).
So, from the Coluber HUD OXP, there are two HUD plist files, one for normal flight mode, and one for when you're docked. The dock version has "-dock" in the filename. The content of these plist files is not important right now - the important thing is that there's two of them that are used in different game states (in space or docked).
Everything else is covered in the "script.js" file. The script file allows for some custom crosshair images to be used, so I'll strip out those references to concentrate on the HUD selector code. That leaves the following code:
Code: Select all
"use strict";
this.name = "coluber_hud_ch01";
this.author = "Captain Beatnik [email protected], Norby [email protected]";
this.licence = "CC BY-NC-SA 4.0";
this.startUp = function () {
player.ship.hud = this.name + "-dock.plist";
var h = worldScripts.hudselector;
if( h ) h.$HUDSelectorAddHUD("Coluber HUD CH01", this.name);
}
this.shipWillDockWithStation = function(station) {
player.ship.hud = this.name + "-dock.plist";
}
this.shipWillLaunchFromStation = function() {
player.ship.hud = this.name + ".plist";
}
this.$HUDSelectorCallBack = function ( off ) {
var w = worldScripts.coluber_hud_ch01;
if( off ) { //do things to disable your HUD like rename functions
if( w.shipWillDockWithStation ) {
w.$save_shipWillDockWithStation = w.shipWillDockWithStation;
delete w.shipWillDockWithStation;
}
if( w.shipWillLaunchFromStation ) {
w.$save_shipWillLaunchFromStation = w.shipWillLaunchFromStation;
delete w.shipWillLaunchFromStation;
}
} else { //do things to activate your HUD like restore disabled functions
// if the player is docked, use the docked version of the HUD
if (player.ship.docked) player.ship.hud = this.name + "-dock.plist";
if( !w.shipWillLaunchFromStation ) {
eval("w.shipWillDockWithStation = "+w.$save_shipWillDockWithStation);
eval("w.shipWillLaunchFromStation = "+w.$save_shipWillLaunchFromStation);
}
}
}
Going through this bit by bit:
Code: Select all
this.startUp = function () {
player.ship.hud = this.name + "-dock.plist";
var h = worldScripts.hudselector;
if( h ) h.$HUDSelectorAddHUD("Coluber HUD CH01", this.name);
}
This code, the "startUp" function world script, runs once when the game starts. When executed, it will set the players HUD file to the Coluber HUD docked version (because you are always docked on startup).
Next we create a reference to the HUD selector worldscript file. If HUD selector isn't installed, the next line of code won't execute. But if it is installed, we execute the $HUDSelectorAddHUD function, passing in the name of the HUD, and the name of the script file.
If there was only one HUD plist file (edit to add: and there was no additional functionality implemented thru worldscript events), that's it. Job done. The HUD is now linked into HUD selector. However, because there are two HUD plists, that are swapped in or out based on your docked status, there's a bit more work to do.
Coluber HUD implements two worldscripts for switching the HUD: shipWillDockWithStation and shipWillLaunchFromStation. However, if another HUD has been selected via HUD Selector, we don't want those functions to be executed, otherwise mass confusion will occur. So, we add the $HUDSelectorCallBack function. HUD Selector will look for and execute this function in a HUD's worldscript whenever it changes the HUD, to either disable or enable the HUD. It notifies the HUD about which state to move to via the passed in paramater, "off". If that value is true, the HUD is being turned off. If it's false, the HUD is being turned on.
When the HUD is being turned off, we need to hide our two worldscript functions from Oolite, by copying the function to a new location and deleting the original. Here's the code for the first worldscript:
Code: Select all
var w = worldScripts.coluber_hud_ch01;
if( off ) { //do things to disable your HUD like rename functions
if( w.shipWillDockWithStation ) {
w.$save_shipWillDockWithStation = w.shipWillDockWithStation;
delete w.shipWillDockWithStation;
}
First, we're adding a reference to the Coluber HUD script, which will make the code afterwards a little easier to read.
Next, we're checking if the "off" parameter is true. If it is, we then check to see if the shipWillDockWithStation is in the place we expect it to be. We're doing this just in case things have gotten out of sync somehow. In 99.999% of cases, shipWillDockWithStation will be present. If so, we then copy the function to a new location, one that won't be picked up by Oolite. And then we delete the original function.
(Note for purists: This code isn't actually "copying" anything. It's setting a new reference to an existing object, then deleting the original reference to that object. However, for the sake of making this tutorial easier to understand for the inexperienced out there, I'm using "copy" terminology.)
The next section of code does the same thing for the shipWillLaunchFromStation worldscript function.
At this point, Coluber HUD has been disabled.
Now, if HUD selector enables Coluber HUD, the function is called again, only now, "off" is false. Let's look at the code that runs in that instance:
Code: Select all
} else { //do things to activate your HUD like restore disabled functions
// if the player is docked, use the docked version of the HUD
if (player.ship.docked) player.ship.hud = this.name + "-dock.plist";
if( !w.shipWillLaunchFromStation ) {
eval("w.shipWillDockWithStation = "+w.$save_shipWillDockWithStation);
eval("w.shipWillLaunchFromStation = "+w.$save_shipWillLaunchFromStation);
}
}
The first thing that happens is that the player's HUD is set to Coluber's docked HUD. (Note: there is actually a bit of a bug in the assumption here. HUD Selector can switch HUD's during flight, so really this code should be doing a check of whether we're in flight or not before setting the HUD)
After this, we are checking to see if there is a shipWillLaunchFromStation function present in our worldscript. If HUD Selector was run previously, then in 99.999% of cases it won't be there. When it doesn't find that function, it then executes two "eval" statements to copy our saved versions of the two worldscript functions back to their original places.
A small visualisation might help is showing what's going on.
If Coluber HUD is the only HUD installed, or if it has been enabled by HUD selector, it's worldscript would look like this:
Code: Select all
this.startUp () {...}
this.shipWillDockWithStation () {...}
this.shipWIllLaunchFromStation () {...}
If Coluber HUD has been disabled by HUD selector, it's worldscript would look like this:
Code: Select all
this.startUp () {...}
this.$save_shipWillDockWithStation () {...}
this.$save_shipWillLaunchFromStation () {...}
And that's it. The important thing to note is that, as more bells and whistles are added to a HUD's worldscript, more code needs to be added to the $HUDSelectorCallback function to disable or enable those functions to prevent HUD's from conflicting with each other.
Hopefully that helps a bit.