Back to Index Page generated: May 8, 2024, 6:16:03 AM

Expansion Primeable Equipment MFD

Content

Warnings

  1. Information URL mismatch between OXP Manifest and Expansion Manager string length at character position 0

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Displays a list of the player ship's primeable equipment in the order that it's primed and indicates the current selection. Displays a list of the player ship's primeable equipment in the order that it's primed and indicates the current selection.
Identifier oolite.oxp.nicksta.primeable-equipment-mfd oolite.oxp.nicksta.primeable-equipment-mfd
Title Primeable Equipment MFD Primeable Equipment MFD
Category HUDs HUDs
Author Nicholas Menchise Nicholas Menchise
Version 1.0 1.0
Tags
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Information URL n/a
Download URL https://wiki.alioth.net/img_auth.php/c/c8/Primeable-Equipment-MFD_1.0.oxz n/a
License CC BY-NC-SA 4.0 CC BY-NC-SA 4.0
File Size n/a
Upload date 1610873469

Documentation

Also read http://wiki.alioth.net/index.php/Primeable%20Equipment%20MFD

readme.txt

Oolite Expansion Pack
Primeable Equipment MFD



    This expansion introduces an MFD that displays a list of primeable equipment in the order that it's primed and an indicator for the current selection. It's intended as a standard feature of the player ship's HUD, so it doesn't appear in the equipment list and doesn't cost anything. All you need is a HUD that displays MFDs. Launch your ship, cycle through the MFDs and it will be there.


Calibration

    Ship manufacturers are still learning how to configure a predictable priming sequence. In the meantime, the MFD needs to be calibrated after primeable equipment items are added to the ship. The MFD will display the instructions when calibration is needed. The instructions are as simple as pressing the prime equipment button until the MFD shows you what you want to see. Calibration is also needed after loading from a saved game.


Compatibility

    This expansion is compatible with Auto-Prime Equipment and any other scripts that change the current selection without using the prime equipment keys, although it will be slightly less responsive in these cases as the changes are detected by a timer.


User Interface Design

    The MFD can only display nine equipment items at a time. It needs to display the list in a way that is useful to the player regardless of how many items are on the ship. A scroll wheel metaphor was chosen for this purpose.

    The current selection is always on the same row, indicated by arrow heads. The next item to be primed is directly below it, the next one after that is on the following line and so on. However, the last item to be primed is directly above the current selection, so the list is looping back on to itself.

    Pressing the prime button will scroll the list. Two numbers on the top right corner of the MFD show the index position of the current selection and the total number of selections, starting from zero for the None setting. A total number greater than eight means that some equipment items are not visible and the player needs to scroll the list to see them.



Copyright 2019 Nicholas Menchise.
End User License: Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) available at https://creativecommons.org/licenses/by-nc-sa/4.0/

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
Config/script.js
"use strict";

this.name = "PrimeableEquipmentMFD";
this.author = "Nicholas Menchise";
this.copyright = "(C) 2019 Nicholas Menchise";
this.licence = "CC BY-NC-SA 4.0";

//
// This world script includes the instructions for an MFD that lists the primeable equipment
// on the player ship and indicates the current selection.
//


// Whether or not the MFD requires calibration.
this.$calibrateMe = false;

// Whether or not there is any functional primeable equipment on the player ship.
this.$primeAnything = false;

// Stores the array of equipment keys for primed equipment on the player ship in the order that it's primed.
// The first value should always be an empty string for the None setting.
this.$primeQueue = [""];

// Stores the index value for the current selection in the prime queue.
this.$primeIndex = 0;

// Stores the timer that checks the calibration and current selection at regular intervals. Set by shipLaunchedFromStation event handler.
this.$detectSelection = null;

// Stores the MFD key.
this.$mfdKey = "nm_primeable-mfd";

// Stores the MFD strings.
// 0 is the MFD title.
// 1 informs the player that no primeable equipment is available.
// 2 informs the player that calibration is required.
// 3 informs the player that calibration is restarting due to error.
// 4 informs the player that calibration was successful.
// 5 is the instruction to initiate the calibration sequence.
// 6 is the instruction to continue the calibration sequence.
//
this.$mfdStrings = [
    "Primeable Equipment",
    "\n\n\n  None available.",
    "\n\n\n  Calibration Required\n\n",
    "\n\n\n  Error found. Restarting...",
    "\n\n\n  Calibration Done\n\n    Press prime button to\n    display list.",
    "    Set prime to None. If already\n    None, set to None again.",
    "    Press prime button until\n    done.  "
];


//
// Updates the MFD.
//
// This function is called by $detectSelection timer.
//
this._updateSelection = function() {
    var thisPrimeEquip = player.ship.primedEquipment;
    var arrayPrimeEquip = this.$primeQueue;
    var mfdText = this.$mfdStrings;
    var mfdTitle = mfdText[0];

    // Checks calibration and requests calibration, if required. See the function below.
    this._checkCalibration(thisPrimeEquip, arrayPrimeEquip, mfdTitle, mfdText[1], mfdText[2], mfdText[5]);
    if (this.$calibrateMe) {
        return;
    }
        else {
            // Compares the primed equipment to the current selection indicated in the MFD. Updates the MFD if they don't match.
            var thatPrimeEquip = "May or may not match.";
            var indexPrimeEquip = this.$primeIndex;
            if (indexPrimeEquip >= 0) thatPrimeEquip = arrayPrimeEquip[indexPrimeEquip];    // see shipWillDockWithStation event handler below
            if (thisPrimeEquip !== thatPrimeEquip) this._regularMfdString(thisPrimeEquip, arrayPrimeEquip, arrayPrimeEquip.length, mfdTitle);
        }

}


//
// Returns the number of functional primeable equipment items on the player ship.
//
// This function is called by _checkCalibration and _calibrateMeUpdate functions.
//
// yourShip argument stores a reference to the object representing the player ship.
//
this._getTotalPrime = function(yourShip) {
    var playerEquip = yourShip.equipment;
    var totalPrime = 0;
    for (var n = 0; n < playerEquip.length; n++) {
        if (playerEquip[n].scriptName.length > 0 && yourShip.equipmentStatus(playerEquip[n]) === "EQUIPMENT_OK") totalPrime++;
    }
    return totalPrime;
}


//
// Checks if calibration is required and requests calibration, if necessary.
//
// This function is called by _updateSelection function.
//
// thisPrimeEquip argument stores the equipment key for the equipment that is currently primed.
// arrayPrimeEquip argument stores the array of equipment keys for primed equipment on the player ship in the order that it's primed.
// mfdTitle argument stores the title string for the MFD.
// mfdNone argument stores the string informing the player that no primeable equipment is available.
// mfdNeed argument stores the string informing the player that calibration is required.
// mfdDo argument stores the string instructing the player to prime the None setting.
//
this._checkCalibration = function(thisPrimeEquip, arrayPrimeEquip, mfdTitle, mfdNone, mfdNeed, mfdDo) {
    var yourShip = player.ship;
    var primeTotal = this._getTotalPrime(yourShip);

    // Calibration not required if there is no functional primeable equipment on the ship. Informs the player that none is available.
    if (primeTotal == 0) {
        this.$detectSelection.stop();    // the timer should be stopped if there's no primeable equipment
        yourShip.setMultiFunctionText(this.$mfdKey, mfdTitle + mfdNone);
        this.$primeAnything = false;
        this.$calibrateMe = false;
        return;
    }
        else {
            this.$primeAnything = true;
            primeTotal++;    // incremented to account for the None option in the prime queue
        }

    // Calibration required if equipmentRepaired event handler set calibrateMe to true.
    var needCalibration = false;
    if (this.$calibrateMe) needCalibration = true;

    // Calibration required if total number of functional primeable equipment items does not match the total in the prime queue.
    if (primeTotal != arrayPrimeEquip.length) needCalibration = true;

    // Calibration required if primed equipment is not found in the prime queue.
    var foundPrimeEquip = arrayPrimeEquip.indexOf(thisPrimeEquip);
    if (foundPrimeEquip < 0) needCalibration = true;

    // Prepares MFD for calibration and instructs player to calibrate.
    if (needCalibration) {
        this.$calibrateMe = true;
        this.$detectSelection.stop();
        this.$primeQueue.length = 0;    // the array should be empty until the player primes the None setting
        yourShip.setMultiFunctionText(this.$mfdKey, mfdTitle + mfdNeed + mfdDo);
    } else {}

}


//
// Assigns calibration update to MFD.
//
// This function is called by playerChangedPrimedEquipment event handler.
//
// newPrimeEquip argument stores the next equipment key for calibration.
// countPrimeEquip argument is the total number of items in the prime queue.
// mfdTitle argument stores the title string for the MFD.
// mfdNeed argument stores the string informing the player that calibration is required.
// mfdError argument stores the string informing the player that calibration is restarting due to error.
// mfdDone argument stores the string informing the player that calibration was successful.
// mfdDo argument stores the string instructing the player to press the prime button until done.
//
this._calibrateMeUpdate = function(newPrimeEquip, countPrimeEquip, mfdTitle, mfdNeed, mfdError, mfdDone, mfdDo) {
    var updateText;
    var yourShip = player.ship;
    var donePresses = this._getTotalPrime(yourShip) + 1;
    var duplicateError = false;

    if (newPrimeEquip === "" && countPrimeEquip == 1) {
        // Calibration sequence begins.
        updateText = mfdTitle + mfdNeed + mfdDo + "0/" + donePresses;
    }
        else if (newPrimeEquip !== "" && countPrimeEquip < donePresses) {
            // Calibration sequence continues.
            var alreadyThere = this.$primeQueue.indexOf(newPrimeEquip);
            if (alreadyThere >= 0) duplicateError = true;    // calibration will fail if the equipment is already in the prime queue
            var x = this.$primeQueue.push(newPrimeEquip);
            updateText = mfdTitle + mfdNeed + mfdDo + countPrimeEquip + "/" + donePresses;
        }
            else if (newPrimeEquip === "" && countPrimeEquip == donePresses) {
                // Calibration sequence finishes.
                this.$calibrateMe = false;
                updateText = mfdTitle + mfdDone;
                this.$detectSelection.start();
            }
                else {
                    duplicateError = true;    // calibration failing, using duplicateError boolean for convenience
                }

    if (duplicateError) {
        // Restarts calibration, if error found. Informs player on the MFD.
        yourShip.setMultiFunctionText(this.$mfdKey, mfdTitle + mfdError);
        this.$primeQueue.length = 0;    // array is emptied to prevent false positive if player keeps pressing prime button
        this.$detectSelection.nextTime = clock.absoluteSeconds + 2;    // timer should not be running when this happens
        this.$detectSelection.start();
    }
        else {
            // Passes calibration update to the MFD.
            yourShip.setMultiFunctionText(this.$mfdKey, updateText);
        }

}


//
// Updates primeable equipment list on MFD.
//
// This function is called by _updateSelection function and playerChangedPrimedEquipment event handler.
//
// nextPrimeEquip argument is the equipment key of the newly primed equipment.
// arrayPrimeEquip argument stores the array of equipment keys for primed equipment on the player ship in the order that it's primed.
// countPrimeEquip argument is the total number of items in the prime queue.
// mfdTitle argument stores the title string for the MFD.
//
this._regularMfdString = function(nextPrimeEquip, arrayPrimeEquip, countPrimeEquip, mfdTitle) {

    // Defines the strings that indicate whether or not the equipment is currently primed.
    var gapUnselected = "      ";
    var gapSelected = ">>  ";

    // Sets the first line of the MFD, which includes title, current selection position and total items in prime queue.
    var sayThisMfd = mfdTitle;
    this.$primeIndex = arrayPrimeEquip.indexOf(nextPrimeEquip);
    var nextPrimeIndex = this.$primeIndex;
    var lastOne = countPrimeEquip - 1;
    sayThisMfd = sayThisMfd + "                  " + nextPrimeIndex + "/" + lastOne + "\n";

    // Sets the second line of the MFD, which is either blank or equipment item prior to the current selection.
    if (countPrimeEquip > 2 && nextPrimeIndex == 0) {
        sayThisMfd += gapUnselected;
        sayThisMfd += this._getEquipName(arrayPrimeEquip[lastOne]);
        sayThisMfd += "\n";
    }
        else if (countPrimeEquip > 2 && nextPrimeIndex > 1) {
            sayThisMfd += gapUnselected;
            sayThisMfd += this._getEquipName(arrayPrimeEquip[nextPrimeIndex - 1]);
            sayThisMfd += "\n";
        }
            else {
                sayThisMfd += "\n";
            }

    // Sets the third line of the MFD, which is the current selection.
    sayThisMfd += gapSelected;
    sayThisMfd += this._getEquipName(arrayPrimeEquip[nextPrimeIndex]);
    sayThisMfd += "\n";

    // Sets the rest of the lines of the MFD, which are the items following the current selection in the prime queue.
    var alreadyShowed = 0;
    if (countPrimeEquip > 2) alreadyShowed = 2;
    if (countPrimeEquip <= 2) alreadyShowed = 1;
    var showLimit = countPrimeEquip - alreadyShowed;
    var x = nextPrimeIndex + 1;
    for (var n = 1; n <= showLimit; n++) {
        if (n == 8) break;    // there are seven lines available in the MFD for this loop
        if (x == countPrimeEquip) x = 0;
        sayThisMfd += gapUnselected;
        sayThisMfd += this._getEquipName(arrayPrimeEquip[x]);
        x++;
        if (n < 7) sayThisMfd += "\n";
    }

    player.ship.setMultiFunctionText(this.$mfdKey, sayThisMfd);
}


//
// Returns the display name of a primeable equipment item. The name is truncated if it's more than 32 characters.
// The None setting is displayed as an empty string.
//
// This function is called by _regularMfdString function.
//
// thisEquipPlease argument is the equipment key of the item to be named.
//
this._getEquipName = function(thisEquipPlease) {
    var thisEquipName = "";
    if (thisEquipPlease.length > 0) thisEquipName = EquipmentInfo.infoForKey(thisEquipPlease).name;
    if (thisEquipName.length > 32) thisEquipName = thisEquipName.substring(0, 30) + "...";
    return thisEquipName;
}


//
// Event handlers.
//


this.shipWillDockWithStation = function(station) {

    // Nullifies the timer. Timer documentation states that timer should be stopped before nullifying.
    // Condition statement is due to the possibility of a shipLaunchedEscapePod event beforehand.
    if (this.$detectSelection != null) this.$detectSelection.stop();
    this.$detectSelection = null;

    // Clears the MFD text and sets negative index value to force MFD update when ship launches, otherwise
    // the MFD will not list anything until the player presses the prime key or calibration is done.
    player.ship.setMultiFunctionText(this.$mfdKey, this.$mfdStrings[0]);
    this.$primeIndex = -1;

}


this.shipLaunchedFromStation = function(station) {
    // Sets the timer.
    this.$detectSelection = new Timer(this, this._updateSelection, 0, 1);
}


this.shipDied = function(whom, why) {
    // Nullifies the timer. Timer documentation states that timer should be stopped before nullifying.
    this.$detectSelection.stop();
    this.$detectSelection = null;
}


this.equipmentDamaged = function(equipment) {
    // Removes the equipment from the prime queue, if it's primeable.
    if (!this.$calibrateMe && EquipmentInfo.infoForKey(equipment).scriptName.length > 0) {
        var x = this.$primeQueue.indexOf(equipment);
        var y = this.$primeQueue.splice(x, 1);
        if (this.$primeIndex > x) this.$primeIndex--;
    } else {}
}


this.equipmentRemoved = function(equipmentKey) {
    // Removes the equipment from the prime queue, if it's there. The condition statement is different from the one in
    // equipmentDamaged event handler due to the possibility of damaged primeable equipment in the argument.
    var x = this.$primeQueue.indexOf(equipmentKey);
    if (!this.$calibrateMe && x >= 0) {
        var y = this.$primeQueue.splice(x, 1);
        if (this.$primeIndex > x) this.$primeIndex--;
    } else {}
}


this.equipmentRepaired = function(equipment) {
    // This code is only intended for in-flight repairs, which is possible with some expansion packs.
    if (!player.ship.docked && EquipmentInfo.infoForKey(equipment).scriptName.length > 0) {
        // Calibration is required, if equipment is primeable. Prepares MFD for calibration and informs the player.
        this.$detectSelection.stop();
        var mfdText = this.$mfdStrings;
        player.ship.setMultiFunctionText(this.$mfdKey, mfdText[0] + mfdText[3]);
        this.$primeQueue.length = 0;    // array is emptied to prevent false positive if calibration already in progress
        if (this.$calibrateMe) this.$detectSelection.nextTime = clock.absoluteSeconds + 2;    // delay if calibration already in progress
        this.$calibrateMe = true;
        this.$detectSelection.start();
    } else {}
}


this.playerChangedPrimedEquipment = function(equipmentKey) {
    var arrayPrimeEquip = this.$primeQueue;
    var howManyPrime = arrayPrimeEquip.length;
    var mfdText = this.$mfdStrings;

    if (equipmentKey === "" && this.$calibrateMe && howManyPrime < 1) {
        // Start calibration sequence.
        var x = this.$primeQueue.push("");
        howManyPrime++;
        this._calibrateMeUpdate(equipmentKey, howManyPrime, mfdText[0], mfdText[2], mfdText[3], mfdText[4], mfdText[6]);
    }
        else if (this.$calibrateMe && howManyPrime > 0) {
            // Continue calibration sequence.
            this._calibrateMeUpdate(equipmentKey, howManyPrime, mfdText[0], mfdText[2], mfdText[3], mfdText[4], mfdText[6]);
        }
            else if (!this.$calibrateMe && this.$primeAnything) {
                // List the primeable equipment.
                this._regularMfdString(equipmentKey, arrayPrimeEquip, howManyPrime, mfdText[0]);
            } else {}

}


this.shipLaunchedEscapePod = function(escapepod) {
    // Nullifies the timer. Timer documentation states that timer should be stopped before nullifying.
    this.$detectSelection.stop();
    this.$detectSelection = null;
}