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;
}
|