Back to Index Page generated: May 17, 2025, 5:47:49 AM

Expansion Contextual Help System

Content

Warnings

  1. http://wiki.alioth.net/index.php/Contextual%20Help%20System -> 404 Not Found
  2. Low hanging fuit: Information URL exists...

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Adds a contextual help page to most game gui screens, accessed with a consistent keypress Adds a contextual help page to most game gui screens, accessed with a consistent keypress
Identifier oolite.oxp.phkb.ContextualHelp oolite.oxp.phkb.ContextualHelp
Title Contextual Help System Contextual Help System
Category Miscellaneous Miscellaneous
Author phkb phkb
Version 1.1 1.1
Tags
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Information URL https://wiki.alioth.net/index.php/Contextual_Help n/a
Download URL https://wiki.alioth.net/img_auth.php/8/81/ContextualHelp.oxz n/a
License CC-BY-NC-SA 4.0 CC-BY-NC-SA 4.0
File Size n/a
Upload date 1743745299

Documentation

readme.txt

Contextual Help
===============
by phkb

Overview
--------
This OXP adds contextual help to 11 different GUI screens, to provide some support for players who are unfamiliar with the game mechanics and ways to interact with each game screen. It also supports the ability for other OXP's to add their own text to the help shown.

The default key used for each page is Ctrl-h. 

OXP integrations
----------------
To add extra help to a particular GUI screen, use the following command:

    var w = worldScripts.ContextualHelp;
    if (w) {
        w.$addHelpTextToGuiScreen(this.name, "GUI_SCREEN_MARKET", "Some extra text to show.");
    }

To apply a specific background image to a GUI screen help page, use the following code:

    var w = worldScripts.ContextualHelp;
    if (w) {
        w.$setBackgroundForHelpScreen("GUI_SCREEN_MARKET", "my_background_image.png");
    }

To apply a specific overlay image to a GUI screen help page, use the following code:

    var w = worldScripts.ContextualHelp;
    if (w) {
        w.$setOverlayForHelpScreen("GUI_SCREEN_MARKET", "my_overlay_image.png");
    }

License
-------
Creative Commons Attribution Non-Commercial Share-Alike 4.0 (https://creativecommons.org/licenses/by-nc-sa/4.0/)

Version History
---------------
1.1
- Small tweak to the info text at the bottom of the screen.
- Removed debug message.
- Expanded readme.txt info.

1.0
- Initial release

Equipment

This expansion declares no equipment. This may be related to warnings.

Ships

This expansion declares no ships. This may be related to warnings.

Models

This expansion declares no models. This may be related to warnings.

Scripts

Path
Scripts/contextual_help.js
"use strict";
this.name        = "ContextualHelp";
this.author      = "phkb";
this.copyright   = "2023 phkb";
this.description = "Implements a contextual help system to most gui screens.";
this.licence     = "CC BY-NC-SA 4.0";

// handling help on OXP pages?

this._page = 0;
this._text = "";
this._selectedKey = "";
this._keyDict = {
    "guiOPTIONS": "GUI_SCREEN_OPTIONS",
    "guiEQUIP": "GUI_SCREEN_EQUIP_SHIP",
    "guiSHIP": "GUI_SCREEN_SHIPYARD",
    "guiINTER": "GUI_SCREEN_INTERFACES",
    "guiSTATUS": "GUI_SCREEN_STATUS",
    "guiMAN": "GUI_SCREEN_MANIFEST",
    "guiLRC": "GUI_SCREEN_LONG_RANGE_CHART",
    "guiSRC": "GUI_SCREEN_SHORT_RANGE_CHART",
    "guiSYS": "GUI_SCREEN_SYSTEM_DATA",
    "guiMKT": "GUI_SCREEN_MARKET",
    "guiMINF": "GUI_SCREEN_MARKETINFO"
};
this._backgroundDict = {};
this._overlayDict = {};
this._extraText = {};
this._shownHints = [];

//-------------------------------------------------------------------------------------------------------------
this.startUp = function() {
    // register our hot key on the various GUI screens
    var keys = Object.keys(this._keyDict);
    var i = keys.length;
    while (i--) {
        var options = {};
        options["guiScreen"] = this._keyDict[keys[i]];
        options["registerKeys"] = {};
        options["registerKeys"][keys[i]] = [{key:"h",mod1:true}];
        options["callback"] = this.$setupHelpPage.bind(this);
        setExtraGuiScreenKeys(this.name, options);
    }
    if (missionVariables.ContextualHelp_Hints) {
        this._shownHints = JSON.parse(missionVariables.ContextualHelp_Hints);
    }
}

//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function() {
    missionVariables.ContextualHelp_Hints = JSON.stringify(this._shownHints);
}

//-------------------------------------------------------------------------------------------------------------
this.guiScreenChanged = function(to, from) {
    var showHint = false;
    if (this._shownHints.indexOf(to) == -1) {
        if (to == "GUI_SCREEN_OPTIONS") showHint = true;
        if (to == "GUI_SCREEN_EQUIP_SHIP") showHint = true;
        if (to == "GUI_SCREEN_SHIPYARD") showHint = true;
        if (to == "GUI_SCREEN_INTERFACES") showHint = true;
        if (to == "GUI_SCREEN_STATUS") showHint = true;
        if (to == "GUI_SCREEN_MANIFEST") showHint = true;
        if (to == "GUI_SCREEN_LONG_RANGE_CHART") showHint = true;
        if (to == "GUI_SCREEN_SHORT_RANGE_CHART") showHint = true;
        if (to == "GUI_SCREEN_SYSTEM_DATA") showHint = true;
        if (to == "GUI_SCREEN_MARKET") showHint = true;
        if (to == "GUI_SCREEN_MARKETINFO") showHint = true;
    }
    if (showHint == true) {
        this._shownHints.push(to);
        player.consoleMessage("Press Ctrl-H to display help");
    }
}

//-------------------------------------------------------------------------------------------------------------
// allows custom help text to be appended to the rest of the help screen text.
// usage $addHelpTextToGuiScreen(this.name, "GUI_SCREEN_MANIFEST", "Some extra helpful notes, hints or suggestions.");
this.$addHelpTextToGuiScreen = function(source, gui, text) {
    if (!source || source == "") {
        log(this.name, "Invalid source specified. Must be a valid text string (eg 'myoxp')");
        return;
    }
    var keys = Object.keys(this._keyDict);
    var i = keys.length;
    var found = false;
    while (i--) {
        if (this._keyDict[keys[i]] == gui) {found = true; break;}
    }
    if (found == false) {
        log(this.name, "Invalid GUI screen code specified: " + gui);
        return;
    }
    if (!this._extraText.hasOwnProperty(source)) {
        this._extraText[source] = {};
    }
    this._extraText[source][gui] = text;
}

//-------------------------------------------------------------------------------------------------------------
// allows custom background images to be set for the various help screens
// usage: $setBackgroundForHelpScreen("GUI_SCREEN_MANIFEST", "my_background_image.png");
this.$setBackgroundForHelpScreen = function(gui, background) {
    this._backgroundDict[gui] = background;
}

//-------------------------------------------------------------------------------------------------------------
// allows custom overlay images to be set for the variable help screens
// usage: $setOverlayForHelpScreen("GUI_SCREEN_MANIFEST", "my_overlay_image.png");
this.$setOverlayForHelpScreen = function(gui, overlay) {
    this._overlayDict[gui] = overlay;
}

//-------------------------------------------------------------------------------------------------------------
this.$setupHelpPage = function(key) {
    this._selectedKey = key;
    var gui = this._keyDict[this._selectedKey];
    var lookup = "[help_" + gui + "]";
    this._text = expandDescription(lookup);
    // add in additional OXP help here
    var keys = Object.keys(this._extraText);
    if (keys && keys.length > 0) {
        for (var i = 0; i < keys.length; i++) {
            if (this._extraText[keys[i]][gui]) this._text += "\n" + expandDescription(this._extraText[keys[i]][gui]);
        }
    }
    this._page = 1;
    this.$showHelpPage();
}

//-------------------------------------------------------------------------------------------------------------
this.$showHelpPage = function $showHelpPage() {
    var that = $showHelpPage;
    var columnText = (that.columnText = that.columnText || this.$columnText);

    // arrange the text into an array of text items that don't overflow the page
    var textLines = columnText(this._text, 32);

    // max rows of text to show
    var rows = 19; // could fit an extra line in, but having a one-line gap at the bottom looks better
    if (player.ship.hudAllowsBigGui) rows = 25;
    // work out the max number of pages we have
    var maxPage = parseInt((textLines.length - 1) / rows) + 1;

    var text = "";
    var counter = 0;
    // set teh start point, based on the current page
    var line = (this._page - 1) * rows;
    // start compiling the text for this page
    do {
        text += textLines[line] + "\n";
        line += 1;
        counter += 1;
        if (line > textLines.length - 1) break;
    } while (counter < rows)

    // build up the options for the mission screen
    var extra = "";
    if (this._page < maxPage || this._page != 1) extra += "Use Page Up/Page Down for more. ";
    var opts = {
        screenID: "oolite-contextual-help-map",
        title: "Help" + (maxPage > 1 ? " (Page " + this._page + " of " + maxPage + ")" : ""),
        allowInterrupt: true,
        exitScreen: this._keyDict[this._selectedKey],
        choices: {"99_EXIT":extra + "Press ESC or Enter to return"},
        registerKeys: {"keyEsc":[{key:"esc"}]},
        message: text
    };
    // if we've been given a background image for this page, set it now
    if (this._backgroundDict[this._keyDict[this._selectedKey]] != "") {
        opts["background"] = this._backgroundDict[this._keyDict[this._selectedKey]];
    }
    // if we've been given an overlay image for this page, set it now
    if (this._overlayDict[this._keyDict[this._selectedKey]] != undefined && this._overlayDict[this._keyDict[this._selectedKey]] != "") {
        //log(this.name, "overlay = " + this._overlayDict[this._keyDict[this._selectedKey]]);
        opts["overlay"] = this._overlayDict[this._keyDict[this._selectedKey]];
    } else {
        // use our default overlay
        log(this.name, "overlay default");
        opts["overlay"] = {name:"ch-info.png", height:546};
    }
    // only add the page up or down keys if there are pages to go to.
    if (this._page > 1) opts["registerKeys"]["keyPgUp"] = [{key:"pageUp"}];
    if (this._page < maxPage) opts["registerKeys"]["keyPgDn"] = [{key:"pageDown"}];

    mission.runScreen(opts, this.$screenHandler, this);
}

//-------------------------------------------------------------------------------------------------------------
this.$screenHandler = function(choice, key) {
    switch (key) {
        case "keyPgUp": this._page -= 1; this.$showHelpPage(); break;
        case "keyPgDn": this._page += 1; this.$showHelpPage(); break;
        case "enter": // we'll accept enter as well for the exit
        case "keyEsc": return;
    }
}

//-------------------------------------------------------------------------------------------------------------
// arranges text into a array of strings with a particular column width
// handles \n codes in the text
this.$columnText = function $columnText(originalText, columnWidth) {
	var returnText = [];
	if (defaultFont.measureString(originalText) > columnWidth) {
        var paras = originalText.split("\n");
        for (var p = 0; p < paras.length; p++) {
            var words = paras[p].split(" ");
            var word = "";
            var line = "";
            for (var w = 0; w < words.length; w++) {
                word = words[w].trim();
                // make sure we have a word to add before trying to add it
                if (word !== "") {
                    if (defaultFont.measureString(line + " " + word) <= columnWidth) {
                        line += (line === "" ? "" : " ") + word;
                    } else {
                        returnText.push(line);
                        line = word;
                    }
                }
            }
            // add any remainder
            returnText.push(line);
        }
	} else {
		returnText.push(originalText);
	}
	return returnText;
}