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 = expandDescription("[shipcomp_hidden_ships]").split("|");
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: expandDescription("[shipcomp_config_alias]"),
Display: expandDescription("[shipcomp_config_display]"),
Alive: "_compConfig",
Notify: "$onChange",
Bool: {
B0: { Name: "_resetData", Def: false, Desc: expandDescription("[shipcomp_reset_data]") },
B1: { Name: "_clearShips", Def: false, Desc: expandDescription("[shipcomp_clear_selections]") },
Info: expandDescription("[shipcomp_config_bool_info]")
}
};
// 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(expandDescription("[shipcomp_reset]"));
}
if (this._clearShips === true) {
this._selectedList = [];
this._clearShips = false;
player.consoleMessage(expandDescription("[shipcomp_clear]"));
}
}
//-------------------------------------------------------------------------------------------------------------
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", expandDescription("[shipcomp_help_keys]"));
}
}
}
//-------------------------------------------------------------------------------------------------------------
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: expandDescription("[shipcomp_interface_title]"),
category: expandDescription("[interfaces-category-ship-systems]"),
summary: expandDescription("[shipcomp_interface_summary]"),
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 = expandDescription("[shipcomp_properties]").split("|");
var outList = [];
for (var i = 0; i < textList.length; i++) outList.push("");
// select ships to be in comparison (up to 4)
text = expandDescription("[shipcomp_select]") + ":\n";
if (this._shipConfig) {
textList.push(expandDescription("[shipcomp_item_equipspace]"));
outList.push("");
sc = worldScripts.ShipConfiguration_Core;
} else {
text += "\n";
}
var na = expandDescription("[shipcomp_na]")
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 expandDescription("[shipcomp_item_shiptype]"):
outList[ol] += this.$padTextRight(shipName, colShip);
break;
case expandDescription("[shipcomp_item_price]"):
if (shipDef._oo_shipyard) {
outList[ol] += this.$padTextRight(formatCredits(parseInt(shipDef._oo_shipyard.price), false, true), colShip);
} else {
log(this.name, expandDescription("[shipcomp_shipyard_error]", { name: shipName, key: keyList[i] }));
}
break;
case expandDescription("[shipcomp_item_speed]"):
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight(na, colShip);
} else {
outList[ol] += this.$padTextRight((parseFloat(shipDef["max_flight_speed"]) / 1000).toFixed(3) + " " + expandDescription("[shipcomp_ls]"), colShip);
}
break;
case expandDescription("[shipcomp_item_thrust]"):
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight(na, colShip);
} else {
outList[ol] += this.$padTextRight((parseFloat(shipDef["thrust"]) / 1000).toFixed(3) + " " + expandDescription("[shipcomp_ls]"), colShip);
}
break;
case expandDescription("[shipcomp_item_injectorspeed]"):
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight(na, 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) + " " + expandDescription("[shipcomp_ls]"), colShip);
}
break;
case expandDescription("[shipcomp_item_pitchrollyaw]"):
if (this._hideListAll.indexOf(shipName) >= 0 || this._hideListBasic.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight(na, 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 expandDescription("[shipcomp_item_weaponfacings]"):
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight(na, 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 = expandDescription("[shipcomp_forward]");
if (facings === "15") {
wpn = expandDescription("[shipcomp_all]");
} else {
if (" 3 7 11 ".indexOf(" " + facings + " ") >= 0) wpn += ", " + expandDescription("[shipcomp_aft]");
if (" 5 7 13 ".indexOf(" " + facings + " ") >= 0) wpn += ", " + expandDescription("[shipcomp_port]");
if (" 9 11 13 ".indexOf(" " + facings + " ") >= 0) wpn += ", " + expandDescription("[shipcomp_starboard]");
}
if (facings === "0") wpn = expandDescription("[shipcomp_none]");
if (facings === na) wpn = na;
outList[ol] += this.$padTextRight(wpn, colShip);
}
break;
case expandDescription("[shipcomp_item_turrets]"):
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight(na, colShip);
} else {
var turrets = 0;
var sub = shipDef["subentities"];
if (sub && sub.length > 0) {
for (var j = 0; j < sub.length; j++) {
if (sub[j].type == "ball_turret") turrets += 1;
}
}
if (turrets > 0) {
outList[ol] += this.$padTextRight(turrets, colShip);
} else {
outList[ol] += this.$padTextRight("", colShip);
}
}
break;
case expandDescription("[shipcomp_item_maxmissiles]"):
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight(na, 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 expandDescription("[shipcomp_item_maxcargo]"):
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight(na, 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 expandDescription("[shipcomp_item_maxenergy]"):
if (this._hideListAll.indexOf(shipName) >= 0 || this._hideListBasic.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight(na, 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 expandDescription("[shipcomp_item_rechargerate]"):
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight(na, 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 expandDescription("[shipcomp_item_hyperspace]"):
var hyper = expandDescription("[shipcomp_yes]");
if (shipDef["hyperspace_motor"] != undefined && (shipDef["hyperspace_motor"] === "no" || shipDef["hyperspace_motor"] === "false" || shipDef["hyperspace_motor"] === "0")) hyper = expandDescription("[shipcomp_no]");
outList[ol] += this.$padTextRight(hyper, colShip);
break;
case expandDescription("[shipcomp_item_equipspace]"):
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight(na, 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 != na && 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]);
outList[ol] += this.$padTextRight(es.equipSpace + (es.cargoSpace != na && 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 : na) });
}
}
break;
case expandDescription("[shipcomp_item_mass]"):
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight(na, 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
if (mass && mass > 0) this._mass[shipName] = mass;
}
if (!mass || mass == 0) {
outList[ol] += this.$padTextRight(na, colShip);
} else {
outList[ol] += this.$padTextRight(mass.toFixed(0), colShip);
}
} else {
var idx = -1
var found = false;
// 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("shipMass") && this._equipSpace[j].shipMass != "N/A") {
outList[ol] += this.$padTextRight(this._equipSpace[j].shipMass.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(na, 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.mass != "N/A" || idx === -1) {
this._equipSpace.push({ shipType: shipName, equipSpace: es.equipSpace, cargoSpace: es.cargoSpace, shipMass: (es.hasOwnProperty("mass") ? es.mass : na) });
} else {
this._equipSpace[idx].shipMass = 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: expandDescription("[shipcomp_change_ship]", { number: this.$numberWord(1), ship: this._shipList[0].name }), color: this._menuColor };
curChoices["02_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", { number: this.$numberWord(2), ship: this._shipList[0].name }), unselectable: true, color: this._disabledColor };
curChoices["03_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", { number: this.$numberWord(3), ship: this._shipList[0].name }), unselectable: true, color: this._disabledColor };
} else {
curChoices["01_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", { number: this.$numberWord(1), ship: this._shipList[this._shipList.length - 1].name }), color: this._menuColor };
curChoices["02_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", { number: this.$numberWord(2), ship: this._shipList[this._shipList.length - 1].name }), unselectable: true, color: this._disabledColor };
curChoices["03_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", { number: this.$numberWord(3), ship: 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: expandDescription("[shipcomp_change_ship]", { number: this.$numberWord(i + 1), ship: this._shipList[j + 1].name }), color: this._menuColor };
} else {
curChoices["0" + (i + 1) + "_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", { number: this.$numberWord(i + 1), ship: this._shipList[0].name }), color: this._menuColor };
}
} else {
if (j > 0) {
curChoices["0" + (i + 1) + "_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", { number: this.$numberWord(i + 1), ship: this._shipList[j - 1].name }), color: this._menuColor };
} else {
curChoices["0" + (i + 1) + "_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", { number: this.$numberWord(i + 1), ship: this._shipList[this._shipList.length - 1].name }), color: this._menuColor };
}
}
}
}
}
if (this._selectedList.length === 1) {
if (this._direction === 1) {
curChoices["02_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", { number: this.$numberWord(2), ship: this._shipList[0].name }), color: this._menuColor };
curChoices["03_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", { number: this.$numberWord(3), ship: this._shipList[0].name }), unselectable: true, color: this._disabledColor };
} else {
curChoices["02_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", { number: this.$numberWord(2), ship: this._shipList[this._shipList.length - 1].name }), color: this._menuColor };
curChoices["03_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", { number: this.$numberWord(3), ship: 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: expandDescription("[shipcomp_change_ship]", { number: this.$numberWord(3), ship: this._shipList[0].name }), color: this._menuColor };
} else {
curChoices["03_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", { number: this.$numberWord(3), ship: this._shipList[this._shipList.length - 1].name }), color: this._menuColor };
}
}
}
curChoices["04_CURRENT"] = { text: "[shipcomp_first_current]", color: this._menuColor };
if (this._limitList == false) {
curChoices["04A_LIMIT"] = { text: "[shipcomp_shipyard_only]", color: this._menuColor };
} else {
curChoices["04B_LIMIT"] = { text: "[shipcomp_all_ships]", color: this._menuColor };
}
curChoices["05_DIRECTION"] = { text: (this._direction === 1 ? "[shipcomp_direction_ascending]" : "[shipcomp_direction_descending]"), color: this._menuColor };
curChoices["06_EQUIPMENT"] = { text: "[shipcomp_view_equipment]", color: this._itemColor };
curChoices["99_EXIT"] = { text: "[shipcomp_return]", color: this._itemColor };
var def = "99_EXIT";
var opts = {
screenID: "oolite-ship-compare-map",
title: expandDescription("[shipcomp_config_alias]"),
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 = [];
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 = expandDescription("[shipcomp_equipment]").split("|");
var outList = [];
for (var i = 0; i < textList.length; i++) outList.push("");
// select ships to be in comparison (up to 4)
text = expandDescription("[shipcomp_select]") + ":\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 expandDescription("[shipcomp_item_shiptype]"):
outList[ol] += this.$padTextRight(shipName, colShip);
break;
case expandDescription("[shipcomp_item_tl]"):
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, expandDescription("[shipcomp_shipyard_error", { name: shipName, key: keyList[i] }));
}
}
break;
case expandDescription("[shipcomp_item_forwardweapon]"):
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("?", colShip);
} else {
outList[ol] += this.$padTextRight(this.$forwardWeaponType(shipDef), colShip);
}
break;
case expandDescription("[shipcomp_item_aftweapon]"):
if (this._hideListAll.indexOf(shipName) >= 0) {
outList[ol] += this.$padTextRight("?", colShip);
} else {
outList[ol] += this.$padTextRight(this.$aftWeaponType(shipDef), colShip);
}
break;
case expandDescription("[shipcomp_item_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 expandDescription("[shipcomp_item_fuelscoops]"):
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 expandDescription("[shipcomp_item_passengers]"):
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 expandDescription("[shipcomp_item_energyunit]"):
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 expandDescription("[shipcomp_item_navalunit]"):
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 expandDescription("[shipcomp_item_dockingcomp]"):
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 expandDescription("[shipcomp_item_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 expandDescription("[shipcomp_item_milbooster]"):
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 expandDescription("[shipcomp_item_galdrive]"):
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 expandDescription("[shipcomp_item_targetenh]"):
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 expandDescription("[shipcomp_item_multitarget]"):
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: expandDescription("[shipcomp_change_ship]", {number:this.$numberWord(1), ship:this._shipList[0].name}), color: this._menuColor };
curChoices["02_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", {number:this.$numberWord(2), ship:this._shipList[0].name}), unselectable: true, color: this._disabledColor };
curChoices["03_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", {number:this.$numberWord(3), ship:this._shipList[0].name}), unselectable: true, color: this._disabledColor };
} else {
curChoices["01_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", {number:this.$numberWord(1), ship:this._shipList[this._shipList.length - 1].name}), color: this._menuColor };
curChoices["02_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", {number:this.$numberWord(2), ship:this._shipList[this._shipList.length - 1].name}), unselectable: true, color: this._disabledColor };
curChoices["03_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", {number:this.$numberWord(3), ship: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: expandDescription("[shipcomp_change_ship]", {number:this.$numberWord(i + 1), ship:this._shipList[j + 1].name}), color: this._menuColor };
} else {
curChoices["0" + (i + 1) + "_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", {number:this.$numberWord(i + 1), ship: this._shipList[0].name}), color: this._menuColor };
}
} else {
if (j > 0) {
curChoices["0" + (i + 1) + "_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", {number:this.$numberWord(i + 1), ship:this._shipList[j - 1].name}), color: this._menuColor };
} else {
curChoices["0" + (i + 1) + "_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", {number:this.$numberWord(i + 1), ship:this._shipList[this._shipList.length - 1].name }), color: this._menuColor };
}
}
}
}
}
if (this._selectedList.length === 1) {
if (this._direction === 1) {
curChoices["02_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", {number:this.$numberWord(2), ship:this._shipList[0].name }), color: this._menuColor };
curChoices["03_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", {number:this.$numberWord(3), ship:this._shipList[0].name }), unselectable: true, color: this._disabledColor };
} else {
curChoices["02_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", {number:this.$numberWord(2), ship:this._shipList[this._shipList.length - 1].name }), color: this._menuColor };
curChoices["03_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", {number:this.$numberWord(3), ship: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: expandDescription("[shipcomp_change_ship]", {number:this.$numberWord(3), ship:this._shipList[0].name }), color: this._menuColor };
} else {
curChoices["03_CHANGE"] = { text: expandDescription("[shipcomp_change_ship]", {number:this.$numberWord(3), ship:this._shipList[this._shipList.length - 1].name }), color: this._menuColor };
}
}
}
curChoices["04_CURRENT"] = { text: "[shipcomp_first_current]", color: this._menuColor };
if (this._limitList == false) {
curChoices["04A_LIMIT"] = { text: "[shipcomp_shipyard_only]", color: this._menuColor };
} else {
curChoices["04B_LIMIT"] = { text: "[shipcomp_all_ships]", color: this._menuColor };
}
curChoices["05_DIRECTION"] = { text: (this._direction === 1 ? "[shipcomp_direction_ascending]" : "[shipcomp_direction_descending]"), color: this._menuColor };
curChoices["06_SHIPSTATS"] = { text: "[shipcomp_general_stats]", color: this._itemColor };
curChoices["99_EXIT"] = { text: "[shipcomp_return]", color: this._itemColor };
var def = "99_EXIT";
var opts = {
screenID: "oolite-ship-compare-map",
title: expandDescription("[shipcomp_config_alias]"),
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 expandDescription("[shipcomp_first]");
case 2: return expandDescription("[shipcomp_second]");
case 3: return expandDescription("[shipcomp_third]");
case 4: return expandDescription("[shipcomp_fourth]"); // in case we ever add a fourth column!
}
}
//-------------------------------------------------------------------------------------------------------------
// appends space to currentText to the specified length in 'em'
this.$padTextRight = function $padTextRight(currentText, desiredLength, leftSwitch) {
if (currentText == null) currentText = "";
currentText = currentText.toString();
var space = " ";
var hairSpace = String.fromCharCode(31);
var ellip = "…";
var currentLength = defaultFont.measureString(currentText.replace(/%%/g, "%"));
var hairSpaceLength = defaultFont.measureString(hairSpace);
var spaceLength = defaultFont.measureString(space);
// calculate number needed to fill remaining length
var spacesNeeded = parseInt(Math.floor((desiredLength - currentLength) / spaceLength));
if (spacesNeeded < 0) {
spacesNeeded = 0;
} else {
if (!leftSwitch || leftSwitch === false) {
currentText += new Array(spacesNeeded).join(space);
} else {
currentText = new Array(spacesNeeded).join(space) + currentText;
}
currentLength = defaultFont.measureString(currentText.replace(/%%/g, "%"));
}
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.replace(/%%/g, "%")) > desiredLength);
currentLength = defaultFont.measureString(tmp.replace(/%%/g, "%"));
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 = "";
if (!def._oo_shipyard) return expandDescription("[shipcomp_data_error]");
if (def._oo_shipyard.standard_equipment.extras && def._oo_shipyard.standard_equipment.extras.indexOf(eqKey) >= 0) found = expandDescription("[shipcomp_standard]");
if (found === "" && def._oo_shipyard.optional_equipment && def._oo_shipyard.optional_equipment.indexOf(eqKey) >= 0) found = expandDescription("[shipcomp_optional]");
return found;
}
//-------------------------------------------------------------------------------------------------------------
this.$forwardWeaponType = function (def) {
var found = expandDescription("[shipcomp_none]");
var facings = parseInt(def["weapon_facings"]);
if (facings == 0) return expandDescription("[shipcomp_na]");
if (!def._oo_shipyard) return expandDescription("[shipcomp_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 = expandDescription("[shipcomp_unknown]");
}
}
return found;
}
//-------------------------------------------------------------------------------------------------------------
this.$aftWeaponType = function (def) {
var found = expandDescription("[shipcomp_none]");
var facings = parseInt(def["weapon_facings"]);
if (facings == 0 || facings == 1) return expandDescription("[shipcomp_na]");
if (!def._oo_shipyard) return expandDescription("[shipcomp_data_error]");
if (def._oo_shipyard.standard_equipment.aft_weapon_type && def._oo_shipyard.standard_equipment.aft_weapon_type != "") {
var eq = EquipmentInfo.infoForKey(def._oo_shipyard.standard_equipment.forward_weapon_type);
if (eq) {
found = eq.name;
} else {
found = expandDescription("[shipcomp_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;
}
}
}
|