Scripts/shiprespray.js |
"use strict";
this.name = "ShipRespray";
this.author = "phkb";
this.copyright = "2015 phkb";
this.description = "Allows user to select a respray of their ship using one of the installed OXP ship styles";
this.license = "CC BY-NC-SA 4.0";
this._data = []; // storage array of ship data keys
this._selectedItem = ""; // currently selected item from the main list
this._selectedIndex = 0; // index of the currently selected item
this._personality = 0; // current entityPersonality setting
this._displayType = 0; // respray gui display mode 0 = main list, 1 = selected item
this._lastchoice = null; // last item chosen from the list
this._curpage = 0; // current page being shown
this._pagesize = 16; // max number of entries on a page
this._lastsubchoice = ""; // last item chosen from the selected item display
this._showDetails = false; // when on, displays the datakey on the list and on the selected item page
this._baseTime = 48; // base time, using cobra mk3 as a reference
this._preCalls = [];
this._postCalls = [];
this._spinning = true;
//-------------------------------------------------------------------------------------------------------------
this.$addPreSprayCall = function (ws, fn) {
this._preCalls.push({ worldScript: ws, functionName: fn });
}
//-------------------------------------------------------------------------------------------------------------
this.$addPostSprayCall = function (ws, fn) {
this._postCalls.push({ worldScript: ws, functionName: fn });
}
//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function () {
this.$compileData();
// pick a random personality to start with
this._personality = this.$rand(32768) - 1;
}
//-------------------------------------------------------------------------------------------------------------
this.playerBoughtEquipment = function (equipment) {
var respray = false;
if (equipment === "EQ_SHIP_RESPRAY") {
player.ship.removeEquipment("EQ_SHIP_RESPRAY");
// for 1.82 and later, refund the credits at this point - if the player buys the respray it will be deducted later
player.credits += 100;
respray = true;
}
if (equipment === "EQ_SHIP_RESPRAY_180") {
player.ship.removeEquipment("EQ_SHIP_RESPRAY_180");
// for 1.80, the cost is already zero.
respray = true;
}
if (respray === true) {
// reset the menu before displaying
this._spinning = true;
this._displayType = 0;
this._curpage = 0;
this._selectedItem = "";
this._selectedIndex = 0;
this._lastchoice = null;
this._lastsubchoice = null;
this.$showPage();
}
}
//-------------------------------------------------------------------------------------------------------------
// get a list of all datakeys available for the players current ship class type (ie. "Cobra Mark III")
this.$compileData = function () {
this._data = [];
// get a list of all ship keys that have a role of "player" (ie. these are playable ships, not NPC ships)
var shipKeys = Ship.keysForRole("player");
// get the shipdata for the player ship, so we can compare like to like.
var psdata = Ship.shipDataForKey(player.ship.dataKey);
// loop through the list
for (var i = 0; i < shipKeys.length; i++) {
// get the shipdata entry for this key
var shipdata = Ship.shipDataForKey(shipKeys[i]);
// does it match the player's current ship?
if (shipdata.name == psdata.name && !this.$shipScriptInfoHasResprayOff(shipdata)) {
// add it to the array if it's not there already
if (this.$itemIsInArray(shipKeys[i], this._data) === false) {
this._data.push(shipKeys[i]);
}
}
}
// sort the array (basic alpha sort)
this._data.sort();
}
this.$shipScriptInfoHasResprayOff = function (shipdata) {
if (!shipdata.hasOwnProperty("scriptInfo")) return false;
if (!shipdata.scriptInfo.hasOwnProperty("respray")) return false;
if (!shipdata.scriptInfo.respray) return false;
return true;
}
//-------------------------------------------------------------------------------------------------------------
this.playerBoughtNewShip = function (ship, price) {
// recompile the list whenever the player buys a new ship
this.$compileData();
}
//=============================================================================================================
// screen interfaces
//-------------------------------------------------------------------------------------------------------------
this.$showPage = function () {
var curChoices = {};
if (this.$isBigGuiActive() === true) {
this._pagesize = 22;
} else {
this._pagesize = 16;
}
if (this._displayType === 0) {
var min = (this._curpage * this._pagesize);
var max = this._curpage * this._pagesize + this._pagesize;
if (max >= this._data.length) max = this._data.length;
for (var i = min; i < max; i++) {
curChoices["01_ITEM_" + (i < 10 ? "0" : "") + i + "~" + this._data[i]] = {
text: player.ship.shipClassName + " respray style " + (i + 1).toString() +
(this._showDetails === true ? " (" + this._data[i] + ")" : ""), color: "orangeColor", alignment: "LEFT"
};
}
if (max - min < this._pagesize) {
for (var i = (this._pagesize - (max - min)); i > 0; i--) {
curChoices["02_SPACER_" + (i < 10 ? "0" : "") + i] = "";
}
}
if (this._showDetails === true) {
curChoices["94_HIDEKEYS"] = { text: expandDescription("[respray_hide_keys]") };
} else {
curChoices["95_SHOWKEYS"] = { text: expandDescription("[respray_show_keys]") };
}
if (this._curpage > 0) {
curChoices["96_PREV"] = { text: expandDescription("[respray_prev_page]"), color: "yellowColor" };
} else {
curChoices["96_PREV"] = { text: expandDescription("[respray_prev_page]"), color: "darkGrayColor", unselectable: true };
}
if (this._data.length > this._pagesize && this._curpage < (Math.ceil(this._data.length / this._pagesize) - 1)) {
curChoices["97_NEXT"] = { text: expandDescription("[respray_next_page]"), color: "yellowColor" };
} else {
curChoices["97_NEXT"] = { text: expandDescription("[respray_next_page]"), color: "darkGrayColor", unselectable: true };
}
curChoices["99_EXIT"] = { text: expandDescription("[respray_exit]"), color: "yellowColor" };
var def = "99_EXIT";
var opts = {
screenID: "oolite-shiprespray-main-map",
title: expandDescription("[respray_screen_title]", { class: player.ship.shipClassName }),
allowInterrupt: true,
overlay: { name: "sr-paint.png", height: 546 },
exitScreen: "GUI_SCREEN_EQUIP_SHIP",
choices: curChoices,
initialChoicesKey: this._lastchoice ? this._lastchoice : def,
message: expandDescription("[respray_select]")
};
}
if (this._displayType === 1) {
var calc = Math.floor((player.ship.mass / 214737.6875) * this._baseTime);
if (calc < 24) calc = 24;
if (worldScripts.HomeSystem && worldScripts.HomeSystem.$isHomeSystem(system.ID) === true) {
calc /= 2;
}
var def = "98_CLOSE";
curChoices["02_SELECT"] = { text: expandDescription("[respray_purchase]", { time: calc.toFixed(1) }), color: "yellowColor" };
curChoices["03_PERSONALITY"] = { text: expandDescription("[respray_personality]", { personality: this._personality }), color: "yellowColor" };
if (this._spinning === true) {
curChoices["04_STOP_SPIN"] = { text: expandDescription("[respray_stop_spin]"), color: "yellowColor" };
} else {
curChoices["05_START_SPIN"] = { text: expandDescription("[respray_start_spin]"), color: "yellowColor" };
}
curChoices["98_CLOSE"] = { text: expandDescription("[respray_close]"), color: "yellowColor" };
var opts = {
screenID: "oolite-shiprespray-item-map",
title: expandDescription("[respray_screen_title]", { class: player.ship.shipClassName }),
model: "[" + this._selectedItem + "]",
spinModel: this._spinning,
modelPersonality: this._personality,
exitScreen: "GUI_SCREEN_EQUIP_SHIP",
allowInterrupt: true,
choices: curChoices,
initialChoicesKey: this._lastsubchoice ? this._lastsubchoice : def,
message: expandDescription("[respray_style]", { class: player.ship.shipClassName, style: (this._selectedIndex + 1).toString() + (this._showDetails === true ? " (" + this._selectedItem + ")" : "") })
};
}
mission.runScreen(opts, this.$selectScreenHandler, this);
}
//-------------------------------------------------------------------------------------------------------------
this.$selectScreenHandler = function (choice) {
if (choice == null) return;
if (choice.indexOf("~") >= 0) {
this._displayType = 1;
this._selectedItem = choice.substring(choice.indexOf("~") + 1);
this._selectedIndex = parseInt(choice.substring(8, 10));
this._lastchoice = choice;
this._lastsubchoice = null;
} else if (choice === "02_SELECT") {
// need code to recreate player ship, transferring all cargo and equipment
this.$resprayShip(this._selectedItem, this._personality);
choice = "99_EXIT";
} else if (choice === "04_STOP_SPIN") {
this._spinning = false;
} else if (choice === "05_START_SPIN") {
this._spinning = true;
} else if (choice === "03_PERSONALITY") {
this._personality = this.$rand(32768) - 1;
this._lastsubchoice = "03_PERSONALITY";
} else if (choice === "94_HIDEKEYS") {
this._showDetails = false;
this._lastchoice = "95_SHOWKEYS";
} else if (choice === "95_SHOWKEYS") {
this._showDetails = true;
this._lastchoice = "94_HIDEKEYS";
} else if (choice === "96_PREV") {
this._curpage -= 1;
if (this._curpage > 0) {
this._lastchoice = choice;
} else {
this._lastchoice = "97_NEXT";
}
} else if (choice === "97_NEXT") {
this._curpage += 1;
if (this._curpage < (Math.ceil(this._data.length / this._pagesize) - 1)) {
this._lastchoice = choice;
} else {
this._lastchoice = "96_PREV";
}
} else if (choice === "98_CLOSE") {
this._displayType = 0;
}
if (choice != "99_EXIT") {
this.$showPage();
}
}
//-------------------------------------------------------------------------------------------------------------
// do the respray, using ShipStorageHelper
this.$resprayShip = function (dataKey, personality) {
var p = player.ship;
var playershipname = p.shipUniqueName;
var hud = p.hud;
if (this._preCalls.length > 0) {
for (var i = 0; i < this._preCalls.length; i++) {
var itm = this._preCalls[i];
worldScripts[itm.worldScript][itm.functionName]();
}
}
// first, store all equipment and cargo the player might have
var shipstr = worldScripts["Ship_Storage_Helper.js"].storeCurrentShip();
// change the datakey to the new one
var data = JSON.parse(shipstr);
data[1] = dataKey; // apply the data key to the ship
data[13] = personality; // apply the selected personality to the ship
shipstr = JSON.stringify(data);
var lmss = worldScripts.LMSS_Core;
if (lmss) lmss._switching = true;
// store the current list of player roles
var roles = [];
for (var i = 0; i < p.roleWeights.length; i++) {
roles.push(p.roleWeights[i]);
}
// restore the players ship
worldScripts["Ship_Storage_Helper.js"].restoreStoredShip(shipstr);
// restore the previous list of roles
for (var i = 0; i < p.roleWeights.length; i++) {
if (roles.length - 1 >= i) p.setPlayerRole(roles[i], i);
}
if (lmss) lmss._switching = false;
// restore some things that the storage helper doesn't replace
p.shipUniqueName = playershipname;
p.hud = hud;
// charge the player
player.credits -= 100;
if (this._postCalls.length > 0) {
for (var i = 0; i < this._postCalls.length; i++) {
var itm = this._postCalls[i];
worldScripts[itm.worldScript][itm.functionName]();
}
}
// send an email if the email system is installed
var w = worldScripts.EmailSystem;
if (w) {
var ga = worldScripts.GalCopAdminServices;
w.$createEmail({
sender: expandDescription("[purchase-maintenance-sender]"),
subject: expandDescription("[respray_screen_title]", { class: p.shipClassName }),
date: global.clock.seconds,
message: expandDescription("[respray_email]", { class: p.shipClassName }),
expiryDays: ga._defaultExpiryDays
}
);
}
// work out how much install time is required
// using cobra mass as the benchmark
var install = Math.floor((p.mass / 214737.6875) * this._baseTime);
if (install < 24) install = 24;
// only half the time if this is our home system
if (worldScripts.HomeSystem && worldScripts.HomeSystem.$isHomeSystem(system.ID) === true) {
install /= 2;
}
install = parseInt(install * 60 * 60);
mission.runScreen({
screenID: "oolite-shiprespray-complete-map",
title: expandDescription("[respray_screen_title]", { class: player.ship.shipClassName }),
model: "[" + dataKey + "]",
modelPersonality: personality,
allowInterrupt: true,
message: expandDescription("[respray_success]"),
exitScreen: "GUI_SCREEN_EQUIP_SHIP",
});
global.clock.addSeconds(install);
// if the station dock control is installed, tell it to check for launched ships
if (worldScripts.StationDockControl) {
var w = worldScripts.StationDockControl;
if (w._disable === false) {
w.$checkForLaunchedShips();
}
}
this._displayType = 0;
this._lastchoice = null;
}
//=============================================================================================================
// helper functions
//-------------------------------------------------------------------------------------------------------------
// return a random number between 1 and max
this.$rand = function (max) {
return Math.floor((Math.random() * max) + 1)
}
//-------------------------------------------------------------------------------------------------------------
// checks if a given element is in the array
this.$itemIsInArray = function (element, array) {
var found = false;
if (array != null && array.length > 0) {
for (var i = 0; i < array.length; i++) {
if (array[i] === element) found = true;
}
}
return found;
}
//-------------------------------------------------------------------------------------------------------------
// returns true if a HUD with allowBigGUI is enabled, otherwise false
this.$isBigGuiActive = function () {
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;
}
}
}
|