Scripts/shipcomparison.js |
"use strict";
this.name = "ShipComparison";
this.author = "phkb";
this.copyright = "2017 phkb";
this.description = "Routines for selecting ships and displaying details of them side-by-side.";
this.license = "CC BY-NC-SA 4.0";
this._lastChoice = "";
this._shipList = [];
this._selectedList = [];
this._direction = 1;
this._itemColor = "yellowColor";
this._menuColor = "orangeColor";
this._exitColor = "yellowColor";
this._disabledColor = "darkGrayColor";
this._hideListBasic = ["GalCop Viper", "GalCop Viper Interceptor"];
this._hideListAll = ["Constrictor"];
this._shipConfig = false;
this._resetData = false;
this._clearShips = false;
this._trueValues = ["yes", "1", 1, "true", true];
this._exitScreen = "GUI_SCREEN_INTERFACES";
this._limitList = false;
this._switch = false;
this._shipMassExceptions = {
"Cobra Mark III": 214737.6875,
};
// configuration settings for use in Lib_Config
this._compConfig = {Name:this.name, Alias:"Ship Comparison", Display:"Config", Alive:"_compConfig", Notify:"$onChange",
Bool:{
B0:{Name:"_resetData", Def:false, Desc:"Reset stored values"},
B1:{Name:"_clearShips", Def:false, Desc:"Clears ship selections"},
Info:"0 - Resets all stored equipment space and ship mass values.\n1 - Clears all the currently selected ships"}
};
// set with this._override[data key] = "New ship name";
this._override = {};
// this is a holding array for equipment space data for ships, if ShipConfig is installed
this._equipSpace = [];
this._mass = {};
// element 1: extra cargo
// element 2: weapon facings
this._extraData = {
};
//-------------------------------------------------------------------------------------------------------------
this.$onChange = function() {
if (this._resetData === true) {
this._equipSpace = [];
this._resetData = false;
player.consoleMessage("Stored ship values cleared");
}
if (this._clearShips === true) {
this._selectedList = [];
this._clearShips = false;
player.consoleMessage("Selected ships cleared");
}
}
//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function() {
// register our settings, if Lib_Config is present
if (worldScripts.Lib_Config) worldScripts.Lib_Config._registerSet(this._compConfig);
if (worldScripts.ShipConfiguration_Core && worldScripts.ShipConfiguration_Core.$getEquipmentSpaceFromShipKey) this._shipConfig = true
// set up the interface screen, if required
this.$initInterface(player.ship.dockedStation);
// load any equipment space calculations that have been done previously
if (missionVariables.ShipComparison_EquipSpace) {
this._equipSpace = JSON.parse(missionVariables.ShipComparison_EquipSpace);
this.$cleanUpEquipSpace();
}
if (missionVariables.ShipComparison_Reset) delete missionVariables.ShipComparison_Reset;
if (oolite.compareVersion("1.91") <= 0) {
setExtraGuiScreenKeys(this.name, {
guiScreen:"GUI_SCREEN_SHIPYARD",
registerKeys:{"sckey1":[{key:"c",mod1:true}]},
callback:this.$directOpen.bind(this)
});
if (worldScripts.ContextualHelp) {
worldScripts.ContextualHelp.$addHelpTextToGuiScreen(this.name, "GUI_SCREEN_SHIPYARD", "\nPress Ctrl-C on this screen to open the Ship Comparison tool.");
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function() {
if (this._equipSpace.length > 0) {
// if we've gone to the trouble of calculating equipment space, we'll retrieve the results so that we keep the speed of lookup values
missionVariables.ShipComparison_EquipSpace = JSON.stringify(this._equipSpace);
} else {
delete missionVariables.ShipComparison_EquipSpace;
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipDockedWithStation = function(station) {
// set up interface screen
this.$initInterface(station);
}
//-------------------------------------------------------------------------------------------------------------
this.missionScreenEnded = function() {
if (player.ship.hudHidden == true) player.ship.hudHidden = false;
}
//-------------------------------------------------------------------------------------------------------------
// initialise the interface screen in the station
this.$initInterface = function(station) {
station.setInterface(this.name,{
title:"Ship comparisons",
category:"Ship Systems",
summary:"Displays side-by-side details of selected ships.",
callback:this.$openComparison.bind(this)
});
}
//-------------------------------------------------------------------------------------------------------------
this.$openComparison = function() {
function compare(a,b) {
return a.name > b.name;
}
this._exitScreen = "GUI_SCREEN_INTERFACES";
this._lastChoice = "";
this.$buildShipList();
this._shipList.sort(compare);
if (this._switch == true) {
this._switch = false;
this.$showComparisonEquipment();
return;
}
this.$showComparison();
}
//-------------------------------------------------------------------------------------------------------------
this.$directOpen = function() {
function compare(a,b) {
return a.name > b.name;
}
this._exitScreen = "GUI_SCREEN_SHIPYARD";
this._lastChoice = "";
this.$buildShipList();
this._shipList.sort(compare);
if (this._switch == true) {
this._switch = false;
this.$showComparisonEquipment();
return;
}
this.$showComparison();
}
//-------------------------------------------------------------------------------------------------------------
this.$showComparison = function() {
var text = "";
var colShip = 10;
var colDesc = 10;
var curChoices = {};
var sc = null;
var keyList = [];
var shipArray = [];
if (this.$isBigGuiActive() === false) player.ship.hudHidden = true;
for (var i = 0; i < this._selectedList.length; i++) {
if (this._selectedList[i] != "") {
var shipDef = Ship.shipDataForKey(this._selectedList[i]);
shipArray.push(shipDef);
keyList.push(this._selectedList[i]);
}
}
colShip = Math.floor(22 / shipArray.length);
var textList = ["Ship type", "", "Price", "Max speed", "Max thrust", "Injector speed", "Pitch/Roll/Yaw",
"Weapon positions", "Missile pylons", "Cargo capacity", "Energy banks", "Energy recharge rate", "Hyperspace capable", "Mass"];
var outList = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", ""];
// select ships to be in comparison (up to 4)
text = "Select up to 3 ships to compare:\n";
if (this._shipConfig) {
textList.push("Equipment space");
outList.push("");
sc = worldScripts.ShipConfiguration_Core;
// if this HUD doesn't have big gui enabled, take out the blank line normally under the ship type so there's room for the extra fields
/*if (player.ship.hudAllowsBigGui === false) {
textList.splice(1, 1);
outList.splice(1, 1);
}*/
} else {
text += "\n";
}
for (var ol = 0; ol < textList.length; ol++) {
outList[ol] = this.$padTextRight(textList[ol] + (textList[ol] != "" ? ":" : ""), colDesc);
for (var i = 0; i < shipArray.length; i++) {
var shipDef = shipArray[i];
var shipName = shipDef.name;
if (this._override[this._selectedList[i]]) shipName = this._override[this._selectedList[i]];
switch (textList[ol]) {
case "Ship type":
outList[ol] += this.$padTextRight(shipName, colShip);
break;
case "Price":
if (shipDef._oo_shipyard) {
outList[ol] += this.$padTextRight(formatCredits(parseInt(shipDef._oo_shipyard.price), false, true), colShip);
} else {
log(this.name, "!!ERROR: _oo_shipyard property not set for ship " + shipName + ", key " + keyList[i]);
}
break;
case "Max speed":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("N/A", colShip);
} else {
outList[ol] += this.$padTextRight((parseFloat(shipDef["max_flight_speed"]) / 1000).toFixed(3) + " LS", colShip);
}
break;
case "Max thrust":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("N/A", colShip);
} else {
outList[ol] += this.$padTextRight((parseFloat(shipDef["thrust"]) / 1000).toFixed(3) + " LS", colShip);
}
break;
case "Injector speed":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("N/A", colShip);
} else {
var inj = 7;
if (0 >= oolite.compareVersion("1.81") && shipDef["injector_speed_factor"] != undefined) inj = parseFloat(shipDef["injector_speed_factor"]);
outList[ol] += this.$padTextRight(((parseFloat(shipDef["max_flight_speed"]) * inj) / 1000).toFixed(3) + " LS", colShip);
}
break;
case "Pitch/Roll/Yaw":
if (this._hideListAll.indexOf(shipName) >= 0 || this._hideListBasic.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("N/A", colShip);
} else {
var yaw = parseFloat(shipDef["max_flight_pitch"]);
if (shipDef["max_flight_yaw"] != undefined) yaw = parseFloat(shipDef["max_flight_yaw"]);
outList[ol] += this.$padTextRight(parseFloat(shipDef["max_flight_pitch"]).toFixed(1)
+ "/" + parseFloat(shipDef["max_flight_roll"]).toFixed(1)
+ "/" + yaw.toFixed(1), colShip);
}
break;
case "Weapon positions":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("N/A", colShip);
} else {
var facings = shipDef["weapon_facings"];
if (shipDef._oo_shipyard && shipDef._oo_shipyard.weapon_facings != undefined) facings = shipDef._oo_shipyard.weapon_facings;
if (this._extraData[shipName] != null) facings = this._extraData[shipName][1].toString();
var wpn = "Forward";
if (facings === "15") {
wpn = "All";
} else {
if (" 3 7 11 ".indexOf(" " + facings + " ") >= 0) wpn += ", Aft";
if (" 5 7 13 ".indexOf(" " + facings + " ") >= 0) wpn += ", Port";
if (" 9 11 13 ".indexOf(" " + facings + " ") >= 0) wpn += ", Starboard";
}
if (facings === "0") wpn = "None";
if (facings === "N/A") wpn = "N/A";
outList[ol] += this.$padTextRight(wpn, colShip);
}
break;
case "Missile pylons":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("N/A", colShip);
} else {
var miss = 0;
if (shipDef["max_missiles"] != undefined) {
miss = parseInt(shipDef["max_missiles"]);
} else {
miss = parseInt(shipDef["missiles"]);
}
outList[ol] += this.$padTextRight(miss, colShip);
}
break;
case "Cargo capacity":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("N/A", colShip);
} else {
var cargo = 0;
if (shipDef["max_cargo"] != undefined) cargo = parseInt(shipDef["max_cargo"]);
var exp = "";
if (shipDef["extra_cargo"] != undefined) {
exp = shipDef["extra_cargo"];
}
if (exp === "") {
if (shipDef._oo_shipyard) {
if ((shipDef._oo_shipyard.standard_equipment.extras && shipDef._oo_shipyard.standard_equipment.extras.indexOf("EQ_CARGO_BAY") >= 0) ||
(shipDef._oo_shipyard.optional_equipment && shipDef._oo_shipyard.optional_equipment.indexOf("EQ_CARGO_BAY") >=0)) exp = 15;
}
}
if (this._extraData[shipName] != null) exp = this._extraData[shipName][0].toString();
if (exp === undefined || exp === "0") exp = "";
outList[ol] += this.$padTextRight(cargo.toString() + (exp != "" ? " (+" + exp + ")" : ""), colShip);
}
break;
case "Energy banks":
if (this._hideListAll.indexOf(shipName) >= 0 || this._hideListBasic.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("N/A", colShip);
} else {
var en = 200;
if (shipDef["max_energy"] != undefined) en = parseInt(shipDef["max_energy"]);
if (Math.floor(en / 64) === 0) en = 64;
outList[ol] += this.$padTextRight(Math.floor(en / 64), colShip);
}
break;
case "Energy recharge rate":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("N/A", colShip);
} else {
var rech = 1;
if (shipDef["energy_recharge_rate"] != undefined) rech = parseFloat(shipDef["energy_recharge_rate"]);
outList[ol] += this.$padTextRight(rech.toFixed(1), colShip);
}
break;
case "Hyperspace capable":
var hyper = "Yes";
if (shipDef["hyperspace_motor"] != undefined && (shipDef["hyperspace_motor"] === "no" || shipDef["hyperspace_motor"] === "false" || shipDef["hyperspace_motor"] === "0")) hyper = "No";
outList[ol] += this.$padTextRight(hyper, colShip);
break;
case "Equipment space":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("N/A", colShip);
} else {
var found = false;
// check to see if we have already analysed this ship type
for (var j = 0; j < this._equipSpace.length; j++) {
if (this._equipSpace[j].shipType == shipName) {
outList[ol] += this.$padTextRight(this._equipSpace[j].equipSpace + (this._equipSpace[j].cargoSpace != "N/A" && this._equipSpace[j].cargoSpace != 0 ? " (+" + this._equipSpace[j].cargoSpace + ")" : ""), colShip);
found = true;
break;
}
}
// if we haven't we will need to execute a query against ShipConfig
if (found === false) {
var es = sc.$getEquipmentSpaceFromShipKey(this._selectedList[i]);
var ms = 0;
outList[ol] += this.$padTextRight(es.equipSpace + (es.cargoSpace != "N/A" && es.cargoSpace != 0 ? " (+" + es.cargoSpace + ")" : ""), colShip);
// store the result so we don't have to run this process again (but only if there was a definite value, not N/A)
if (es.equipSpace != "N/A") this._equipSpace.push({shipType:shipName, equipSpace:es.equipSpace, cargoSpace:es.cargoSpace, shipMass:(es.hasOwnProperty("mass") ? es.mass : "N/A")});
}
}
break;
case "Mass":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("N/A", colShip);
} else {
// check to see if we have already analysed this ship type
if (!sc) {
// if ship config is not installed
var mass = this._mass[shipName];
if (!mass) {
mass = this.$getMassFromShipKey(this._selectedList[i]);
// store the result so we don't have to do this again
this._mass[shipName] = mass;
}
if (!mass || mass == 0) {
outList[ol] += this.$padTextRight("N/A", colShip);
} else {
outList[ol] += this.$padTextRight(mass.toFixed(0), colShip);
}
} else {
// if ship config is installed
for (var j = 0; j < this._equipSpace.length; j++) {
if (this._equipSpace[j].shipType === shipName) {
idx = j;
if (this._equipSpace[j].hasOwnProperty("mass") && this._equipSpace[j].mass != "N/A") {
outList[ol] += this.$padTextRight(this._equipSpace[j].mass.toFixed(0), colShip);
found = true;
}
break;
}
}
// if we haven't we will need to execute a query against ShipConfig
if (found === false) {
var es = sc.$getEquipmentSpaceFromShipKey(this._selectedList[i]);
if (es.hasOwnProperty("mass") && es.mass != "N/A") {
outList[ol] += this.$padTextRight(es.mass.toFixed(0), colShip);
} else {
outList[ol] += this.$padTextRight("N/A", colShip);
}
// store the result so we don't have to run this process again (but only if there was a definite value, not N/A)
if (es.equipSpace != "N/A" || idx === -1) {
this._equipSpace.push({shipType:shipName, equipSpace:es.equipSpace, cargoSpace:es.cargoSpace, shipMass:(es.hasOwnProperty("mass") ? es.mass : "N/A")});
} else {
this._equipSpace[idx].mass = es.mass;
}
}
}
}
break;
}
}
}
for (var i = 0; i < outList.length; i++) {
text += outList[i] + "\n";
}
if (this._selectedList.length === 0) {
if (this._direction === 1) {
curChoices["01_CHANGE"] = {text:"Change first ship to '" + this._shipList[0].name + "'", color:this._menuColor};
curChoices["02_CHANGE"] = {text:"Change second ship to '" + this._shipList[0].name + "'", unselectable:true, color:this._disabledColor};
curChoices["03_CHANGE"] = {text:"Change third ship to '" + this._shipList[0].name + "'", unselectable:true, color:this._disabledColor};
} else {
curChoices["01_CHANGE"] = {text:"Change first ship to '" + this._shipList[this._shipList.length - 1].name + "'", color:this._menuColor};
curChoices["02_CHANGE"] = {text:"Change second ship to '" + this._shipList[this._shipList.length - 1].name + "'", unselectable:true, color:this._disabledColor};
curChoices["03_CHANGE"] = {text:"Change third ship to '" + this._shipList[this._shipList.length - 1].name + "'", unselectable:true, color:this._disabledColor};
}
} else {
for (var i = 0; i < this._selectedList.length; i++) {
for (var j = 0; j < this._shipList.length; j++) {
if (this._shipList[j].key === this._selectedList[i]) {
if (this._direction === 1) {
if (j < this._shipList.length - 1) {
curChoices["0" + (i + 1) + "_CHANGE"] = {text:"Change " + this.$numberWord(i + 1) + " ship to '" + this._shipList[j + 1].name + "'", color:this._menuColor};
} else {
curChoices["0" + (i + 1) + "_CHANGE"] = {text:"Change " + this.$numberWord(i + 1) + " ship to '" + this._shipList[0].name + "'", color:this._menuColor};
}
} else {
if (j > 0) {
curChoices["0" + (i + 1) + "_CHANGE"] = {text:"Change " + this.$numberWord(i + 1) + " ship to '" + this._shipList[j - 1].name + "'", color:this._menuColor};
} else {
curChoices["0" + (i + 1) + "_CHANGE"] = {text:"Change " + this.$numberWord(i + 1) + " ship to '" + this._shipList[this._shipList.length - 1].name + "'", color:this._menuColor};
}
}
}
}
}
if (this._selectedList.length === 1) {
if (this._direction === 1) {
curChoices["02_CHANGE"] = {text:"Change second ship to '" + this._shipList[0].name + "'", color:this._menuColor};
curChoices["03_CHANGE"] = {text:"Change third ship to '" + this._shipList[0].name + "'", unselectable:true, color:this._disabledColor};
} else {
curChoices["02_CHANGE"] = {text:"Change second ship to '" + this._shipList[this._shipList.length - 1].name + "'", color:this._menuColor};
curChoices["03_CHANGE"] = {text:"Change third ship to '" + this._shipList[this._shipList.length - 1].name + "'", unselectable:true, color:this._disabledColor};
}
}
if (this._selectedList.length === 2) {
if (this._direction === 1) {
curChoices["03_CHANGE"] = {text:"Change third ship to '" + this._shipList[0].name + "'", color:this._menuColor};
} else {
curChoices["03_CHANGE"] = {text:"Change third ship to '" + this._shipList[this._shipList.length - 1].name + "'", color:this._menuColor};
}
}
}
curChoices["04_CURRENT"] = {text:"Set first ship to current ship", color:this._menuColor};
if (this._limitList == false) {
curChoices["04A_LIMIT"] = {text:"Only include ships in current shipyard", color:this._menuColor};
} else {
curChoices["04B_LIMIT"] = {text:"Include all ships", color:this._menuColor};
}
curChoices["05_DIRECTION"] = {text:(this._direction === 1 ? "Change scroll direction to ascending" : "Change scroll direction to descending"), color:this._menuColor};
curChoices["06_EQUIPMENT"] = {text:"View standard equipment availability", color:this._itemColor};
curChoices["99_EXIT"] = {text:"Return", color:this._itemColor};
var def = "99_EXIT";
var opts = {
screenID: "oolite-ship-compare-map",
title: "Ship Comparison",
allowInterrupt: true,
exitScreen: this._exitScreen,
overlay: {name:"compare-balance.png", height:546},
choices: curChoices,
initialChoicesKey: (this._lastChoice ? this._lastChoice : def),
message: text
};
mission.runScreen(opts, this.$screenHandler, this);
}
//-------------------------------------------------------------------------------------------------------------
this.$showComparisonEquipment = function() {
var text = "";
var colShip = 10;
var colDesc = 10;
var curChoices = {};
var sc = null;
var keyList = [];
var shipArray = [];
for (var i = 0; i < this._selectedList.length; i++) {
if (this._selectedList[i] != "") {
var shipDef = Ship.shipDataForKey(this._selectedList[i]);
shipArray.push(shipDef);
keyList.push(this._selectedList[i]);
}
}
colShip = Math.floor(22 / shipArray.length);
var textList = ["Ship type", "", "Techlevel", "Forward weapon type", "ECM", "Fuel scoops", "Passenger berths", "Energy unit", "Naval energy unit",
"Docking computer", "Shield booster", "Military shield enhancement", "Galactic hyperdrive", "Scanner targeting enhancement", "Multi-targeting system"];
var outList = ["", "", "", "", "", "", "", "", "", "", "", "", "", ""];
// select ships to be in comparison (up to 4)
text = "Select up to 3 ships to compare:\n";
if (this._shipConfig) {
// if this HUD doesn't have big gui enabled, take out the blank line normally under the ship type so there's room for the extra fields
if (player.ship.hudAllowsBigGui === false) {
textList.splice(1, 1);
outList.splice(1, 1);
}
} else {
text += "\n";
}
for (var ol = 0; ol < textList.length; ol++) {
outList[ol] = this.$padTextRight(textList[ol] + (textList[ol] != "" ? ":" : ""), colDesc);
for (var i = 0; i < shipArray.length; i++) {
var shipDef = shipArray[i];
var shipName = shipDef.name;
if (this._override[this._selectedList[i]]) shipName = this._override[this._selectedList[i]];
switch (textList[ol]) {
case "Ship type":
outList[ol] += this.$padTextRight(shipName, colShip);
break;
case "Techlevel":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("?", colShip);
} else {
if (shipDef._oo_shipyard) {
outList[ol] += this.$padTextRight(shipDef._oo_shipyard.techlevel, colShip);
} else {
log(this.name, "!!ERROR: _oo_shipyard property not set for ship " + shipName + ", key " + keyList[i]);
}
}
break;
case "Forward weapon type":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("?", colShip);
} else {
outList[ol] += this.$padTextRight(this.$forwardWeaponType(shipDef), colShip);
}
break;
case "ECM":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("?", colShip);
} else {
outList[ol] += this.$padTextRight(this.$shipDefHasOption(shipDef, "EQ_ECM"), colShip);
}
break;
case "Fuel scoops":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("?", colShip);
} else {
outList[ol] += this.$padTextRight(this.$shipDefHasOption(shipDef, "EQ_FUEL_SCOOPS"), colShip);
}
break;
case "Passenger berths":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("?", colShip);
} else {
outList[ol] += this.$padTextRight(this.$shipDefHasOption(shipDef, "EQ_PASSENGER_BERTH"), colShip);
}
break;
case "Energy unit":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("?", colShip);
} else {
outList[ol] += this.$padTextRight(this.$shipDefHasOption(shipDef, "EQ_ENERGY_UNIT"), colShip);
}
break;
case "Naval energy unit":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("?", colShip);
} else {
outList[ol] += this.$padTextRight(this.$shipDefHasOption(shipDef, "EQ_NAVAL_ENERGY_UNIT"), colShip);
}
break;
case "Docking computer":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("?", colShip);
} else {
outList[ol] += this.$padTextRight(this.$shipDefHasOption(shipDef, "EQ_DOCK_COMP"), colShip);
}
break;
case "Shield booster":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("?", colShip);
} else {
outList[ol] += this.$padTextRight(this.$shipDefHasOption(shipDef, "EQ_SHIELD_BOOSTER"), colShip);
}
break;
case "Military shield enhancement":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("?", colShip);
} else {
outList[ol] += this.$padTextRight(this.$shipDefHasOption(shipDef, "EQ_NAVAL_SHIELD_BOOSTER"), colShip);
}
break;
case "Galactic hyperdrive":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("?", colShip);
} else {
outList[ol] += this.$padTextRight(this.$shipDefHasOption(shipDef, "EQ_GAL_DRIVE"), colShip);
}
break;
case "Scanner targeting enhancement":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("?", colShip);
} else {
outList[ol] += this.$padTextRight(this.$shipDefHasOption(shipDef, "EQ_SCANNER_SHOW_MISSILE_TARGET"), colShip);
}
break;
case "Multi-targeting system":
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("?", colShip);
} else {
outList[ol] += this.$padTextRight(this.$shipDefHasOption(shipDef, "EQ_MULTI_TARGET"), colShip);
}
break;
}
}
}
for (var i = 0; i < outList.length; i++) {
text += outList[i] + "\n";
}
if (this._selectedList.length === 0) {
if (this._direction === 1) {
curChoices["01_CHANGE"] = {text:"Change first ship to '" + this._shipList[0].name + "'", color:this._menuColor};
curChoices["02_CHANGE"] = {text:"Change second ship to '" + this._shipList[0].name + "'", unselectable:true, color:this._disabledColor};
curChoices["03_CHANGE"] = {text:"Change third ship to '" + this._shipList[0].name + "'", unselectable:true, color:this._disabledColor};
} else {
curChoices["01_CHANGE"] = {text:"Change first ship to '" + this._shipList[this._shipList.length - 1].name + "'", color:this._menuColor};
curChoices["02_CHANGE"] = {text:"Change second ship to '" + this._shipList[this._shipList.length - 1].name + "'", unselectable:true, color:this._disabledColor};
curChoices["03_CHANGE"] = {text:"Change third ship to '" + this._shipList[this._shipList.length - 1].name + "'", unselectable:true, color:this._disabledColor};
}
} else {
for (var i = 0; i < this._selectedList.length; i++) {
for (var j = 0; j < this._shipList.length; j++) {
if (this._shipList[j].key === this._selectedList[i]) {
if (this._direction === 1) {
if (j < this._shipList.length - 1) {
curChoices["0" + (i + 1) + "_CHANGE"] = {text:"Change " + this.$numberWord(i + 1) + " ship to '" + this._shipList[j + 1].name + "'", color:this._menuColor};
} else {
curChoices["0" + (i + 1) + "_CHANGE"] = {text:"Change " + this.$numberWord(i + 1) + " ship to '" + this._shipList[0].name + "'", color:this._menuColor};
}
} else {
if (j > 0) {
curChoices["0" + (i + 1) + "_CHANGE"] = {text:"Change " + this.$numberWord(i + 1) + " ship to '" + this._shipList[j - 1].name + "'", color:this._menuColor};
} else {
curChoices["0" + (i + 1) + "_CHANGE"] = {text:"Change " + this.$numberWord(i + 1) + " ship to '" + this._shipList[this._shipList.length - 1].name + "'", color:this._menuColor};
}
}
}
}
}
if (this._selectedList.length === 1) {
if (this._direction === 1) {
curChoices["02_CHANGE"] = {text:"Change second ship to '" + this._shipList[0].name + "'", color:this._menuColor};
curChoices["03_CHANGE"] = {text:"Change third ship to '" + this._shipList[0].name + "'", unselectable:true, color:this._disabledColor};
} else {
curChoices["02_CHANGE"] = {text:"Change second ship to '" + this._shipList[this._shipList.length - 1].name + "'", color:this._menuColor};
curChoices["03_CHANGE"] = {text:"Change third ship to '" + this._shipList[this._shipList.length - 1].name + "'", unselectable:true, color:this._disabledColor};
}
}
if (this._selectedList.length === 2) {
if (this._direction === 1) {
curChoices["03_CHANGE"] = {text:"Change third ship to '" + this._shipList[0].name + "'", color:this._menuColor};
} else {
curChoices["03_CHANGE"] = {text:"Change third ship to '" + this._shipList[this._shipList.length - 1].name + "'", color:this._menuColor};
}
}
}
curChoices["04_CURRENT"] = {text:"Set first ship to current ship", color:this._menuColor};
if (this._limitList == false) {
curChoices["04A_LIMIT"] = {text:"Only include ships in current shipyard", color:this._menuColor};
} else {
curChoices["04B_LIMIT"] = {text:"Include all ships", color:this._menuColor};
}
curChoices["05_DIRECTION"] = {text:(this._direction === 1 ? "Change scroll direction to ascending" : "Change scroll direction to descending"), color:this._menuColor};
curChoices["06_SHIPSTATS"] = {text:"View general ship statistics", color:this._itemColor};
curChoices["99_EXIT"] = {text:"Return", color:this._itemColor};
var def = "99_EXIT";
var opts = {
screenID: "oolite-ship-compare-map",
title: "Ship Comparison",
allowInterrupt: true,
exitScreen: this._exitScreen,
overlay: {name:"compare-balance.png", height:546},
choices: curChoices,
initialChoicesKey: (this._lastChoice ? this._lastChoice : def),
message: text
};
mission.runScreen(opts, this.$screenHandlerEq, this);
}
//-------------------------------------------------------------------------------------------------------------
this.$screenHandler = function(choice) {
if (!choice) return;
this._lastChoice = choice;
switch (choice) {
case "01_CHANGE":
this.$getNewItem(0);
break;
case "02_CHANGE":
this.$getNewItem(1);
break;
case "03_CHANGE":
this.$getNewItem(2);
break;
case "04_CURRENT":
var idx = this.$findCurrentShip();
if (idx >= 0) {
this._selectedList[0] = this._shipList[idx].key;
}
break;
case "04A_LIMIT":
this._limitList = true;
this._selectedList.length = 0;
if (this._exitScreen == "GUI_SCREEN_INTERFACES") {
this.$openComparison();
} else {
this.$directOpen();
}
return;
case "04B_LIMIT":
this._limitList = false;
this._selectedList.length = 0;
if (this._exitScreen == "GUI_SCREEN_INTERFACES") {
this.$openComparison();
} else {
this.$directOpen();
}
return;
case "06_EQUIPMENT":
this._lastChoice = "06_SHIPSTATS";
this.$showComparisonEquipment();
return;
case "05_DIRECTION":
if (this._direction === 1) {
this._direction = -1;
} else {
this._direction = 1;
}
break;
}
if (choice != "99_EXIT") this.$showComparison();
}
//-------------------------------------------------------------------------------------------------------------
this.$screenHandlerEq = function(choice) {
if (!choice) return;
this._lastChoice = choice;
switch (choice) {
case "01_CHANGE":
this.$getNewItem(0);
break;
case "02_CHANGE":
this.$getNewItem(1);
break;
case "03_CHANGE":
this.$getNewItem(2);
break;
case "04_CURRENT":
var idx = this.$findCurrentShip();
if (idx >= 0) {
this._selectedList[0] = this._shipList[idx].key;
}
break;
case "04A_LIMIT":
this._limitList = true;
this._selectedList.length = 0;
this._switch = true;
if (this._exitScreen == "GUI_SCREEN_INTERFACES") {
this.$openComparison();
} else {
this.$directOpen();
}
return;
case "04B_LIMIT":
this._limitList = false;
this._selectedList.length = 0;
this._switch = true;
if (this._exitScreen == "GUI_SCREEN_INTERFACES") {
this.$openComparison();
} else {
this.$directOpen();
}
return;
case "06_SHIPSTATS":
this._lastChoice = "06_EQUIPMENT";
this.$showComparison();
return;
case "05_DIRECTION":
if (this._direction === 1) {
this._direction = -1;
} else {
this._direction = 1;
}
break;
}
if (choice != "99_EXIT") this.$showComparisonEquipment();
}
//-------------------------------------------------------------------------------------------------------------
this.$getNewItem = function(idx) {
var cur = "";
if (this._selectedList.length >= (idx + 1)) {
cur = this._selectedList[idx];
}
if (cur === "") {
this._selectedList.push(this._shipList[0].key);
} else {
for (var i = 0; i < this._shipList.length; i++) {
if (this._shipList[i].key === cur) {
if (this._direction === 1) {
if (i === this._shipList.length - 1) {
this._selectedList[idx] = this._shipList[0].key;
} else {
this._selectedList[idx] = this._shipList[i + 1].key;
}
} else {
if (i === 0) {
this._selectedList[idx] = this._shipList[this._shipList.length - 1].key;
} else {
this._selectedList[idx] = this._shipList[i - 1].key;
}
}
break;
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.$findCurrentShip = function() {
var p = player.ship;
for (var i = 0; i < this._shipList.length; i++) {
if (this._shipList[i].name == p.shipClassName) return i;
}
return -1;
}
//-------------------------------------------------------------------------------------------------------------
this.$buildShipList = function() {
var truevalues = this._trueValues;
var keys = Ship.keysForRole("player");
this._shipList.length = 0;
if (this._limitList) {
var stn = player.ship.dockedStation;
// get all ships in the shipyard
var numShips = stn.shipyard.length;
for (var i = 0; i < numShips; i++) {
var shp = stn.shipyard[i];
this.$addItemToArray(shp.ship.name, shp.shipdata_key);
}
// make sure the player ship is added, though
this.$addItemToArray(player.ship.shipClassName, player.ship.dataKey);
} else {
for (var i = 0; i < keys.length; i++) {
var shp = Ship.shipDataForKey(keys[i]);
// only add records that have a corresponding shipyard entry
if (shp._oo_shipyard) {
if (!shp.script_info || !shp.script_info["sc_ignore"] || truevalues.indexOf(shp.script_info["sc_ignore"]) === -1)
this.$addItemToArray(shp.name, keys[i]);
}
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.$addItemToArray = function(shipName, shipKey) {
var ovr = this._override[shipKey];
if (ovr) shipName = ovr;
for (var i = 0; i < this._shipList.length; i++) {
if (this._shipList[i].name === shipName) return;
}
this._shipList.push({name:shipName, key:shipKey});
}
//-------------------------------------------------------------------------------------------------------------
this.$numberWord = function(nbr) {
switch (nbr) {
case 1: return "First";
case 2: return "Second";
case 3: return "Third";
case 4: return "Fourth"; // in case we ever add a fourth column!
}
}
//-------------------------------------------------------------------------------------------------------------
// appends space to currentText to the specified length in 'em'
this.$padTextRight = function(currentText, desiredLength, leftSwitch) {
if (currentText === null) currentText = "";
var hairSpace = String.fromCharCode(31);
var ellip = "…";
var currentLength = defaultFont.measureString(currentText);
var hairSpaceLength = defaultFont.measureString(hairSpace);
// calculate number needed to fill remaining length
var padsNeeded = Math.floor((desiredLength - currentLength) / hairSpaceLength);
if (padsNeeded < 1) {
// text is too long for column, so start pulling characters off
var tmp = currentText;
do {
tmp = tmp.substring(0, tmp.length - 2) + ellip;
if (tmp === ellip) break;
} while (defaultFont.measureString(tmp) > desiredLength);
currentLength = defaultFont.measureString(tmp);
padsNeeded = Math.floor((desiredLength - currentLength) / hairSpaceLength);
currentText = tmp;
}
// quick way of generating a repeated string of that number
if (!leftSwitch || leftSwitch === false) {
return currentText + new Array(padsNeeded).join(hairSpace);
} else {
return new Array(padsNeeded).join(hairSpace) + currentText;
}
}
//-------------------------------------------------------------------------------------------------------------
// appends space to currentText to the specified length in 'em'
this.$padTextLeft = function(currentText, desiredLength) {
return this.$padTextRight(currentText, desiredLength, true);
}
//-------------------------------------------------------------------------------------------------------------
this.$shipDefHasOption = function(def, eqKey) {
var found = "N/A";
if (!def._oo_shipyard) return "Data error";
if (def._oo_shipyard.standard_equipment.extras && def._oo_shipyard.standard_equipment.extras.indexOf(eqKey) >= 0) found = "Standard";
if (found === "N/A" && def._oo_shipyard.optional_equipment && def._oo_shipyard.optional_equipment.indexOf(eqKey) >= 0) found = "Optional";
return found;
}
//-------------------------------------------------------------------------------------------------------------
this.$forwardWeaponType = function(def) {
var found = "None";
if (!def._oo_shipyard) return "Data error";
if (def._oo_shipyard.standard_equipment.forward_weapon_type && def._oo_shipyard.standard_equipment.forward_weapon_type != "") {
var eq = EquipmentInfo.infoForKey(def._oo_shipyard.standard_equipment.forward_weapon_type);
if (eq) {
found = eq.name;
} else {
found = "Unknown";
}
}
return found;
}
//-------------------------------------------------------------------------------------------------------------
this.$cleanUpEquipSpace = function $cleanUpEquipSpace() {
var newData = [];
for (var i = 0; i < this._equipSpace.length; i++) {
var found = false;
for (var j = 0; j < newData.length; j++) {
if (newData[j].shipType == this._equipSpace[i].shipType) {
found = true;
break;
}
}
if (found === false) {
newData.push(JSON.parse(JSON.stringify(this._equipSpace[i])));
}
}
this._equipSpace.length = 0;
this._equipSpace = newData;
}
//-------------------------------------------------------------------------------------------------------------
// external routine to return the mass for a ship key
// we'll create a temporary ship object and use that to get the details
this.$getMassFromShipKey = function $getMassFromShipKey(shipKey) {
var result = 0;
// find a spot well away from any possible objects
if (system.sun) {
var temppos = system.sun.position.cross(system.mainPlanet.position).direction().multiply(4E9).subtract(system.mainPlanet.position);
} else {
var temppos = Vector3D(0, 0, 0);
}
// add a ship with the particular key
var tempship = system.addShips("[" + shipKey + "]", 1, temppos, 0);
if (tempship != null) {
// force this ship to be "dead" in space - we don't want it to do anything disruptive!
tempship[0].switchAI("oolite-nullAI.js");
result = this.$getShipMass(tempship[0]);
// clean up our temp ship
tempship[0].remove(true);
} else {
// this could happen if the ship is not allowed to be spawned in this system due to constraints in the shipdata.plist file for the ship
result = 0;
}
return result;
}
//-------------------------------------------------------------------------------------------------------------
// returns the ships mass, either from the exception list, or from the ship itself
this.$getShipMass = function $getShipMass(ship) {
var mass = this._shipMassExceptions[ship.shipClassName];
if (!mass) mass = ship.mass;
return mass;
}
//-------------------------------------------------------------------------------------------------------------
// returns true if a HUD with allowBigGUI is enabled, otherwise false
this.$isBigGuiActive = function $isBigGuiActive() {
if (oolite.compareVersion("1.83") <= 0) {
return player.ship.hudAllowsBigGui;
} else {
var bigGuiHUD = ["XenonHUD.plist", "coluber_hud_ch01-dock.plist"]; // until there is a property we can check, I'll be listing HUD's that have the allow_big_gui property set here
if (bigGuiHUD.indexOf(player.ship.hud) >= 0) {
return true;
} else {
return false;
}
}
}
|